@@ -41,6 +41,9 @@ import (
4141// ErrNoSpace indicates insufficient space for transaction in block
4242var ErrNoSpace = errors .New ("block does not have space for transaction" )
4343
44+ // ErrRoundZero is self-explanatory
45+ var ErrRoundZero = errors .New ("cannot start evaluator for round 0" )
46+
4447// maxPaysetHint makes sure that we don't allocate too much memory up front
4548// in the block evaluator, since there cannot reasonably be more than this
4649// many transactions in a block.
@@ -383,20 +386,37 @@ func (l *Ledger) StartEvaluator(hdr bookkeeping.BlockHeader, paysetHint int) (*B
383386}
384387
385388func startEvaluator (l ledgerForEvaluator , hdr bookkeeping.BlockHeader , proto config.ConsensusParams , paysetHint int , validate bool , generate bool ) (* BlockEvaluator , error ) {
389+ if hdr .Round == 0 {
390+ return nil , ErrRoundZero
391+ }
392+
393+ prevHeader , err := l .BlockHdr (hdr .Round - 1 )
394+ if err != nil {
395+ return nil , fmt .Errorf (
396+ "can't evaluate block %d without previous header: %v" , hdr .Round , err )
397+ }
398+
399+ prevProto , ok := config .Consensus [prevHeader .CurrentProtocol ]
400+ if ! ok {
401+ return nil , protocol .Error (prevHeader .CurrentProtocol )
402+ }
403+
386404 base := & roundCowBase {
387405 l : l ,
388406 // round that lookups come from is previous block. We validate
389407 // the block at this round below, so underflow will be caught.
390408 // If we are not validating, we must have previously checked
391409 // an agreement.Certificate attesting that hdr is valid.
392410 rnd : hdr .Round - 1 ,
411+ txnCount : prevHeader .TxnCounter ,
393412 proto : proto ,
394413 accounts : make (map [basics.Address ]basics.AccountData ),
395414 }
396415
397416 eval := & BlockEvaluator {
398417 validate : validate ,
399418 generate : generate ,
419+ prevHeader : prevHeader ,
400420 block : bookkeeping.Block {BlockHeader : hdr },
401421 proto : proto ,
402422 genesisHash : l .GenesisHash (),
@@ -412,35 +432,18 @@ func startEvaluator(l ledgerForEvaluator, hdr bookkeeping.BlockHeader, proto con
412432 eval .block .Payset = make ([]transactions.SignedTxnInBlock , 0 , paysetHint )
413433 }
414434
415- prevProto := proto
435+ base . compactCertNextRnd = eval . prevHeader . CompactCert [ protocol . CompactCertBasic ]. CompactCertNextRound
416436
417- if hdr .Round > 0 {
418- var err error
419- eval .prevHeader , err = l .BlockHdr (base .rnd )
420- if err != nil {
421- return nil , fmt .Errorf ("can't evaluate block %v without previous header: %v" , hdr .Round , err )
422- }
437+ // Check if compact certs are being enabled as of this block.
438+ if base .compactCertNextRnd == 0 && proto .CompactCertRounds != 0 {
439+ // Determine the first block that will contain a Merkle
440+ // commitment to the voters. We need to account for the
441+ // fact that the voters come from CompactCertVotersLookback
442+ // rounds ago.
443+ votersRound := (hdr .Round + basics .Round (proto .CompactCertVotersLookback )).RoundUpToMultipleOf (basics .Round (proto .CompactCertRounds ))
423444
424- base .txnCount = eval .prevHeader .TxnCounter
425- base .compactCertNextRnd = eval .prevHeader .CompactCert [protocol .CompactCertBasic ].CompactCertNextRound
426-
427- var ok bool
428- prevProto , ok = config .Consensus [eval .prevHeader .CurrentProtocol ]
429- if ! ok {
430- return nil , protocol .Error (eval .prevHeader .CurrentProtocol )
431- }
432-
433- // Check if compact certs are being enabled as of this block.
434- if base .compactCertNextRnd == 0 && proto .CompactCertRounds != 0 {
435- // Determine the first block that will contain a Merkle
436- // commitment to the voters. We need to account for the
437- // fact that the voters come from CompactCertVotersLookback
438- // rounds ago.
439- votersRound := (hdr .Round + basics .Round (proto .CompactCertVotersLookback )).RoundUpToMultipleOf (basics .Round (proto .CompactCertRounds ))
440-
441- // The first compact cert will appear CompactCertRounds after that.
442- base .compactCertNextRnd = votersRound + basics .Round (proto .CompactCertRounds )
443- }
445+ // The first compact cert will appear CompactCertRounds after that.
446+ base .compactCertNextRnd = votersRound + basics .Round (proto .CompactCertRounds )
444447 }
445448
446449 prevTotals , err := l .Totals (eval .prevHeader .Round )
0 commit comments