github.com/jimmyx0x/go-ethereum@v1.10.28/core/blockchain.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package core implements the Ethereum consensus protocol.
    18  package core
    19  
    20  import (
    21  	"errors"
    22  	"fmt"
    23  	"io"
    24  	"math/big"
    25  	"runtime"
    26  	"sort"
    27  	"strings"
    28  	"sync"
    29  	"sync/atomic"
    30  	"time"
    31  
    32  	"github.com/ethereum/go-ethereum/common"
    33  	"github.com/ethereum/go-ethereum/common/lru"
    34  	"github.com/ethereum/go-ethereum/common/mclock"
    35  	"github.com/ethereum/go-ethereum/common/prque"
    36  	"github.com/ethereum/go-ethereum/consensus"
    37  	"github.com/ethereum/go-ethereum/core/rawdb"
    38  	"github.com/ethereum/go-ethereum/core/state"
    39  	"github.com/ethereum/go-ethereum/core/state/snapshot"
    40  	"github.com/ethereum/go-ethereum/core/types"
    41  	"github.com/ethereum/go-ethereum/core/vm"
    42  	"github.com/ethereum/go-ethereum/ethdb"
    43  	"github.com/ethereum/go-ethereum/event"
    44  	"github.com/ethereum/go-ethereum/internal/syncx"
    45  	"github.com/ethereum/go-ethereum/internal/version"
    46  	"github.com/ethereum/go-ethereum/log"
    47  	"github.com/ethereum/go-ethereum/metrics"
    48  	"github.com/ethereum/go-ethereum/params"
    49  	"github.com/ethereum/go-ethereum/rlp"
    50  	"github.com/ethereum/go-ethereum/trie"
    51  )
    52  
    53  var (
    54  	headBlockGauge          = metrics.NewRegisteredGauge("chain/head/block", nil)
    55  	headHeaderGauge         = metrics.NewRegisteredGauge("chain/head/header", nil)
    56  	headFastBlockGauge      = metrics.NewRegisteredGauge("chain/head/receipt", nil)
    57  	headFinalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil)
    58  	headSafeBlockGauge      = metrics.NewRegisteredGauge("chain/head/safe", nil)
    59  
    60  	accountReadTimer   = metrics.NewRegisteredTimer("chain/account/reads", nil)
    61  	accountHashTimer   = metrics.NewRegisteredTimer("chain/account/hashes", nil)
    62  	accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil)
    63  	accountCommitTimer = metrics.NewRegisteredTimer("chain/account/commits", nil)
    64  
    65  	storageReadTimer   = metrics.NewRegisteredTimer("chain/storage/reads", nil)
    66  	storageHashTimer   = metrics.NewRegisteredTimer("chain/storage/hashes", nil)
    67  	storageUpdateTimer = metrics.NewRegisteredTimer("chain/storage/updates", nil)
    68  	storageCommitTimer = metrics.NewRegisteredTimer("chain/storage/commits", nil)
    69  
    70  	snapshotAccountReadTimer = metrics.NewRegisteredTimer("chain/snapshot/account/reads", nil)
    71  	snapshotStorageReadTimer = metrics.NewRegisteredTimer("chain/snapshot/storage/reads", nil)
    72  	snapshotCommitTimer      = metrics.NewRegisteredTimer("chain/snapshot/commits", nil)
    73  
    74  	triedbCommitTimer = metrics.NewRegisteredTimer("chain/triedb/commits", nil)
    75  
    76  	blockInsertTimer     = metrics.NewRegisteredTimer("chain/inserts", nil)
    77  	blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil)
    78  	blockExecutionTimer  = metrics.NewRegisteredTimer("chain/execution", nil)
    79  	blockWriteTimer      = metrics.NewRegisteredTimer("chain/write", nil)
    80  
    81  	blockReorgMeter     = metrics.NewRegisteredMeter("chain/reorg/executes", nil)
    82  	blockReorgAddMeter  = metrics.NewRegisteredMeter("chain/reorg/add", nil)
    83  	blockReorgDropMeter = metrics.NewRegisteredMeter("chain/reorg/drop", nil)
    84  
    85  	blockPrefetchExecuteTimer   = metrics.NewRegisteredTimer("chain/prefetch/executes", nil)
    86  	blockPrefetchInterruptMeter = metrics.NewRegisteredMeter("chain/prefetch/interrupts", nil)
    87  
    88  	errInsertionInterrupted = errors.New("insertion is interrupted")
    89  	errChainStopped         = errors.New("blockchain is stopped")
    90  )
    91  
    92  const (
    93  	bodyCacheLimit      = 256
    94  	blockCacheLimit     = 256
    95  	receiptsCacheLimit  = 32
    96  	txLookupCacheLimit  = 1024
    97  	maxFutureBlocks     = 256
    98  	maxTimeFutureBlocks = 30
    99  	TriesInMemory       = 128
   100  
   101  	// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
   102  	//
   103  	// Changelog:
   104  	//
   105  	// - Version 4
   106  	//   The following incompatible database changes were added:
   107  	//   * the `BlockNumber`, `TxHash`, `TxIndex`, `BlockHash` and `Index` fields of log are deleted
   108  	//   * the `Bloom` field of receipt is deleted
   109  	//   * the `BlockIndex` and `TxIndex` fields of txlookup are deleted
   110  	// - Version 5
   111  	//  The following incompatible database changes were added:
   112  	//    * the `TxHash`, `GasCost`, and `ContractAddress` fields are no longer stored for a receipt
   113  	//    * the `TxHash`, `GasCost`, and `ContractAddress` fields are computed by looking up the
   114  	//      receipts' corresponding block
   115  	// - Version 6
   116  	//  The following incompatible database changes were added:
   117  	//    * Transaction lookup information stores the corresponding block number instead of block hash
   118  	// - Version 7
   119  	//  The following incompatible database changes were added:
   120  	//    * Use freezer as the ancient database to maintain all ancient data
   121  	// - Version 8
   122  	//  The following incompatible database changes were added:
   123  	//    * New scheme for contract code in order to separate the codes and trie nodes
   124  	BlockChainVersion uint64 = 8
   125  )
   126  
   127  // CacheConfig contains the configuration values for the trie database
   128  // that's resident in a blockchain.
   129  type CacheConfig struct {
   130  	TrieCleanLimit      int           // Memory allowance (MB) to use for caching trie nodes in memory
   131  	TrieCleanJournal    string        // Disk journal for saving clean cache entries.
   132  	TrieCleanRejournal  time.Duration // Time interval to dump clean cache to disk periodically
   133  	TrieCleanNoPrefetch bool          // Whether to disable heuristic state prefetching for followup blocks
   134  	TrieDirtyLimit      int           // Memory limit (MB) at which to start flushing dirty trie nodes to disk
   135  	TrieDirtyDisabled   bool          // Whether to disable trie write caching and GC altogether (archive node)
   136  	TrieTimeLimit       time.Duration // Time limit after which to flush the current in-memory trie to disk
   137  	SnapshotLimit       int           // Memory allowance (MB) to use for caching snapshot entries in memory
   138  	Preimages           bool          // Whether to store preimage of trie key to the disk
   139  
   140  	SnapshotNoBuild bool // Whether the background generation is allowed
   141  	SnapshotWait    bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it
   142  }
   143  
   144  // defaultCacheConfig are the default caching values if none are specified by the
   145  // user (also used during testing).
   146  var defaultCacheConfig = &CacheConfig{
   147  	TrieCleanLimit: 256,
   148  	TrieDirtyLimit: 256,
   149  	TrieTimeLimit:  5 * time.Minute,
   150  	SnapshotLimit:  256,
   151  	SnapshotWait:   true,
   152  }
   153  
   154  // BlockChain represents the canonical chain given a database with a genesis
   155  // block. The Blockchain manages chain imports, reverts, chain reorganisations.
   156  //
   157  // Importing blocks in to the block chain happens according to the set of rules
   158  // defined by the two stage Validator. Processing of blocks is done using the
   159  // Processor which processes the included transaction. The validation of the state
   160  // is done in the second part of the Validator. Failing results in aborting of
   161  // the import.
   162  //
   163  // The BlockChain also helps in returning blocks from **any** chain included
   164  // in the database as well as blocks that represents the canonical chain. It's
   165  // important to note that GetBlock can return any block and does not need to be
   166  // included in the canonical one where as GetBlockByNumber always represents the
   167  // canonical chain.
   168  type BlockChain struct {
   169  	chainConfig *params.ChainConfig // Chain & network configuration
   170  	cacheConfig *CacheConfig        // Cache configuration for pruning
   171  
   172  	db            ethdb.Database // Low level persistent database to store final content in
   173  	snaps         *snapshot.Tree // Snapshot tree for fast trie leaf access
   174  	triegc        *prque.Prque   // Priority queue mapping block numbers to tries to gc
   175  	gcproc        time.Duration  // Accumulates canonical block processing for trie dumping
   176  	lastWrite     uint64         // Last block when the state was flushed
   177  	flushInterval int64          // Time interval (processing time) after which to flush a state
   178  	triedb        *trie.Database // The database handler for maintaining trie nodes.
   179  	stateCache    state.Database // State database to reuse between imports (contains state cache)
   180  
   181  	// txLookupLimit is the maximum number of blocks from head whose tx indices
   182  	// are reserved:
   183  	//  * 0:   means no limit and regenerate any missing indexes
   184  	//  * N:   means N block limit [HEAD-N+1, HEAD] and delete extra indexes
   185  	//  * nil: disable tx reindexer/deleter, but still index new blocks
   186  	txLookupLimit uint64
   187  
   188  	hc            *HeaderChain
   189  	rmLogsFeed    event.Feed
   190  	chainFeed     event.Feed
   191  	chainSideFeed event.Feed
   192  	chainHeadFeed event.Feed
   193  	logsFeed      event.Feed
   194  	blockProcFeed event.Feed
   195  	scope         event.SubscriptionScope
   196  	genesisBlock  *types.Block
   197  
   198  	// This mutex synchronizes chain write operations.
   199  	// Readers don't need to take it, they can just read the database.
   200  	chainmu *syncx.ClosableMutex
   201  
   202  	currentBlock          atomic.Value // Current head of the block chain
   203  	currentFastBlock      atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
   204  	currentFinalizedBlock atomic.Value // Current finalized head
   205  	currentSafeBlock      atomic.Value // Current safe head
   206  
   207  	bodyCache     *lru.Cache[common.Hash, *types.Body]
   208  	bodyRLPCache  *lru.Cache[common.Hash, rlp.RawValue]
   209  	receiptsCache *lru.Cache[common.Hash, []*types.Receipt]
   210  	blockCache    *lru.Cache[common.Hash, *types.Block]
   211  	txLookupCache *lru.Cache[common.Hash, *rawdb.LegacyTxLookupEntry]
   212  
   213  	// future blocks are blocks added for later processing
   214  	futureBlocks *lru.Cache[common.Hash, *types.Block]
   215  
   216  	wg            sync.WaitGroup //
   217  	quit          chan struct{}  // shutdown signal, closed in Stop.
   218  	running       int32          // 0 if chain is running, 1 when stopped
   219  	procInterrupt int32          // interrupt signaler for block processing
   220  
   221  	engine     consensus.Engine
   222  	validator  Validator // Block and state validator interface
   223  	prefetcher Prefetcher
   224  	processor  Processor // Block transaction processor interface
   225  	forker     *ForkChoice
   226  	vmConfig   vm.Config
   227  }
   228  
   229  // NewBlockChain returns a fully initialised block chain using information
   230  // available in the database. It initialises the default Ethereum Validator
   231  // and Processor.
   232  func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, overrides *ChainOverrides, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64) (*BlockChain, error) {
   233  	if cacheConfig == nil {
   234  		cacheConfig = defaultCacheConfig
   235  	}
   236  
   237  	// Open trie database with provided config
   238  	triedb := trie.NewDatabaseWithConfig(db, &trie.Config{
   239  		Cache:     cacheConfig.TrieCleanLimit,
   240  		Journal:   cacheConfig.TrieCleanJournal,
   241  		Preimages: cacheConfig.Preimages,
   242  	})
   243  	// Setup the genesis block, commit the provided genesis specification
   244  	// to database if the genesis block is not present yet, or load the
   245  	// stored one from database.
   246  	chainConfig, genesisHash, genesisErr := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides)
   247  	if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
   248  		return nil, genesisErr
   249  	}
   250  	log.Info("")
   251  	log.Info(strings.Repeat("-", 153))
   252  	for _, line := range strings.Split(chainConfig.Description(), "\n") {
   253  		log.Info(line)
   254  	}
   255  	log.Info(strings.Repeat("-", 153))
   256  	log.Info("")
   257  
   258  	bc := &BlockChain{
   259  		chainConfig:   chainConfig,
   260  		cacheConfig:   cacheConfig,
   261  		db:            db,
   262  		triedb:        triedb,
   263  		flushInterval: int64(cacheConfig.TrieTimeLimit),
   264  		triegc:        prque.New(nil),
   265  		quit:          make(chan struct{}),
   266  		chainmu:       syncx.NewClosableMutex(),
   267  		bodyCache:     lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
   268  		bodyRLPCache:  lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
   269  		receiptsCache: lru.NewCache[common.Hash, []*types.Receipt](receiptsCacheLimit),
   270  		blockCache:    lru.NewCache[common.Hash, *types.Block](blockCacheLimit),
   271  		txLookupCache: lru.NewCache[common.Hash, *rawdb.LegacyTxLookupEntry](txLookupCacheLimit),
   272  		futureBlocks:  lru.NewCache[common.Hash, *types.Block](maxFutureBlocks),
   273  		engine:        engine,
   274  		vmConfig:      vmConfig,
   275  	}
   276  	bc.forker = NewForkChoice(bc, shouldPreserve)
   277  	bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb)
   278  	bc.validator = NewBlockValidator(chainConfig, bc, engine)
   279  	bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine)
   280  	bc.processor = NewStateProcessor(chainConfig, bc, engine)
   281  
   282  	var err error
   283  	bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped)
   284  	if err != nil {
   285  		return nil, err
   286  	}
   287  	bc.genesisBlock = bc.GetBlockByNumber(0)
   288  	if bc.genesisBlock == nil {
   289  		return nil, ErrNoGenesis
   290  	}
   291  
   292  	var nilBlock *types.Block
   293  	bc.currentBlock.Store(nilBlock)
   294  	bc.currentFastBlock.Store(nilBlock)
   295  	bc.currentFinalizedBlock.Store(nilBlock)
   296  	bc.currentSafeBlock.Store(nilBlock)
   297  
   298  	// If Geth is initialized with an external ancient store, re-initialize the
   299  	// missing chain indexes and chain flags. This procedure can survive crash
   300  	// and can be resumed in next restart since chain flags are updated in last step.
   301  	if bc.empty() {
   302  		rawdb.InitDatabaseFromFreezer(bc.db)
   303  	}
   304  	// Load blockchain states from disk
   305  	if err := bc.loadLastState(); err != nil {
   306  		return nil, err
   307  	}
   308  	// Make sure the state associated with the block is available
   309  	head := bc.CurrentBlock()
   310  	if !bc.HasState(head.Root()) {
   311  		// Head state is missing, before the state recovery, find out the
   312  		// disk layer point of snapshot(if it's enabled). Make sure the
   313  		// rewound point is lower than disk layer.
   314  		var diskRoot common.Hash
   315  		if bc.cacheConfig.SnapshotLimit > 0 {
   316  			diskRoot = rawdb.ReadSnapshotRoot(bc.db)
   317  		}
   318  		if diskRoot != (common.Hash{}) {
   319  			log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot)
   320  
   321  			snapDisk, err := bc.setHeadBeyondRoot(head.NumberU64(), 0, diskRoot, true)
   322  			if err != nil {
   323  				return nil, err
   324  			}
   325  			// Chain rewound, persist old snapshot number to indicate recovery procedure
   326  			if snapDisk != 0 {
   327  				rawdb.WriteSnapshotRecoveryNumber(bc.db, snapDisk)
   328  			}
   329  		} else {
   330  			log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash())
   331  			if _, err := bc.setHeadBeyondRoot(head.NumberU64(), 0, common.Hash{}, true); err != nil {
   332  				return nil, err
   333  			}
   334  		}
   335  	}
   336  
   337  	// Ensure that a previous crash in SetHead doesn't leave extra ancients
   338  	if frozen, err := bc.db.Ancients(); err == nil && frozen > 0 {
   339  		var (
   340  			needRewind bool
   341  			low        uint64
   342  		)
   343  		// The head full block may be rolled back to a very low height due to
   344  		// blockchain repair. If the head full block is even lower than the ancient
   345  		// chain, truncate the ancient store.
   346  		fullBlock := bc.CurrentBlock()
   347  		if fullBlock != nil && fullBlock.Hash() != bc.genesisBlock.Hash() && fullBlock.NumberU64() < frozen-1 {
   348  			needRewind = true
   349  			low = fullBlock.NumberU64()
   350  		}
   351  		// In fast sync, it may happen that ancient data has been written to the
   352  		// ancient store, but the LastFastBlock has not been updated, truncate the
   353  		// extra data here.
   354  		fastBlock := bc.CurrentFastBlock()
   355  		if fastBlock != nil && fastBlock.NumberU64() < frozen-1 {
   356  			needRewind = true
   357  			if fastBlock.NumberU64() < low || low == 0 {
   358  				low = fastBlock.NumberU64()
   359  			}
   360  		}
   361  		if needRewind {
   362  			log.Error("Truncating ancient chain", "from", bc.CurrentHeader().Number.Uint64(), "to", low)
   363  			if err := bc.SetHead(low); err != nil {
   364  				return nil, err
   365  			}
   366  		}
   367  	}
   368  	// The first thing the node will do is reconstruct the verification data for
   369  	// the head block (ethash cache or clique voting snapshot). Might as well do
   370  	// it in advance.
   371  	bc.engine.VerifyHeader(bc, bc.CurrentHeader(), true)
   372  
   373  	// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
   374  	for hash := range BadHashes {
   375  		if header := bc.GetHeaderByHash(hash); header != nil {
   376  			// get the canonical block corresponding to the offending header's number
   377  			headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64())
   378  			// make sure the headerByNumber (if present) is in our current canonical chain
   379  			if headerByNumber != nil && headerByNumber.Hash() == header.Hash() {
   380  				log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash)
   381  				if err := bc.SetHead(header.Number.Uint64() - 1); err != nil {
   382  					return nil, err
   383  				}
   384  				log.Error("Chain rewind was successful, resuming normal operation")
   385  			}
   386  		}
   387  	}
   388  
   389  	// Load any existing snapshot, regenerating it if loading failed
   390  	if bc.cacheConfig.SnapshotLimit > 0 {
   391  		// If the chain was rewound past the snapshot persistent layer (causing
   392  		// a recovery block number to be persisted to disk), check if we're still
   393  		// in recovery mode and in that case, don't invalidate the snapshot on a
   394  		// head mismatch.
   395  		var recover bool
   396  
   397  		head := bc.CurrentBlock()
   398  		if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer >= head.NumberU64() {
   399  			log.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer)
   400  			recover = true
   401  		}
   402  		snapconfig := snapshot.Config{
   403  			CacheSize:  bc.cacheConfig.SnapshotLimit,
   404  			Recovery:   recover,
   405  			NoBuild:    bc.cacheConfig.SnapshotNoBuild,
   406  			AsyncBuild: !bc.cacheConfig.SnapshotWait,
   407  		}
   408  		bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root())
   409  	}
   410  
   411  	// Start future block processor.
   412  	bc.wg.Add(1)
   413  	go bc.updateFutureBlocks()
   414  
   415  	// If periodic cache journal is required, spin it up.
   416  	if bc.cacheConfig.TrieCleanRejournal > 0 {
   417  		if bc.cacheConfig.TrieCleanRejournal < time.Minute {
   418  			log.Warn("Sanitizing invalid trie cache journal time", "provided", bc.cacheConfig.TrieCleanRejournal, "updated", time.Minute)
   419  			bc.cacheConfig.TrieCleanRejournal = time.Minute
   420  		}
   421  		bc.wg.Add(1)
   422  		go func() {
   423  			defer bc.wg.Done()
   424  			bc.triedb.SaveCachePeriodically(bc.cacheConfig.TrieCleanJournal, bc.cacheConfig.TrieCleanRejournal, bc.quit)
   425  		}()
   426  	}
   427  	// Rewind the chain in case of an incompatible config upgrade.
   428  	if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
   429  		log.Warn("Rewinding chain to upgrade configuration", "err", compat)
   430  		if compat.RewindToTime > 0 {
   431  			bc.SetHeadWithTimestamp(compat.RewindToTime)
   432  		} else {
   433  			bc.SetHead(compat.RewindToBlock)
   434  		}
   435  		rawdb.WriteChainConfig(db, genesisHash, chainConfig)
   436  	}
   437  	// Start tx indexer/unindexer if required.
   438  	if txLookupLimit != nil {
   439  		bc.txLookupLimit = *txLookupLimit
   440  
   441  		bc.wg.Add(1)
   442  		go bc.maintainTxIndex()
   443  	}
   444  	return bc, nil
   445  }
   446  
   447  // empty returns an indicator whether the blockchain is empty.
   448  // Note, it's a special case that we connect a non-empty ancient
   449  // database with an empty node, so that we can plugin the ancient
   450  // into node seamlessly.
   451  func (bc *BlockChain) empty() bool {
   452  	genesis := bc.genesisBlock.Hash()
   453  	for _, hash := range []common.Hash{rawdb.ReadHeadBlockHash(bc.db), rawdb.ReadHeadHeaderHash(bc.db), rawdb.ReadHeadFastBlockHash(bc.db)} {
   454  		if hash != genesis {
   455  			return false
   456  		}
   457  	}
   458  	return true
   459  }
   460  
   461  // loadLastState loads the last known chain state from the database. This method
   462  // assumes that the chain manager mutex is held.
   463  func (bc *BlockChain) loadLastState() error {
   464  	// Restore the last known head block
   465  	head := rawdb.ReadHeadBlockHash(bc.db)
   466  	if head == (common.Hash{}) {
   467  		// Corrupt or empty database, init from scratch
   468  		log.Warn("Empty database, resetting chain")
   469  		return bc.Reset()
   470  	}
   471  	// Make sure the entire head block is available
   472  	currentBlock := bc.GetBlockByHash(head)
   473  	if currentBlock == nil {
   474  		// Corrupt or empty database, init from scratch
   475  		log.Warn("Head block missing, resetting chain", "hash", head)
   476  		return bc.Reset()
   477  	}
   478  	// Everything seems to be fine, set as the head block
   479  	bc.currentBlock.Store(currentBlock)
   480  	headBlockGauge.Update(int64(currentBlock.NumberU64()))
   481  
   482  	// Restore the last known head header
   483  	currentHeader := currentBlock.Header()
   484  	if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
   485  		if header := bc.GetHeaderByHash(head); header != nil {
   486  			currentHeader = header
   487  		}
   488  	}
   489  	bc.hc.SetCurrentHeader(currentHeader)
   490  
   491  	// Restore the last known head fast block
   492  	bc.currentFastBlock.Store(currentBlock)
   493  	headFastBlockGauge.Update(int64(currentBlock.NumberU64()))
   494  
   495  	if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
   496  		if block := bc.GetBlockByHash(head); block != nil {
   497  			bc.currentFastBlock.Store(block)
   498  			headFastBlockGauge.Update(int64(block.NumberU64()))
   499  		}
   500  	}
   501  
   502  	// Restore the last known finalized block and safe block
   503  	// Note: the safe block is not stored on disk and it is set to the last
   504  	// known finalized block on startup
   505  	if head := rawdb.ReadFinalizedBlockHash(bc.db); head != (common.Hash{}) {
   506  		if block := bc.GetBlockByHash(head); block != nil {
   507  			bc.currentFinalizedBlock.Store(block)
   508  			headFinalizedBlockGauge.Update(int64(block.NumberU64()))
   509  			bc.currentSafeBlock.Store(block)
   510  			headSafeBlockGauge.Update(int64(block.NumberU64()))
   511  		}
   512  	}
   513  	// Issue a status log for the user
   514  	currentFastBlock := bc.CurrentFastBlock()
   515  	currentFinalizedBlock := bc.CurrentFinalizedBlock()
   516  
   517  	headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
   518  	blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
   519  	fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64())
   520  
   521  	log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time), 0)))
   522  	log.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(currentBlock.Time()), 0)))
   523  	log.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentFastBlock.Time()), 0)))
   524  
   525  	if currentFinalizedBlock != nil {
   526  		finalTd := bc.GetTd(currentFinalizedBlock.Hash(), currentFinalizedBlock.NumberU64())
   527  		log.Info("Loaded most recent local finalized block", "number", currentFinalizedBlock.Number(), "hash", currentFinalizedBlock.Hash(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalizedBlock.Time()), 0)))
   528  	}
   529  	if pivot := rawdb.ReadLastPivotNumber(bc.db); pivot != nil {
   530  		log.Info("Loaded last fast-sync pivot marker", "number", *pivot)
   531  	}
   532  	return nil
   533  }
   534  
   535  // SetHead rewinds the local chain to a new head. Depending on whether the node
   536  // was fast synced or full synced and in which state, the method will try to
   537  // delete minimal data from disk whilst retaining chain consistency.
   538  func (bc *BlockChain) SetHead(head uint64) error {
   539  	if _, err := bc.setHeadBeyondRoot(head, 0, common.Hash{}, false); err != nil {
   540  		return err
   541  	}
   542  	// Send chain head event to update the transaction pool
   543  	bc.chainHeadFeed.Send(ChainHeadEvent{Block: bc.CurrentBlock()})
   544  	return nil
   545  }
   546  
   547  // SetHeadWithTimestamp rewinds the local chain to a new head that has at max
   548  // the given timestamp. Depending on whether the node was fast synced or full
   549  // synced and in which state, the method will try to delete minimal data from
   550  // disk whilst retaining chain consistency.
   551  func (bc *BlockChain) SetHeadWithTimestamp(timestamp uint64) error {
   552  	if _, err := bc.setHeadBeyondRoot(0, timestamp, common.Hash{}, false); err != nil {
   553  		return err
   554  	}
   555  	// Send chain head event to update the transaction pool
   556  	bc.chainHeadFeed.Send(ChainHeadEvent{Block: bc.CurrentBlock()})
   557  	return nil
   558  }
   559  
   560  // SetFinalized sets the finalized block.
   561  func (bc *BlockChain) SetFinalized(block *types.Block) {
   562  	bc.currentFinalizedBlock.Store(block)
   563  	if block != nil {
   564  		rawdb.WriteFinalizedBlockHash(bc.db, block.Hash())
   565  		headFinalizedBlockGauge.Update(int64(block.NumberU64()))
   566  	} else {
   567  		rawdb.WriteFinalizedBlockHash(bc.db, common.Hash{})
   568  		headFinalizedBlockGauge.Update(0)
   569  	}
   570  }
   571  
   572  // SetSafe sets the safe block.
   573  func (bc *BlockChain) SetSafe(block *types.Block) {
   574  	bc.currentSafeBlock.Store(block)
   575  	if block != nil {
   576  		headSafeBlockGauge.Update(int64(block.NumberU64()))
   577  	} else {
   578  		headSafeBlockGauge.Update(0)
   579  	}
   580  }
   581  
   582  // setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
   583  // that the rewind must pass the specified state root. This method is meant to be
   584  // used when rewinding with snapshots enabled to ensure that we go back further than
   585  // persistent disk layer. Depending on whether the node was fast synced or full, and
   586  // in which state, the method will try to delete minimal data from disk whilst
   587  // retaining chain consistency.
   588  //
   589  // The method also works in timestamp mode if `head == 0` but `time != 0`. In that
   590  // case blocks are rolled back until the new head becomes older or equal to the
   591  // requested time. If both `head` and `time` is 0, the chain is rewound to genesis.
   592  //
   593  // The method returns the block number where the requested root cap was found.
   594  func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Hash, repair bool) (uint64, error) {
   595  	if !bc.chainmu.TryLock() {
   596  		return 0, errChainStopped
   597  	}
   598  	defer bc.chainmu.Unlock()
   599  
   600  	// Track the block number of the requested root hash
   601  	var rootNumber uint64 // (no root == always 0)
   602  
   603  	// Retrieve the last pivot block to short circuit rollbacks beyond it and the
   604  	// current freezer limit to start nuking id underflown
   605  	pivot := rawdb.ReadLastPivotNumber(bc.db)
   606  	frozen, _ := bc.db.Ancients()
   607  
   608  	updateFn := func(db ethdb.KeyValueWriter, header *types.Header) (*types.Header, bool) {
   609  		// Rewind the blockchain, ensuring we don't end up with a stateless head
   610  		// block. Note, depth equality is permitted to allow using SetHead as a
   611  		// chain reparation mechanism without deleting any data!
   612  		if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() {
   613  			newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
   614  			if newHeadBlock == nil {
   615  				log.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash())
   616  				newHeadBlock = bc.genesisBlock
   617  			} else {
   618  				// Block exists, keep rewinding until we find one with state,
   619  				// keeping rewinding until we exceed the optional threshold
   620  				// root hash
   621  				beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true)
   622  
   623  				for {
   624  					// If a root threshold was requested but not yet crossed, check
   625  					if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root {
   626  						beyondRoot, rootNumber = true, newHeadBlock.NumberU64()
   627  					}
   628  					if !bc.HasState(newHeadBlock.Root()) {
   629  						log.Trace("Block state missing, rewinding further", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
   630  						if pivot == nil || newHeadBlock.NumberU64() > *pivot {
   631  							parent := bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1)
   632  							if parent != nil {
   633  								newHeadBlock = parent
   634  								continue
   635  							}
   636  							log.Error("Missing block in the middle, aiming genesis", "number", newHeadBlock.NumberU64()-1, "hash", newHeadBlock.ParentHash())
   637  							newHeadBlock = bc.genesisBlock
   638  						} else {
   639  							log.Trace("Rewind passed pivot, aiming genesis", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "pivot", *pivot)
   640  							newHeadBlock = bc.genesisBlock
   641  						}
   642  					}
   643  					if beyondRoot || newHeadBlock.NumberU64() == 0 {
   644  						if newHeadBlock.NumberU64() == 0 {
   645  							// Recommit the genesis state into disk in case the rewinding destination
   646  							// is genesis block and the relevant state is gone. In the future this
   647  							// rewinding destination can be the earliest block stored in the chain
   648  							// if the historical chain pruning is enabled. In that case the logic
   649  							// needs to be improved here.
   650  							if !bc.HasState(bc.genesisBlock.Root()) {
   651  								if err := CommitGenesisState(bc.db, bc.triedb, bc.genesisBlock.Hash()); err != nil {
   652  									log.Crit("Failed to commit genesis state", "err", err)
   653  								}
   654  								log.Debug("Recommitted genesis state to disk")
   655  							}
   656  						}
   657  						log.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
   658  						break
   659  					}
   660  					log.Debug("Skipping block with threshold state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "root", newHeadBlock.Root())
   661  					newHeadBlock = bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) // Keep rewinding
   662  				}
   663  			}
   664  			rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash())
   665  
   666  			// Degrade the chain markers if they are explicitly reverted.
   667  			// In theory we should update all in-memory markers in the
   668  			// last step, however the direction of SetHead is from high
   669  			// to low, so it's safe to update in-memory markers directly.
   670  			bc.currentBlock.Store(newHeadBlock)
   671  			headBlockGauge.Update(int64(newHeadBlock.NumberU64()))
   672  		}
   673  		// Rewind the fast block in a simpleton way to the target head
   674  		if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() {
   675  			newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
   676  			// If either blocks reached nil, reset to the genesis state
   677  			if newHeadFastBlock == nil {
   678  				newHeadFastBlock = bc.genesisBlock
   679  			}
   680  			rawdb.WriteHeadFastBlockHash(db, newHeadFastBlock.Hash())
   681  
   682  			// Degrade the chain markers if they are explicitly reverted.
   683  			// In theory we should update all in-memory markers in the
   684  			// last step, however the direction of SetHead is from high
   685  			// to low, so it's safe the update in-memory markers directly.
   686  			bc.currentFastBlock.Store(newHeadFastBlock)
   687  			headFastBlockGauge.Update(int64(newHeadFastBlock.NumberU64()))
   688  		}
   689  		var (
   690  			headHeader = bc.CurrentBlock().Header()
   691  			headNumber = headHeader.Number.Uint64()
   692  		)
   693  		// If setHead underflown the freezer threshold and the block processing
   694  		// intent afterwards is full block importing, delete the chain segment
   695  		// between the stateful-block and the sethead target.
   696  		var wipe bool
   697  		if headNumber+1 < frozen {
   698  			wipe = pivot == nil || headNumber >= *pivot
   699  		}
   700  		return headHeader, wipe // Only force wipe if full synced
   701  	}
   702  	// Rewind the header chain, deleting all block bodies until then
   703  	delFn := func(db ethdb.KeyValueWriter, hash common.Hash, num uint64) {
   704  		// Ignore the error here since light client won't hit this path
   705  		frozen, _ := bc.db.Ancients()
   706  		if num+1 <= frozen {
   707  			// Truncate all relative data(header, total difficulty, body, receipt
   708  			// and canonical hash) from ancient store.
   709  			if err := bc.db.TruncateHead(num); err != nil {
   710  				log.Crit("Failed to truncate ancient data", "number", num, "err", err)
   711  			}
   712  			// Remove the hash <-> number mapping from the active store.
   713  			rawdb.DeleteHeaderNumber(db, hash)
   714  		} else {
   715  			// Remove relative body and receipts from the active store.
   716  			// The header, total difficulty and canonical hash will be
   717  			// removed in the hc.SetHead function.
   718  			rawdb.DeleteBody(db, hash, num)
   719  			rawdb.DeleteReceipts(db, hash, num)
   720  		}
   721  		// Todo(rjl493456442) txlookup, bloombits, etc
   722  	}
   723  	// If SetHead was only called as a chain reparation method, try to skip
   724  	// touching the header chain altogether, unless the freezer is broken
   725  	if repair {
   726  		if target, force := updateFn(bc.db, bc.CurrentBlock().Header()); force {
   727  			bc.hc.SetHead(target.Number.Uint64(), updateFn, delFn)
   728  		}
   729  	} else {
   730  		// Rewind the chain to the requested head and keep going backwards until a
   731  		// block with a state is found or fast sync pivot is passed
   732  		if time > 0 {
   733  			log.Warn("Rewinding blockchain to timestamp", "target", time)
   734  			bc.hc.SetHeadWithTimestamp(time, updateFn, delFn)
   735  		} else {
   736  			log.Warn("Rewinding blockchain to block", "target", head)
   737  			bc.hc.SetHead(head, updateFn, delFn)
   738  		}
   739  	}
   740  	// Clear out any stale content from the caches
   741  	bc.bodyCache.Purge()
   742  	bc.bodyRLPCache.Purge()
   743  	bc.receiptsCache.Purge()
   744  	bc.blockCache.Purge()
   745  	bc.txLookupCache.Purge()
   746  	bc.futureBlocks.Purge()
   747  
   748  	// Clear safe block, finalized block if needed
   749  	if safe := bc.CurrentSafeBlock(); safe != nil && head < safe.NumberU64() {
   750  		log.Warn("SetHead invalidated safe block")
   751  		bc.SetSafe(nil)
   752  	}
   753  	if finalized := bc.CurrentFinalizedBlock(); finalized != nil && head < finalized.NumberU64() {
   754  		log.Error("SetHead invalidated finalized block")
   755  		bc.SetFinalized(nil)
   756  	}
   757  
   758  	return rootNumber, bc.loadLastState()
   759  }
   760  
   761  // SnapSyncCommitHead sets the current head block to the one defined by the hash
   762  // irrelevant what the chain contents were prior.
   763  func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error {
   764  	// Make sure that both the block as well at its state trie exists
   765  	block := bc.GetBlockByHash(hash)
   766  	if block == nil {
   767  		return fmt.Errorf("non existent block [%x..]", hash[:4])
   768  	}
   769  	root := block.Root()
   770  	if !bc.HasState(root) {
   771  		return fmt.Errorf("non existent state [%x..]", root[:4])
   772  	}
   773  	// If all checks out, manually set the head block.
   774  	if !bc.chainmu.TryLock() {
   775  		return errChainStopped
   776  	}
   777  	bc.currentBlock.Store(block)
   778  	headBlockGauge.Update(int64(block.NumberU64()))
   779  	bc.chainmu.Unlock()
   780  
   781  	// Destroy any existing state snapshot and regenerate it in the background,
   782  	// also resuming the normal maintenance of any previously paused snapshot.
   783  	if bc.snaps != nil {
   784  		bc.snaps.Rebuild(root)
   785  	}
   786  	log.Info("Committed new head block", "number", block.Number(), "hash", hash)
   787  	return nil
   788  }
   789  
   790  // Reset purges the entire blockchain, restoring it to its genesis state.
   791  func (bc *BlockChain) Reset() error {
   792  	return bc.ResetWithGenesisBlock(bc.genesisBlock)
   793  }
   794  
   795  // ResetWithGenesisBlock purges the entire blockchain, restoring it to the
   796  // specified genesis state.
   797  func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
   798  	// Dump the entire block chain and purge the caches
   799  	if err := bc.SetHead(0); err != nil {
   800  		return err
   801  	}
   802  	if !bc.chainmu.TryLock() {
   803  		return errChainStopped
   804  	}
   805  	defer bc.chainmu.Unlock()
   806  
   807  	// Prepare the genesis block and reinitialise the chain
   808  	batch := bc.db.NewBatch()
   809  	rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
   810  	rawdb.WriteBlock(batch, genesis)
   811  	if err := batch.Write(); err != nil {
   812  		log.Crit("Failed to write genesis block", "err", err)
   813  	}
   814  	bc.writeHeadBlock(genesis)
   815  
   816  	// Last update all in-memory chain markers
   817  	bc.genesisBlock = genesis
   818  	bc.currentBlock.Store(bc.genesisBlock)
   819  	headBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
   820  	bc.hc.SetGenesis(bc.genesisBlock.Header())
   821  	bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
   822  	bc.currentFastBlock.Store(bc.genesisBlock)
   823  	headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
   824  	return nil
   825  }
   826  
   827  // Export writes the active chain to the given writer.
   828  func (bc *BlockChain) Export(w io.Writer) error {
   829  	return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64())
   830  }
   831  
   832  // ExportN writes a subset of the active chain to the given writer.
   833  func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
   834  	if first > last {
   835  		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
   836  	}
   837  	log.Info("Exporting batch of blocks", "count", last-first+1)
   838  
   839  	var (
   840  		parentHash common.Hash
   841  		start      = time.Now()
   842  		reported   = time.Now()
   843  	)
   844  	for nr := first; nr <= last; nr++ {
   845  		block := bc.GetBlockByNumber(nr)
   846  		if block == nil {
   847  			return fmt.Errorf("export failed on #%d: not found", nr)
   848  		}
   849  		if nr > first && block.ParentHash() != parentHash {
   850  			return fmt.Errorf("export failed: chain reorg during export")
   851  		}
   852  		parentHash = block.Hash()
   853  		if err := block.EncodeRLP(w); err != nil {
   854  			return err
   855  		}
   856  		if time.Since(reported) >= statsReportLimit {
   857  			log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start)))
   858  			reported = time.Now()
   859  		}
   860  	}
   861  	return nil
   862  }
   863  
   864  // writeHeadBlock injects a new head block into the current block chain. This method
   865  // assumes that the block is indeed a true head. It will also reset the head
   866  // header and the head fast sync block to this very same block if they are older
   867  // or if they are on a different side chain.
   868  //
   869  // Note, this function assumes that the `mu` mutex is held!
   870  func (bc *BlockChain) writeHeadBlock(block *types.Block) {
   871  	// Add the block to the canonical chain number scheme and mark as the head
   872  	batch := bc.db.NewBatch()
   873  	rawdb.WriteHeadHeaderHash(batch, block.Hash())
   874  	rawdb.WriteHeadFastBlockHash(batch, block.Hash())
   875  	rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
   876  	rawdb.WriteTxLookupEntriesByBlock(batch, block)
   877  	rawdb.WriteHeadBlockHash(batch, block.Hash())
   878  
   879  	// Flush the whole batch into the disk, exit the node if failed
   880  	if err := batch.Write(); err != nil {
   881  		log.Crit("Failed to update chain indexes and markers", "err", err)
   882  	}
   883  	// Update all in-memory chain markers in the last step
   884  	bc.hc.SetCurrentHeader(block.Header())
   885  
   886  	bc.currentFastBlock.Store(block)
   887  	headFastBlockGauge.Update(int64(block.NumberU64()))
   888  
   889  	bc.currentBlock.Store(block)
   890  	headBlockGauge.Update(int64(block.NumberU64()))
   891  }
   892  
   893  // stop stops the blockchain service. If any imports are currently in progress
   894  // it will abort them using the procInterrupt. This method stops all running
   895  // goroutines, but does not do all the post-stop work of persisting data.
   896  // OBS! It is generally recommended to use the Stop method!
   897  // This method has been exposed to allow tests to stop the blockchain while simulating
   898  // a crash.
   899  func (bc *BlockChain) stopWithoutSaving() {
   900  	if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
   901  		return
   902  	}
   903  
   904  	// Unsubscribe all subscriptions registered from blockchain.
   905  	bc.scope.Close()
   906  
   907  	// Signal shutdown to all goroutines.
   908  	close(bc.quit)
   909  	bc.StopInsert()
   910  
   911  	// Now wait for all chain modifications to end and persistent goroutines to exit.
   912  	//
   913  	// Note: Close waits for the mutex to become available, i.e. any running chain
   914  	// modification will have exited when Close returns. Since we also called StopInsert,
   915  	// the mutex should become available quickly. It cannot be taken again after Close has
   916  	// returned.
   917  	bc.chainmu.Close()
   918  	bc.wg.Wait()
   919  }
   920  
   921  // Stop stops the blockchain service. If any imports are currently in progress
   922  // it will abort them using the procInterrupt.
   923  func (bc *BlockChain) Stop() {
   924  	bc.stopWithoutSaving()
   925  
   926  	// Ensure that the entirety of the state snapshot is journalled to disk.
   927  	var snapBase common.Hash
   928  	if bc.snaps != nil {
   929  		var err error
   930  		if snapBase, err = bc.snaps.Journal(bc.CurrentBlock().Root()); err != nil {
   931  			log.Error("Failed to journal state snapshot", "err", err)
   932  		}
   933  	}
   934  
   935  	// Ensure the state of a recent block is also stored to disk before exiting.
   936  	// We're writing three different states to catch different restart scenarios:
   937  	//  - HEAD:     So we don't need to reprocess any blocks in the general case
   938  	//  - HEAD-1:   So we don't do large reorgs if our HEAD becomes an uncle
   939  	//  - HEAD-127: So we have a hard limit on the number of blocks reexecuted
   940  	if !bc.cacheConfig.TrieDirtyDisabled {
   941  		triedb := bc.triedb
   942  
   943  		for _, offset := range []uint64{0, 1, TriesInMemory - 1} {
   944  			if number := bc.CurrentBlock().NumberU64(); number > offset {
   945  				recent := bc.GetBlockByNumber(number - offset)
   946  
   947  				log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
   948  				if err := triedb.Commit(recent.Root(), true, nil); err != nil {
   949  					log.Error("Failed to commit recent state trie", "err", err)
   950  				}
   951  			}
   952  		}
   953  		if snapBase != (common.Hash{}) {
   954  			log.Info("Writing snapshot state to disk", "root", snapBase)
   955  			if err := triedb.Commit(snapBase, true, nil); err != nil {
   956  				log.Error("Failed to commit recent state trie", "err", err)
   957  			}
   958  		}
   959  		for !bc.triegc.Empty() {
   960  			triedb.Dereference(bc.triegc.PopItem().(common.Hash))
   961  		}
   962  		if size, _ := triedb.Size(); size != 0 {
   963  			log.Error("Dangling trie nodes after full cleanup")
   964  		}
   965  	}
   966  	// Flush the collected preimages to disk
   967  	if err := bc.stateCache.TrieDB().CommitPreimages(); err != nil {
   968  		log.Error("Failed to commit trie preimages", "err", err)
   969  	}
   970  	// Ensure all live cached entries be saved into disk, so that we can skip
   971  	// cache warmup when node restarts.
   972  	if bc.cacheConfig.TrieCleanJournal != "" {
   973  		bc.triedb.SaveCache(bc.cacheConfig.TrieCleanJournal)
   974  	}
   975  	log.Info("Blockchain stopped")
   976  }
   977  
   978  // StopInsert interrupts all insertion methods, causing them to return
   979  // errInsertionInterrupted as soon as possible. Insertion is permanently disabled after
   980  // calling this method.
   981  func (bc *BlockChain) StopInsert() {
   982  	atomic.StoreInt32(&bc.procInterrupt, 1)
   983  }
   984  
   985  // insertStopped returns true after StopInsert has been called.
   986  func (bc *BlockChain) insertStopped() bool {
   987  	return atomic.LoadInt32(&bc.procInterrupt) == 1
   988  }
   989  
   990  func (bc *BlockChain) procFutureBlocks() {
   991  	blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
   992  	for _, hash := range bc.futureBlocks.Keys() {
   993  		if block, exist := bc.futureBlocks.Peek(hash); exist {
   994  			blocks = append(blocks, block)
   995  		}
   996  	}
   997  	if len(blocks) > 0 {
   998  		sort.Slice(blocks, func(i, j int) bool {
   999  			return blocks[i].NumberU64() < blocks[j].NumberU64()
  1000  		})
  1001  		// Insert one by one as chain insertion needs contiguous ancestry between blocks
  1002  		for i := range blocks {
  1003  			bc.InsertChain(blocks[i : i+1])
  1004  		}
  1005  	}
  1006  }
  1007  
  1008  // WriteStatus status of write
  1009  type WriteStatus byte
  1010  
  1011  const (
  1012  	NonStatTy WriteStatus = iota
  1013  	CanonStatTy
  1014  	SideStatTy
  1015  )
  1016  
  1017  // InsertReceiptChain attempts to complete an already existing header chain with
  1018  // transaction and receipt data.
  1019  func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error) {
  1020  	// We don't require the chainMu here since we want to maximize the
  1021  	// concurrency of header insertion and receipt insertion.
  1022  	bc.wg.Add(1)
  1023  	defer bc.wg.Done()
  1024  
  1025  	var (
  1026  		ancientBlocks, liveBlocks     types.Blocks
  1027  		ancientReceipts, liveReceipts []types.Receipts
  1028  	)
  1029  	// Do a sanity check that the provided chain is actually ordered and linked
  1030  	for i := 0; i < len(blockChain); i++ {
  1031  		if i != 0 {
  1032  			if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() {
  1033  				log.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(),
  1034  					"prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash())
  1035  				return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, blockChain[i-1].NumberU64(),
  1036  					blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4])
  1037  			}
  1038  		}
  1039  		if blockChain[i].NumberU64() <= ancientLimit {
  1040  			ancientBlocks, ancientReceipts = append(ancientBlocks, blockChain[i]), append(ancientReceipts, receiptChain[i])
  1041  		} else {
  1042  			liveBlocks, liveReceipts = append(liveBlocks, blockChain[i]), append(liveReceipts, receiptChain[i])
  1043  		}
  1044  	}
  1045  
  1046  	var (
  1047  		stats = struct{ processed, ignored int32 }{}
  1048  		start = time.Now()
  1049  		size  = int64(0)
  1050  	)
  1051  
  1052  	// updateHead updates the head fast sync block if the inserted blocks are better
  1053  	// and returns an indicator whether the inserted blocks are canonical.
  1054  	updateHead := func(head *types.Block) bool {
  1055  		if !bc.chainmu.TryLock() {
  1056  			return false
  1057  		}
  1058  		defer bc.chainmu.Unlock()
  1059  
  1060  		// Rewind may have occurred, skip in that case.
  1061  		if bc.CurrentHeader().Number.Cmp(head.Number()) >= 0 {
  1062  			reorg, err := bc.forker.ReorgNeeded(bc.CurrentFastBlock().Header(), head.Header())
  1063  			if err != nil {
  1064  				log.Warn("Reorg failed", "err", err)
  1065  				return false
  1066  			} else if !reorg {
  1067  				return false
  1068  			}
  1069  			rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
  1070  			bc.currentFastBlock.Store(head)
  1071  			headFastBlockGauge.Update(int64(head.NumberU64()))
  1072  			return true
  1073  		}
  1074  		return false
  1075  	}
  1076  
  1077  	// writeAncient writes blockchain and corresponding receipt chain into ancient store.
  1078  	//
  1079  	// this function only accepts canonical chain data. All side chain will be reverted
  1080  	// eventually.
  1081  	writeAncient := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
  1082  		first := blockChain[0]
  1083  		last := blockChain[len(blockChain)-1]
  1084  
  1085  		// Ensure genesis is in ancients.
  1086  		if first.NumberU64() == 1 {
  1087  			if frozen, _ := bc.db.Ancients(); frozen == 0 {
  1088  				b := bc.genesisBlock
  1089  				td := bc.genesisBlock.Difficulty()
  1090  				writeSize, err := rawdb.WriteAncientBlocks(bc.db, []*types.Block{b}, []types.Receipts{nil}, td)
  1091  				size += writeSize
  1092  				if err != nil {
  1093  					log.Error("Error writing genesis to ancients", "err", err)
  1094  					return 0, err
  1095  				}
  1096  				log.Info("Wrote genesis to ancients")
  1097  			}
  1098  		}
  1099  		// Before writing the blocks to the ancients, we need to ensure that
  1100  		// they correspond to the what the headerchain 'expects'.
  1101  		// We only check the last block/header, since it's a contiguous chain.
  1102  		if !bc.HasHeader(last.Hash(), last.NumberU64()) {
  1103  			return 0, fmt.Errorf("containing header #%d [%x..] unknown", last.Number(), last.Hash().Bytes()[:4])
  1104  		}
  1105  
  1106  		// Write all chain data to ancients.
  1107  		td := bc.GetTd(first.Hash(), first.NumberU64())
  1108  		writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain, td)
  1109  		size += writeSize
  1110  		if err != nil {
  1111  			log.Error("Error importing chain data to ancients", "err", err)
  1112  			return 0, err
  1113  		}
  1114  
  1115  		// Write tx indices if any condition is satisfied:
  1116  		// * If user requires to reserve all tx indices(txlookuplimit=0)
  1117  		// * If all ancient tx indices are required to be reserved(txlookuplimit is even higher than ancientlimit)
  1118  		// * If block number is large enough to be regarded as a recent block
  1119  		// It means blocks below the ancientLimit-txlookupLimit won't be indexed.
  1120  		//
  1121  		// But if the `TxIndexTail` is not nil, e.g. Geth is initialized with
  1122  		// an external ancient database, during the setup, blockchain will start
  1123  		// a background routine to re-indexed all indices in [ancients - txlookupLimit, ancients)
  1124  		// range. In this case, all tx indices of newly imported blocks should be
  1125  		// generated.
  1126  		var batch = bc.db.NewBatch()
  1127  		for i, block := range blockChain {
  1128  			if bc.txLookupLimit == 0 || ancientLimit <= bc.txLookupLimit || block.NumberU64() >= ancientLimit-bc.txLookupLimit {
  1129  				rawdb.WriteTxLookupEntriesByBlock(batch, block)
  1130  			} else if rawdb.ReadTxIndexTail(bc.db) != nil {
  1131  				rawdb.WriteTxLookupEntriesByBlock(batch, block)
  1132  			}
  1133  			stats.processed++
  1134  
  1135  			if batch.ValueSize() > ethdb.IdealBatchSize || i == len(blockChain)-1 {
  1136  				size += int64(batch.ValueSize())
  1137  				if err = batch.Write(); err != nil {
  1138  					fastBlock := bc.CurrentFastBlock().NumberU64()
  1139  					if err := bc.db.TruncateHead(fastBlock + 1); err != nil {
  1140  						log.Error("Can't truncate ancient store after failed insert", "err", err)
  1141  					}
  1142  					return 0, err
  1143  				}
  1144  				batch.Reset()
  1145  			}
  1146  		}
  1147  
  1148  		// Sync the ancient store explicitly to ensure all data has been flushed to disk.
  1149  		if err := bc.db.Sync(); err != nil {
  1150  			return 0, err
  1151  		}
  1152  		// Update the current fast block because all block data is now present in DB.
  1153  		previousFastBlock := bc.CurrentFastBlock().NumberU64()
  1154  		if !updateHead(blockChain[len(blockChain)-1]) {
  1155  			// We end up here if the header chain has reorg'ed, and the blocks/receipts
  1156  			// don't match the canonical chain.
  1157  			if err := bc.db.TruncateHead(previousFastBlock + 1); err != nil {
  1158  				log.Error("Can't truncate ancient store after failed insert", "err", err)
  1159  			}
  1160  			return 0, errSideChainReceipts
  1161  		}
  1162  
  1163  		// Delete block data from the main database.
  1164  		batch.Reset()
  1165  		canonHashes := make(map[common.Hash]struct{})
  1166  		for _, block := range blockChain {
  1167  			canonHashes[block.Hash()] = struct{}{}
  1168  			if block.NumberU64() == 0 {
  1169  				continue
  1170  			}
  1171  			rawdb.DeleteCanonicalHash(batch, block.NumberU64())
  1172  			rawdb.DeleteBlockWithoutNumber(batch, block.Hash(), block.NumberU64())
  1173  		}
  1174  		// Delete side chain hash-to-number mappings.
  1175  		for _, nh := range rawdb.ReadAllHashesInRange(bc.db, first.NumberU64(), last.NumberU64()) {
  1176  			if _, canon := canonHashes[nh.Hash]; !canon {
  1177  				rawdb.DeleteHeader(batch, nh.Hash, nh.Number)
  1178  			}
  1179  		}
  1180  		if err := batch.Write(); err != nil {
  1181  			return 0, err
  1182  		}
  1183  		return 0, nil
  1184  	}
  1185  
  1186  	// writeLive writes blockchain and corresponding receipt chain into active store.
  1187  	writeLive := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
  1188  		skipPresenceCheck := false
  1189  		batch := bc.db.NewBatch()
  1190  		for i, block := range blockChain {
  1191  			// Short circuit insertion if shutting down or processing failed
  1192  			if bc.insertStopped() {
  1193  				return 0, errInsertionInterrupted
  1194  			}
  1195  			// Short circuit if the owner header is unknown
  1196  			if !bc.HasHeader(block.Hash(), block.NumberU64()) {
  1197  				return i, fmt.Errorf("containing header #%d [%x..] unknown", block.Number(), block.Hash().Bytes()[:4])
  1198  			}
  1199  			if !skipPresenceCheck {
  1200  				// Ignore if the entire data is already known
  1201  				if bc.HasBlock(block.Hash(), block.NumberU64()) {
  1202  					stats.ignored++
  1203  					continue
  1204  				} else {
  1205  					// If block N is not present, neither are the later blocks.
  1206  					// This should be true, but if we are mistaken, the shortcut
  1207  					// here will only cause overwriting of some existing data
  1208  					skipPresenceCheck = true
  1209  				}
  1210  			}
  1211  			// Write all the data out into the database
  1212  			rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
  1213  			rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
  1214  			rawdb.WriteTxLookupEntriesByBlock(batch, block) // Always write tx indices for live blocks, we assume they are needed
  1215  
  1216  			// Write everything belongs to the blocks into the database. So that
  1217  			// we can ensure all components of body is completed(body, receipts,
  1218  			// tx indexes)
  1219  			if batch.ValueSize() >= ethdb.IdealBatchSize {
  1220  				if err := batch.Write(); err != nil {
  1221  					return 0, err
  1222  				}
  1223  				size += int64(batch.ValueSize())
  1224  				batch.Reset()
  1225  			}
  1226  			stats.processed++
  1227  		}
  1228  		// Write everything belongs to the blocks into the database. So that
  1229  		// we can ensure all components of body is completed(body, receipts,
  1230  		// tx indexes)
  1231  		if batch.ValueSize() > 0 {
  1232  			size += int64(batch.ValueSize())
  1233  			if err := batch.Write(); err != nil {
  1234  				return 0, err
  1235  			}
  1236  		}
  1237  		updateHead(blockChain[len(blockChain)-1])
  1238  		return 0, nil
  1239  	}
  1240  
  1241  	// Write downloaded chain data and corresponding receipt chain data
  1242  	if len(ancientBlocks) > 0 {
  1243  		if n, err := writeAncient(ancientBlocks, ancientReceipts); err != nil {
  1244  			if err == errInsertionInterrupted {
  1245  				return 0, nil
  1246  			}
  1247  			return n, err
  1248  		}
  1249  	}
  1250  	// Write the tx index tail (block number from where we index) before write any live blocks
  1251  	if len(liveBlocks) > 0 && liveBlocks[0].NumberU64() == ancientLimit+1 {
  1252  		// The tx index tail can only be one of the following two options:
  1253  		// * 0: all ancient blocks have been indexed
  1254  		// * ancient-limit: the indices of blocks before ancient-limit are ignored
  1255  		if tail := rawdb.ReadTxIndexTail(bc.db); tail == nil {
  1256  			if bc.txLookupLimit == 0 || ancientLimit <= bc.txLookupLimit {
  1257  				rawdb.WriteTxIndexTail(bc.db, 0)
  1258  			} else {
  1259  				rawdb.WriteTxIndexTail(bc.db, ancientLimit-bc.txLookupLimit)
  1260  			}
  1261  		}
  1262  	}
  1263  	if len(liveBlocks) > 0 {
  1264  		if n, err := writeLive(liveBlocks, liveReceipts); err != nil {
  1265  			if err == errInsertionInterrupted {
  1266  				return 0, nil
  1267  			}
  1268  			return n, err
  1269  		}
  1270  	}
  1271  
  1272  	head := blockChain[len(blockChain)-1]
  1273  	context := []interface{}{
  1274  		"count", stats.processed, "elapsed", common.PrettyDuration(time.Since(start)),
  1275  		"number", head.Number(), "hash", head.Hash(), "age", common.PrettyAge(time.Unix(int64(head.Time()), 0)),
  1276  		"size", common.StorageSize(size),
  1277  	}
  1278  	if stats.ignored > 0 {
  1279  		context = append(context, []interface{}{"ignored", stats.ignored}...)
  1280  	}
  1281  	log.Info("Imported new block receipts", context...)
  1282  
  1283  	return 0, nil
  1284  }
  1285  
  1286  // writeBlockWithoutState writes only the block and its metadata to the database,
  1287  // but does not write any state. This is used to construct competing side forks
  1288  // up to the point where they exceed the canonical total difficulty.
  1289  func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (err error) {
  1290  	if bc.insertStopped() {
  1291  		return errInsertionInterrupted
  1292  	}
  1293  
  1294  	batch := bc.db.NewBatch()
  1295  	rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td)
  1296  	rawdb.WriteBlock(batch, block)
  1297  	if err := batch.Write(); err != nil {
  1298  		log.Crit("Failed to write block into disk", "err", err)
  1299  	}
  1300  	return nil
  1301  }
  1302  
  1303  // writeKnownBlock updates the head block flag with a known block
  1304  // and introduces chain reorg if necessary.
  1305  func (bc *BlockChain) writeKnownBlock(block *types.Block) error {
  1306  	current := bc.CurrentBlock()
  1307  	if block.ParentHash() != current.Hash() {
  1308  		if err := bc.reorg(current, block); err != nil {
  1309  			return err
  1310  		}
  1311  	}
  1312  	bc.writeHeadBlock(block)
  1313  	return nil
  1314  }
  1315  
  1316  // writeBlockWithState writes block, metadata and corresponding state data to the
  1317  // database.
  1318  func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) error {
  1319  	// Calculate the total difficulty of the block
  1320  	ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
  1321  	if ptd == nil {
  1322  		return consensus.ErrUnknownAncestor
  1323  	}
  1324  	// Make sure no inconsistent state is leaked during insertion
  1325  	externTd := new(big.Int).Add(block.Difficulty(), ptd)
  1326  
  1327  	// Irrelevant of the canonical status, write the block itself to the database.
  1328  	//
  1329  	// Note all the components of block(td, hash->number map, header, body, receipts)
  1330  	// should be written atomically. BlockBatch is used for containing all components.
  1331  	blockBatch := bc.db.NewBatch()
  1332  	rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
  1333  	rawdb.WriteBlock(blockBatch, block)
  1334  	rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
  1335  	rawdb.WritePreimages(blockBatch, state.Preimages())
  1336  	if err := blockBatch.Write(); err != nil {
  1337  		log.Crit("Failed to write block into disk", "err", err)
  1338  	}
  1339  	// Commit all cached state changes into underlying memory database.
  1340  	root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number()))
  1341  	if err != nil {
  1342  		return err
  1343  	}
  1344  	// If we're running an archive node, always flush
  1345  	if bc.cacheConfig.TrieDirtyDisabled {
  1346  		return bc.triedb.Commit(root, false, nil)
  1347  	}
  1348  	// Full but not archive node, do proper garbage collection
  1349  	bc.triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive
  1350  	bc.triegc.Push(root, -int64(block.NumberU64()))
  1351  
  1352  	current := block.NumberU64()
  1353  	// Flush limits are not considered for the first TriesInMemory blocks.
  1354  	if current <= TriesInMemory {
  1355  		return nil
  1356  	}
  1357  	// If we exceeded our memory allowance, flush matured singleton nodes to disk
  1358  	var (
  1359  		nodes, imgs = bc.triedb.Size()
  1360  		limit       = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
  1361  	)
  1362  	if nodes > limit || imgs > 4*1024*1024 {
  1363  		bc.triedb.Cap(limit - ethdb.IdealBatchSize)
  1364  	}
  1365  	// Find the next state trie we need to commit
  1366  	chosen := current - TriesInMemory
  1367  	flushInterval := time.Duration(atomic.LoadInt64(&bc.flushInterval))
  1368  	// If we exceeded time allowance, flush an entire trie to disk
  1369  	if bc.gcproc > flushInterval {
  1370  		// If the header is missing (canonical chain behind), we're reorging a low
  1371  		// diff sidechain. Suspend committing until this operation is completed.
  1372  		header := bc.GetHeaderByNumber(chosen)
  1373  		if header == nil {
  1374  			log.Warn("Reorg in progress, trie commit postponed", "number", chosen)
  1375  		} else {
  1376  			// If we're exceeding limits but haven't reached a large enough memory gap,
  1377  			// warn the user that the system is becoming unstable.
  1378  			if chosen < bc.lastWrite+TriesInMemory && bc.gcproc >= 2*flushInterval {
  1379  				log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", flushInterval, "optimum", float64(chosen-bc.lastWrite)/TriesInMemory)
  1380  			}
  1381  			// Flush an entire trie and restart the counters
  1382  			bc.triedb.Commit(header.Root, true, nil)
  1383  			bc.lastWrite = chosen
  1384  			bc.gcproc = 0
  1385  		}
  1386  	}
  1387  	// Garbage collect anything below our required write retention
  1388  	for !bc.triegc.Empty() {
  1389  		root, number := bc.triegc.Pop()
  1390  		if uint64(-number) > chosen {
  1391  			bc.triegc.Push(root, number)
  1392  			break
  1393  		}
  1394  		bc.triedb.Dereference(root.(common.Hash))
  1395  	}
  1396  	return nil
  1397  }
  1398  
  1399  // WriteBlockAndSetHead writes the given block and all associated state to the database,
  1400  // and applies the block as the new chain head.
  1401  func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
  1402  	if !bc.chainmu.TryLock() {
  1403  		return NonStatTy, errChainStopped
  1404  	}
  1405  	defer bc.chainmu.Unlock()
  1406  
  1407  	return bc.writeBlockAndSetHead(block, receipts, logs, state, emitHeadEvent)
  1408  }
  1409  
  1410  // writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead.
  1411  // This function expects the chain mutex to be held.
  1412  func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
  1413  	if err := bc.writeBlockWithState(block, receipts, state); err != nil {
  1414  		return NonStatTy, err
  1415  	}
  1416  	currentBlock := bc.CurrentBlock()
  1417  	reorg, err := bc.forker.ReorgNeeded(currentBlock.Header(), block.Header())
  1418  	if err != nil {
  1419  		return NonStatTy, err
  1420  	}
  1421  	if reorg {
  1422  		// Reorganise the chain if the parent is not the head block
  1423  		if block.ParentHash() != currentBlock.Hash() {
  1424  			if err := bc.reorg(currentBlock, block); err != nil {
  1425  				return NonStatTy, err
  1426  			}
  1427  		}
  1428  		status = CanonStatTy
  1429  	} else {
  1430  		status = SideStatTy
  1431  	}
  1432  	// Set new head.
  1433  	if status == CanonStatTy {
  1434  		bc.writeHeadBlock(block)
  1435  	}
  1436  	bc.futureBlocks.Remove(block.Hash())
  1437  
  1438  	if status == CanonStatTy {
  1439  		bc.chainFeed.Send(ChainEvent{Block: block, Hash: block.Hash(), Logs: logs})
  1440  		if len(logs) > 0 {
  1441  			bc.logsFeed.Send(logs)
  1442  		}
  1443  		// In theory, we should fire a ChainHeadEvent when we inject
  1444  		// a canonical block, but sometimes we can insert a batch of
  1445  		// canonical blocks. Avoid firing too many ChainHeadEvents,
  1446  		// we will fire an accumulated ChainHeadEvent and disable fire
  1447  		// event here.
  1448  		if emitHeadEvent {
  1449  			bc.chainHeadFeed.Send(ChainHeadEvent{Block: block})
  1450  		}
  1451  	} else {
  1452  		bc.chainSideFeed.Send(ChainSideEvent{Block: block})
  1453  	}
  1454  	return status, nil
  1455  }
  1456  
  1457  // addFutureBlock checks if the block is within the max allowed window to get
  1458  // accepted for future processing, and returns an error if the block is too far
  1459  // ahead and was not added.
  1460  //
  1461  // TODO after the transition, the future block shouldn't be kept. Because
  1462  // it's not checked in the Geth side anymore.
  1463  func (bc *BlockChain) addFutureBlock(block *types.Block) error {
  1464  	max := uint64(time.Now().Unix() + maxTimeFutureBlocks)
  1465  	if block.Time() > max {
  1466  		return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max)
  1467  	}
  1468  	if block.Difficulty().Cmp(common.Big0) == 0 {
  1469  		// Never add PoS blocks into the future queue
  1470  		return nil
  1471  	}
  1472  	bc.futureBlocks.Add(block.Hash(), block)
  1473  	return nil
  1474  }
  1475  
  1476  // InsertChain attempts to insert the given batch of blocks in to the canonical
  1477  // chain or, otherwise, create a fork. If an error is returned it will return
  1478  // the index number of the failing block as well an error describing what went
  1479  // wrong. After insertion is done, all accumulated events will be fired.
  1480  func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
  1481  	// Sanity check that we have something meaningful to import
  1482  	if len(chain) == 0 {
  1483  		return 0, nil
  1484  	}
  1485  	bc.blockProcFeed.Send(true)
  1486  	defer bc.blockProcFeed.Send(false)
  1487  
  1488  	// Do a sanity check that the provided chain is actually ordered and linked.
  1489  	for i := 1; i < len(chain); i++ {
  1490  		block, prev := chain[i], chain[i-1]
  1491  		if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() {
  1492  			log.Error("Non contiguous block insert",
  1493  				"number", block.Number(),
  1494  				"hash", block.Hash(),
  1495  				"parent", block.ParentHash(),
  1496  				"prevnumber", prev.Number(),
  1497  				"prevhash", prev.Hash(),
  1498  			)
  1499  			return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, prev.NumberU64(),
  1500  				prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4])
  1501  		}
  1502  	}
  1503  	// Pre-checks passed, start the full block imports
  1504  	if !bc.chainmu.TryLock() {
  1505  		return 0, errChainStopped
  1506  	}
  1507  	defer bc.chainmu.Unlock()
  1508  	return bc.insertChain(chain, true, true)
  1509  }
  1510  
  1511  // insertChain is the internal implementation of InsertChain, which assumes that
  1512  // 1) chains are contiguous, and 2) The chain mutex is held.
  1513  //
  1514  // This method is split out so that import batches that require re-injecting
  1515  // historical blocks can do so without releasing the lock, which could lead to
  1516  // racey behaviour. If a sidechain import is in progress, and the historic state
  1517  // is imported, but then new canon-head is added before the actual sidechain
  1518  // completes, then the historic state could be pruned again
  1519  func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) (int, error) {
  1520  	// If the chain is terminating, don't even bother starting up.
  1521  	if bc.insertStopped() {
  1522  		return 0, nil
  1523  	}
  1524  
  1525  	// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
  1526  	SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)
  1527  
  1528  	var (
  1529  		stats     = insertStats{startTime: mclock.Now()}
  1530  		lastCanon *types.Block
  1531  	)
  1532  	// Fire a single chain head event if we've progressed the chain
  1533  	defer func() {
  1534  		if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
  1535  			bc.chainHeadFeed.Send(ChainHeadEvent{lastCanon})
  1536  		}
  1537  	}()
  1538  	// Start the parallel header verifier
  1539  	headers := make([]*types.Header, len(chain))
  1540  	seals := make([]bool, len(chain))
  1541  
  1542  	for i, block := range chain {
  1543  		headers[i] = block.Header()
  1544  		seals[i] = verifySeals
  1545  	}
  1546  	abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
  1547  	defer close(abort)
  1548  
  1549  	// Peek the error for the first block to decide the directing import logic
  1550  	it := newInsertIterator(chain, results, bc.validator)
  1551  	block, err := it.next()
  1552  
  1553  	// Left-trim all the known blocks that don't need to build snapshot
  1554  	if bc.skipBlock(err, it) {
  1555  		// First block (and state) is known
  1556  		//   1. We did a roll-back, and should now do a re-import
  1557  		//   2. The block is stored as a sidechain, and is lying about it's stateroot, and passes a stateroot
  1558  		//      from the canonical chain, which has not been verified.
  1559  		// Skip all known blocks that are behind us.
  1560  		var (
  1561  			reorg   bool
  1562  			current = bc.CurrentBlock()
  1563  		)
  1564  		for block != nil && bc.skipBlock(err, it) {
  1565  			reorg, err = bc.forker.ReorgNeeded(current.Header(), block.Header())
  1566  			if err != nil {
  1567  				return it.index, err
  1568  			}
  1569  			if reorg {
  1570  				// Switch to import mode if the forker says the reorg is necessary
  1571  				// and also the block is not on the canonical chain.
  1572  				// In eth2 the forker always returns true for reorg decision (blindly trusting
  1573  				// the external consensus engine), but in order to prevent the unnecessary
  1574  				// reorgs when importing known blocks, the special case is handled here.
  1575  				if block.NumberU64() > current.NumberU64() || bc.GetCanonicalHash(block.NumberU64()) != block.Hash() {
  1576  					break
  1577  				}
  1578  			}
  1579  			log.Debug("Ignoring already known block", "number", block.Number(), "hash", block.Hash())
  1580  			stats.ignored++
  1581  
  1582  			block, err = it.next()
  1583  		}
  1584  		// The remaining blocks are still known blocks, the only scenario here is:
  1585  		// During the fast sync, the pivot point is already submitted but rollback
  1586  		// happens. Then node resets the head full block to a lower height via `rollback`
  1587  		// and leaves a few known blocks in the database.
  1588  		//
  1589  		// When node runs a fast sync again, it can re-import a batch of known blocks via
  1590  		// `insertChain` while a part of them have higher total difficulty than current
  1591  		// head full block(new pivot point).
  1592  		for block != nil && bc.skipBlock(err, it) {
  1593  			log.Debug("Writing previously known block", "number", block.Number(), "hash", block.Hash())
  1594  			if err := bc.writeKnownBlock(block); err != nil {
  1595  				return it.index, err
  1596  			}
  1597  			lastCanon = block
  1598  
  1599  			block, err = it.next()
  1600  		}
  1601  		// Falls through to the block import
  1602  	}
  1603  	switch {
  1604  	// First block is pruned
  1605  	case errors.Is(err, consensus.ErrPrunedAncestor):
  1606  		if setHead {
  1607  			// First block is pruned, insert as sidechain and reorg only if TD grows enough
  1608  			log.Debug("Pruned ancestor, inserting as sidechain", "number", block.Number(), "hash", block.Hash())
  1609  			return bc.insertSideChain(block, it)
  1610  		} else {
  1611  			// We're post-merge and the parent is pruned, try to recover the parent state
  1612  			log.Debug("Pruned ancestor", "number", block.Number(), "hash", block.Hash())
  1613  			_, err := bc.recoverAncestors(block)
  1614  			return it.index, err
  1615  		}
  1616  	// First block is future, shove it (and all children) to the future queue (unknown ancestor)
  1617  	case errors.Is(err, consensus.ErrFutureBlock) || (errors.Is(err, consensus.ErrUnknownAncestor) && bc.futureBlocks.Contains(it.first().ParentHash())):
  1618  		for block != nil && (it.index == 0 || errors.Is(err, consensus.ErrUnknownAncestor)) {
  1619  			log.Debug("Future block, postponing import", "number", block.Number(), "hash", block.Hash())
  1620  			if err := bc.addFutureBlock(block); err != nil {
  1621  				return it.index, err
  1622  			}
  1623  			block, err = it.next()
  1624  		}
  1625  		stats.queued += it.processed()
  1626  		stats.ignored += it.remaining()
  1627  
  1628  		// If there are any still remaining, mark as ignored
  1629  		return it.index, err
  1630  
  1631  	// Some other error(except ErrKnownBlock) occurred, abort.
  1632  	// ErrKnownBlock is allowed here since some known blocks
  1633  	// still need re-execution to generate snapshots that are missing
  1634  	case err != nil && !errors.Is(err, ErrKnownBlock):
  1635  		bc.futureBlocks.Remove(block.Hash())
  1636  		stats.ignored += len(it.chain)
  1637  		bc.reportBlock(block, nil, err)
  1638  		return it.index, err
  1639  	}
  1640  	// No validation errors for the first block (or chain prefix skipped)
  1641  	var activeState *state.StateDB
  1642  	defer func() {
  1643  		// The chain importer is starting and stopping trie prefetchers. If a bad
  1644  		// block or other error is hit however, an early return may not properly
  1645  		// terminate the background threads. This defer ensures that we clean up
  1646  		// and dangling prefetcher, without defering each and holding on live refs.
  1647  		if activeState != nil {
  1648  			activeState.StopPrefetcher()
  1649  		}
  1650  	}()
  1651  
  1652  	for ; block != nil && err == nil || errors.Is(err, ErrKnownBlock); block, err = it.next() {
  1653  		// If the chain is terminating, stop processing blocks
  1654  		if bc.insertStopped() {
  1655  			log.Debug("Abort during block processing")
  1656  			break
  1657  		}
  1658  		// If the header is a banned one, straight out abort
  1659  		if BadHashes[block.Hash()] {
  1660  			bc.reportBlock(block, nil, ErrBannedHash)
  1661  			return it.index, ErrBannedHash
  1662  		}
  1663  		// If the block is known (in the middle of the chain), it's a special case for
  1664  		// Clique blocks where they can share state among each other, so importing an
  1665  		// older block might complete the state of the subsequent one. In this case,
  1666  		// just skip the block (we already validated it once fully (and crashed), since
  1667  		// its header and body was already in the database). But if the corresponding
  1668  		// snapshot layer is missing, forcibly rerun the execution to build it.
  1669  		if bc.skipBlock(err, it) {
  1670  			logger := log.Debug
  1671  			if bc.chainConfig.Clique == nil {
  1672  				logger = log.Warn
  1673  			}
  1674  			logger("Inserted known block", "number", block.Number(), "hash", block.Hash(),
  1675  				"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(),
  1676  				"root", block.Root())
  1677  
  1678  			// Special case. Commit the empty receipt slice if we meet the known
  1679  			// block in the middle. It can only happen in the clique chain. Whenever
  1680  			// we insert blocks via `insertSideChain`, we only commit `td`, `header`
  1681  			// and `body` if it's non-existent. Since we don't have receipts without
  1682  			// reexecution, so nothing to commit. But if the sidechain will be adopted
  1683  			// as the canonical chain eventually, it needs to be reexecuted for missing
  1684  			// state, but if it's this special case here(skip reexecution) we will lose
  1685  			// the empty receipt entry.
  1686  			if len(block.Transactions()) == 0 {
  1687  				rawdb.WriteReceipts(bc.db, block.Hash(), block.NumberU64(), nil)
  1688  			} else {
  1689  				log.Error("Please file an issue, skip known block execution without receipt",
  1690  					"hash", block.Hash(), "number", block.NumberU64())
  1691  			}
  1692  			if err := bc.writeKnownBlock(block); err != nil {
  1693  				return it.index, err
  1694  			}
  1695  			stats.processed++
  1696  
  1697  			// We can assume that logs are empty here, since the only way for consecutive
  1698  			// Clique blocks to have the same state is if there are no transactions.
  1699  			lastCanon = block
  1700  			continue
  1701  		}
  1702  
  1703  		// Retrieve the parent block and it's state to execute on top
  1704  		start := time.Now()
  1705  		parent := it.previous()
  1706  		if parent == nil {
  1707  			parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
  1708  		}
  1709  		statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
  1710  		if err != nil {
  1711  			return it.index, err
  1712  		}
  1713  
  1714  		// Enable prefetching to pull in trie node paths while processing transactions
  1715  		statedb.StartPrefetcher("chain")
  1716  		activeState = statedb
  1717  
  1718  		// If we have a followup block, run that against the current state to pre-cache
  1719  		// transactions and probabilistically some of the account/storage trie nodes.
  1720  		var followupInterrupt uint32
  1721  		if !bc.cacheConfig.TrieCleanNoPrefetch {
  1722  			if followup, err := it.peek(); followup != nil && err == nil {
  1723  				throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps)
  1724  
  1725  				go func(start time.Time, followup *types.Block, throwaway *state.StateDB, interrupt *uint32) {
  1726  					bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt)
  1727  
  1728  					blockPrefetchExecuteTimer.Update(time.Since(start))
  1729  					if atomic.LoadUint32(interrupt) == 1 {
  1730  						blockPrefetchInterruptMeter.Mark(1)
  1731  					}
  1732  				}(time.Now(), followup, throwaway, &followupInterrupt)
  1733  			}
  1734  		}
  1735  
  1736  		// Process block using the parent state as reference point
  1737  		substart := time.Now()
  1738  		receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig)
  1739  		if err != nil {
  1740  			bc.reportBlock(block, receipts, err)
  1741  			atomic.StoreUint32(&followupInterrupt, 1)
  1742  			return it.index, err
  1743  		}
  1744  
  1745  		// Update the metrics touched during block processing
  1746  		accountReadTimer.Update(statedb.AccountReads)                 // Account reads are complete, we can mark them
  1747  		storageReadTimer.Update(statedb.StorageReads)                 // Storage reads are complete, we can mark them
  1748  		accountUpdateTimer.Update(statedb.AccountUpdates)             // Account updates are complete, we can mark them
  1749  		storageUpdateTimer.Update(statedb.StorageUpdates)             // Storage updates are complete, we can mark them
  1750  		snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete, we can mark them
  1751  		snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete, we can mark them
  1752  		triehash := statedb.AccountHashes + statedb.StorageHashes     // Save to not double count in validation
  1753  		trieproc := statedb.SnapshotAccountReads + statedb.AccountReads + statedb.AccountUpdates
  1754  		trieproc += statedb.SnapshotStorageReads + statedb.StorageReads + statedb.StorageUpdates
  1755  
  1756  		blockExecutionTimer.Update(time.Since(substart) - trieproc - triehash)
  1757  
  1758  		// Validate the state using the default validator
  1759  		substart = time.Now()
  1760  		if err := bc.validator.ValidateState(block, statedb, receipts, usedGas); err != nil {
  1761  			bc.reportBlock(block, receipts, err)
  1762  			atomic.StoreUint32(&followupInterrupt, 1)
  1763  			return it.index, err
  1764  		}
  1765  		proctime := time.Since(start)
  1766  
  1767  		// Update the metrics touched during block validation
  1768  		accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete, we can mark them
  1769  		storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete, we can mark them
  1770  		blockValidationTimer.Update(time.Since(substart) - (statedb.AccountHashes + statedb.StorageHashes - triehash))
  1771  
  1772  		// Write the block to the chain and get the status.
  1773  		substart = time.Now()
  1774  		var status WriteStatus
  1775  		if !setHead {
  1776  			// Don't set the head, only insert the block
  1777  			err = bc.writeBlockWithState(block, receipts, statedb)
  1778  		} else {
  1779  			status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false)
  1780  		}
  1781  		atomic.StoreUint32(&followupInterrupt, 1)
  1782  		if err != nil {
  1783  			return it.index, err
  1784  		}
  1785  		// Update the metrics touched during block commit
  1786  		accountCommitTimer.Update(statedb.AccountCommits)   // Account commits are complete, we can mark them
  1787  		storageCommitTimer.Update(statedb.StorageCommits)   // Storage commits are complete, we can mark them
  1788  		snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them
  1789  		triedbCommitTimer.Update(statedb.TrieDBCommits)     // Triedb commits are complete, we can mark them
  1790  
  1791  		blockWriteTimer.Update(time.Since(substart) - statedb.AccountCommits - statedb.StorageCommits - statedb.SnapshotCommits - statedb.TrieDBCommits)
  1792  		blockInsertTimer.UpdateSince(start)
  1793  
  1794  		// Report the import stats before returning the various results
  1795  		stats.processed++
  1796  		stats.usedGas += usedGas
  1797  
  1798  		dirty, _ := bc.triedb.Size()
  1799  		stats.report(chain, it.index, dirty, setHead)
  1800  
  1801  		if !setHead {
  1802  			// After merge we expect few side chains. Simply count
  1803  			// all blocks the CL gives us for GC processing time
  1804  			bc.gcproc += proctime
  1805  
  1806  			return it.index, nil // Direct block insertion of a single block
  1807  		}
  1808  		switch status {
  1809  		case CanonStatTy:
  1810  			log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(),
  1811  				"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(),
  1812  				"elapsed", common.PrettyDuration(time.Since(start)),
  1813  				"root", block.Root())
  1814  
  1815  			lastCanon = block
  1816  
  1817  			// Only count canonical blocks for GC processing time
  1818  			bc.gcproc += proctime
  1819  
  1820  		case SideStatTy:
  1821  			log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(),
  1822  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  1823  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  1824  				"root", block.Root())
  1825  
  1826  		default:
  1827  			// This in theory is impossible, but lets be nice to our future selves and leave
  1828  			// a log, instead of trying to track down blocks imports that don't emit logs.
  1829  			log.Warn("Inserted block with unknown status", "number", block.Number(), "hash", block.Hash(),
  1830  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  1831  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  1832  				"root", block.Root())
  1833  		}
  1834  	}
  1835  
  1836  	// Any blocks remaining here? The only ones we care about are the future ones
  1837  	if block != nil && errors.Is(err, consensus.ErrFutureBlock) {
  1838  		if err := bc.addFutureBlock(block); err != nil {
  1839  			return it.index, err
  1840  		}
  1841  		block, err = it.next()
  1842  
  1843  		for ; block != nil && errors.Is(err, consensus.ErrUnknownAncestor); block, err = it.next() {
  1844  			if err := bc.addFutureBlock(block); err != nil {
  1845  				return it.index, err
  1846  			}
  1847  			stats.queued++
  1848  		}
  1849  	}
  1850  	stats.ignored += it.remaining()
  1851  
  1852  	return it.index, err
  1853  }
  1854  
  1855  // insertSideChain is called when an import batch hits upon a pruned ancestor
  1856  // error, which happens when a sidechain with a sufficiently old fork-block is
  1857  // found.
  1858  //
  1859  // The method writes all (header-and-body-valid) blocks to disk, then tries to
  1860  // switch over to the new chain if the TD exceeded the current chain.
  1861  // insertSideChain is only used pre-merge.
  1862  func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (int, error) {
  1863  	var (
  1864  		externTd  *big.Int
  1865  		lastBlock = block
  1866  		current   = bc.CurrentBlock()
  1867  	)
  1868  	// The first sidechain block error is already verified to be ErrPrunedAncestor.
  1869  	// Since we don't import them here, we expect ErrUnknownAncestor for the remaining
  1870  	// ones. Any other errors means that the block is invalid, and should not be written
  1871  	// to disk.
  1872  	err := consensus.ErrPrunedAncestor
  1873  	for ; block != nil && errors.Is(err, consensus.ErrPrunedAncestor); block, err = it.next() {
  1874  		// Check the canonical state root for that number
  1875  		if number := block.NumberU64(); current.NumberU64() >= number {
  1876  			canonical := bc.GetBlockByNumber(number)
  1877  			if canonical != nil && canonical.Hash() == block.Hash() {
  1878  				// Not a sidechain block, this is a re-import of a canon block which has it's state pruned
  1879  
  1880  				// Collect the TD of the block. Since we know it's a canon one,
  1881  				// we can get it directly, and not (like further below) use
  1882  				// the parent and then add the block on top
  1883  				externTd = bc.GetTd(block.Hash(), block.NumberU64())
  1884  				continue
  1885  			}
  1886  			if canonical != nil && canonical.Root() == block.Root() {
  1887  				// This is most likely a shadow-state attack. When a fork is imported into the
  1888  				// database, and it eventually reaches a block height which is not pruned, we
  1889  				// just found that the state already exist! This means that the sidechain block
  1890  				// refers to a state which already exists in our canon chain.
  1891  				//
  1892  				// If left unchecked, we would now proceed importing the blocks, without actually
  1893  				// having verified the state of the previous blocks.
  1894  				log.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root())
  1895  
  1896  				// If someone legitimately side-mines blocks, they would still be imported as usual. However,
  1897  				// we cannot risk writing unverified blocks to disk when they obviously target the pruning
  1898  				// mechanism.
  1899  				return it.index, errors.New("sidechain ghost-state attack")
  1900  			}
  1901  		}
  1902  		if externTd == nil {
  1903  			externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1)
  1904  		}
  1905  		externTd = new(big.Int).Add(externTd, block.Difficulty())
  1906  
  1907  		if !bc.HasBlock(block.Hash(), block.NumberU64()) {
  1908  			start := time.Now()
  1909  			if err := bc.writeBlockWithoutState(block, externTd); err != nil {
  1910  				return it.index, err
  1911  			}
  1912  			log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(),
  1913  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  1914  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  1915  				"root", block.Root())
  1916  		}
  1917  		lastBlock = block
  1918  	}
  1919  	// At this point, we've written all sidechain blocks to database. Loop ended
  1920  	// either on some other error or all were processed. If there was some other
  1921  	// error, we can ignore the rest of those blocks.
  1922  	//
  1923  	// If the externTd was larger than our local TD, we now need to reimport the previous
  1924  	// blocks to regenerate the required state
  1925  	reorg, err := bc.forker.ReorgNeeded(current.Header(), lastBlock.Header())
  1926  	if err != nil {
  1927  		return it.index, err
  1928  	}
  1929  	if !reorg {
  1930  		localTd := bc.GetTd(current.Hash(), current.NumberU64())
  1931  		log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd)
  1932  		return it.index, err
  1933  	}
  1934  	// Gather all the sidechain hashes (full blocks may be memory heavy)
  1935  	var (
  1936  		hashes  []common.Hash
  1937  		numbers []uint64
  1938  	)
  1939  	parent := it.previous()
  1940  	for parent != nil && !bc.HasState(parent.Root) {
  1941  		hashes = append(hashes, parent.Hash())
  1942  		numbers = append(numbers, parent.Number.Uint64())
  1943  
  1944  		parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1)
  1945  	}
  1946  	if parent == nil {
  1947  		return it.index, errors.New("missing parent")
  1948  	}
  1949  	// Import all the pruned blocks to make the state available
  1950  	var (
  1951  		blocks []*types.Block
  1952  		memory uint64
  1953  	)
  1954  	for i := len(hashes) - 1; i >= 0; i-- {
  1955  		// Append the next block to our batch
  1956  		block := bc.GetBlock(hashes[i], numbers[i])
  1957  
  1958  		blocks = append(blocks, block)
  1959  		memory += block.Size()
  1960  
  1961  		// If memory use grew too large, import and continue. Sadly we need to discard
  1962  		// all raised events and logs from notifications since we're too heavy on the
  1963  		// memory here.
  1964  		if len(blocks) >= 2048 || memory > 64*1024*1024 {
  1965  			log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64())
  1966  			if _, err := bc.insertChain(blocks, false, true); err != nil {
  1967  				return 0, err
  1968  			}
  1969  			blocks, memory = blocks[:0], 0
  1970  
  1971  			// If the chain is terminating, stop processing blocks
  1972  			if bc.insertStopped() {
  1973  				log.Debug("Abort during blocks processing")
  1974  				return 0, nil
  1975  			}
  1976  		}
  1977  	}
  1978  	if len(blocks) > 0 {
  1979  		log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64())
  1980  		return bc.insertChain(blocks, false, true)
  1981  	}
  1982  	return 0, nil
  1983  }
  1984  
  1985  // recoverAncestors finds the closest ancestor with available state and re-execute
  1986  // all the ancestor blocks since that.
  1987  // recoverAncestors is only used post-merge.
  1988  // We return the hash of the latest block that we could correctly validate.
  1989  func (bc *BlockChain) recoverAncestors(block *types.Block) (common.Hash, error) {
  1990  	// Gather all the sidechain hashes (full blocks may be memory heavy)
  1991  	var (
  1992  		hashes  []common.Hash
  1993  		numbers []uint64
  1994  		parent  = block
  1995  	)
  1996  	for parent != nil && !bc.HasState(parent.Root()) {
  1997  		hashes = append(hashes, parent.Hash())
  1998  		numbers = append(numbers, parent.NumberU64())
  1999  		parent = bc.GetBlock(parent.ParentHash(), parent.NumberU64()-1)
  2000  
  2001  		// If the chain is terminating, stop iteration
  2002  		if bc.insertStopped() {
  2003  			log.Debug("Abort during blocks iteration")
  2004  			return common.Hash{}, errInsertionInterrupted
  2005  		}
  2006  	}
  2007  	if parent == nil {
  2008  		return common.Hash{}, errors.New("missing parent")
  2009  	}
  2010  	// Import all the pruned blocks to make the state available
  2011  	for i := len(hashes) - 1; i >= 0; i-- {
  2012  		// If the chain is terminating, stop processing blocks
  2013  		if bc.insertStopped() {
  2014  			log.Debug("Abort during blocks processing")
  2015  			return common.Hash{}, errInsertionInterrupted
  2016  		}
  2017  		var b *types.Block
  2018  		if i == 0 {
  2019  			b = block
  2020  		} else {
  2021  			b = bc.GetBlock(hashes[i], numbers[i])
  2022  		}
  2023  		if _, err := bc.insertChain(types.Blocks{b}, false, false); err != nil {
  2024  			return b.ParentHash(), err
  2025  		}
  2026  	}
  2027  	return block.Hash(), nil
  2028  }
  2029  
  2030  // collectLogs collects the logs that were generated or removed during
  2031  // the processing of a block. These logs are later announced as deleted or reborn.
  2032  func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log {
  2033  	receipts := rawdb.ReadRawReceipts(bc.db, b.Hash(), b.NumberU64())
  2034  	receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.Transactions())
  2035  
  2036  	var logs []*types.Log
  2037  	for _, receipt := range receipts {
  2038  		for _, log := range receipt.Logs {
  2039  			l := *log
  2040  			if removed {
  2041  				l.Removed = true
  2042  			}
  2043  			logs = append(logs, &l)
  2044  		}
  2045  	}
  2046  	return logs
  2047  }
  2048  
  2049  // reorg takes two blocks, an old chain and a new chain and will reconstruct the
  2050  // blocks and inserts them to be part of the new canonical chain and accumulates
  2051  // potential missing transactions and post an event about them.
  2052  // Note the new head block won't be processed here, callers need to handle it
  2053  // externally.
  2054  func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
  2055  	var (
  2056  		newChain    types.Blocks
  2057  		oldChain    types.Blocks
  2058  		commonBlock *types.Block
  2059  
  2060  		deletedTxs []common.Hash
  2061  		addedTxs   []common.Hash
  2062  	)
  2063  	// Reduce the longer chain to the same number as the shorter one
  2064  	if oldBlock.NumberU64() > newBlock.NumberU64() {
  2065  		// Old chain is longer, gather all transactions and logs as deleted ones
  2066  		for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
  2067  			oldChain = append(oldChain, oldBlock)
  2068  			for _, tx := range oldBlock.Transactions() {
  2069  				deletedTxs = append(deletedTxs, tx.Hash())
  2070  			}
  2071  		}
  2072  	} else {
  2073  		// New chain is longer, stash all blocks away for subsequent insertion
  2074  		for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) {
  2075  			newChain = append(newChain, newBlock)
  2076  		}
  2077  	}
  2078  	if oldBlock == nil {
  2079  		return fmt.Errorf("invalid old chain")
  2080  	}
  2081  	if newBlock == nil {
  2082  		return fmt.Errorf("invalid new chain")
  2083  	}
  2084  	// Both sides of the reorg are at the same number, reduce both until the common
  2085  	// ancestor is found
  2086  	for {
  2087  		// If the common ancestor was found, bail out
  2088  		if oldBlock.Hash() == newBlock.Hash() {
  2089  			commonBlock = oldBlock
  2090  			break
  2091  		}
  2092  		// Remove an old block as well as stash away a new block
  2093  		oldChain = append(oldChain, oldBlock)
  2094  		for _, tx := range oldBlock.Transactions() {
  2095  			deletedTxs = append(deletedTxs, tx.Hash())
  2096  		}
  2097  		newChain = append(newChain, newBlock)
  2098  
  2099  		// Step back with both chains
  2100  		oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1)
  2101  		if oldBlock == nil {
  2102  			return fmt.Errorf("invalid old chain")
  2103  		}
  2104  		newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
  2105  		if newBlock == nil {
  2106  			return fmt.Errorf("invalid new chain")
  2107  		}
  2108  	}
  2109  
  2110  	// Ensure the user sees large reorgs
  2111  	if len(oldChain) > 0 && len(newChain) > 0 {
  2112  		logFn := log.Info
  2113  		msg := "Chain reorg detected"
  2114  		if len(oldChain) > 63 {
  2115  			msg = "Large chain reorg detected"
  2116  			logFn = log.Warn
  2117  		}
  2118  		logFn(msg, "number", commonBlock.Number(), "hash", commonBlock.Hash(),
  2119  			"drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash())
  2120  		blockReorgAddMeter.Mark(int64(len(newChain)))
  2121  		blockReorgDropMeter.Mark(int64(len(oldChain)))
  2122  		blockReorgMeter.Mark(1)
  2123  	} else if len(newChain) > 0 {
  2124  		// Special case happens in the post merge stage that current head is
  2125  		// the ancestor of new head while these two blocks are not consecutive
  2126  		log.Info("Extend chain", "add", len(newChain), "number", newChain[0].Number(), "hash", newChain[0].Hash())
  2127  		blockReorgAddMeter.Mark(int64(len(newChain)))
  2128  	} else {
  2129  		// len(newChain) == 0 && len(oldChain) > 0
  2130  		// rewind the canonical chain to a lower point.
  2131  		log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "oldblocks", len(oldChain), "newnum", newBlock.Number(), "newhash", newBlock.Hash(), "newblocks", len(newChain))
  2132  	}
  2133  	// Insert the new chain(except the head block(reverse order)),
  2134  	// taking care of the proper incremental order.
  2135  	for i := len(newChain) - 1; i >= 1; i-- {
  2136  		// Insert the block in the canonical way, re-writing history
  2137  		bc.writeHeadBlock(newChain[i])
  2138  
  2139  		// Collect the new added transactions.
  2140  		for _, tx := range newChain[i].Transactions() {
  2141  			addedTxs = append(addedTxs, tx.Hash())
  2142  		}
  2143  	}
  2144  
  2145  	// Delete useless indexes right now which includes the non-canonical
  2146  	// transaction indexes, canonical chain indexes which above the head.
  2147  	indexesBatch := bc.db.NewBatch()
  2148  	for _, tx := range types.HashDifference(deletedTxs, addedTxs) {
  2149  		rawdb.DeleteTxLookupEntry(indexesBatch, tx)
  2150  	}
  2151  
  2152  	// Delete all hash markers that are not part of the new canonical chain.
  2153  	// Because the reorg function does not handle new chain head, all hash
  2154  	// markers greater than or equal to new chain head should be deleted.
  2155  	number := commonBlock.NumberU64()
  2156  	if len(newChain) > 1 {
  2157  		number = newChain[1].NumberU64()
  2158  	}
  2159  	for i := number + 1; ; i++ {
  2160  		hash := rawdb.ReadCanonicalHash(bc.db, i)
  2161  		if hash == (common.Hash{}) {
  2162  			break
  2163  		}
  2164  		rawdb.DeleteCanonicalHash(indexesBatch, i)
  2165  	}
  2166  	if err := indexesBatch.Write(); err != nil {
  2167  		log.Crit("Failed to delete useless indexes", "err", err)
  2168  	}
  2169  
  2170  	// Send out events for logs from the old canon chain, and 'reborn'
  2171  	// logs from the new canon chain. The number of logs can be very
  2172  	// high, so the events are sent in batches of size around 512.
  2173  
  2174  	// Deleted logs + blocks:
  2175  	var deletedLogs []*types.Log
  2176  	for i := len(oldChain) - 1; i >= 0; i-- {
  2177  		// Also send event for blocks removed from the canon chain.
  2178  		bc.chainSideFeed.Send(ChainSideEvent{Block: oldChain[i]})
  2179  
  2180  		// Collect deleted logs for notification
  2181  		if logs := bc.collectLogs(oldChain[i], true); len(logs) > 0 {
  2182  			deletedLogs = append(deletedLogs, logs...)
  2183  		}
  2184  		if len(deletedLogs) > 512 {
  2185  			bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
  2186  			deletedLogs = nil
  2187  		}
  2188  	}
  2189  	if len(deletedLogs) > 0 {
  2190  		bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
  2191  	}
  2192  
  2193  	// New logs:
  2194  	var rebirthLogs []*types.Log
  2195  	for i := len(newChain) - 1; i >= 1; i-- {
  2196  		if logs := bc.collectLogs(newChain[i], false); len(logs) > 0 {
  2197  			rebirthLogs = append(rebirthLogs, logs...)
  2198  		}
  2199  		if len(rebirthLogs) > 512 {
  2200  			bc.logsFeed.Send(rebirthLogs)
  2201  			rebirthLogs = nil
  2202  		}
  2203  	}
  2204  	if len(rebirthLogs) > 0 {
  2205  		bc.logsFeed.Send(rebirthLogs)
  2206  	}
  2207  	return nil
  2208  }
  2209  
  2210  // InsertBlockWithoutSetHead executes the block, runs the necessary verification
  2211  // upon it and then persist the block and the associate state into the database.
  2212  // The key difference between the InsertChain is it won't do the canonical chain
  2213  // updating. It relies on the additional SetCanonical call to finalize the entire
  2214  // procedure.
  2215  func (bc *BlockChain) InsertBlockWithoutSetHead(block *types.Block) error {
  2216  	if !bc.chainmu.TryLock() {
  2217  		return errChainStopped
  2218  	}
  2219  	defer bc.chainmu.Unlock()
  2220  
  2221  	_, err := bc.insertChain(types.Blocks{block}, true, false)
  2222  	return err
  2223  }
  2224  
  2225  // SetCanonical rewinds the chain to set the new head block as the specified
  2226  // block. It's possible that the state of the new head is missing, and it will
  2227  // be recovered in this function as well.
  2228  func (bc *BlockChain) SetCanonical(head *types.Block) (common.Hash, error) {
  2229  	if !bc.chainmu.TryLock() {
  2230  		return common.Hash{}, errChainStopped
  2231  	}
  2232  	defer bc.chainmu.Unlock()
  2233  
  2234  	// Re-execute the reorged chain in case the head state is missing.
  2235  	if !bc.HasState(head.Root()) {
  2236  		if latestValidHash, err := bc.recoverAncestors(head); err != nil {
  2237  			return latestValidHash, err
  2238  		}
  2239  		log.Info("Recovered head state", "number", head.Number(), "hash", head.Hash())
  2240  	}
  2241  	// Run the reorg if necessary and set the given block as new head.
  2242  	start := time.Now()
  2243  	if head.ParentHash() != bc.CurrentBlock().Hash() {
  2244  		if err := bc.reorg(bc.CurrentBlock(), head); err != nil {
  2245  			return common.Hash{}, err
  2246  		}
  2247  	}
  2248  	bc.writeHeadBlock(head)
  2249  
  2250  	// Emit events
  2251  	logs := bc.collectLogs(head, false)
  2252  	bc.chainFeed.Send(ChainEvent{Block: head, Hash: head.Hash(), Logs: logs})
  2253  	if len(logs) > 0 {
  2254  		bc.logsFeed.Send(logs)
  2255  	}
  2256  	bc.chainHeadFeed.Send(ChainHeadEvent{Block: head})
  2257  
  2258  	context := []interface{}{
  2259  		"number", head.Number(),
  2260  		"hash", head.Hash(),
  2261  		"root", head.Root(),
  2262  		"elapsed", time.Since(start),
  2263  	}
  2264  	if timestamp := time.Unix(int64(head.Time()), 0); time.Since(timestamp) > time.Minute {
  2265  		context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
  2266  	}
  2267  	log.Info("Chain head was updated", context...)
  2268  	return head.Hash(), nil
  2269  }
  2270  
  2271  func (bc *BlockChain) updateFutureBlocks() {
  2272  	futureTimer := time.NewTicker(5 * time.Second)
  2273  	defer futureTimer.Stop()
  2274  	defer bc.wg.Done()
  2275  	for {
  2276  		select {
  2277  		case <-futureTimer.C:
  2278  			bc.procFutureBlocks()
  2279  		case <-bc.quit:
  2280  			return
  2281  		}
  2282  	}
  2283  }
  2284  
  2285  // skipBlock returns 'true', if the block being imported can be skipped over, meaning
  2286  // that the block does not need to be processed but can be considered already fully 'done'.
  2287  func (bc *BlockChain) skipBlock(err error, it *insertIterator) bool {
  2288  	// We can only ever bypass processing if the only error returned by the validator
  2289  	// is ErrKnownBlock, which means all checks passed, but we already have the block
  2290  	// and state.
  2291  	if !errors.Is(err, ErrKnownBlock) {
  2292  		return false
  2293  	}
  2294  	// If we're not using snapshots, we can skip this, since we have both block
  2295  	// and (trie-) state
  2296  	if bc.snaps == nil {
  2297  		return true
  2298  	}
  2299  	var (
  2300  		header     = it.current() // header can't be nil
  2301  		parentRoot common.Hash
  2302  	)
  2303  	// If we also have the snapshot-state, we can skip the processing.
  2304  	if bc.snaps.Snapshot(header.Root) != nil {
  2305  		return true
  2306  	}
  2307  	// In this case, we have the trie-state but not snapshot-state. If the parent
  2308  	// snapshot-state exists, we need to process this in order to not get a gap
  2309  	// in the snapshot layers.
  2310  	// Resolve parent block
  2311  	if parent := it.previous(); parent != nil {
  2312  		parentRoot = parent.Root
  2313  	} else if parent = bc.GetHeaderByHash(header.ParentHash); parent != nil {
  2314  		parentRoot = parent.Root
  2315  	}
  2316  	if parentRoot == (common.Hash{}) {
  2317  		return false // Theoretically impossible case
  2318  	}
  2319  	// Parent is also missing snapshot: we can skip this. Otherwise process.
  2320  	if bc.snaps.Snapshot(parentRoot) == nil {
  2321  		return true
  2322  	}
  2323  	return false
  2324  }
  2325  
  2326  // indexBlocks reindexes or unindexes transactions depending on user configuration
  2327  func (bc *BlockChain) indexBlocks(tail *uint64, head uint64, done chan struct{}) {
  2328  	defer func() { close(done) }()
  2329  
  2330  	// The tail flag is not existent, it means the node is just initialized
  2331  	// and all blocks(may from ancient store) are not indexed yet.
  2332  	if tail == nil {
  2333  		from := uint64(0)
  2334  		if bc.txLookupLimit != 0 && head >= bc.txLookupLimit {
  2335  			from = head - bc.txLookupLimit + 1
  2336  		}
  2337  		rawdb.IndexTransactions(bc.db, from, head+1, bc.quit)
  2338  		return
  2339  	}
  2340  	// The tail flag is existent, but the whole chain is required to be indexed.
  2341  	if bc.txLookupLimit == 0 || head < bc.txLookupLimit {
  2342  		if *tail > 0 {
  2343  			// It can happen when chain is rewound to a historical point which
  2344  			// is even lower than the indexes tail, recap the indexing target
  2345  			// to new head to avoid reading non-existent block bodies.
  2346  			end := *tail
  2347  			if end > head+1 {
  2348  				end = head + 1
  2349  			}
  2350  			rawdb.IndexTransactions(bc.db, 0, end, bc.quit)
  2351  		}
  2352  		return
  2353  	}
  2354  	// Update the transaction index to the new chain state
  2355  	if head-bc.txLookupLimit+1 < *tail {
  2356  		// Reindex a part of missing indices and rewind index tail to HEAD-limit
  2357  		rawdb.IndexTransactions(bc.db, head-bc.txLookupLimit+1, *tail, bc.quit)
  2358  	} else {
  2359  		// Unindex a part of stale indices and forward index tail to HEAD-limit
  2360  		rawdb.UnindexTransactions(bc.db, *tail, head-bc.txLookupLimit+1, bc.quit)
  2361  	}
  2362  }
  2363  
  2364  // maintainTxIndex is responsible for the construction and deletion of the
  2365  // transaction index.
  2366  //
  2367  // User can use flag `txlookuplimit` to specify a "recentness" block, below
  2368  // which ancient tx indices get deleted. If `txlookuplimit` is 0, it means
  2369  // all tx indices will be reserved.
  2370  //
  2371  // The user can adjust the txlookuplimit value for each launch after sync,
  2372  // Geth will automatically construct the missing indices or delete the extra
  2373  // indices.
  2374  func (bc *BlockChain) maintainTxIndex() {
  2375  	defer bc.wg.Done()
  2376  
  2377  	// Listening to chain events and manipulate the transaction indexes.
  2378  	var (
  2379  		done   chan struct{}                  // Non-nil if background unindexing or reindexing routine is active.
  2380  		headCh = make(chan ChainHeadEvent, 1) // Buffered to avoid locking up the event feed
  2381  	)
  2382  	sub := bc.SubscribeChainHeadEvent(headCh)
  2383  	if sub == nil {
  2384  		return
  2385  	}
  2386  	defer sub.Unsubscribe()
  2387  
  2388  	for {
  2389  		select {
  2390  		case head := <-headCh:
  2391  			if done == nil {
  2392  				done = make(chan struct{})
  2393  				go bc.indexBlocks(rawdb.ReadTxIndexTail(bc.db), head.Block.NumberU64(), done)
  2394  			}
  2395  		case <-done:
  2396  			done = nil
  2397  		case <-bc.quit:
  2398  			if done != nil {
  2399  				log.Info("Waiting background transaction indexer to exit")
  2400  				<-done
  2401  			}
  2402  			return
  2403  		}
  2404  	}
  2405  }
  2406  
  2407  // reportBlock logs a bad block error.
  2408  func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) {
  2409  	rawdb.WriteBadBlock(bc.db, block)
  2410  	log.Error(summarizeBadBlock(block, receipts, bc.Config(), err))
  2411  }
  2412  
  2413  // summarizeBadBlock returns a string summarizing the bad block and other
  2414  // relevant information.
  2415  func summarizeBadBlock(block *types.Block, receipts []*types.Receipt, config *params.ChainConfig, err error) string {
  2416  	var receiptString string
  2417  	for i, receipt := range receipts {
  2418  		receiptString += fmt.Sprintf("\n  %d: cumulative: %v gas: %v contract: %v status: %v tx: %v logs: %v bloom: %x state: %x",
  2419  			i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(),
  2420  			receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState)
  2421  	}
  2422  	version, vcs := version.Info()
  2423  	platform := fmt.Sprintf("%s %s %s %s", version, runtime.Version(), runtime.GOARCH, runtime.GOOS)
  2424  	if vcs != "" {
  2425  		vcs = fmt.Sprintf("\nVCS: %s", vcs)
  2426  	}
  2427  	return fmt.Sprintf(`
  2428  ########## BAD BLOCK #########
  2429  Block: %v (%#x)
  2430  Error: %v
  2431  Platform: %v%v
  2432  Chain config: %#v
  2433  Receipts: %v
  2434  ##############################
  2435  `, block.Number(), block.Hash(), err, platform, vcs, config, receiptString)
  2436  }
  2437  
  2438  // InsertHeaderChain attempts to insert the given header chain in to the local
  2439  // chain, possibly creating a reorg. If an error is returned, it will return the
  2440  // index number of the failing header as well an error describing what went wrong.
  2441  //
  2442  // The verify parameter can be used to fine tune whether nonce verification
  2443  // should be done or not. The reason behind the optional check is because some
  2444  // of the header retrieval mechanisms already need to verify nonces, as well as
  2445  // because nonces can be verified sparsely, not needing to check each.
  2446  func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
  2447  	if len(chain) == 0 {
  2448  		return 0, nil
  2449  	}
  2450  	start := time.Now()
  2451  	if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil {
  2452  		return i, err
  2453  	}
  2454  
  2455  	if !bc.chainmu.TryLock() {
  2456  		return 0, errChainStopped
  2457  	}
  2458  	defer bc.chainmu.Unlock()
  2459  	_, err := bc.hc.InsertHeaderChain(chain, start, bc.forker)
  2460  	return 0, err
  2461  }
  2462  
  2463  // SetBlockValidatorAndProcessorForTesting sets the current validator and processor.
  2464  // This method can be used to force an invalid blockchain to be verified for tests.
  2465  // This method is unsafe and should only be used before block import starts.
  2466  func (bc *BlockChain) SetBlockValidatorAndProcessorForTesting(v Validator, p Processor) {
  2467  	bc.validator = v
  2468  	bc.processor = p
  2469  }
  2470  
  2471  // SetTrieFlushInterval configures how often in-memory tries are persisted to disk.
  2472  // The interval is in terms of block processing time, not wall clock.
  2473  // It is thread-safe and can be called repeatedly without side effects.
  2474  func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
  2475  	atomic.StoreInt64(&bc.flushInterval, int64(interval))
  2476  }