Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 47 additions & 6 deletions ledger/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,15 +383,15 @@ type ledgerForCowBase interface {
// payset being evaluated is known in advance, a paysetHint >= 0 can be
// passed, avoiding unnecessary payset slice growth.
func (l *Ledger) StartEvaluator(hdr bookkeeping.BlockHeader, paysetHint int) (*BlockEvaluator, error) {
return startEvaluator(l, hdr, paysetHint, true, true)
}

func startEvaluator(l ledgerForEvaluator, hdr bookkeeping.BlockHeader, paysetHint int, validate bool, generate bool) (*BlockEvaluator, error) {
proto, ok := config.Consensus[hdr.CurrentProtocol]
if !ok {
return nil, protocol.Error(hdr.CurrentProtocol)
}

return startEvaluator(l, hdr, proto, paysetHint, true, true)
}

func startEvaluator(l ledgerForEvaluator, hdr bookkeeping.BlockHeader, proto config.ConsensusParams, paysetHint int, validate bool, generate bool) (*BlockEvaluator, error) {
base := &roundCowBase{
l: l,
// round that lookups come from is previous block. We validate
Expand Down Expand Up @@ -432,6 +432,8 @@ func startEvaluator(l ledgerForEvaluator, hdr bookkeeping.BlockHeader, paysetHin

base.txnCount = eval.prevHeader.TxnCounter
base.compactCertNextRnd = eval.prevHeader.CompactCert[protocol.CompactCertBasic].CompactCertNextRound

var ok bool
prevProto, ok = config.Consensus[eval.prevHeader.CurrentProtocol]
if !ok {
return nil, protocol.Error(eval.prevHeader.CurrentProtocol)
Expand Down Expand Up @@ -1166,7 +1168,13 @@ func (validator *evalTxValidator) run() {
// AddBlock: eval(context.Background(), l, blk, false, txcache, nil, true)
// tracker: eval(context.Background(), l, blk, false, txcache, nil, false)
func eval(ctx context.Context, l ledgerForEvaluator, blk bookkeeping.Block, validate bool, txcache verify.VerifiedTransactionCache, executionPool execpool.BacklogPool) (ledgercore.StateDelta, error) {
eval, err := startEvaluator(l, blk.BlockHeader, len(blk.Payset), validate, false)
proto, ok := config.Consensus[blk.BlockHeader.CurrentProtocol]
if !ok {
return ledgercore.StateDelta{}, protocol.Error(blk.BlockHeader.CurrentProtocol)
}

eval, err := startEvaluator(
l, blk.BlockHeader, proto, len(blk.Payset), validate, false)
if err != nil {
return ledgercore.StateDelta{}, err
}
Expand Down Expand Up @@ -1240,7 +1248,7 @@ transactionGroupLoop:
}
}

// Finally, proceeds any pending end-of-block state changes
// Finally, process any pending end-of-block state changes.
err = eval.endOfBlock()
if err != nil {
return ledgercore.StateDelta{}, err
Expand Down Expand Up @@ -1488,3 +1496,36 @@ func (vb ValidatedBlock) WithSeed(s committee.Seed) ValidatedBlock {
delta: vb.delta,
}
}

// Eval evaluates a block without validation using the given `proto`. Return the state
// delta and transactions with modified apply data according to `proto`.
// This function is used by Indexer which modifies `proto` to retrieve the asset
// close amount for each transaction even when the real consensus parameters do not
// support it.
func Eval(l ledgerForEvaluator, blk *bookkeeping.Block, proto config.ConsensusParams) (ledgercore.StateDelta, []transactions.SignedTxnInBlock, error) {
eval, err := startEvaluator(
l, blk.BlockHeader, proto, len(blk.Payset), false, false)
if err != nil {
return ledgercore.StateDelta{}, []transactions.SignedTxnInBlock{}, err
}

paysetgroups, err := blk.DecodePaysetGroups()
if err != nil {
return ledgercore.StateDelta{}, []transactions.SignedTxnInBlock{}, err
}

for _, group := range paysetgroups {
err = eval.TransactionGroup(group)
if err != nil {
return ledgercore.StateDelta{}, []transactions.SignedTxnInBlock{}, err
}
}

// Finally, process any pending end-of-block state changes.
err = eval.endOfBlock()
if err != nil {
return ledgercore.StateDelta{}, []transactions.SignedTxnInBlock{}, err
}

return eval.state.deltas(), eval.block.Payset, nil
}