func (s *ShardMempool) GetTransactions(maxBytes int) (*primitives.TransactionPackage, uint64, error) {
	transactionsToInclude := make([]primitives.ShardTransaction, 0)
	s.mempoolLock.RLock()
	defer s.mempoolLock.RUnlock()

	totalBytes := 0

	_, tipState := s.GetTipState()

	startRootHash, err := tipState.Hash()
	if err != nil {
		return nil, 0, err
	}

	startSlot := s.stateManager.GetTipSlot()

	var startRoot [32]byte
	copy(startRoot[:], startRootHash[:])

	packageTreeCache, err := csmt.NewTreeMemoryCache(tipState)
	if err != nil {
		return nil, 0, err
	}

	updates := make([]primitives.UpdateWitness, 0)
	verifications := make([]primitives.VerificationWitness, 0)

	// we have two layers of transactions here. The first layer, we want to rollback if something outright fails. This
	// could happen when we can't access part of the state for one reason or another.
	// The second layer we want to rollback if a transaction doesn't fit into the current execution state. For example,
	// a previous transaction may invalidate the next transaction.
	for _, tx := range s.mempoolOrder {
		if totalBytes+len(tx.tx) > maxBytes && maxBytes != -1 {
			continue
		}

		transactionTreeCache, err := csmt.NewTreeMemoryCache(packageTreeCache)
		if err != nil {
			return nil, 0, err
		}
		tree := csmt.NewTree(transactionTreeCache)

		trackingTree, err := state.NewTrackingState(tree)
		if err != nil {
			return nil, 0, err
		}

		err = trackingTree.Update(func(treeTx csmt.TreeTransactionAccess) error {
			// try to transition
			_, err := state.Transition(treeTx, tx.tx, s.shardInfo)
			return err
		})
		if err != nil {
			continue
		}

		totalBytes += len(tx.tx)

		transactionsToInclude = append(transactionsToInclude, primitives.ShardTransaction{
			TransactionData: tx.tx,
		})

		err = transactionTreeCache.Flush()
		if err != nil {
			return nil, 0, err
		}

		_, txVerifications, txUpdates := trackingTree.GetWitnesses()

		updates = append(updates, txUpdates...)
		verifications = append(verifications, txVerifications...)
	}

	endHash := primitives.EmptyTree

	err = packageTreeCache.View(func(tx csmt.TreeDatabaseTransaction) error {
		rootNode, err := tx.Root()
		if err != nil {
			return err
		}
		if rootNode != nil {
			endHash = rootNode.GetHash()
		}
		return nil
	})
	if err != nil {
		return nil, 0, err
	}

	txPackage := &primitives.TransactionPackage{
		StartRoot:     startRoot,
		EndRoot:       endHash,
		Updates:       updates,
		Verifications: verifications,
		Transactions:  transactionsToInclude,
	}

	return txPackage, startSlot, nil
}
// GetTransactions gets transactions to include.
GetTransactions gets transactions to include.
// GetTransactions gets transactions to include .
func (s *ShardMempool) GetTransactions(maxBytes int) (*primitives.TransactionPackage, uint64, error) {
	transactionsToInclude := make([]primitives.ShardTransaction, 0)
	s.mempoolLock.RLock()
	defer s.mempoolLock.RUnlock()
	totalBytes := 0
	_, tipState := s.GetTipState()
	startRootHash, err := tipState.Hash()
	if err != nil {
		return nil, 0, err
	}
	startSlot := s.stateManager.GetTipSlot()
	var startRoot [32]byte
	copy(startRoot[:], startRootHash[:])
	packageTreeCache, err := csmt.NewTreeMemoryCache(tipState)
	if err != nil {
		return nil, 0, err
	}
	updates := make([]primitives.UpdateWitness, 0)
	verifications := make([]primitives.VerificationWitness, 0)
	for _, tx := range s.mempoolOrder {
		if totalBytes+len(tx.tx) > maxBytes && maxBytes != -1 {
			continue
		}
		transactionTreeCache, err := csmt.NewTreeMemoryCache(packageTreeCache)
		if err != nil {
			return nil, 0, err
		}
		tree := csmt.NewTree(transactionTreeCache)
		trackingTree, err := state.NewTrackingState(tree)
		if err != nil {
			return nil, 0, err
		}
		err = trackingTree.Update(func(treeTx csmt.TreeTransactionAccess) error {
			_, err := state.Transition(treeTx, tx.tx, s.shardInfo)
			return err
		})
		if err != nil {
			continue
		}
		totalBytes += len(tx.tx)
		transactionsToInclude = append(transactionsToInclude, primitives.ShardTransaction{
			TransactionData: tx.tx,
		})
		err = transactionTreeCache.Flush()
		if err != nil {
			return nil, 0, err
		}
		_, txVerifications, txUpdates := trackingTree.GetWitnesses()
		updates = append(updates, txUpdates...)
		verifications = append(verifications, txVerifications...)
	}
	endHash := primitives.EmptyTree
	err = packageTreeCache.View(func(tx csmt.TreeDatabaseTransaction) error {
		rootNode, err := tx.Root()
		if err != nil {
			return err
		}
		if rootNode != nil {
			endHash = rootNode.GetHash()
		}
		return nil
	})
	if err != nil {
		return nil, 0, err
	}
	txPackage := &primitives.TransactionPackage{
		StartRoot:     startRoot,
		EndRoot:       endHash,
		Updates:       updates,
		Verifications: verifications,
		Transactions:  transactionsToInclude,
	}
	return txPackage, startSlot, nil
}
func ( s * ShardMempool ) GetTransactions ( maxBytes int ) ( * primitives . TransactionPackage , uint64 , error ) { transactionsToInclude := make ( [ ] primitives . ShardTransaction , 0 ) s . mempoolLock . RLock ( ) defer s . mempoolLock . RUnlock ( ) totalBytes := 0 _ , tipState := s . GetTipState ( ) startRootHash , err := tipState . Hash ( ) if err != nil { return nil , 0 , err } startSlot := s . stateManager . GetTipSlot ( ) var startRoot [ 32 ] byte copy ( startRoot [ : ] , startRootHash [ : ] ) packageTreeCache , err := csmt . NewTreeMemoryCache ( tipState ) if err != nil { return nil , 0 , err } updates := make ( [ ] primitives . UpdateWitness , 0 ) verifications := make ( [ ] primitives . VerificationWitness , 0 ) for _ , tx := range s . mempoolOrder { if totalBytes + len ( tx . tx ) > maxBytes && maxBytes != - 1 { continue } transactionTreeCache , err := csmt . NewTreeMemoryCache ( packageTreeCache ) if err != nil { return nil , 0 , err } tree := csmt . NewTree ( transactionTreeCache ) trackingTree , err := state . NewTrackingState ( tree ) if err != nil { return nil , 0 , err } err = trackingTree . Update ( func ( treeTx csmt . TreeTransactionAccess ) error { _ , err := state . Transition ( treeTx , tx . tx , s . shardInfo ) return err } ) if err != nil { continue } totalBytes += len ( tx . tx ) transactionsToInclude = append ( transactionsToInclude , primitives . ShardTransaction { TransactionData : tx . tx , } ) err = transactionTreeCache . Flush ( ) if err != nil { return nil , 0 , err } _ , txVerifications , txUpdates := trackingTree . GetWitnesses ( ) updates = append ( updates , txUpdates ... ) verifications = append ( verifications , txVerifications ... ) } endHash := primitives . EmptyTree err = packageTreeCache . View ( func ( tx csmt . TreeDatabaseTransaction ) error { rootNode , err := tx . Root ( ) if err != nil { return err } if rootNode != nil { endHash = rootNode . GetHash ( ) } return nil } ) if err != nil { return nil , 0 , err } txPackage := & primitives . TransactionPackage { StartRoot : startRoot , EndRoot : endHash , Updates : updates , Verifications : verifications , Transactions : transactionsToInclude , } return txPackage , startSlot , nil }
GetTransactions gets transactions to include.
GetTransactions gets transactions to include .
// we have two layers of transactions here. The first layer, we want to rollback if something outright fails. This // could happen when we can't access part of the state for one reason or another. // The second layer we want to rollback if a transaction doesn't fit into the current execution state. For example, // a previous transaction may invalidate the next transaction. // try to transition