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