github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/consensus/bor/bor.go (about)

     1  package bor
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/hex"
     7  	"encoding/json"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"math/big"
    12  	"sort"
    13  	"strconv"
    14  	"sync"
    15  	"sync/atomic"
    16  	"time"
    17  
    18  	lru "github.com/hashicorp/golang-lru"
    19  	"go.opentelemetry.io/otel/attribute"
    20  	"go.opentelemetry.io/otel/trace"
    21  	"golang.org/x/crypto/sha3"
    22  
    23  	"github.com/ethereum/go-ethereum/accounts"
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/common/tracing"
    26  	"github.com/ethereum/go-ethereum/consensus"
    27  	"github.com/ethereum/go-ethereum/consensus/bor/api"
    28  	"github.com/ethereum/go-ethereum/consensus/bor/clerk"
    29  	"github.com/ethereum/go-ethereum/consensus/bor/heimdall/span"
    30  	"github.com/ethereum/go-ethereum/consensus/bor/statefull"
    31  	"github.com/ethereum/go-ethereum/consensus/bor/valset"
    32  	"github.com/ethereum/go-ethereum/consensus/misc"
    33  	"github.com/ethereum/go-ethereum/core"
    34  	"github.com/ethereum/go-ethereum/core/state"
    35  	"github.com/ethereum/go-ethereum/core/types"
    36  	"github.com/ethereum/go-ethereum/crypto"
    37  	"github.com/ethereum/go-ethereum/ethdb"
    38  	"github.com/ethereum/go-ethereum/log"
    39  	"github.com/ethereum/go-ethereum/params"
    40  	"github.com/ethereum/go-ethereum/rlp"
    41  	"github.com/ethereum/go-ethereum/rpc"
    42  	"github.com/ethereum/go-ethereum/trie"
    43  )
    44  
    45  const (
    46  	checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
    47  	inmemorySnapshots  = 128  // Number of recent vote snapshots to keep in memory
    48  	inmemorySignatures = 4096 // Number of recent block signatures to keep in memory
    49  )
    50  
    51  // Bor protocol constants.
    52  var (
    53  	defaultSprintLength = map[string]uint64{
    54  		"0": 64,
    55  	} // Default number of blocks after which to checkpoint and reset the pending votes
    56  
    57  	extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
    58  	extraSeal   = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
    59  
    60  	uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW.
    61  
    62  	validatorHeaderBytesLength = common.AddressLength + 20 // address + power
    63  )
    64  
    65  // Various error messages to mark blocks invalid. These should be private to
    66  // prevent engine specific errors from being referenced in the remainder of the
    67  // codebase, inherently breaking if the engine is swapped out. Please put common
    68  // error types into the consensus package.
    69  var (
    70  	// errUnknownBlock is returned when the list of signers is requested for a block
    71  	// that is not part of the local blockchain.
    72  	errUnknownBlock = errors.New("unknown block")
    73  
    74  	// errMissingVanity is returned if a block's extra-data section is shorter than
    75  	// 32 bytes, which is required to store the signer vanity.
    76  	errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing")
    77  
    78  	// errMissingSignature is returned if a block's extra-data section doesn't seem
    79  	// to contain a 65 byte secp256k1 signature.
    80  	errMissingSignature = errors.New("extra-data 65 byte signature suffix missing")
    81  
    82  	// errExtraValidators is returned if non-sprint-end block contain validator data in
    83  	// their extra-data fields.
    84  	errExtraValidators = errors.New("non-sprint-end block contains extra validator list")
    85  
    86  	// errInvalidSpanValidators is returned if a block contains an
    87  	// invalid list of validators (i.e. non divisible by 40 bytes).
    88  	errInvalidSpanValidators = errors.New("invalid validator list on sprint end block")
    89  
    90  	// errInvalidMixDigest is returned if a block's mix digest is non-zero.
    91  	errInvalidMixDigest = errors.New("non-zero mix digest")
    92  
    93  	// errInvalidUncleHash is returned if a block contains an non-empty uncle list.
    94  	errInvalidUncleHash = errors.New("non empty uncle hash")
    95  
    96  	// errInvalidDifficulty is returned if the difficulty of a block neither 1 or 2.
    97  	errInvalidDifficulty = errors.New("invalid difficulty")
    98  
    99  	// ErrInvalidTimestamp is returned if the timestamp of a block is lower than
   100  	// the previous block's timestamp + the minimum block period.
   101  	ErrInvalidTimestamp = errors.New("invalid timestamp")
   102  
   103  	// errOutOfRangeChain is returned if an authorization list is attempted to
   104  	// be modified via out-of-range or non-contiguous headers.
   105  	errOutOfRangeChain = errors.New("out of range or non-contiguous chain")
   106  
   107  	errUncleDetected     = errors.New("uncles not allowed")
   108  	errUnknownValidators = errors.New("unknown validators")
   109  )
   110  
   111  // SignerFn is a signer callback function to request a header to be signed by a
   112  // backing account.
   113  type SignerFn func(accounts.Account, string, []byte) ([]byte, error)
   114  
   115  // ecrecover extracts the Ethereum account address from a signed header.
   116  func ecrecover(header *types.Header, sigcache *lru.ARCCache, c *params.BorConfig) (common.Address, error) {
   117  	// If the signature's already cached, return that
   118  	hash := header.Hash()
   119  	if address, known := sigcache.Get(hash); known {
   120  		return address.(common.Address), nil
   121  	}
   122  	// Retrieve the signature from the header extra-data
   123  	if len(header.Extra) < extraSeal {
   124  		return common.Address{}, errMissingSignature
   125  	}
   126  
   127  	signature := header.Extra[len(header.Extra)-extraSeal:]
   128  
   129  	// Recover the public key and the Ethereum address
   130  	pubkey, err := crypto.Ecrecover(SealHash(header, c).Bytes(), signature)
   131  	if err != nil {
   132  		return common.Address{}, err
   133  	}
   134  
   135  	var signer common.Address
   136  
   137  	copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
   138  
   139  	sigcache.Add(hash, signer)
   140  
   141  	return signer, nil
   142  }
   143  
   144  // SealHash returns the hash of a block prior to it being sealed.
   145  func SealHash(header *types.Header, c *params.BorConfig) (hash common.Hash) {
   146  	hasher := sha3.NewLegacyKeccak256()
   147  	encodeSigHeader(hasher, header, c)
   148  	hasher.Sum(hash[:0])
   149  
   150  	return hash
   151  }
   152  
   153  func encodeSigHeader(w io.Writer, header *types.Header, c *params.BorConfig) {
   154  	enc := []interface{}{
   155  		header.ParentHash,
   156  		header.UncleHash,
   157  		header.Coinbase,
   158  		header.Root,
   159  		header.TxHash,
   160  		header.ReceiptHash,
   161  		header.Bloom,
   162  		header.Difficulty,
   163  		header.Number,
   164  		header.GasLimit,
   165  		header.GasUsed,
   166  		header.Time,
   167  		header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
   168  		header.MixDigest,
   169  		header.Nonce,
   170  	}
   171  
   172  	if c.IsJaipur(header.Number) {
   173  		if header.BaseFee != nil {
   174  			enc = append(enc, header.BaseFee)
   175  		}
   176  	}
   177  
   178  	if err := rlp.Encode(w, enc); err != nil {
   179  		panic("can't encode: " + err.Error())
   180  	}
   181  }
   182  
   183  // CalcProducerDelay is the block delay algorithm based on block time, period, producerDelay and turn-ness of a signer
   184  func CalcProducerDelay(number uint64, succession int, c *params.BorConfig) uint64 {
   185  	// When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`.
   186  	// That is to allow time for block propagation in the last sprint
   187  	delay := c.CalculatePeriod(number)
   188  	if number%c.CalculateSprint(number) == 0 {
   189  		delay = c.CalculateProducerDelay(number)
   190  	}
   191  
   192  	if succession > 0 {
   193  		delay += uint64(succession) * c.CalculateBackupMultiplier(number)
   194  	}
   195  
   196  	return delay
   197  }
   198  
   199  // BorRLP returns the rlp bytes which needs to be signed for the bor
   200  // sealing. The RLP to sign consists of the entire header apart from the 65 byte signature
   201  // contained at the end of the extra data.
   202  //
   203  // Note, the method requires the extra data to be at least 65 bytes, otherwise it
   204  // panics. This is done to avoid accidentally using both forms (signature present
   205  // or not), which could be abused to produce different hashes for the same header.
   206  func BorRLP(header *types.Header, c *params.BorConfig) []byte {
   207  	b := new(bytes.Buffer)
   208  	encodeSigHeader(b, header, c)
   209  
   210  	return b.Bytes()
   211  }
   212  
   213  // Bor is the matic-bor consensus engine
   214  type Bor struct {
   215  	chainConfig *params.ChainConfig // Chain config
   216  	config      *params.BorConfig   // Consensus engine configuration parameters for bor consensus
   217  	db          ethdb.Database      // Database to store and retrieve snapshot checkpoints
   218  
   219  	recents    *lru.ARCCache // Snapshots for recent block to speed up reorgs
   220  	signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
   221  
   222  	authorizedSigner atomic.Pointer[signer] // Ethereum address and sign function of the signing key
   223  
   224  	ethAPI                 api.Caller
   225  	spanner                Spanner
   226  	GenesisContractsClient GenesisContract
   227  	HeimdallClient         IHeimdallClient
   228  
   229  	// The fields below are for testing only
   230  	fakeDiff      bool // Skip difficulty verifications
   231  	devFakeAuthor bool
   232  
   233  	closeOnce sync.Once
   234  }
   235  
   236  type signer struct {
   237  	signer common.Address // Ethereum address of the signing key
   238  	signFn SignerFn       // Signer function to authorize hashes with
   239  }
   240  
   241  // New creates a Matic Bor consensus engine.
   242  func New(
   243  	chainConfig *params.ChainConfig,
   244  	db ethdb.Database,
   245  	ethAPI api.Caller,
   246  	spanner Spanner,
   247  	heimdallClient IHeimdallClient,
   248  	genesisContracts GenesisContract,
   249  	devFakeAuthor bool,
   250  ) *Bor {
   251  	// get bor config
   252  	borConfig := chainConfig.Bor
   253  
   254  	// Set any missing consensus parameters to their defaults
   255  	if borConfig != nil && borConfig.CalculateSprint(0) == 0 {
   256  		borConfig.Sprint = defaultSprintLength
   257  	}
   258  	// Allocate the snapshot caches and create the engine
   259  	recents, _ := lru.NewARC(inmemorySnapshots)
   260  	signatures, _ := lru.NewARC(inmemorySignatures)
   261  
   262  	c := &Bor{
   263  		chainConfig:            chainConfig,
   264  		config:                 borConfig,
   265  		db:                     db,
   266  		ethAPI:                 ethAPI,
   267  		recents:                recents,
   268  		signatures:             signatures,
   269  		spanner:                spanner,
   270  		GenesisContractsClient: genesisContracts,
   271  		HeimdallClient:         heimdallClient,
   272  		devFakeAuthor:          devFakeAuthor,
   273  	}
   274  
   275  	c.authorizedSigner.Store(&signer{
   276  		common.Address{},
   277  		func(_ accounts.Account, _ string, i []byte) ([]byte, error) {
   278  			// return an error to prevent panics
   279  			return nil, &UnauthorizedSignerError{0, common.Address{}.Bytes()}
   280  		},
   281  	})
   282  
   283  	// make sure we can decode all the GenesisAlloc in the BorConfig.
   284  	for key, genesisAlloc := range c.config.BlockAlloc {
   285  		if _, err := decodeGenesisAlloc(genesisAlloc); err != nil {
   286  			panic(fmt.Sprintf("BUG: Block alloc '%s' in genesis is not correct: %v", key, err))
   287  		}
   288  	}
   289  
   290  	return c
   291  }
   292  
   293  // Author implements consensus.Engine, returning the Ethereum address recovered
   294  // from the signature in the header's extra-data section.
   295  func (c *Bor) Author(header *types.Header) (common.Address, error) {
   296  	return ecrecover(header, c.signatures, c.config)
   297  }
   298  
   299  // VerifyHeader checks whether a header conforms to the consensus rules.
   300  func (c *Bor) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, _ bool) error {
   301  	return c.verifyHeader(chain, header, nil)
   302  }
   303  
   304  func (c *Bor) GetSpanner() Spanner {
   305  	return c.spanner
   306  }
   307  
   308  func (c *Bor) SetSpanner(spanner Spanner) {
   309  	c.spanner = spanner
   310  }
   311  
   312  // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
   313  // method returns a quit channel to abort the operations and a results channel to
   314  // retrieve the async verifications (the order is that of the input slice).
   315  func (c *Bor) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, _ []bool) (chan<- struct{}, <-chan error) {
   316  	abort := make(chan struct{})
   317  	results := make(chan error, len(headers))
   318  
   319  	go func() {
   320  		for i, header := range headers {
   321  			err := c.verifyHeader(chain, header, headers[:i])
   322  
   323  			select {
   324  			case <-abort:
   325  				return
   326  			case results <- err:
   327  			}
   328  		}
   329  	}()
   330  
   331  	return abort, results
   332  }
   333  
   334  // verifyHeader checks whether a header conforms to the consensus rules.The
   335  // caller may optionally pass in a batch of parents (ascending order) to avoid
   336  // looking those up from the database. This is useful for concurrently verifying
   337  // a batch of new headers.
   338  func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
   339  	if header.Number == nil {
   340  		return errUnknownBlock
   341  	}
   342  
   343  	number := header.Number.Uint64()
   344  
   345  	// Don't waste time checking blocks from the future
   346  	if header.Time > uint64(time.Now().Unix()) {
   347  		return consensus.ErrFutureBlock
   348  	}
   349  
   350  	if err := validateHeaderExtraField(header.Extra); err != nil {
   351  		return err
   352  	}
   353  
   354  	// check extr adata
   355  	isSprintEnd := IsSprintStart(number+1, c.config.CalculateSprint(number))
   356  
   357  	// Ensure that the extra-data contains a signer list on checkpoint, but none otherwise
   358  	signersBytes := len(header.Extra) - extraVanity - extraSeal
   359  	if !isSprintEnd && signersBytes != 0 {
   360  		return errExtraValidators
   361  	}
   362  
   363  	if isSprintEnd && signersBytes%validatorHeaderBytesLength != 0 {
   364  		return errInvalidSpanValidators
   365  	}
   366  
   367  	// Ensure that the mix digest is zero as we don't have fork protection currently
   368  	if header.MixDigest != (common.Hash{}) {
   369  		return errInvalidMixDigest
   370  	}
   371  
   372  	// Ensure that the block doesn't contain any uncles which are meaningless in PoA
   373  	if header.UncleHash != uncleHash {
   374  		return errInvalidUncleHash
   375  	}
   376  
   377  	// Ensure that the block's difficulty is meaningful (may not be correct at this point)
   378  	if number > 0 {
   379  		if header.Difficulty == nil {
   380  			return errInvalidDifficulty
   381  		}
   382  	}
   383  
   384  	// Verify that the gas limit is <= 2^63-1
   385  	gasCap := uint64(0x7fffffffffffffff)
   386  
   387  	if header.GasLimit > gasCap {
   388  		return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, gasCap)
   389  	}
   390  
   391  	// If all checks passed, validate any special fields for hard forks
   392  	if err := misc.VerifyForkHashes(chain.Config(), header, false); err != nil {
   393  		return err
   394  	}
   395  
   396  	// All basic checks passed, verify cascading fields
   397  	return c.verifyCascadingFields(chain, header, parents)
   398  }
   399  
   400  // validateHeaderExtraField validates that the extra-data contains both the vanity and signature.
   401  // header.Extra = header.Vanity + header.ProducerBytes (optional) + header.Seal
   402  func validateHeaderExtraField(extraBytes []byte) error {
   403  	if len(extraBytes) < extraVanity {
   404  		return errMissingVanity
   405  	}
   406  
   407  	if len(extraBytes) < extraVanity+extraSeal {
   408  		return errMissingSignature
   409  	}
   410  
   411  	return nil
   412  }
   413  
   414  // verifyCascadingFields verifies all the header fields that are not standalone,
   415  // rather depend on a batch of previous headers. The caller may optionally pass
   416  // in a batch of parents (ascending order) to avoid looking those up from the
   417  // database. This is useful for concurrently verifying a batch of new headers.
   418  func (c *Bor) verifyCascadingFields(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
   419  	// The genesis block is the always valid dead-end
   420  	number := header.Number.Uint64()
   421  
   422  	if number == 0 {
   423  		return nil
   424  	}
   425  
   426  	// Ensure that the block's timestamp isn't too close to it's parent
   427  	var parent *types.Header
   428  
   429  	if len(parents) > 0 {
   430  		parent = parents[len(parents)-1]
   431  	} else {
   432  		parent = chain.GetHeader(header.ParentHash, number-1)
   433  	}
   434  
   435  	if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
   436  		return consensus.ErrUnknownAncestor
   437  	}
   438  
   439  	// Verify that the gasUsed is <= gasLimit
   440  	if header.GasUsed > header.GasLimit {
   441  		return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
   442  	}
   443  
   444  	if !chain.Config().IsLondon(header.Number) {
   445  		// Verify BaseFee not present before EIP-1559 fork.
   446  		if header.BaseFee != nil {
   447  			return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)
   448  		}
   449  
   450  		if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
   451  			return err
   452  		}
   453  	} else if err := misc.VerifyEip1559Header(chain.Config(), parent, header); err != nil {
   454  		// Verify the header's EIP-1559 attributes.
   455  		return err
   456  	}
   457  
   458  	if parent.Time+c.config.CalculatePeriod(number) > header.Time {
   459  		return ErrInvalidTimestamp
   460  	}
   461  
   462  	// Retrieve the snapshot needed to verify this header and cache it
   463  	snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
   464  	if err != nil {
   465  		return err
   466  	}
   467  
   468  	// Verify the validator list match the local contract
   469  	if IsSprintStart(number+1, c.config.CalculateSprint(number)) {
   470  		newValidators, err := c.spanner.GetCurrentValidatorsByBlockNrOrHash(context.Background(), rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber), number+1)
   471  
   472  		if err != nil {
   473  			return err
   474  		}
   475  
   476  		sort.Sort(valset.ValidatorsByAddress(newValidators))
   477  
   478  		headerVals, err := valset.ParseValidators(header.Extra[extraVanity : len(header.Extra)-extraSeal])
   479  
   480  		if err != nil {
   481  			return err
   482  		}
   483  
   484  		if len(newValidators) != len(headerVals) {
   485  			return errInvalidSpanValidators
   486  		}
   487  
   488  		for i, val := range newValidators {
   489  			if !bytes.Equal(val.HeaderBytes(), headerVals[i].HeaderBytes()) {
   490  				return errInvalidSpanValidators
   491  			}
   492  		}
   493  	}
   494  
   495  	// verify the validator list in the last sprint block
   496  	if IsSprintStart(number, c.config.CalculateSprint(number)) {
   497  		parentValidatorBytes := parent.Extra[extraVanity : len(parent.Extra)-extraSeal]
   498  		validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength)
   499  
   500  		currentValidators := snap.ValidatorSet.Copy().Validators
   501  		// sort validator by address
   502  		sort.Sort(valset.ValidatorsByAddress(currentValidators))
   503  
   504  		for i, validator := range currentValidators {
   505  			copy(validatorsBytes[i*validatorHeaderBytesLength:], validator.HeaderBytes())
   506  		}
   507  		// len(header.Extra) >= extraVanity+extraSeal has already been validated in validateHeaderExtraField, so this won't result in a panic
   508  		if !bytes.Equal(parentValidatorBytes, validatorsBytes) {
   509  			return &MismatchingValidatorsError{number - 1, validatorsBytes, parentValidatorBytes}
   510  		}
   511  	}
   512  
   513  	// All basic checks passed, verify the seal and return
   514  	return c.verifySeal(chain, header, parents)
   515  }
   516  
   517  // snapshot retrieves the authorization snapshot at a given point in time.
   518  // nolint: gocognit
   519  func (c *Bor) snapshot(chain consensus.ChainHeaderReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
   520  	// Search for a snapshot in memory or on disk for checkpoints
   521  
   522  	signer := common.BytesToAddress(c.authorizedSigner.Load().signer.Bytes())
   523  	if c.devFakeAuthor && signer.String() != "0x0000000000000000000000000000000000000000" {
   524  		log.Info("👨‍💻Using DevFakeAuthor", "signer", signer)
   525  
   526  		val := valset.NewValidator(signer, 1000)
   527  		validatorset := valset.NewValidatorSet([]*valset.Validator{val})
   528  
   529  		snapshot := newSnapshot(c.config, c.signatures, number, hash, validatorset.Validators)
   530  
   531  		return snapshot, nil
   532  	}
   533  
   534  	var snap *Snapshot
   535  
   536  	headers := make([]*types.Header, 0, 16)
   537  
   538  	//nolint:govet
   539  	for snap == nil {
   540  		// If an in-memory snapshot was found, use that
   541  		if s, ok := c.recents.Get(hash); ok {
   542  			snap = s.(*Snapshot)
   543  
   544  			break
   545  		}
   546  
   547  		// If an on-disk checkpoint snapshot can be found, use that
   548  		if number%checkpointInterval == 0 {
   549  			if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil {
   550  				log.Trace("Loaded snapshot from disk", "number", number, "hash", hash)
   551  
   552  				snap = s
   553  
   554  				break
   555  			}
   556  		}
   557  
   558  		// If we're at the genesis, snapshot the initial state. Alternatively if we're
   559  		// at a checkpoint block without a parent (light client CHT), or we have piled
   560  		// up more headers than allowed to be reorged (chain reinit from a freezer),
   561  		// consider the checkpoint trusted and snapshot it.
   562  
   563  		// TODO fix this
   564  		// nolint:nestif
   565  		if number == 0 {
   566  			checkpoint := chain.GetHeaderByNumber(number)
   567  			if checkpoint != nil {
   568  				// get checkpoint data
   569  				hash := checkpoint.Hash()
   570  
   571  				// get validators and current span
   572  				validators, err := c.spanner.GetCurrentValidatorsByHash(context.Background(), hash, number+1)
   573  				if err != nil {
   574  					return nil, err
   575  				}
   576  
   577  				// new snap shot
   578  				snap = newSnapshot(c.config, c.signatures, number, hash, validators)
   579  				if err := snap.store(c.db); err != nil {
   580  					return nil, err
   581  				}
   582  
   583  				log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash)
   584  
   585  				break
   586  			}
   587  		}
   588  
   589  		// No snapshot for this header, gather the header and move backward
   590  		var header *types.Header
   591  		if len(parents) > 0 {
   592  			// If we have explicit parents, pick from there (enforced)
   593  			header = parents[len(parents)-1]
   594  			if header.Hash() != hash || header.Number.Uint64() != number {
   595  				return nil, consensus.ErrUnknownAncestor
   596  			}
   597  
   598  			parents = parents[:len(parents)-1]
   599  		} else {
   600  			// No explicit parents (or no more left), reach out to the database
   601  			header = chain.GetHeader(hash, number)
   602  			if header == nil {
   603  				return nil, consensus.ErrUnknownAncestor
   604  			}
   605  		}
   606  
   607  		headers = append(headers, header)
   608  		number, hash = number-1, header.ParentHash
   609  	}
   610  
   611  	// check if snapshot is nil
   612  	if snap == nil {
   613  		return nil, fmt.Errorf("unknown error while retrieving snapshot at block number %v", number)
   614  	}
   615  
   616  	// Previous snapshot found, apply any pending headers on top of it
   617  	for i := 0; i < len(headers)/2; i++ {
   618  		headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i]
   619  	}
   620  
   621  	snap, err := snap.apply(headers)
   622  	if err != nil {
   623  		return nil, err
   624  	}
   625  
   626  	c.recents.Add(snap.Hash, snap)
   627  
   628  	// If we've generated a new checkpoint snapshot, save to disk
   629  	if snap.Number%checkpointInterval == 0 && len(headers) > 0 {
   630  		if err = snap.store(c.db); err != nil {
   631  			return nil, err
   632  		}
   633  
   634  		log.Trace("Stored snapshot to disk", "number", snap.Number, "hash", snap.Hash)
   635  	}
   636  
   637  	return snap, err
   638  }
   639  
   640  // VerifyUncles implements consensus.Engine, always returning an error for any
   641  // uncles as this consensus mechanism doesn't permit uncles.
   642  func (c *Bor) VerifyUncles(_ consensus.ChainReader, block *types.Block) error {
   643  	if len(block.Uncles()) > 0 {
   644  		return errUncleDetected
   645  	}
   646  
   647  	return nil
   648  }
   649  
   650  // VerifySeal implements consensus.Engine, checking whether the signature contained
   651  // in the header satisfies the consensus protocol requirements.
   652  func (c *Bor) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error {
   653  	return c.verifySeal(chain, header, nil)
   654  }
   655  
   656  // verifySeal checks whether the signature contained in the header satisfies the
   657  // consensus protocol requirements. The method accepts an optional list of parent
   658  // headers that aren't yet part of the local blockchain to generate the snapshots
   659  // from.
   660  func (c *Bor) verifySeal(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error {
   661  	// Verifying the genesis block is not supported
   662  	number := header.Number.Uint64()
   663  	if number == 0 {
   664  		return errUnknownBlock
   665  	}
   666  	// Retrieve the snapshot needed to verify this header and cache it
   667  	snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
   668  	if err != nil {
   669  		return err
   670  	}
   671  
   672  	// Resolve the authorization key and check against signers
   673  	signer, err := ecrecover(header, c.signatures, c.config)
   674  	if err != nil {
   675  		return err
   676  	}
   677  
   678  	if !snap.ValidatorSet.HasAddress(signer) {
   679  		// Check the UnauthorizedSignerError.Error() msg to see why we pass number-1
   680  		return &UnauthorizedSignerError{number - 1, signer.Bytes()}
   681  	}
   682  
   683  	succession, err := snap.GetSignerSuccessionNumber(signer)
   684  	if err != nil {
   685  		return err
   686  	}
   687  
   688  	var parent *types.Header
   689  	if len(parents) > 0 { // if parents is nil, len(parents) is zero
   690  		parent = parents[len(parents)-1]
   691  	} else if number > 0 {
   692  		parent = chain.GetHeader(header.ParentHash, number-1)
   693  	}
   694  
   695  	if IsBlockOnTime(parent, header, number, succession, c.config) {
   696  		return &BlockTooSoonError{number, succession}
   697  	}
   698  
   699  	// Ensure that the difficulty corresponds to the turn-ness of the signer
   700  	if !c.fakeDiff {
   701  		difficulty := Difficulty(snap.ValidatorSet, signer)
   702  		if header.Difficulty.Uint64() != difficulty {
   703  			return &WrongDifficultyError{number, difficulty, header.Difficulty.Uint64(), signer.Bytes()}
   704  		}
   705  	}
   706  
   707  	return nil
   708  }
   709  
   710  func IsBlockOnTime(parent *types.Header, header *types.Header, number uint64, succession int, cfg *params.BorConfig) bool {
   711  	return parent != nil && header.Time < parent.Time+CalcProducerDelay(number, succession, cfg)
   712  }
   713  
   714  // Prepare implements consensus.Engine, preparing all the consensus fields of the
   715  // header for running the transactions on top.
   716  func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
   717  	// If the block isn't a checkpoint, cast a random vote (good enough for now)
   718  	header.Coinbase = common.Address{}
   719  	header.Nonce = types.BlockNonce{}
   720  
   721  	number := header.Number.Uint64()
   722  	// Assemble the validator snapshot to check which votes make sense
   723  	snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
   724  	if err != nil {
   725  		return err
   726  	}
   727  
   728  	currentSigner := *c.authorizedSigner.Load()
   729  
   730  	// Set the correct difficulty
   731  	header.Difficulty = new(big.Int).SetUint64(Difficulty(snap.ValidatorSet, currentSigner.signer))
   732  
   733  	// Ensure the extra data has all it's components
   734  	if len(header.Extra) < extraVanity {
   735  		header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...)
   736  	}
   737  
   738  	header.Extra = header.Extra[:extraVanity]
   739  
   740  	// get validator set if number
   741  	if IsSprintStart(number+1, c.config.CalculateSprint(number)) {
   742  		newValidators, err := c.spanner.GetCurrentValidatorsByHash(context.Background(), header.ParentHash, number+1)
   743  		if err != nil {
   744  			return errUnknownValidators
   745  		}
   746  
   747  		// sort validator by address
   748  		sort.Sort(valset.ValidatorsByAddress(newValidators))
   749  
   750  		for _, validator := range newValidators {
   751  			header.Extra = append(header.Extra, validator.HeaderBytes()...)
   752  		}
   753  	}
   754  
   755  	// add extra seal space
   756  	header.Extra = append(header.Extra, make([]byte, extraSeal)...)
   757  
   758  	// Mix digest is reserved for now, set to empty
   759  	header.MixDigest = common.Hash{}
   760  
   761  	// Ensure the timestamp has the correct delay
   762  	parent := chain.GetHeader(header.ParentHash, number-1)
   763  	if parent == nil {
   764  		return consensus.ErrUnknownAncestor
   765  	}
   766  
   767  	var succession int
   768  	// if signer is not empty
   769  	if currentSigner.signer != (common.Address{}) {
   770  		succession, err = snap.GetSignerSuccessionNumber(currentSigner.signer)
   771  		if err != nil {
   772  			return err
   773  		}
   774  	}
   775  
   776  	header.Time = parent.Time + CalcProducerDelay(number, succession, c.config)
   777  	if header.Time < uint64(time.Now().Unix()) {
   778  		header.Time = uint64(time.Now().Unix())
   779  	}
   780  
   781  	return nil
   782  }
   783  
   784  // Finalize implements consensus.Engine, ensuring no uncles are set, nor block
   785  // rewards given.
   786  func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, _ []*types.Transaction, _ []*types.Header) {
   787  	var (
   788  		stateSyncData []*types.StateSyncData
   789  		err           error
   790  	)
   791  
   792  	headerNumber := header.Number.Uint64()
   793  
   794  	if IsSprintStart(headerNumber, c.config.CalculateSprint(headerNumber)) {
   795  		ctx := context.Background()
   796  		cx := statefull.ChainContext{Chain: chain, Bor: c}
   797  		// check and commit span
   798  		if err := c.checkAndCommitSpan(ctx, state, header, cx); err != nil {
   799  			log.Error("Error while committing span", "error", err)
   800  			return
   801  		}
   802  
   803  		if c.HeimdallClient != nil {
   804  			// commit states
   805  			stateSyncData, err = c.CommitStates(ctx, state, header, cx)
   806  			if err != nil {
   807  				log.Error("Error while committing states", "error", err)
   808  				return
   809  			}
   810  		}
   811  	}
   812  
   813  	if err = c.changeContractCodeIfNeeded(headerNumber, state); err != nil {
   814  		log.Error("Error changing contract code", "error", err)
   815  		return
   816  	}
   817  
   818  	// No block rewards in PoA, so the state remains as is and uncles are dropped
   819  	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   820  	header.UncleHash = types.CalcUncleHash(nil)
   821  
   822  	// Set state sync data to blockchain
   823  	bc := chain.(*core.BlockChain)
   824  	bc.SetStateSync(stateSyncData)
   825  }
   826  
   827  func decodeGenesisAlloc(i interface{}) (core.GenesisAlloc, error) {
   828  	var alloc core.GenesisAlloc
   829  
   830  	b, err := json.Marshal(i)
   831  	if err != nil {
   832  		return nil, err
   833  	}
   834  
   835  	if err := json.Unmarshal(b, &alloc); err != nil {
   836  		return nil, err
   837  	}
   838  
   839  	return alloc, nil
   840  }
   841  
   842  func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.StateDB) error {
   843  	for blockNumber, genesisAlloc := range c.config.BlockAlloc {
   844  		if blockNumber == strconv.FormatUint(headerNumber, 10) {
   845  			allocs, err := decodeGenesisAlloc(genesisAlloc)
   846  			if err != nil {
   847  				return fmt.Errorf("failed to decode genesis alloc: %w", err)
   848  			}
   849  
   850  			for addr, account := range allocs {
   851  				log.Info("change contract code", "address", addr)
   852  				state.SetCode(addr, account.Code)
   853  			}
   854  		}
   855  	}
   856  
   857  	return nil
   858  }
   859  
   860  // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
   861  // nor block rewards given, and returns the final block.
   862  func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
   863  	finalizeCtx, finalizeSpan := tracing.StartSpan(ctx, "bor.FinalizeAndAssemble")
   864  	defer tracing.EndSpan(finalizeSpan)
   865  
   866  	stateSyncData := []*types.StateSyncData{}
   867  
   868  	headerNumber := header.Number.Uint64()
   869  
   870  	var err error
   871  
   872  	if IsSprintStart(headerNumber, c.config.CalculateSprint(headerNumber)) {
   873  		cx := statefull.ChainContext{Chain: chain, Bor: c}
   874  
   875  		tracing.Exec(finalizeCtx, "", "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
   876  			// check and commit span
   877  			err = c.checkAndCommitSpan(finalizeCtx, state, header, cx)
   878  		})
   879  
   880  		if err != nil {
   881  			log.Error("Error while committing span", "error", err)
   882  			return nil, err
   883  		}
   884  
   885  		if c.HeimdallClient != nil {
   886  			tracing.Exec(finalizeCtx, "", "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
   887  				// commit states
   888  				stateSyncData, err = c.CommitStates(finalizeCtx, state, header, cx)
   889  			})
   890  
   891  			if err != nil {
   892  				log.Error("Error while committing states", "error", err)
   893  				return nil, err
   894  			}
   895  		}
   896  	}
   897  
   898  	tracing.Exec(finalizeCtx, "", "bor.changeContractCodeIfNeeded", func(ctx context.Context, span trace.Span) {
   899  		err = c.changeContractCodeIfNeeded(headerNumber, state)
   900  	})
   901  
   902  	if err != nil {
   903  		log.Error("Error changing contract code", "error", err)
   904  		return nil, err
   905  	}
   906  
   907  	// No block rewards in PoA, so the state remains as it is
   908  	tracing.Exec(finalizeCtx, "", "bor.IntermediateRoot", func(ctx context.Context, span trace.Span) {
   909  		header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
   910  	})
   911  
   912  	// Uncles are dropped
   913  	header.UncleHash = types.CalcUncleHash(nil)
   914  
   915  	// Assemble block
   916  	block := types.NewBlock(header, txs, nil, receipts, new(trie.Trie))
   917  
   918  	// set state sync
   919  	bc := chain.(core.BorStateSyncer)
   920  	bc.SetStateSync(stateSyncData)
   921  
   922  	tracing.SetAttributes(
   923  		finalizeSpan,
   924  		attribute.Int("number", int(header.Number.Int64())),
   925  		attribute.String("hash", header.Hash().String()),
   926  		attribute.Int("number of txs", len(txs)),
   927  		attribute.Int("gas used", int(block.GasUsed())),
   928  	)
   929  
   930  	// return the final block for sealing
   931  	return block, nil
   932  }
   933  
   934  // Authorize injects a private key into the consensus engine to mint new blocks
   935  // with.
   936  func (c *Bor) Authorize(currentSigner common.Address, signFn SignerFn) {
   937  	c.authorizedSigner.Store(&signer{
   938  		signer: currentSigner,
   939  		signFn: signFn,
   940  	})
   941  }
   942  
   943  // Seal implements consensus.Engine, attempting to create a sealed block using
   944  // the local signing credentials.
   945  func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
   946  	_, sealSpan := tracing.StartSpan(ctx, "bor.Seal")
   947  
   948  	var endSpan bool = true
   949  
   950  	defer func() {
   951  		// Only end span in case of early-returns/errors
   952  		if endSpan {
   953  			tracing.EndSpan(sealSpan)
   954  		}
   955  	}()
   956  
   957  	header := block.Header()
   958  	// Sealing the genesis block is not supported
   959  	number := header.Number.Uint64()
   960  	if number == 0 {
   961  		return errUnknownBlock
   962  	}
   963  	// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
   964  	if c.config.CalculatePeriod(number) == 0 && len(block.Transactions()) == 0 {
   965  		log.Info("Sealing paused, waiting for transactions")
   966  		return nil
   967  	}
   968  
   969  	// Don't hold the signer fields for the entire sealing procedure
   970  	currentSigner := *c.authorizedSigner.Load()
   971  
   972  	snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
   973  	if err != nil {
   974  		return err
   975  	}
   976  
   977  	// Bail out if we're unauthorized to sign a block
   978  	if !snap.ValidatorSet.HasAddress(currentSigner.signer) {
   979  		// Check the UnauthorizedSignerError.Error() msg to see why we pass number-1
   980  		return &UnauthorizedSignerError{number - 1, currentSigner.signer.Bytes()}
   981  	}
   982  
   983  	successionNumber, err := snap.GetSignerSuccessionNumber(currentSigner.signer)
   984  	if err != nil {
   985  		return err
   986  	}
   987  
   988  	// Sweet, the protocol permits us to sign the block, wait for our time
   989  	delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple
   990  	// wiggle was already accounted for in header.Time, this is just for logging
   991  	wiggle := time.Duration(successionNumber) * time.Duration(c.config.CalculateBackupMultiplier(number)) * time.Second
   992  
   993  	// Sign all the things!
   994  	err = Sign(currentSigner.signFn, currentSigner.signer, header, c.config)
   995  	if err != nil {
   996  		return err
   997  	}
   998  
   999  	// Wait until sealing is terminated or delay timeout.
  1000  	log.Info("Waiting for slot to sign and propagate", "number", number, "hash", header.Hash, "delay-in-sec", uint(delay), "delay", common.PrettyDuration(delay))
  1001  
  1002  	go func(sealSpan trace.Span) {
  1003  		select {
  1004  		case <-stop:
  1005  			log.Debug("Discarding sealing operation for block", "number", number)
  1006  			return
  1007  		case <-time.After(delay):
  1008  			if wiggle > 0 {
  1009  				log.Info(
  1010  					"Sealing out-of-turn",
  1011  					"number", number,
  1012  					"hash", header.Hash,
  1013  					"wiggle-in-sec", uint(wiggle),
  1014  					"wiggle", common.PrettyDuration(wiggle),
  1015  					"in-turn-signer", snap.ValidatorSet.GetProposer().Address.Hex(),
  1016  				)
  1017  			}
  1018  
  1019  			log.Info(
  1020  				"Sealing successful",
  1021  				"number", number,
  1022  				"delay", delay,
  1023  				"headerDifficulty", header.Difficulty,
  1024  			)
  1025  
  1026  			tracing.SetAttributes(
  1027  				sealSpan,
  1028  				attribute.Int("number", int(number)),
  1029  				attribute.String("hash", header.Hash().String()),
  1030  				attribute.Int("delay", int(delay.Milliseconds())),
  1031  				attribute.Int("wiggle", int(wiggle.Milliseconds())),
  1032  				attribute.Bool("out-of-turn", wiggle > 0),
  1033  			)
  1034  
  1035  			tracing.EndSpan(sealSpan)
  1036  		}
  1037  		select {
  1038  		case results <- block.WithSeal(header):
  1039  		default:
  1040  			log.Warn("Sealing result was not read by miner", "number", number, "sealhash", SealHash(header, c.config))
  1041  		}
  1042  	}(sealSpan)
  1043  
  1044  	// Set the endSpan flag to false, as the go routine will handle it
  1045  	endSpan = false
  1046  
  1047  	return nil
  1048  }
  1049  
  1050  func Sign(signFn SignerFn, signer common.Address, header *types.Header, c *params.BorConfig) error {
  1051  	sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header, c))
  1052  	if err != nil {
  1053  		return err
  1054  	}
  1055  
  1056  	copy(header.Extra[len(header.Extra)-extraSeal:], sighash)
  1057  
  1058  	return nil
  1059  }
  1060  
  1061  // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
  1062  // that a new block should have based on the previous blocks in the chain and the
  1063  // current signer.
  1064  func (c *Bor) CalcDifficulty(chain consensus.ChainHeaderReader, _ uint64, parent *types.Header) *big.Int {
  1065  	snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil)
  1066  	if err != nil {
  1067  		return nil
  1068  	}
  1069  
  1070  	return new(big.Int).SetUint64(Difficulty(snap.ValidatorSet, c.authorizedSigner.Load().signer))
  1071  }
  1072  
  1073  // SealHash returns the hash of a block prior to it being sealed.
  1074  func (c *Bor) SealHash(header *types.Header) common.Hash {
  1075  	return SealHash(header, c.config)
  1076  }
  1077  
  1078  // APIs implements consensus.Engine, returning the user facing RPC API to allow
  1079  // controlling the signer voting.
  1080  func (c *Bor) APIs(chain consensus.ChainHeaderReader) []rpc.API {
  1081  	return []rpc.API{{
  1082  		Namespace: "bor",
  1083  		Version:   "1.0",
  1084  		Service:   &API{chain: chain, bor: c},
  1085  		Public:    false,
  1086  	}}
  1087  }
  1088  
  1089  // Close implements consensus.Engine. It's a noop for bor as there are no background threads.
  1090  func (c *Bor) Close() error {
  1091  	c.closeOnce.Do(func() {
  1092  		if c.HeimdallClient != nil {
  1093  			c.HeimdallClient.Close()
  1094  		}
  1095  	})
  1096  
  1097  	return nil
  1098  }
  1099  
  1100  func (c *Bor) checkAndCommitSpan(
  1101  	ctx context.Context,
  1102  	state *state.StateDB,
  1103  	header *types.Header,
  1104  	chain core.ChainContext,
  1105  ) error {
  1106  	headerNumber := header.Number.Uint64()
  1107  
  1108  	span, err := c.spanner.GetCurrentSpan(ctx, header.ParentHash)
  1109  	if err != nil {
  1110  		return err
  1111  	}
  1112  
  1113  	if c.needToCommitSpan(span, headerNumber) {
  1114  		return c.FetchAndCommitSpan(ctx, span.ID+1, state, header, chain)
  1115  	}
  1116  
  1117  	return nil
  1118  }
  1119  
  1120  func (c *Bor) needToCommitSpan(currentSpan *span.Span, headerNumber uint64) bool {
  1121  	// if span is nil
  1122  	if currentSpan == nil {
  1123  		return false
  1124  	}
  1125  
  1126  	// check span is not set initially
  1127  	if currentSpan.EndBlock == 0 {
  1128  		return true
  1129  	}
  1130  
  1131  	// if current block is first block of last sprint in current span
  1132  	if currentSpan.EndBlock > c.config.CalculateSprint(headerNumber) && currentSpan.EndBlock-c.config.CalculateSprint(headerNumber)+1 == headerNumber {
  1133  		return true
  1134  	}
  1135  
  1136  	return false
  1137  }
  1138  
  1139  func (c *Bor) FetchAndCommitSpan(
  1140  	ctx context.Context,
  1141  	newSpanID uint64,
  1142  	state *state.StateDB,
  1143  	header *types.Header,
  1144  	chain core.ChainContext,
  1145  ) error {
  1146  	var heimdallSpan span.HeimdallSpan
  1147  
  1148  	if c.HeimdallClient == nil {
  1149  		// fixme: move to a new mock or fake and remove c.HeimdallClient completely
  1150  		s, err := c.getNextHeimdallSpanForTest(ctx, newSpanID, header, chain)
  1151  		if err != nil {
  1152  			return err
  1153  		}
  1154  
  1155  		heimdallSpan = *s
  1156  	} else {
  1157  		response, err := c.HeimdallClient.Span(ctx, newSpanID)
  1158  		if err != nil {
  1159  			return err
  1160  		}
  1161  
  1162  		heimdallSpan = *response
  1163  	}
  1164  
  1165  	// check if chain id matches with Heimdall span
  1166  	if heimdallSpan.ChainID != c.chainConfig.ChainID.String() {
  1167  		return fmt.Errorf(
  1168  			"chain id proposed span, %s, and bor chain id, %s, doesn't match",
  1169  			heimdallSpan.ChainID,
  1170  			c.chainConfig.ChainID,
  1171  		)
  1172  	}
  1173  
  1174  	return c.spanner.CommitSpan(ctx, heimdallSpan, state, header, chain)
  1175  }
  1176  
  1177  // CommitStates commit states
  1178  func (c *Bor) CommitStates(
  1179  	ctx context.Context,
  1180  	state *state.StateDB,
  1181  	header *types.Header,
  1182  	chain statefull.ChainContext,
  1183  ) ([]*types.StateSyncData, error) {
  1184  	fetchStart := time.Now()
  1185  	number := header.Number.Uint64()
  1186  
  1187  	var (
  1188  		lastStateIDBig *big.Int
  1189  		from           uint64
  1190  		to             time.Time
  1191  		err            error
  1192  	)
  1193  
  1194  	if c.config.IsIndore(header.Number) {
  1195  		// Fetch the LastStateId from contract via current state instance
  1196  		lastStateIDBig, err = c.GenesisContractsClient.LastStateId(state.Copy(), number-1, header.ParentHash)
  1197  		if err != nil {
  1198  			return nil, err
  1199  		}
  1200  
  1201  		stateSyncDelay := c.config.CalculateStateSyncDelay(number)
  1202  		to = time.Unix(int64(header.Time-stateSyncDelay), 0)
  1203  	} else {
  1204  		lastStateIDBig, err = c.GenesisContractsClient.LastStateId(nil, number-1, header.ParentHash)
  1205  		if err != nil {
  1206  			return nil, err
  1207  		}
  1208  
  1209  		to = time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.CalculateSprint(number)).Time), 0)
  1210  	}
  1211  
  1212  	lastStateID := lastStateIDBig.Uint64()
  1213  	from = lastStateID + 1
  1214  
  1215  	log.Info(
  1216  		"Fetching state updates from Heimdall",
  1217  		"fromID", from,
  1218  		"to", to.Format(time.RFC3339))
  1219  
  1220  	eventRecords, err := c.HeimdallClient.StateSyncEvents(ctx, from, to.Unix())
  1221  	if err != nil {
  1222  		log.Error("Error occurred when fetching state sync events", "fromID", from, "to", to.Unix(), "err", err)
  1223  	}
  1224  
  1225  	if c.config.OverrideStateSyncRecords != nil {
  1226  		if val, ok := c.config.OverrideStateSyncRecords[strconv.FormatUint(number, 10)]; ok {
  1227  			eventRecords = eventRecords[0:val]
  1228  		}
  1229  	}
  1230  
  1231  	fetchTime := time.Since(fetchStart)
  1232  	processStart := time.Now()
  1233  	totalGas := 0 /// limit on gas for state sync per block
  1234  	chainID := c.chainConfig.ChainID.String()
  1235  	stateSyncs := make([]*types.StateSyncData, 0, len(eventRecords))
  1236  
  1237  	var gasUsed uint64
  1238  
  1239  	for _, eventRecord := range eventRecords {
  1240  		if eventRecord.ID <= lastStateID {
  1241  			continue
  1242  		}
  1243  
  1244  		if err = validateEventRecord(eventRecord, number, to, lastStateID, chainID); err != nil {
  1245  			log.Error("while validating event record", "block", number, "to", to, "stateID", lastStateID+1, "error", err.Error())
  1246  			break
  1247  		}
  1248  
  1249  		stateData := types.StateSyncData{
  1250  			ID:       eventRecord.ID,
  1251  			Contract: eventRecord.Contract,
  1252  			Data:     hex.EncodeToString(eventRecord.Data),
  1253  			TxHash:   eventRecord.TxHash,
  1254  		}
  1255  
  1256  		stateSyncs = append(stateSyncs, &stateData)
  1257  
  1258  		// we expect that this call MUST emit an event, otherwise we wouldn't make a receipt
  1259  		// if the receiver address is not a contract then we'll skip the most of the execution and emitting an event as well
  1260  		// https://github.com/maticnetwork/genesis-contracts/blob/master/contracts/StateReceiver.sol#L27
  1261  		gasUsed, err = c.GenesisContractsClient.CommitState(eventRecord, state, header, chain)
  1262  		if err != nil {
  1263  			return nil, err
  1264  		}
  1265  
  1266  		totalGas += int(gasUsed)
  1267  
  1268  		lastStateID++
  1269  	}
  1270  
  1271  	processTime := time.Since(processStart)
  1272  
  1273  	log.Info("StateSyncData", "gas", totalGas, "number", number, "lastStateID", lastStateID, "total records", len(eventRecords), "fetch time", int(fetchTime.Milliseconds()), "process time", int(processTime.Milliseconds()))
  1274  
  1275  	return stateSyncs, nil
  1276  }
  1277  
  1278  func validateEventRecord(eventRecord *clerk.EventRecordWithTime, number uint64, to time.Time, lastStateID uint64, chainID string) error {
  1279  	// event id should be sequential and event.Time should lie in the range [from, to)
  1280  	if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || !eventRecord.Time.Before(to) {
  1281  		return &InvalidStateReceivedError{number, lastStateID, &to, eventRecord}
  1282  	}
  1283  
  1284  	return nil
  1285  }
  1286  
  1287  func (c *Bor) SetHeimdallClient(h IHeimdallClient) {
  1288  	c.HeimdallClient = h
  1289  }
  1290  
  1291  func (c *Bor) GetCurrentValidators(ctx context.Context, headerHash common.Hash, blockNumber uint64) ([]*valset.Validator, error) {
  1292  	return c.spanner.GetCurrentValidatorsByHash(ctx, headerHash, blockNumber)
  1293  }
  1294  
  1295  //
  1296  // Private methods
  1297  //
  1298  
  1299  func (c *Bor) getNextHeimdallSpanForTest(
  1300  	ctx context.Context,
  1301  	newSpanID uint64,
  1302  	header *types.Header,
  1303  	chain core.ChainContext,
  1304  ) (*span.HeimdallSpan, error) {
  1305  	headerNumber := header.Number.Uint64()
  1306  
  1307  	spanBor, err := c.spanner.GetCurrentSpan(ctx, header.ParentHash)
  1308  	if err != nil {
  1309  		return nil, err
  1310  	}
  1311  
  1312  	// get local chain context object
  1313  	localContext := chain.(statefull.ChainContext)
  1314  	// Retrieve the snapshot needed to verify this header and cache it
  1315  	snap, err := c.snapshot(localContext.Chain, headerNumber-1, header.ParentHash, nil)
  1316  	if err != nil {
  1317  		return nil, err
  1318  	}
  1319  
  1320  	// new span
  1321  	spanBor.ID = newSpanID
  1322  	if spanBor.EndBlock == 0 {
  1323  		spanBor.StartBlock = 256
  1324  	} else {
  1325  		spanBor.StartBlock = spanBor.EndBlock + 1
  1326  	}
  1327  
  1328  	spanBor.EndBlock = spanBor.StartBlock + (100 * c.config.CalculateSprint(headerNumber)) - 1
  1329  
  1330  	selectedProducers := make([]valset.Validator, len(snap.ValidatorSet.Validators))
  1331  	for i, v := range snap.ValidatorSet.Validators {
  1332  		selectedProducers[i] = *v
  1333  	}
  1334  
  1335  	heimdallSpan := &span.HeimdallSpan{
  1336  		Span:              *spanBor,
  1337  		ValidatorSet:      *snap.ValidatorSet,
  1338  		SelectedProducers: selectedProducers,
  1339  		ChainID:           c.chainConfig.ChainID.String(),
  1340  	}
  1341  
  1342  	return heimdallSpan, nil
  1343  }
  1344  
  1345  func validatorContains(a []*valset.Validator, x *valset.Validator) (*valset.Validator, bool) {
  1346  	for _, n := range a {
  1347  		if n.Address == x.Address {
  1348  			return n, true
  1349  		}
  1350  	}
  1351  
  1352  	return nil, false
  1353  }
  1354  
  1355  func getUpdatedValidatorSet(oldValidatorSet *valset.ValidatorSet, newVals []*valset.Validator) *valset.ValidatorSet {
  1356  	v := oldValidatorSet
  1357  	oldVals := v.Validators
  1358  
  1359  	changes := make([]*valset.Validator, 0, len(oldVals))
  1360  
  1361  	for _, ov := range oldVals {
  1362  		if f, ok := validatorContains(newVals, ov); ok {
  1363  			ov.VotingPower = f.VotingPower
  1364  		} else {
  1365  			ov.VotingPower = 0
  1366  		}
  1367  
  1368  		changes = append(changes, ov)
  1369  	}
  1370  
  1371  	for _, nv := range newVals {
  1372  		if _, ok := validatorContains(changes, nv); !ok {
  1373  			changes = append(changes, nv)
  1374  		}
  1375  	}
  1376  
  1377  	if err := v.UpdateWithChangeSet(changes); err != nil {
  1378  		log.Error("Error while updating change set", "error", err)
  1379  	}
  1380  
  1381  	return v
  1382  }
  1383  
  1384  func IsSprintStart(number, sprint uint64) bool {
  1385  	return number%sprint == 0
  1386  }