github.com/phillinzzz/newBsc@v1.1.6/core/blockchain.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package core implements the Ethereum consensus protocol.
    18  package core
    19  
    20  import (
    21  	"errors"
    22  	"fmt"
    23  	"io"
    24  	"math/big"
    25  	mrand "math/rand"
    26  	"sort"
    27  	"sync"
    28  	"sync/atomic"
    29  	"time"
    30  
    31  	lru "github.com/hashicorp/golang-lru"
    32  
    33  	"github.com/phillinzzz/newBsc/common"
    34  	"github.com/phillinzzz/newBsc/common/mclock"
    35  	"github.com/phillinzzz/newBsc/common/prque"
    36  	"github.com/phillinzzz/newBsc/consensus"
    37  	"github.com/phillinzzz/newBsc/core/rawdb"
    38  	"github.com/phillinzzz/newBsc/core/state"
    39  	"github.com/phillinzzz/newBsc/core/state/snapshot"
    40  	"github.com/phillinzzz/newBsc/core/types"
    41  	"github.com/phillinzzz/newBsc/core/vm"
    42  	"github.com/phillinzzz/newBsc/ethdb"
    43  	"github.com/phillinzzz/newBsc/event"
    44  	"github.com/phillinzzz/newBsc/log"
    45  	"github.com/phillinzzz/newBsc/metrics"
    46  	"github.com/phillinzzz/newBsc/params"
    47  	"github.com/phillinzzz/newBsc/rlp"
    48  	"github.com/phillinzzz/newBsc/trie"
    49  )
    50  
    51  var (
    52  	headBlockGauge     = metrics.NewRegisteredGauge("chain/head/block", nil)
    53  	headHeaderGauge    = metrics.NewRegisteredGauge("chain/head/header", nil)
    54  	headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil)
    55  
    56  	accountReadTimer   = metrics.NewRegisteredTimer("chain/account/reads", nil)
    57  	accountHashTimer   = metrics.NewRegisteredTimer("chain/account/hashes", nil)
    58  	accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil)
    59  	accountCommitTimer = metrics.NewRegisteredTimer("chain/account/commits", nil)
    60  
    61  	storageReadTimer   = metrics.NewRegisteredTimer("chain/storage/reads", nil)
    62  	storageHashTimer   = metrics.NewRegisteredTimer("chain/storage/hashes", nil)
    63  	storageUpdateTimer = metrics.NewRegisteredTimer("chain/storage/updates", nil)
    64  	storageCommitTimer = metrics.NewRegisteredTimer("chain/storage/commits", nil)
    65  
    66  	snapshotAccountReadTimer = metrics.NewRegisteredTimer("chain/snapshot/account/reads", nil)
    67  	snapshotStorageReadTimer = metrics.NewRegisteredTimer("chain/snapshot/storage/reads", nil)
    68  	snapshotCommitTimer      = metrics.NewRegisteredTimer("chain/snapshot/commits", nil)
    69  
    70  	blockInsertTimer     = metrics.NewRegisteredTimer("chain/inserts", nil)
    71  	blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil)
    72  	blockExecutionTimer  = metrics.NewRegisteredTimer("chain/execution", nil)
    73  	blockWriteTimer      = metrics.NewRegisteredTimer("chain/write", nil)
    74  
    75  	blockReorgMeter         = metrics.NewRegisteredMeter("chain/reorg/executes", nil)
    76  	blockReorgAddMeter      = metrics.NewRegisteredMeter("chain/reorg/add", nil)
    77  	blockReorgDropMeter     = metrics.NewRegisteredMeter("chain/reorg/drop", nil)
    78  	blockReorgInvalidatedTx = metrics.NewRegisteredMeter("chain/reorg/invalidTx", nil)
    79  
    80  	errInsertionInterrupted = errors.New("insertion is interrupted")
    81  )
    82  
    83  const (
    84  	bodyCacheLimit         = 256
    85  	blockCacheLimit        = 256
    86  	diffLayerCacheLimit    = 1024
    87  	diffLayerRLPCacheLimit = 256
    88  	receiptsCacheLimit     = 10000
    89  	txLookupCacheLimit     = 1024
    90  	maxFutureBlocks        = 256
    91  	maxTimeFutureBlocks    = 30
    92  	maxBeyondBlocks        = 2048
    93  
    94  	diffLayerFreezerRecheckInterval = 3 * time.Second
    95  	diffLayerPruneRecheckInterval   = 1 * time.Second // The interval to prune unverified diff layers
    96  	maxDiffQueueDist                = 2048            // Maximum allowed distance from the chain head to queue diffLayers
    97  	maxDiffLimit                    = 2048            // Maximum number of unique diff layers a peer may have responded
    98  	maxDiffForkDist                 = 11              // Maximum allowed backward distance from the chain head
    99  	maxDiffLimitForBroadcast        = 128             // Maximum number of unique diff layers a peer may have broadcasted
   100  
   101  	// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
   102  	//
   103  	// Changelog:
   104  	//
   105  	// - Version 4
   106  	//   The following incompatible database changes were added:
   107  	//   * the `BlockNumber`, `TxHash`, `TxIndex`, `BlockHash` and `Index` fields of log are deleted
   108  	//   * the `Bloom` field of receipt is deleted
   109  	//   * the `BlockIndex` and `TxIndex` fields of txlookup are deleted
   110  	// - Version 5
   111  	//  The following incompatible database changes were added:
   112  	//    * the `TxHash`, `GasCost`, and `ContractAddress` fields are no longer stored for a receipt
   113  	//    * the `TxHash`, `GasCost`, and `ContractAddress` fields are computed by looking up the
   114  	//      receipts' corresponding block
   115  	// - Version 6
   116  	//  The following incompatible database changes were added:
   117  	//    * Transaction lookup information stores the corresponding block number instead of block hash
   118  	// - Version 7
   119  	//  The following incompatible database changes were added:
   120  	//    * Use freezer as the ancient database to maintain all ancient data
   121  	// - Version 8
   122  	//  The following incompatible database changes were added:
   123  	//    * New scheme for contract code in order to separate the codes and trie nodes
   124  	BlockChainVersion uint64 = 8
   125  )
   126  
   127  // CacheConfig contains the configuration values for the trie caching/pruning
   128  // that's resident in a blockchain.
   129  type CacheConfig struct {
   130  	TrieCleanLimit     int           // Memory allowance (MB) to use for caching trie nodes in memory
   131  	TrieCleanJournal   string        // Disk journal for saving clean cache entries.
   132  	TrieCleanRejournal time.Duration // Time interval to dump clean cache to disk periodically
   133  	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  	TriesInMemory      uint64        // How many tries keeps in memory
   139  
   140  	SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it
   141  }
   142  
   143  // To avoid cycle import
   144  type PeerIDer interface {
   145  	ID() string
   146  }
   147  
   148  // defaultCacheConfig are the default caching values if none are specified by the
   149  // user (also used during testing).
   150  var defaultCacheConfig = &CacheConfig{
   151  	TrieCleanLimit: 256,
   152  	TrieDirtyLimit: 256,
   153  	TrieTimeLimit:  5 * time.Minute,
   154  	SnapshotLimit:  256,
   155  	TriesInMemory:  128,
   156  	SnapshotWait:   true,
   157  }
   158  
   159  type BlockChainOption func(*BlockChain) *BlockChain
   160  
   161  // BlockChain represents the canonical chain given a database with a genesis
   162  // block. The Blockchain manages chain imports, reverts, chain reorganisations.
   163  //
   164  // Importing blocks in to the block chain happens according to the set of rules
   165  // defined by the two stage Validator. Processing of blocks is done using the
   166  // Processor which processes the included transaction. The validation of the state
   167  // is done in the second part of the Validator. Failing results in aborting of
   168  // the import.
   169  //
   170  // The BlockChain also helps in returning blocks from **any** chain included
   171  // in the database as well as blocks that represents the canonical chain. It's
   172  // important to note that GetBlock can return any block and does not need to be
   173  // included in the canonical one where as GetBlockByNumber always represents the
   174  // canonical chain.
   175  type BlockChain struct {
   176  	chainConfig *params.ChainConfig // Chain & network configuration
   177  	cacheConfig *CacheConfig        // Cache configuration for pruning
   178  
   179  	db     ethdb.Database // Low level persistent database to store final content in
   180  	snaps  *snapshot.Tree // Snapshot tree for fast trie leaf access
   181  	triegc *prque.Prque   // Priority queue mapping block numbers to tries to gc
   182  	gcproc time.Duration  // Accumulates canonical block processing for trie dumping
   183  
   184  	// txLookupLimit is the maximum number of blocks from head whose tx indices
   185  	// are reserved:
   186  	//  * 0:   means no limit and regenerate any missing indexes
   187  	//  * N:   means N block limit [HEAD-N+1, HEAD] and delete extra indexes
   188  	//  * nil: disable tx reindexer/deleter, but still index new blocks
   189  	txLookupLimit uint64
   190  	triesInMemory uint64
   191  
   192  	hc            *HeaderChain
   193  	rmLogsFeed    event.Feed
   194  	chainFeed     event.Feed
   195  	chainSideFeed event.Feed
   196  	chainHeadFeed event.Feed
   197  	logsFeed      event.Feed
   198  	blockProcFeed event.Feed
   199  	scope         event.SubscriptionScope
   200  	genesisBlock  *types.Block
   201  
   202  	chainmu sync.RWMutex // blockchain insertion lock
   203  
   204  	currentBlock          atomic.Value // Current head of the block chain
   205  	currentFastBlock      atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
   206  	highestVerifiedHeader atomic.Value
   207  
   208  	stateCache    state.Database // State database to reuse between imports (contains state cache)
   209  	bodyCache     *lru.Cache     // Cache for the most recent block bodies
   210  	bodyRLPCache  *lru.Cache     // Cache for the most recent block bodies in RLP encoded format
   211  	receiptsCache *lru.Cache     // Cache for the most recent receipts per block
   212  	blockCache    *lru.Cache     // Cache for the most recent entire blocks
   213  	txLookupCache *lru.Cache     // Cache for the most recent transaction lookup data.
   214  	futureBlocks  *lru.Cache     // future blocks are blocks added for later processing
   215  
   216  	// trusted diff layers
   217  	diffLayerCache             *lru.Cache   // Cache for the diffLayers
   218  	diffLayerRLPCache          *lru.Cache   // Cache for the rlp encoded diffLayers
   219  	diffQueue                  *prque.Prque // A Priority queue to store recent diff layer
   220  	diffQueueBuffer            chan *types.DiffLayer
   221  	diffLayerFreezerBlockLimit uint64
   222  
   223  	// untrusted diff layers
   224  	diffMux               sync.RWMutex
   225  	blockHashToDiffLayers map[common.Hash]map[common.Hash]*types.DiffLayer // map[blockHash] map[DiffHash]Diff
   226  	diffHashToBlockHash   map[common.Hash]common.Hash                      // map[diffHash]blockHash
   227  	diffHashToPeers       map[common.Hash]map[string]struct{}              // map[diffHash]map[pid]
   228  	diffNumToBlockHashes  map[uint64]map[common.Hash]struct{}              // map[number]map[blockHash]
   229  	diffPeersToDiffHashes map[string]map[common.Hash]struct{}              // map[pid]map[diffHash]
   230  
   231  	quit          chan struct{}  // blockchain quit channel
   232  	wg            sync.WaitGroup // chain processing wait group for shutting down
   233  	running       int32          // 0 if chain is running, 1 when stopped
   234  	procInterrupt int32          // interrupt signaler for block processing
   235  
   236  	engine    consensus.Engine
   237  	validator Validator // Block and state validator interface
   238  	processor Processor // Block transaction processor interface
   239  	vmConfig  vm.Config
   240  
   241  	shouldPreserve  func(*types.Block) bool        // Function used to determine whether should preserve the given block.
   242  	terminateInsert func(common.Hash, uint64) bool // Testing hook used to terminate ancient receipt chain insertion.
   243  }
   244  
   245  // NewBlockChain returns a fully initialised block chain using information
   246  // available in the database. It initialises the default Ethereum Validator and
   247  // Processor.
   248  func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine,
   249  	vmConfig vm.Config, shouldPreserve func(block *types.Block) bool, txLookupLimit *uint64,
   250  	options ...BlockChainOption) (*BlockChain, error) {
   251  	if cacheConfig == nil {
   252  		cacheConfig = defaultCacheConfig
   253  	}
   254  	if cacheConfig.TriesInMemory != 128 {
   255  		log.Warn("TriesInMemory isn't the default value(128), you need specify exact same TriesInMemory when prune data",
   256  			"triesInMemory", cacheConfig.TriesInMemory)
   257  	}
   258  	bodyCache, _ := lru.New(bodyCacheLimit)
   259  	bodyRLPCache, _ := lru.New(bodyCacheLimit)
   260  	receiptsCache, _ := lru.New(receiptsCacheLimit)
   261  	blockCache, _ := lru.New(blockCacheLimit)
   262  	txLookupCache, _ := lru.New(txLookupCacheLimit)
   263  	futureBlocks, _ := lru.New(maxFutureBlocks)
   264  	diffLayerCache, _ := lru.New(diffLayerCacheLimit)
   265  	diffLayerRLPCache, _ := lru.New(diffLayerRLPCacheLimit)
   266  
   267  	bc := &BlockChain{
   268  		chainConfig: chainConfig,
   269  		cacheConfig: cacheConfig,
   270  		db:          db,
   271  		triegc:      prque.New(nil),
   272  		stateCache: state.NewDatabaseWithConfigAndCache(db, &trie.Config{
   273  			Cache:     cacheConfig.TrieCleanLimit,
   274  			Journal:   cacheConfig.TrieCleanJournal,
   275  			Preimages: cacheConfig.Preimages,
   276  		}),
   277  		triesInMemory:         cacheConfig.TriesInMemory,
   278  		quit:                  make(chan struct{}),
   279  		shouldPreserve:        shouldPreserve,
   280  		bodyCache:             bodyCache,
   281  		bodyRLPCache:          bodyRLPCache,
   282  		receiptsCache:         receiptsCache,
   283  		blockCache:            blockCache,
   284  		diffLayerCache:        diffLayerCache,
   285  		diffLayerRLPCache:     diffLayerRLPCache,
   286  		txLookupCache:         txLookupCache,
   287  		futureBlocks:          futureBlocks,
   288  		engine:                engine,
   289  		vmConfig:              vmConfig,
   290  		diffQueue:             prque.New(nil),
   291  		diffQueueBuffer:       make(chan *types.DiffLayer),
   292  		blockHashToDiffLayers: make(map[common.Hash]map[common.Hash]*types.DiffLayer),
   293  		diffHashToBlockHash:   make(map[common.Hash]common.Hash),
   294  		diffHashToPeers:       make(map[common.Hash]map[string]struct{}),
   295  		diffNumToBlockHashes:  make(map[uint64]map[common.Hash]struct{}),
   296  		diffPeersToDiffHashes: make(map[string]map[common.Hash]struct{}),
   297  	}
   298  	bc.validator = NewBlockValidator(chainConfig, bc, engine)
   299  	bc.processor = NewStateProcessor(chainConfig, bc, engine)
   300  
   301  	var err error
   302  	bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped)
   303  	if err != nil {
   304  		return nil, err
   305  	}
   306  	bc.genesisBlock = bc.GetBlockByNumber(0)
   307  	if bc.genesisBlock == nil {
   308  		return nil, ErrNoGenesis
   309  	}
   310  
   311  	var nilBlock *types.Block
   312  	bc.currentBlock.Store(nilBlock)
   313  	bc.currentFastBlock.Store(nilBlock)
   314  
   315  	var nilHeader *types.Header
   316  	bc.highestVerifiedHeader.Store(nilHeader)
   317  
   318  	// Initialize the chain with ancient data if it isn't empty.
   319  	var txIndexBlock uint64
   320  
   321  	if bc.empty() {
   322  		rawdb.InitDatabaseFromFreezer(bc.db)
   323  		// If ancient database is not empty, reconstruct all missing
   324  		// indices in the background.
   325  		frozen, _ := bc.db.Ancients()
   326  		if frozen > 0 {
   327  			txIndexBlock = frozen
   328  		}
   329  	}
   330  	if err := bc.loadLastState(); err != nil {
   331  		return nil, err
   332  	}
   333  	// Make sure the state associated with the block is available
   334  	head := bc.CurrentBlock()
   335  	if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil {
   336  		// Head state is missing, before the state recovery, find out the
   337  		// disk layer point of snapshot(if it's enabled). Make sure the
   338  		// rewound point is lower than disk layer.
   339  		var diskRoot common.Hash
   340  		if bc.cacheConfig.SnapshotLimit > 0 {
   341  			diskRoot = rawdb.ReadSnapshotRoot(bc.db)
   342  		}
   343  		if diskRoot != (common.Hash{}) {
   344  			log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot)
   345  
   346  			snapDisk, err := bc.SetHeadBeyondRoot(head.NumberU64(), diskRoot)
   347  			if err != nil {
   348  				return nil, err
   349  			}
   350  			// Chain rewound, persist old snapshot number to indicate recovery procedure
   351  			if snapDisk != 0 {
   352  				rawdb.WriteSnapshotRecoveryNumber(bc.db, snapDisk)
   353  			}
   354  		} else {
   355  			log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash())
   356  			if err := bc.SetHead(head.NumberU64()); err != nil {
   357  				return nil, err
   358  			}
   359  		}
   360  	}
   361  	// Ensure that a previous crash in SetHead doesn't leave extra ancients
   362  	if frozen, err := bc.db.Ancients(); err == nil && frozen > 0 {
   363  		var (
   364  			needRewind bool
   365  			low        uint64
   366  		)
   367  		// The head full block may be rolled back to a very low height due to
   368  		// blockchain repair. If the head full block is even lower than the ancient
   369  		// chain, truncate the ancient store.
   370  		fullBlock := bc.CurrentBlock()
   371  		if fullBlock != nil && fullBlock.Hash() != bc.genesisBlock.Hash() && fullBlock.NumberU64() < frozen-1 {
   372  			needRewind = true
   373  			low = fullBlock.NumberU64()
   374  		}
   375  		// In fast sync, it may happen that ancient data has been written to the
   376  		// ancient store, but the LastFastBlock has not been updated, truncate the
   377  		// extra data here.
   378  		fastBlock := bc.CurrentFastBlock()
   379  		if fastBlock != nil && fastBlock.NumberU64() < frozen-1 {
   380  			needRewind = true
   381  			if fastBlock.NumberU64() < low || low == 0 {
   382  				low = fastBlock.NumberU64()
   383  			}
   384  		}
   385  		if needRewind {
   386  			log.Error("Truncating ancient chain", "from", bc.CurrentHeader().Number.Uint64(), "to", low)
   387  			if err := bc.SetHead(low); err != nil {
   388  				return nil, err
   389  			}
   390  		}
   391  	}
   392  	// The first thing the node will do is reconstruct the verification data for
   393  	// the head block (ethash cache or clique voting snapshot). Might as well do
   394  	// it in advance.
   395  	bc.engine.VerifyHeader(bc, bc.CurrentHeader(), true)
   396  
   397  	// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
   398  	for hash := range BadHashes {
   399  		if header := bc.GetHeaderByHash(hash); header != nil {
   400  			// get the canonical block corresponding to the offending header's number
   401  			headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64())
   402  			// make sure the headerByNumber (if present) is in our current canonical chain
   403  			if headerByNumber != nil && headerByNumber.Hash() == header.Hash() {
   404  				log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash)
   405  				if err := bc.SetHead(header.Number.Uint64() - 1); err != nil {
   406  					return nil, err
   407  				}
   408  				log.Error("Chain rewind was successful, resuming normal operation")
   409  			}
   410  		}
   411  	}
   412  	// Load any existing snapshot, regenerating it if loading failed
   413  	if bc.cacheConfig.SnapshotLimit > 0 {
   414  		// If the chain was rewound past the snapshot persistent layer (causing
   415  		// a recovery block number to be persisted to disk), check if we're still
   416  		// in recovery mode and in that case, don't invalidate the snapshot on a
   417  		// head mismatch.
   418  		var recover bool
   419  
   420  		head := bc.CurrentBlock()
   421  		if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer > head.NumberU64() {
   422  			log.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer)
   423  			recover = true
   424  		}
   425  		bc.snaps, _ = snapshot.New(bc.db, bc.stateCache.TrieDB(), bc.cacheConfig.SnapshotLimit, int(bc.cacheConfig.TriesInMemory), head.Root(), !bc.cacheConfig.SnapshotWait, true, recover)
   426  	}
   427  	// do options before start any routine
   428  	for _, option := range options {
   429  		bc = option(bc)
   430  	}
   431  	// Take ownership of this particular state
   432  	go bc.update()
   433  	if txLookupLimit != nil {
   434  		bc.txLookupLimit = *txLookupLimit
   435  
   436  		bc.wg.Add(1)
   437  		go bc.maintainTxIndex(txIndexBlock)
   438  	}
   439  	// If periodic cache journal is required, spin it up.
   440  	if bc.cacheConfig.TrieCleanRejournal > 0 {
   441  		if bc.cacheConfig.TrieCleanRejournal < time.Minute {
   442  			log.Warn("Sanitizing invalid trie cache journal time", "provided", bc.cacheConfig.TrieCleanRejournal, "updated", time.Minute)
   443  			bc.cacheConfig.TrieCleanRejournal = time.Minute
   444  		}
   445  		triedb := bc.stateCache.TrieDB()
   446  		bc.wg.Add(1)
   447  		go func() {
   448  			defer bc.wg.Done()
   449  			triedb.SaveCachePeriodically(bc.cacheConfig.TrieCleanJournal, bc.cacheConfig.TrieCleanRejournal, bc.quit)
   450  		}()
   451  	}
   452  	// Need persist and prune diff layer
   453  	if bc.db.DiffStore() != nil {
   454  		go bc.trustedDiffLayerLoop()
   455  	}
   456  	go bc.untrustedDiffLayerPruneLoop()
   457  
   458  	return bc, nil
   459  }
   460  
   461  // GetVMConfig returns the block chain VM config.
   462  func (bc *BlockChain) GetVMConfig() *vm.Config {
   463  	return &bc.vmConfig
   464  }
   465  
   466  func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts) {
   467  	// TODO, This is a hot fix for the block hash of logs is `0x0000000000000000000000000000000000000000000000000000000000000000` for system tx
   468  	// Please check details in https://github.com/binance-chain/bsc/issues/443
   469  	// This is a temporary fix, the official fix should be a hard fork.
   470  	const possibleSystemReceipts = 3 // One slash tx, two reward distribute txs.
   471  	numOfReceipts := len(receipts)
   472  	for i := numOfReceipts - 1; i >= 0 && i >= numOfReceipts-possibleSystemReceipts; i-- {
   473  		for j := 0; j < len(receipts[i].Logs); j++ {
   474  			receipts[i].Logs[j].BlockHash = hash
   475  		}
   476  	}
   477  	bc.receiptsCache.Add(hash, receipts)
   478  }
   479  
   480  func (bc *BlockChain) cacheDiffLayer(diffLayer *types.DiffLayer) {
   481  	bc.diffLayerCache.Add(diffLayer.BlockHash, diffLayer)
   482  	if bc.db.DiffStore() != nil {
   483  		// push to priority queue before persisting
   484  		bc.diffQueueBuffer <- diffLayer
   485  	}
   486  }
   487  
   488  func (bc *BlockChain) cacheBlock(hash common.Hash, block *types.Block) {
   489  	bc.blockCache.Add(hash, block)
   490  }
   491  
   492  // empty returns an indicator whether the blockchain is empty.
   493  // Note, it's a special case that we connect a non-empty ancient
   494  // database with an empty node, so that we can plugin the ancient
   495  // into node seamlessly.
   496  func (bc *BlockChain) empty() bool {
   497  	genesis := bc.genesisBlock.Hash()
   498  	for _, hash := range []common.Hash{rawdb.ReadHeadBlockHash(bc.db), rawdb.ReadHeadHeaderHash(bc.db), rawdb.ReadHeadFastBlockHash(bc.db)} {
   499  		if hash != genesis {
   500  			return false
   501  		}
   502  	}
   503  	return true
   504  }
   505  
   506  // loadLastState loads the last known chain state from the database. This method
   507  // assumes that the chain manager mutex is held.
   508  func (bc *BlockChain) loadLastState() error {
   509  	// Restore the last known head block
   510  	head := rawdb.ReadHeadBlockHash(bc.db)
   511  	if head == (common.Hash{}) {
   512  		// Corrupt or empty database, init from scratch
   513  		log.Warn("Empty database, resetting chain")
   514  		return bc.Reset()
   515  	}
   516  	// Make sure the entire head block is available
   517  	currentBlock := bc.GetBlockByHash(head)
   518  	if currentBlock == nil {
   519  		// Corrupt or empty database, init from scratch
   520  		log.Warn("Head block missing, resetting chain", "hash", head)
   521  		return bc.Reset()
   522  	}
   523  	// Everything seems to be fine, set as the head block
   524  	bc.currentBlock.Store(currentBlock)
   525  	headBlockGauge.Update(int64(currentBlock.NumberU64()))
   526  
   527  	// Restore the last known head header
   528  	currentHeader := currentBlock.Header()
   529  	if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
   530  		if header := bc.GetHeaderByHash(head); header != nil {
   531  			currentHeader = header
   532  		}
   533  	}
   534  	bc.hc.SetCurrentHeader(currentHeader)
   535  
   536  	// Restore the last known head fast block
   537  	bc.currentFastBlock.Store(currentBlock)
   538  	headFastBlockGauge.Update(int64(currentBlock.NumberU64()))
   539  
   540  	if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
   541  		if block := bc.GetBlockByHash(head); block != nil {
   542  			bc.currentFastBlock.Store(block)
   543  			headFastBlockGauge.Update(int64(block.NumberU64()))
   544  		}
   545  	}
   546  	// Issue a status log for the user
   547  	currentFastBlock := bc.CurrentFastBlock()
   548  
   549  	headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
   550  	blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
   551  	fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64())
   552  
   553  	log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time), 0)))
   554  	log.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(currentBlock.Time()), 0)))
   555  	log.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentFastBlock.Time()), 0)))
   556  	if pivot := rawdb.ReadLastPivotNumber(bc.db); pivot != nil {
   557  		log.Info("Loaded last fast-sync pivot marker", "number", *pivot)
   558  	}
   559  	return nil
   560  }
   561  
   562  // SetHead rewinds the local chain to a new head. Depending on whether the node
   563  // was fast synced or full synced and in which state, the method will try to
   564  // delete minimal data from disk whilst retaining chain consistency.
   565  func (bc *BlockChain) SetHead(head uint64) error {
   566  	_, err := bc.SetHeadBeyondRoot(head, common.Hash{})
   567  	return err
   568  }
   569  
   570  // SetHeadBeyondRoot rewinds the local chain to a new head with the extra condition
   571  // that the rewind must pass the specified state root. This method is meant to be
   572  // used when rewinding with snapshots enabled to ensure that we go back further than
   573  // persistent disk layer. Depending on whether the node was fast synced or full, and
   574  // in which state, the method will try to delete minimal data from disk whilst
   575  // retaining chain consistency.
   576  //
   577  // The method returns the block number where the requested root cap was found.
   578  func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64, error) {
   579  	bc.chainmu.Lock()
   580  	defer bc.chainmu.Unlock()
   581  
   582  	// Track the block number of the requested root hash
   583  	var rootNumber uint64 // (no root == always 0)
   584  
   585  	// Retrieve the last pivot block to short circuit rollbacks beyond it and the
   586  	// current freezer limit to start nuking id underflown
   587  	pivot := rawdb.ReadLastPivotNumber(bc.db)
   588  	frozen, _ := bc.db.Ancients()
   589  
   590  	updateFn := func(db ethdb.KeyValueWriter, header *types.Header) (uint64, bool) {
   591  		// Rewind the block chain, ensuring we don't end up with a stateless head
   592  		// block. Note, depth equality is permitted to allow using SetHead as a
   593  		// chain reparation mechanism without deleting any data!
   594  		if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() {
   595  			newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
   596  			lastBlockNum := header.Number.Uint64()
   597  			if newHeadBlock == nil {
   598  				log.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash())
   599  				newHeadBlock = bc.genesisBlock
   600  			} else {
   601  				// Block exists, keep rewinding until we find one with state,
   602  				// keeping rewinding until we exceed the optional threshold
   603  				// root hash
   604  				beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true)
   605  				enoughBeyondCount := false
   606  				beyondCount := 0
   607  				for {
   608  					beyondCount++
   609  					// If a root threshold was requested but not yet crossed, check
   610  					if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root {
   611  						beyondRoot, rootNumber = true, newHeadBlock.NumberU64()
   612  					}
   613  
   614  					enoughBeyondCount = beyondCount > maxBeyondBlocks
   615  
   616  					if _, err := state.New(newHeadBlock.Root(), bc.stateCache, bc.snaps); err != nil {
   617  						log.Trace("Block state missing, rewinding further", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
   618  						if pivot == nil || newHeadBlock.NumberU64() > *pivot {
   619  							parent := bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1)
   620  							if parent != nil {
   621  								newHeadBlock = parent
   622  								continue
   623  							}
   624  							log.Error("Missing block in the middle, aiming genesis", "number", newHeadBlock.NumberU64()-1, "hash", newHeadBlock.ParentHash())
   625  							newHeadBlock = bc.genesisBlock
   626  						} else {
   627  							log.Trace("Rewind passed pivot, aiming genesis", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "pivot", *pivot)
   628  							newHeadBlock = bc.genesisBlock
   629  						}
   630  					}
   631  					if beyondRoot || (enoughBeyondCount && root != common.Hash{}) || newHeadBlock.NumberU64() == 0 {
   632  						if enoughBeyondCount && (root != common.Hash{}) && rootNumber == 0 {
   633  							for {
   634  								lastBlockNum++
   635  								block := bc.GetBlockByNumber(lastBlockNum)
   636  								if block == nil {
   637  									break
   638  								}
   639  								if block.Root() == root {
   640  									rootNumber = block.NumberU64()
   641  									break
   642  								}
   643  							}
   644  						}
   645  						log.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
   646  						break
   647  					}
   648  					log.Debug("Skipping block with threshold state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "root", newHeadBlock.Root())
   649  					newHeadBlock = bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) // Keep rewinding
   650  				}
   651  			}
   652  			rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash())
   653  
   654  			// Degrade the chain markers if they are explicitly reverted.
   655  			// In theory we should update all in-memory markers in the
   656  			// last step, however the direction of SetHead is from high
   657  			// to low, so it's safe the update in-memory markers directly.
   658  			bc.currentBlock.Store(newHeadBlock)
   659  			headBlockGauge.Update(int64(newHeadBlock.NumberU64()))
   660  		}
   661  		// Rewind the fast block in a simpleton way to the target head
   662  		if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() {
   663  			newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
   664  			// If either blocks reached nil, reset to the genesis state
   665  			if newHeadFastBlock == nil {
   666  				newHeadFastBlock = bc.genesisBlock
   667  			}
   668  			rawdb.WriteHeadFastBlockHash(db, newHeadFastBlock.Hash())
   669  
   670  			// Degrade the chain markers if they are explicitly reverted.
   671  			// In theory we should update all in-memory markers in the
   672  			// last step, however the direction of SetHead is from high
   673  			// to low, so it's safe the update in-memory markers directly.
   674  			bc.currentFastBlock.Store(newHeadFastBlock)
   675  			headFastBlockGauge.Update(int64(newHeadFastBlock.NumberU64()))
   676  		}
   677  		head := bc.CurrentBlock().NumberU64()
   678  
   679  		// If setHead underflown the freezer threshold and the block processing
   680  		// intent afterwards is full block importing, delete the chain segment
   681  		// between the stateful-block and the sethead target.
   682  		var wipe bool
   683  		if head+1 < frozen {
   684  			wipe = pivot == nil || head >= *pivot
   685  		}
   686  		return head, wipe // Only force wipe if full synced
   687  	}
   688  	// Rewind the header chain, deleting all block bodies until then
   689  	delFn := func(db ethdb.KeyValueWriter, hash common.Hash, num uint64) {
   690  		// Ignore the error here since light client won't hit this path
   691  		frozen, _ := bc.db.Ancients()
   692  		if num+1 <= frozen {
   693  			// Truncate all relative data(header, total difficulty, body, receipt
   694  			// and canonical hash) from ancient store.
   695  			if err := bc.db.TruncateAncients(num); err != nil {
   696  				log.Crit("Failed to truncate ancient data", "number", num, "err", err)
   697  			}
   698  			// Remove the hash <-> number mapping from the active store.
   699  			rawdb.DeleteHeaderNumber(db, hash)
   700  		} else {
   701  			// Remove relative body and receipts from the active store.
   702  			// The header, total difficulty and canonical hash will be
   703  			// removed in the hc.SetHead function.
   704  			rawdb.DeleteBody(db, hash, num)
   705  			rawdb.DeleteReceipts(db, hash, num)
   706  		}
   707  		// Todo(rjl493456442) txlookup, bloombits, etc
   708  	}
   709  	// If SetHead was only called as a chain reparation method, try to skip
   710  	// touching the header chain altogether, unless the freezer is broken
   711  	if block := bc.CurrentBlock(); block.NumberU64() == head {
   712  		if target, force := updateFn(bc.db, block.Header()); force {
   713  			bc.hc.SetHead(target, updateFn, delFn)
   714  		}
   715  	} else {
   716  		// Rewind the chain to the requested head and keep going backwards until a
   717  		// block with a state is found or fast sync pivot is passed
   718  		log.Warn("Rewinding blockchain", "target", head)
   719  		bc.hc.SetHead(head, updateFn, delFn)
   720  	}
   721  	// Clear out any stale content from the caches
   722  	bc.bodyCache.Purge()
   723  	bc.bodyRLPCache.Purge()
   724  	bc.receiptsCache.Purge()
   725  	bc.blockCache.Purge()
   726  	bc.txLookupCache.Purge()
   727  	bc.futureBlocks.Purge()
   728  
   729  	return rootNumber, bc.loadLastState()
   730  }
   731  
   732  // FastSyncCommitHead sets the current head block to the one defined by the hash
   733  // irrelevant what the chain contents were prior.
   734  func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
   735  	// Make sure that both the block as well at its state trie exists
   736  	block := bc.GetBlockByHash(hash)
   737  	if block == nil {
   738  		return fmt.Errorf("non existent block [%x..]", hash[:4])
   739  	}
   740  	if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil {
   741  		return err
   742  	}
   743  	// If all checks out, manually set the head block
   744  	bc.chainmu.Lock()
   745  	bc.currentBlock.Store(block)
   746  	headBlockGauge.Update(int64(block.NumberU64()))
   747  	bc.chainmu.Unlock()
   748  
   749  	// Destroy any existing state snapshot and regenerate it in the background,
   750  	// also resuming the normal maintenance of any previously paused snapshot.
   751  	if bc.snaps != nil {
   752  		bc.snaps.Rebuild(block.Root())
   753  	}
   754  	log.Info("Committed new head block", "number", block.Number(), "hash", hash)
   755  	return nil
   756  }
   757  
   758  // GasLimit returns the gas limit of the current HEAD block.
   759  func (bc *BlockChain) GasLimit() uint64 {
   760  	return bc.CurrentBlock().GasLimit()
   761  }
   762  
   763  // CurrentBlock retrieves the current head block of the canonical chain. The
   764  // block is retrieved from the blockchain's internal cache.
   765  func (bc *BlockChain) CurrentBlock() *types.Block {
   766  	return bc.currentBlock.Load().(*types.Block)
   767  }
   768  
   769  // Snapshots returns the blockchain snapshot tree.
   770  func (bc *BlockChain) Snapshots() *snapshot.Tree {
   771  	return bc.snaps
   772  }
   773  
   774  // CurrentFastBlock retrieves the current fast-sync head block of the canonical
   775  // chain. The block is retrieved from the blockchain's internal cache.
   776  func (bc *BlockChain) CurrentFastBlock() *types.Block {
   777  	return bc.currentFastBlock.Load().(*types.Block)
   778  }
   779  
   780  // Validator returns the current validator.
   781  func (bc *BlockChain) Validator() Validator {
   782  	return bc.validator
   783  }
   784  
   785  // Processor returns the current processor.
   786  func (bc *BlockChain) Processor() Processor {
   787  	return bc.processor
   788  }
   789  
   790  // State returns a new mutable state based on the current HEAD block.
   791  func (bc *BlockChain) State() (*state.StateDB, error) {
   792  	return bc.StateAt(bc.CurrentBlock().Root())
   793  }
   794  
   795  // StateAt returns a new mutable state based on a particular point in time.
   796  func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
   797  	return state.New(root, bc.stateCache, bc.snaps)
   798  }
   799  
   800  // StateCache returns the caching database underpinning the blockchain instance.
   801  func (bc *BlockChain) StateCache() state.Database {
   802  	return bc.stateCache
   803  }
   804  
   805  // Reset purges the entire blockchain, restoring it to its genesis state.
   806  func (bc *BlockChain) Reset() error {
   807  	return bc.ResetWithGenesisBlock(bc.genesisBlock)
   808  }
   809  
   810  // ResetWithGenesisBlock purges the entire blockchain, restoring it to the
   811  // specified genesis state.
   812  func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
   813  	// Dump the entire block chain and purge the caches
   814  	if err := bc.SetHead(0); err != nil {
   815  		return err
   816  	}
   817  	bc.chainmu.Lock()
   818  	defer bc.chainmu.Unlock()
   819  
   820  	// Prepare the genesis block and reinitialise the chain
   821  	batch := bc.db.NewBatch()
   822  	rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
   823  	rawdb.WriteBlock(batch, genesis)
   824  	if err := batch.Write(); err != nil {
   825  		log.Crit("Failed to write genesis block", "err", err)
   826  	}
   827  	bc.writeHeadBlock(genesis)
   828  
   829  	// Last update all in-memory chain markers
   830  	bc.genesisBlock = genesis
   831  	bc.currentBlock.Store(bc.genesisBlock)
   832  	headBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
   833  	bc.hc.SetGenesis(bc.genesisBlock.Header())
   834  	bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
   835  	bc.currentFastBlock.Store(bc.genesisBlock)
   836  	headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64()))
   837  	return nil
   838  }
   839  
   840  // Export writes the active chain to the given writer.
   841  func (bc *BlockChain) Export(w io.Writer) error {
   842  	return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64())
   843  }
   844  
   845  // ExportN writes a subset of the active chain to the given writer.
   846  func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
   847  	bc.chainmu.RLock()
   848  	defer bc.chainmu.RUnlock()
   849  
   850  	if first > last {
   851  		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
   852  	}
   853  	log.Info("Exporting batch of blocks", "count", last-first+1)
   854  
   855  	start, reported := time.Now(), time.Now()
   856  	for nr := first; nr <= last; nr++ {
   857  		block := bc.GetBlockByNumber(nr)
   858  		if block == nil {
   859  			return fmt.Errorf("export failed on #%d: not found", nr)
   860  		}
   861  		if err := block.EncodeRLP(w); err != nil {
   862  			return err
   863  		}
   864  		if time.Since(reported) >= statsReportLimit {
   865  			log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start)))
   866  			reported = time.Now()
   867  		}
   868  	}
   869  	return nil
   870  }
   871  
   872  // writeHeadBlock injects a new head block into the current block chain. This method
   873  // assumes that the block is indeed a true head. It will also reset the head
   874  // header and the head fast sync block to this very same block if they are older
   875  // or if they are on a different side chain.
   876  //
   877  // Note, this function assumes that the `mu` mutex is held!
   878  func (bc *BlockChain) writeHeadBlock(block *types.Block) {
   879  	// If the block is on a side chain or an unknown one, force other heads onto it too
   880  	updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash()
   881  
   882  	// Add the block to the canonical chain number scheme and mark as the head
   883  	batch := bc.db.NewBatch()
   884  	rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
   885  	rawdb.WriteTxLookupEntriesByBlock(batch, block)
   886  	rawdb.WriteHeadBlockHash(batch, block.Hash())
   887  
   888  	// If the block is better than our head or is on a different chain, force update heads
   889  	if updateHeads {
   890  		rawdb.WriteHeadHeaderHash(batch, block.Hash())
   891  		rawdb.WriteHeadFastBlockHash(batch, block.Hash())
   892  	}
   893  	// Flush the whole batch into the disk, exit the node if failed
   894  	if err := batch.Write(); err != nil {
   895  		log.Crit("Failed to update chain indexes and markers", "err", err)
   896  	}
   897  	// Update all in-memory chain markers in the last step
   898  	if updateHeads {
   899  		bc.hc.SetCurrentHeader(block.Header())
   900  		bc.currentFastBlock.Store(block)
   901  		headFastBlockGauge.Update(int64(block.NumberU64()))
   902  	}
   903  	bc.currentBlock.Store(block)
   904  	headBlockGauge.Update(int64(block.NumberU64()))
   905  }
   906  
   907  // Genesis retrieves the chain's genesis block.
   908  func (bc *BlockChain) Genesis() *types.Block {
   909  	return bc.genesisBlock
   910  }
   911  
   912  // GetBody retrieves a block body (transactions and uncles) from the database by
   913  // hash, caching it if found.
   914  func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
   915  	// Short circuit if the body's already in the cache, retrieve otherwise
   916  	if cached, ok := bc.bodyCache.Get(hash); ok {
   917  		body := cached.(*types.Body)
   918  		return body
   919  	}
   920  	number := bc.hc.GetBlockNumber(hash)
   921  	if number == nil {
   922  		return nil
   923  	}
   924  	body := rawdb.ReadBody(bc.db, hash, *number)
   925  	if body == nil {
   926  		return nil
   927  	}
   928  	// Cache the found body for next time and return
   929  	bc.bodyCache.Add(hash, body)
   930  	return body
   931  }
   932  
   933  // GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
   934  // caching it if found.
   935  func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
   936  	// Short circuit if the body's already in the cache, retrieve otherwise
   937  	if cached, ok := bc.bodyRLPCache.Get(hash); ok {
   938  		return cached.(rlp.RawValue)
   939  	}
   940  	number := bc.hc.GetBlockNumber(hash)
   941  	if number == nil {
   942  		return nil
   943  	}
   944  	body := rawdb.ReadBodyRLP(bc.db, hash, *number)
   945  	if len(body) == 0 {
   946  		return nil
   947  	}
   948  	// Cache the found body for next time and return
   949  	bc.bodyRLPCache.Add(hash, body)
   950  	return body
   951  }
   952  
   953  // GetDiffLayerRLP retrieves a diff layer in RLP encoding from the cache or database by blockHash
   954  func (bc *BlockChain) GetDiffLayerRLP(blockHash common.Hash) rlp.RawValue {
   955  	// Short circuit if the diffLayer's already in the cache, retrieve otherwise
   956  	if cached, ok := bc.diffLayerRLPCache.Get(blockHash); ok {
   957  		return cached.(rlp.RawValue)
   958  	}
   959  	if cached, ok := bc.diffLayerCache.Get(blockHash); ok {
   960  		diff := cached.(*types.DiffLayer)
   961  		bz, err := rlp.EncodeToBytes(diff)
   962  		if err != nil {
   963  			return nil
   964  		}
   965  		bc.diffLayerRLPCache.Add(blockHash, rlp.RawValue(bz))
   966  		return bz
   967  	}
   968  
   969  	// fallback to untrusted sources.
   970  	diff := bc.GetUnTrustedDiffLayer(blockHash, "")
   971  	if diff != nil {
   972  		bz, err := rlp.EncodeToBytes(diff)
   973  		if err != nil {
   974  			return nil
   975  		}
   976  		// No need to cache untrusted data
   977  		return bz
   978  	}
   979  
   980  	// fallback to disk
   981  	diffStore := bc.db.DiffStore()
   982  	if diffStore == nil {
   983  		return nil
   984  	}
   985  	rawData := rawdb.ReadDiffLayerRLP(diffStore, blockHash)
   986  	if len(rawData) != 0 {
   987  		bc.diffLayerRLPCache.Add(blockHash, rawData)
   988  	}
   989  	return rawData
   990  }
   991  
   992  func (bc *BlockChain) GetDiffAccounts(blockHash common.Hash) ([]common.Address, error) {
   993  	var (
   994  		accounts  []common.Address
   995  		diffLayer *types.DiffLayer
   996  	)
   997  
   998  	header := bc.GetHeaderByHash(blockHash)
   999  	if header == nil {
  1000  		return nil, fmt.Errorf("no block found")
  1001  	}
  1002  
  1003  	if cached, ok := bc.diffLayerCache.Get(blockHash); ok {
  1004  		diffLayer = cached.(*types.DiffLayer)
  1005  	} else if diffStore := bc.db.DiffStore(); diffStore != nil {
  1006  		diffLayer = rawdb.ReadDiffLayer(diffStore, blockHash)
  1007  	}
  1008  
  1009  	if diffLayer == nil {
  1010  		if header.TxHash != types.EmptyRootHash {
  1011  			return nil, fmt.Errorf("no diff layer found")
  1012  		}
  1013  
  1014  		return nil, nil
  1015  	}
  1016  
  1017  	for _, diffAccounts := range diffLayer.Accounts {
  1018  		accounts = append(accounts, diffAccounts.Account)
  1019  	}
  1020  
  1021  	if header.TxHash != types.EmptyRootHash && len(accounts) == 0 {
  1022  		return nil, fmt.Errorf("no diff account in block, maybe bad diff layer")
  1023  	}
  1024  
  1025  	return accounts, nil
  1026  }
  1027  
  1028  // HasBlock checks if a block is fully present in the database or not.
  1029  func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
  1030  	if bc.blockCache.Contains(hash) {
  1031  		return true
  1032  	}
  1033  	return rawdb.HasBody(bc.db, hash, number)
  1034  }
  1035  
  1036  // HasFastBlock checks if a fast block is fully present in the database or not.
  1037  func (bc *BlockChain) HasFastBlock(hash common.Hash, number uint64) bool {
  1038  	if !bc.HasBlock(hash, number) {
  1039  		return false
  1040  	}
  1041  	if bc.receiptsCache.Contains(hash) {
  1042  		return true
  1043  	}
  1044  	return rawdb.HasReceipts(bc.db, hash, number)
  1045  }
  1046  
  1047  // HasState checks if state trie is fully present in the database or not.
  1048  func (bc *BlockChain) HasState(hash common.Hash) bool {
  1049  	_, err := bc.stateCache.OpenTrie(hash)
  1050  	return err == nil
  1051  }
  1052  
  1053  // HasBlockAndState checks if a block and associated state trie is fully present
  1054  // in the database or not, caching it if present.
  1055  func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
  1056  	// Check first that the block itself is known
  1057  	block := bc.GetBlock(hash, number)
  1058  	if block == nil {
  1059  		return false
  1060  	}
  1061  	return bc.HasState(block.Root())
  1062  }
  1063  
  1064  // GetBlock retrieves a block from the database by hash and number,
  1065  // caching it if found.
  1066  func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
  1067  	// Short circuit if the block's already in the cache, retrieve otherwise
  1068  	if block, ok := bc.blockCache.Get(hash); ok {
  1069  		return block.(*types.Block)
  1070  	}
  1071  	block := rawdb.ReadBlock(bc.db, hash, number)
  1072  	if block == nil {
  1073  		return nil
  1074  	}
  1075  	// Cache the found block for next time and return
  1076  	bc.blockCache.Add(block.Hash(), block)
  1077  	return block
  1078  }
  1079  
  1080  // GetBlockByHash retrieves a block from the database by hash, caching it if found.
  1081  func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
  1082  	number := bc.hc.GetBlockNumber(hash)
  1083  	if number == nil {
  1084  		return nil
  1085  	}
  1086  	return bc.GetBlock(hash, *number)
  1087  }
  1088  
  1089  // GetBlockByNumber retrieves a block from the database by number, caching it
  1090  // (associated with its hash) if found.
  1091  func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
  1092  	hash := rawdb.ReadCanonicalHash(bc.db, number)
  1093  	if hash == (common.Hash{}) {
  1094  		return nil
  1095  	}
  1096  	return bc.GetBlock(hash, number)
  1097  }
  1098  
  1099  // GetReceiptsByHash retrieves the receipts for all transactions in a given block.
  1100  func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
  1101  	if receipts, ok := bc.receiptsCache.Get(hash); ok {
  1102  		return receipts.(types.Receipts)
  1103  	}
  1104  	number := rawdb.ReadHeaderNumber(bc.db, hash)
  1105  	if number == nil {
  1106  		return nil
  1107  	}
  1108  	receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig)
  1109  	if receipts == nil {
  1110  		return nil
  1111  	}
  1112  	bc.receiptsCache.Add(hash, receipts)
  1113  	return receipts
  1114  }
  1115  
  1116  // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
  1117  // [deprecated by eth/62]
  1118  func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
  1119  	number := bc.hc.GetBlockNumber(hash)
  1120  	if number == nil {
  1121  		return nil
  1122  	}
  1123  	for i := 0; i < n; i++ {
  1124  		block := bc.GetBlock(hash, *number)
  1125  		if block == nil {
  1126  			break
  1127  		}
  1128  		blocks = append(blocks, block)
  1129  		hash = block.ParentHash()
  1130  		*number--
  1131  	}
  1132  	return
  1133  }
  1134  
  1135  // GetUnclesInChain retrieves all the uncles from a given block backwards until
  1136  // a specific distance is reached.
  1137  func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
  1138  	uncles := []*types.Header{}
  1139  	for i := 0; block != nil && i < length; i++ {
  1140  		uncles = append(uncles, block.Uncles()...)
  1141  		block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
  1142  	}
  1143  	return uncles
  1144  }
  1145  
  1146  // TrieNode retrieves a blob of data associated with a trie node
  1147  // either from ephemeral in-memory cache, or from persistent storage.
  1148  func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) {
  1149  	return bc.stateCache.TrieDB().Node(hash)
  1150  }
  1151  
  1152  // ContractCode retrieves a blob of data associated with a contract hash
  1153  // either from ephemeral in-memory cache, or from persistent storage.
  1154  func (bc *BlockChain) ContractCode(hash common.Hash) ([]byte, error) {
  1155  	return bc.stateCache.ContractCode(common.Hash{}, hash)
  1156  }
  1157  
  1158  // ContractCodeWithPrefix retrieves a blob of data associated with a contract
  1159  // hash either from ephemeral in-memory cache, or from persistent storage.
  1160  //
  1161  // If the code doesn't exist in the in-memory cache, check the storage with
  1162  // new code scheme.
  1163  func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
  1164  	type codeReader interface {
  1165  		ContractCodeWithPrefix(addrHash, codeHash common.Hash) ([]byte, error)
  1166  	}
  1167  	return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Hash{}, hash)
  1168  }
  1169  
  1170  // Stop stops the blockchain service. If any imports are currently in progress
  1171  // it will abort them using the procInterrupt.
  1172  func (bc *BlockChain) Stop() {
  1173  	if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
  1174  		return
  1175  	}
  1176  	// Unsubscribe all subscriptions registered from blockchain
  1177  	bc.scope.Close()
  1178  	close(bc.quit)
  1179  	bc.StopInsert()
  1180  	bc.wg.Wait()
  1181  
  1182  	// Ensure that the entirety of the state snapshot is journalled to disk.
  1183  	var snapBase common.Hash
  1184  	if bc.snaps != nil {
  1185  		var err error
  1186  		if snapBase, err = bc.snaps.Journal(bc.CurrentBlock().Root()); err != nil {
  1187  			log.Error("Failed to journal state snapshot", "err", err)
  1188  		}
  1189  	}
  1190  	// Ensure the state of a recent block is also stored to disk before exiting.
  1191  	// We're writing three different states to catch different restart scenarios:
  1192  	//  - HEAD:     So we don't need to reprocess any blocks in the general case
  1193  	//  - HEAD-1:   So we don't do large reorgs if our HEAD becomes an uncle
  1194  	//  - HEAD-127: So we have a hard limit on the number of blocks reexecuted
  1195  	if !bc.cacheConfig.TrieDirtyDisabled {
  1196  		triedb := bc.stateCache.TrieDB()
  1197  
  1198  		for _, offset := range []uint64{0, 1, bc.triesInMemory - 1} {
  1199  			if number := bc.CurrentBlock().NumberU64(); number > offset {
  1200  				recent := bc.GetBlockByNumber(number - offset)
  1201  
  1202  				log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
  1203  				if err := triedb.Commit(recent.Root(), true, nil); err != nil {
  1204  					log.Error("Failed to commit recent state trie", "err", err)
  1205  				}
  1206  			}
  1207  		}
  1208  		if snapBase != (common.Hash{}) {
  1209  			log.Info("Writing snapshot state to disk", "root", snapBase)
  1210  			if err := triedb.Commit(snapBase, true, nil); err != nil {
  1211  				log.Error("Failed to commit recent state trie", "err", err)
  1212  			}
  1213  		}
  1214  		for !bc.triegc.Empty() {
  1215  			go triedb.Dereference(bc.triegc.PopItem().(common.Hash))
  1216  		}
  1217  		if size, _ := triedb.Size(); size != 0 {
  1218  			log.Error("Dangling trie nodes after full cleanup")
  1219  		}
  1220  	}
  1221  	// Ensure all live cached entries be saved into disk, so that we can skip
  1222  	// cache warmup when node restarts.
  1223  	if bc.cacheConfig.TrieCleanJournal != "" {
  1224  		triedb := bc.stateCache.TrieDB()
  1225  		triedb.SaveCache(bc.cacheConfig.TrieCleanJournal)
  1226  	}
  1227  	log.Info("Blockchain stopped")
  1228  }
  1229  
  1230  // StopInsert interrupts all insertion methods, causing them to return
  1231  // errInsertionInterrupted as soon as possible. Insertion is permanently disabled after
  1232  // calling this method.
  1233  func (bc *BlockChain) StopInsert() {
  1234  	atomic.StoreInt32(&bc.procInterrupt, 1)
  1235  }
  1236  
  1237  // insertStopped returns true after StopInsert has been called.
  1238  func (bc *BlockChain) insertStopped() bool {
  1239  	return atomic.LoadInt32(&bc.procInterrupt) == 1
  1240  }
  1241  
  1242  func (bc *BlockChain) procFutureBlocks() {
  1243  	blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
  1244  	for _, hash := range bc.futureBlocks.Keys() {
  1245  		if block, exist := bc.futureBlocks.Peek(hash); exist {
  1246  			blocks = append(blocks, block.(*types.Block))
  1247  		}
  1248  	}
  1249  	if len(blocks) > 0 {
  1250  		sort.Slice(blocks, func(i, j int) bool {
  1251  			return blocks[i].NumberU64() < blocks[j].NumberU64()
  1252  		})
  1253  		// Insert one by one as chain insertion needs contiguous ancestry between blocks
  1254  		for i := range blocks {
  1255  			bc.InsertChain(blocks[i : i+1])
  1256  		}
  1257  	}
  1258  }
  1259  
  1260  // WriteStatus status of write
  1261  type WriteStatus byte
  1262  
  1263  const (
  1264  	NonStatTy WriteStatus = iota
  1265  	CanonStatTy
  1266  	SideStatTy
  1267  )
  1268  
  1269  // truncateAncient rewinds the blockchain to the specified header and deletes all
  1270  // data in the ancient store that exceeds the specified header.
  1271  func (bc *BlockChain) truncateAncient(head uint64) error {
  1272  	frozen, err := bc.db.Ancients()
  1273  	if err != nil {
  1274  		return err
  1275  	}
  1276  	// Short circuit if there is no data to truncate in ancient store.
  1277  	if frozen <= head+1 {
  1278  		return nil
  1279  	}
  1280  	// Truncate all the data in the freezer beyond the specified head
  1281  	if err := bc.db.TruncateAncients(head + 1); err != nil {
  1282  		return err
  1283  	}
  1284  	// Clear out any stale content from the caches
  1285  	bc.hc.headerCache.Purge()
  1286  	bc.hc.tdCache.Purge()
  1287  	bc.hc.numberCache.Purge()
  1288  
  1289  	// Clear out any stale content from the caches
  1290  	bc.bodyCache.Purge()
  1291  	bc.bodyRLPCache.Purge()
  1292  	bc.receiptsCache.Purge()
  1293  	bc.blockCache.Purge()
  1294  	bc.txLookupCache.Purge()
  1295  	bc.futureBlocks.Purge()
  1296  
  1297  	log.Info("Rewind ancient data", "number", head)
  1298  	return nil
  1299  }
  1300  
  1301  // numberHash is just a container for a number and a hash, to represent a block
  1302  type numberHash struct {
  1303  	number uint64
  1304  	hash   common.Hash
  1305  }
  1306  
  1307  // InsertReceiptChain attempts to complete an already existing header chain with
  1308  // transaction and receipt data.
  1309  func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error) {
  1310  	// We don't require the chainMu here since we want to maximize the
  1311  	// concurrency of header insertion and receipt insertion.
  1312  	bc.wg.Add(1)
  1313  	defer bc.wg.Done()
  1314  
  1315  	var (
  1316  		ancientBlocks, liveBlocks     types.Blocks
  1317  		ancientReceipts, liveReceipts []types.Receipts
  1318  	)
  1319  	// Do a sanity check that the provided chain is actually ordered and linked
  1320  	for i := 0; i < len(blockChain); i++ {
  1321  		if i != 0 {
  1322  			if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() {
  1323  				log.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(),
  1324  					"prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash())
  1325  				return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, blockChain[i-1].NumberU64(),
  1326  					blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4])
  1327  			}
  1328  		}
  1329  		if blockChain[i].NumberU64() <= ancientLimit {
  1330  			ancientBlocks, ancientReceipts = append(ancientBlocks, blockChain[i]), append(ancientReceipts, receiptChain[i])
  1331  		} else {
  1332  			liveBlocks, liveReceipts = append(liveBlocks, blockChain[i]), append(liveReceipts, receiptChain[i])
  1333  		}
  1334  	}
  1335  
  1336  	var (
  1337  		stats = struct{ processed, ignored int32 }{}
  1338  		start = time.Now()
  1339  		size  = 0
  1340  	)
  1341  	// updateHead updates the head fast sync block if the inserted blocks are better
  1342  	// and returns an indicator whether the inserted blocks are canonical.
  1343  	updateHead := func(head *types.Block) bool {
  1344  		bc.chainmu.Lock()
  1345  
  1346  		// Rewind may have occurred, skip in that case.
  1347  		if bc.CurrentHeader().Number.Cmp(head.Number()) >= 0 {
  1348  			currentFastBlock, td := bc.CurrentFastBlock(), bc.GetTd(head.Hash(), head.NumberU64())
  1349  			if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 {
  1350  				rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
  1351  				bc.currentFastBlock.Store(head)
  1352  				headFastBlockGauge.Update(int64(head.NumberU64()))
  1353  				bc.chainmu.Unlock()
  1354  				return true
  1355  			}
  1356  		}
  1357  		bc.chainmu.Unlock()
  1358  		return false
  1359  	}
  1360  	// writeAncient writes blockchain and corresponding receipt chain into ancient store.
  1361  	//
  1362  	// this function only accepts canonical chain data. All side chain will be reverted
  1363  	// eventually.
  1364  	writeAncient := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
  1365  		var (
  1366  			previous = bc.CurrentFastBlock()
  1367  			batch    = bc.db.NewBatch()
  1368  		)
  1369  		// If any error occurs before updating the head or we are inserting a side chain,
  1370  		// all the data written this time wll be rolled back.
  1371  		defer func() {
  1372  			if previous != nil {
  1373  				if err := bc.truncateAncient(previous.NumberU64()); err != nil {
  1374  					log.Crit("Truncate ancient store failed", "err", err)
  1375  				}
  1376  			}
  1377  		}()
  1378  		var deleted []*numberHash
  1379  		for i, block := range blockChain {
  1380  			// Short circuit insertion if shutting down or processing failed
  1381  			if bc.insertStopped() {
  1382  				return 0, errInsertionInterrupted
  1383  			}
  1384  			// Short circuit insertion if it is required(used in testing only)
  1385  			if bc.terminateInsert != nil && bc.terminateInsert(block.Hash(), block.NumberU64()) {
  1386  				return i, errors.New("insertion is terminated for testing purpose")
  1387  			}
  1388  			// Short circuit if the owner header is unknown
  1389  			if !bc.HasHeader(block.Hash(), block.NumberU64()) {
  1390  				return i, fmt.Errorf("containing header #%d [%x..] unknown", block.Number(), block.Hash().Bytes()[:4])
  1391  			}
  1392  			if block.NumberU64() == 1 {
  1393  				// Make sure to write the genesis into the freezer
  1394  				if frozen, _ := bc.db.Ancients(); frozen == 0 {
  1395  					h := rawdb.ReadCanonicalHash(bc.db, 0)
  1396  					b := rawdb.ReadBlock(bc.db, h, 0)
  1397  					size += rawdb.WriteAncientBlock(bc.db, b, rawdb.ReadReceipts(bc.db, h, 0, bc.chainConfig), rawdb.ReadTd(bc.db, h, 0))
  1398  					log.Info("Wrote genesis to ancients")
  1399  				}
  1400  			}
  1401  			// Flush data into ancient database.
  1402  			size += rawdb.WriteAncientBlock(bc.db, block, receiptChain[i], bc.GetTd(block.Hash(), block.NumberU64()))
  1403  
  1404  			// Write tx indices if any condition is satisfied:
  1405  			// * If user requires to reserve all tx indices(txlookuplimit=0)
  1406  			// * If all ancient tx indices are required to be reserved(txlookuplimit is even higher than ancientlimit)
  1407  			// * If block number is large enough to be regarded as a recent block
  1408  			// It means blocks below the ancientLimit-txlookupLimit won't be indexed.
  1409  			//
  1410  			// But if the `TxIndexTail` is not nil, e.g. Geth is initialized with
  1411  			// an external ancient database, during the setup, blockchain will start
  1412  			// a background routine to re-indexed all indices in [ancients - txlookupLimit, ancients)
  1413  			// range. In this case, all tx indices of newly imported blocks should be
  1414  			// generated.
  1415  			if bc.txLookupLimit == 0 || ancientLimit <= bc.txLookupLimit || block.NumberU64() >= ancientLimit-bc.txLookupLimit {
  1416  				rawdb.WriteTxLookupEntriesByBlock(batch, block)
  1417  			} else if rawdb.ReadTxIndexTail(bc.db) != nil {
  1418  				rawdb.WriteTxLookupEntriesByBlock(batch, block)
  1419  			}
  1420  			stats.processed++
  1421  		}
  1422  		// Flush all tx-lookup index data.
  1423  		size += batch.ValueSize()
  1424  		if err := batch.Write(); err != nil {
  1425  			return 0, err
  1426  		}
  1427  		batch.Reset()
  1428  
  1429  		// Sync the ancient store explicitly to ensure all data has been flushed to disk.
  1430  		if err := bc.db.Sync(); err != nil {
  1431  			return 0, err
  1432  		}
  1433  		if !updateHead(blockChain[len(blockChain)-1]) {
  1434  			return 0, errors.New("side blocks can't be accepted as the ancient chain data")
  1435  		}
  1436  		previous = nil // disable rollback explicitly
  1437  
  1438  		// Wipe out canonical block data.
  1439  		for _, nh := range deleted {
  1440  			rawdb.DeleteBlockWithoutNumber(batch, nh.hash, nh.number)
  1441  			rawdb.DeleteCanonicalHash(batch, nh.number)
  1442  		}
  1443  		for _, block := range blockChain {
  1444  			// Always keep genesis block in active database.
  1445  			if block.NumberU64() != 0 {
  1446  				rawdb.DeleteBlockWithoutNumber(batch, block.Hash(), block.NumberU64())
  1447  				rawdb.DeleteCanonicalHash(batch, block.NumberU64())
  1448  			}
  1449  		}
  1450  		if err := batch.Write(); err != nil {
  1451  			return 0, err
  1452  		}
  1453  		batch.Reset()
  1454  
  1455  		// Wipe out side chain too.
  1456  		for _, nh := range deleted {
  1457  			for _, hash := range rawdb.ReadAllHashes(bc.db, nh.number) {
  1458  				rawdb.DeleteBlock(batch, hash, nh.number)
  1459  			}
  1460  		}
  1461  		for _, block := range blockChain {
  1462  			// Always keep genesis block in active database.
  1463  			if block.NumberU64() != 0 {
  1464  				for _, hash := range rawdb.ReadAllHashes(bc.db, block.NumberU64()) {
  1465  					rawdb.DeleteBlock(batch, hash, block.NumberU64())
  1466  				}
  1467  			}
  1468  		}
  1469  		if err := batch.Write(); err != nil {
  1470  			return 0, err
  1471  		}
  1472  		return 0, nil
  1473  	}
  1474  	// writeLive writes blockchain and corresponding receipt chain into active store.
  1475  	writeLive := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
  1476  		skipPresenceCheck := false
  1477  		batch := bc.db.NewBatch()
  1478  		for i, block := range blockChain {
  1479  			// Short circuit insertion if shutting down or processing failed
  1480  			if bc.insertStopped() {
  1481  				return 0, errInsertionInterrupted
  1482  			}
  1483  			// Short circuit if the owner header is unknown
  1484  			if !bc.HasHeader(block.Hash(), block.NumberU64()) {
  1485  				return i, fmt.Errorf("containing header #%d [%x..] unknown", block.Number(), block.Hash().Bytes()[:4])
  1486  			}
  1487  			if !skipPresenceCheck {
  1488  				// Ignore if the entire data is already known
  1489  				if bc.HasBlock(block.Hash(), block.NumberU64()) {
  1490  					stats.ignored++
  1491  					continue
  1492  				} else {
  1493  					// If block N is not present, neither are the later blocks.
  1494  					// This should be true, but if we are mistaken, the shortcut
  1495  					// here will only cause overwriting of some existing data
  1496  					skipPresenceCheck = true
  1497  				}
  1498  			}
  1499  			// Write all the data out into the database
  1500  			rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
  1501  			rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
  1502  			rawdb.WriteTxLookupEntriesByBlock(batch, block) // Always write tx indices for live blocks, we assume they are needed
  1503  
  1504  			// Write everything belongs to the blocks into the database. So that
  1505  			// we can ensure all components of body is completed(body, receipts,
  1506  			// tx indexes)
  1507  			if batch.ValueSize() >= ethdb.IdealBatchSize {
  1508  				if err := batch.Write(); err != nil {
  1509  					return 0, err
  1510  				}
  1511  				size += batch.ValueSize()
  1512  				batch.Reset()
  1513  			}
  1514  			stats.processed++
  1515  		}
  1516  		// Write everything belongs to the blocks into the database. So that
  1517  		// we can ensure all components of body is completed(body, receipts,
  1518  		// tx indexes)
  1519  		if batch.ValueSize() > 0 {
  1520  			size += batch.ValueSize()
  1521  			if err := batch.Write(); err != nil {
  1522  				return 0, err
  1523  			}
  1524  		}
  1525  		updateHead(blockChain[len(blockChain)-1])
  1526  		return 0, nil
  1527  	}
  1528  	// Write downloaded chain data and corresponding receipt chain data
  1529  	if len(ancientBlocks) > 0 {
  1530  		if n, err := writeAncient(ancientBlocks, ancientReceipts); err != nil {
  1531  			if err == errInsertionInterrupted {
  1532  				return 0, nil
  1533  			}
  1534  			return n, err
  1535  		}
  1536  	}
  1537  	// Write the tx index tail (block number from where we index) before write any live blocks
  1538  	if len(liveBlocks) > 0 && liveBlocks[0].NumberU64() == ancientLimit+1 {
  1539  		// The tx index tail can only be one of the following two options:
  1540  		// * 0: all ancient blocks have been indexed
  1541  		// * ancient-limit: the indices of blocks before ancient-limit are ignored
  1542  		if tail := rawdb.ReadTxIndexTail(bc.db); tail == nil {
  1543  			if bc.txLookupLimit == 0 || ancientLimit <= bc.txLookupLimit {
  1544  				rawdb.WriteTxIndexTail(bc.db, 0)
  1545  			} else {
  1546  				rawdb.WriteTxIndexTail(bc.db, ancientLimit-bc.txLookupLimit)
  1547  			}
  1548  		}
  1549  	}
  1550  	if len(liveBlocks) > 0 {
  1551  		if n, err := writeLive(liveBlocks, liveReceipts); err != nil {
  1552  			if err == errInsertionInterrupted {
  1553  				return 0, nil
  1554  			}
  1555  			return n, err
  1556  		}
  1557  	}
  1558  
  1559  	head := blockChain[len(blockChain)-1]
  1560  	context := []interface{}{
  1561  		"count", stats.processed, "elapsed", common.PrettyDuration(time.Since(start)),
  1562  		"number", head.Number(), "hash", head.Hash(), "age", common.PrettyAge(time.Unix(int64(head.Time()), 0)),
  1563  		"size", common.StorageSize(size),
  1564  	}
  1565  	if stats.ignored > 0 {
  1566  		context = append(context, []interface{}{"ignored", stats.ignored}...)
  1567  	}
  1568  	log.Info("Imported new block receipts", context...)
  1569  
  1570  	return 0, nil
  1571  }
  1572  
  1573  // SetTxLookupLimit is responsible for updating the txlookup limit to the
  1574  // original one stored in db if the new mismatches with the old one.
  1575  func (bc *BlockChain) SetTxLookupLimit(limit uint64) {
  1576  	bc.txLookupLimit = limit
  1577  }
  1578  
  1579  // TxLookupLimit retrieves the txlookup limit used by blockchain to prune
  1580  // stale transaction indices.
  1581  func (bc *BlockChain) TxLookupLimit() uint64 {
  1582  	return bc.txLookupLimit
  1583  }
  1584  
  1585  var lastWrite uint64
  1586  
  1587  // writeBlockWithoutState writes only the block and its metadata to the database,
  1588  // but does not write any state. This is used to construct competing side forks
  1589  // up to the point where they exceed the canonical total difficulty.
  1590  func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (err error) {
  1591  	bc.wg.Add(1)
  1592  	defer bc.wg.Done()
  1593  
  1594  	batch := bc.db.NewBatch()
  1595  	rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td)
  1596  	rawdb.WriteBlock(batch, block)
  1597  	if err := batch.Write(); err != nil {
  1598  		log.Crit("Failed to write block into disk", "err", err)
  1599  	}
  1600  	return nil
  1601  }
  1602  
  1603  // writeKnownBlock updates the head block flag with a known block
  1604  // and introduces chain reorg if necessary.
  1605  func (bc *BlockChain) writeKnownBlock(block *types.Block) error {
  1606  	bc.wg.Add(1)
  1607  	defer bc.wg.Done()
  1608  
  1609  	current := bc.CurrentBlock()
  1610  	if block.ParentHash() != current.Hash() {
  1611  		if err := bc.reorg(current, block); err != nil {
  1612  			return err
  1613  		}
  1614  	}
  1615  	bc.writeHeadBlock(block)
  1616  	return nil
  1617  }
  1618  
  1619  // WriteBlockWithState writes the block and all associated state to the database.
  1620  func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
  1621  	bc.chainmu.Lock()
  1622  	defer bc.chainmu.Unlock()
  1623  
  1624  	return bc.writeBlockWithState(block, receipts, logs, state, emitHeadEvent)
  1625  }
  1626  
  1627  // writeBlockWithState writes the block and all associated state to the database,
  1628  // but is expects the chain mutex to be held.
  1629  func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
  1630  	bc.wg.Add(1)
  1631  	defer bc.wg.Done()
  1632  
  1633  	// Calculate the total difficulty of the block
  1634  	ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
  1635  	if ptd == nil {
  1636  		return NonStatTy, consensus.ErrUnknownAncestor
  1637  	}
  1638  	// Make sure no inconsistent state is leaked during insertion
  1639  	currentBlock := bc.CurrentBlock()
  1640  	localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
  1641  	externTd := new(big.Int).Add(block.Difficulty(), ptd)
  1642  
  1643  	// Irrelevant of the canonical status, write the block itself to the database.
  1644  	//
  1645  	// Note all the components of block(td, hash->number map, header, body, receipts)
  1646  	// should be written atomically. BlockBatch is used for containing all components.
  1647  	wg := sync.WaitGroup{}
  1648  	wg.Add(1)
  1649  	go func() {
  1650  		blockBatch := bc.db.NewBatch()
  1651  		rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
  1652  		rawdb.WriteBlock(blockBatch, block)
  1653  		rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
  1654  		rawdb.WritePreimages(blockBatch, state.Preimages())
  1655  		if err := blockBatch.Write(); err != nil {
  1656  			log.Crit("Failed to write block into disk", "err", err)
  1657  		}
  1658  		wg.Done()
  1659  	}()
  1660  	// Commit all cached state changes into underlying memory database.
  1661  	root, diffLayer, err := state.Commit(bc.chainConfig.IsEIP158(block.Number()))
  1662  	if err != nil {
  1663  		return NonStatTy, err
  1664  	}
  1665  
  1666  	// Ensure no empty block body
  1667  	if diffLayer != nil && block.Header().TxHash != types.EmptyRootHash {
  1668  		// Filling necessary field
  1669  		diffLayer.Receipts = receipts
  1670  		diffLayer.BlockHash = block.Hash()
  1671  		diffLayer.Number = block.NumberU64()
  1672  		bc.cacheDiffLayer(diffLayer)
  1673  	}
  1674  	triedb := bc.stateCache.TrieDB()
  1675  
  1676  	// If we're running an archive node, always flush
  1677  	if bc.cacheConfig.TrieDirtyDisabled {
  1678  		if err := triedb.Commit(root, false, nil); err != nil {
  1679  			return NonStatTy, err
  1680  		}
  1681  	} else {
  1682  		// Full but not archive node, do proper garbage collection
  1683  		triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive
  1684  		bc.triegc.Push(root, -int64(block.NumberU64()))
  1685  
  1686  		if current := block.NumberU64(); current > bc.triesInMemory {
  1687  			// If we exceeded our memory allowance, flush matured singleton nodes to disk
  1688  			var (
  1689  				nodes, imgs = triedb.Size()
  1690  				limit       = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
  1691  			)
  1692  			if nodes > limit || imgs > 4*1024*1024 {
  1693  				triedb.Cap(limit - ethdb.IdealBatchSize)
  1694  			}
  1695  			// Find the next state trie we need to commit
  1696  			chosen := current - bc.triesInMemory
  1697  
  1698  			// If we exceeded out time allowance, flush an entire trie to disk
  1699  			if bc.gcproc > bc.cacheConfig.TrieTimeLimit {
  1700  				canWrite := true
  1701  				if posa, ok := bc.engine.(consensus.PoSA); ok {
  1702  					if !posa.EnoughDistance(bc, block.Header()) {
  1703  						canWrite = false
  1704  					}
  1705  				}
  1706  				if canWrite {
  1707  					// If the header is missing (canonical chain behind), we're reorging a low
  1708  					// diff sidechain. Suspend committing until this operation is completed.
  1709  					header := bc.GetHeaderByNumber(chosen)
  1710  					if header == nil {
  1711  						log.Warn("Reorg in progress, trie commit postponed", "number", chosen)
  1712  					} else {
  1713  						// If we're exceeding limits but haven't reached a large enough memory gap,
  1714  						// warn the user that the system is becoming unstable.
  1715  						if chosen < lastWrite+bc.triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit {
  1716  							log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/float64(bc.triesInMemory))
  1717  						}
  1718  						// Flush an entire trie and restart the counters
  1719  						triedb.Commit(header.Root, true, nil)
  1720  						lastWrite = chosen
  1721  						bc.gcproc = 0
  1722  					}
  1723  				}
  1724  			}
  1725  			// Garbage collect anything below our required write retention
  1726  			for !bc.triegc.Empty() {
  1727  				root, number := bc.triegc.Pop()
  1728  				if uint64(-number) > chosen {
  1729  					bc.triegc.Push(root, number)
  1730  					break
  1731  				}
  1732  				go triedb.Dereference(root.(common.Hash))
  1733  			}
  1734  		}
  1735  	}
  1736  	wg.Wait()
  1737  	// If the total difficulty is higher than our known, add it to the canonical chain
  1738  	// Second clause in the if statement reduces the vulnerability to selfish mining.
  1739  	// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
  1740  	reorg := externTd.Cmp(localTd) > 0
  1741  	currentBlock = bc.CurrentBlock()
  1742  	if !reorg && externTd.Cmp(localTd) == 0 {
  1743  		// Split same-difficulty blocks by number, then preferentially select
  1744  		// the block generated by the local miner as the canonical block.
  1745  		if block.NumberU64() < currentBlock.NumberU64() || block.Time() < currentBlock.Time() {
  1746  			reorg = true
  1747  		} else if p, ok := bc.engine.(consensus.PoSA); ok && p.IsLocalBlock(currentBlock.Header()) {
  1748  			reorg = true
  1749  		} else if block.NumberU64() == currentBlock.NumberU64() {
  1750  			var currentPreserve, blockPreserve bool
  1751  			if bc.shouldPreserve != nil {
  1752  				currentPreserve, blockPreserve = bc.shouldPreserve(currentBlock), bc.shouldPreserve(block)
  1753  			}
  1754  			reorg = !currentPreserve && (blockPreserve || mrand.Float64() < 0.5)
  1755  		}
  1756  	}
  1757  	if reorg {
  1758  		// Reorganise the chain if the parent is not the head block
  1759  		if block.ParentHash() != currentBlock.Hash() {
  1760  			if err := bc.reorg(currentBlock, block); err != nil {
  1761  				return NonStatTy, err
  1762  			}
  1763  		}
  1764  		status = CanonStatTy
  1765  	} else {
  1766  		status = SideStatTy
  1767  	}
  1768  	// Set new head.
  1769  	if status == CanonStatTy {
  1770  		bc.writeHeadBlock(block)
  1771  	}
  1772  	bc.futureBlocks.Remove(block.Hash())
  1773  
  1774  	if status == CanonStatTy {
  1775  		bc.chainFeed.Send(ChainEvent{Block: block, Hash: block.Hash(), Logs: logs})
  1776  		if len(logs) > 0 {
  1777  			bc.logsFeed.Send(logs)
  1778  		}
  1779  		// In theory we should fire a ChainHeadEvent when we inject
  1780  		// a canonical block, but sometimes we can insert a batch of
  1781  		// canonicial blocks. Avoid firing too much ChainHeadEvents,
  1782  		// we will fire an accumulated ChainHeadEvent and disable fire
  1783  		// event here.
  1784  		if emitHeadEvent {
  1785  			bc.chainHeadFeed.Send(ChainHeadEvent{Block: block})
  1786  		}
  1787  	} else {
  1788  		bc.chainSideFeed.Send(ChainSideEvent{Block: block})
  1789  	}
  1790  	return status, nil
  1791  }
  1792  
  1793  // addFutureBlock checks if the block is within the max allowed window to get
  1794  // accepted for future processing, and returns an error if the block is too far
  1795  // ahead and was not added.
  1796  func (bc *BlockChain) addFutureBlock(block *types.Block) error {
  1797  	max := uint64(time.Now().Unix() + maxTimeFutureBlocks)
  1798  	if block.Time() > max {
  1799  		return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max)
  1800  	}
  1801  	bc.futureBlocks.Add(block.Hash(), block)
  1802  	return nil
  1803  }
  1804  
  1805  // InsertChain attempts to insert the given batch of blocks in to the canonical
  1806  // chain or, otherwise, create a fork. If an error is returned it will return
  1807  // the index number of the failing block as well an error describing what went
  1808  // wrong.
  1809  //
  1810  // After insertion is done, all accumulated events will be fired.
  1811  func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
  1812  	// Sanity check that we have something meaningful to import
  1813  	if len(chain) == 0 {
  1814  		return 0, nil
  1815  	}
  1816  
  1817  	bc.blockProcFeed.Send(true)
  1818  	defer bc.blockProcFeed.Send(false)
  1819  
  1820  	// Remove already known canon-blocks
  1821  	var (
  1822  		block, prev *types.Block
  1823  	)
  1824  	// Do a sanity check that the provided chain is actually ordered and linked
  1825  	for i := 1; i < len(chain); i++ {
  1826  		block = chain[i]
  1827  		prev = chain[i-1]
  1828  		if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() {
  1829  			// Chain broke ancestry, log a message (programming error) and skip insertion
  1830  			log.Error("Non contiguous block insert", "number", block.Number(), "hash", block.Hash(),
  1831  				"parent", block.ParentHash(), "prevnumber", prev.Number(), "prevhash", prev.Hash())
  1832  
  1833  			return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, prev.NumberU64(),
  1834  				prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4])
  1835  		}
  1836  	}
  1837  	// Pre-checks passed, start the full block imports
  1838  	bc.wg.Add(1)
  1839  	bc.chainmu.Lock()
  1840  	n, err := bc.insertChain(chain, true)
  1841  	bc.chainmu.Unlock()
  1842  	bc.wg.Done()
  1843  
  1844  	return n, err
  1845  }
  1846  
  1847  // InsertChainWithoutSealVerification works exactly the same
  1848  // except for seal verification, seal verification is omitted
  1849  func (bc *BlockChain) InsertChainWithoutSealVerification(block *types.Block) (int, error) {
  1850  	bc.blockProcFeed.Send(true)
  1851  	defer bc.blockProcFeed.Send(false)
  1852  
  1853  	// Pre-checks passed, start the full block imports
  1854  	bc.wg.Add(1)
  1855  	bc.chainmu.Lock()
  1856  	n, err := bc.insertChain(types.Blocks([]*types.Block{block}), false)
  1857  	bc.chainmu.Unlock()
  1858  	bc.wg.Done()
  1859  
  1860  	return n, err
  1861  }
  1862  
  1863  // insertChain is the internal implementation of InsertChain, which assumes that
  1864  // 1) chains are contiguous, and 2) The chain mutex is held.
  1865  //
  1866  // This method is split out so that import batches that require re-injecting
  1867  // historical blocks can do so without releasing the lock, which could lead to
  1868  // racey behaviour. If a sidechain import is in progress, and the historic state
  1869  // is imported, but then new canon-head is added before the actual sidechain
  1870  // completes, then the historic state could be pruned again
  1871  func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, error) {
  1872  	// If the chain is terminating, don't even bother starting up
  1873  	if atomic.LoadInt32(&bc.procInterrupt) == 1 {
  1874  		return 0, nil
  1875  	}
  1876  	// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
  1877  	signer := types.MakeSigner(bc.chainConfig, chain[0].Number())
  1878  	go senderCacher.recoverFromBlocks(signer, chain)
  1879  
  1880  	var (
  1881  		stats     = insertStats{startTime: mclock.Now()}
  1882  		lastCanon *types.Block
  1883  	)
  1884  	// Fire a single chain head event if we've progressed the chain
  1885  	defer func() {
  1886  		if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
  1887  			bc.chainHeadFeed.Send(ChainHeadEvent{lastCanon})
  1888  		}
  1889  	}()
  1890  	// Start the parallel header verifier
  1891  	headers := make([]*types.Header, len(chain))
  1892  	seals := make([]bool, len(chain))
  1893  
  1894  	for i, block := range chain {
  1895  		headers[i] = block.Header()
  1896  		seals[i] = verifySeals
  1897  	}
  1898  	abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
  1899  	defer close(abort)
  1900  
  1901  	// Peek the error for the first block to decide the directing import logic
  1902  	it := newInsertIterator(chain, results, bc.validator)
  1903  
  1904  	block, err := it.next()
  1905  
  1906  	// Left-trim all the known blocks
  1907  	if err == ErrKnownBlock {
  1908  		// First block (and state) is known
  1909  		//   1. We did a roll-back, and should now do a re-import
  1910  		//   2. The block is stored as a sidechain, and is lying about it's stateroot, and passes a stateroot
  1911  		// 	    from the canonical chain, which has not been verified.
  1912  		// Skip all known blocks that are behind us
  1913  		var (
  1914  			current  = bc.CurrentBlock()
  1915  			localTd  = bc.GetTd(current.Hash(), current.NumberU64())
  1916  			externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) // The first block can't be nil
  1917  		)
  1918  		for block != nil && err == ErrKnownBlock {
  1919  			externTd = new(big.Int).Add(externTd, block.Difficulty())
  1920  			if localTd.Cmp(externTd) < 0 {
  1921  				break
  1922  			}
  1923  			log.Debug("Ignoring already known block", "number", block.Number(), "hash", block.Hash())
  1924  			stats.ignored++
  1925  
  1926  			block, err = it.next()
  1927  		}
  1928  		// The remaining blocks are still known blocks, the only scenario here is:
  1929  		// During the fast sync, the pivot point is already submitted but rollback
  1930  		// happens. Then node resets the head full block to a lower height via `rollback`
  1931  		// and leaves a few known blocks in the database.
  1932  		//
  1933  		// When node runs a fast sync again, it can re-import a batch of known blocks via
  1934  		// `insertChain` while a part of them have higher total difficulty than current
  1935  		// head full block(new pivot point).
  1936  		for block != nil && err == ErrKnownBlock {
  1937  			log.Debug("Writing previously known block", "number", block.Number(), "hash", block.Hash())
  1938  			if err := bc.writeKnownBlock(block); err != nil {
  1939  				return it.index, err
  1940  			}
  1941  			lastCanon = block
  1942  
  1943  			block, err = it.next()
  1944  		}
  1945  		// Falls through to the block import
  1946  	}
  1947  	switch {
  1948  	// First block is pruned, insert as sidechain and reorg only if TD grows enough
  1949  	case errors.Is(err, consensus.ErrPrunedAncestor):
  1950  		log.Debug("Pruned ancestor, inserting as sidechain", "number", block.Number(), "hash", block.Hash())
  1951  		return bc.insertSideChain(block, it)
  1952  
  1953  	// First block is future, shove it (and all children) to the future queue (unknown ancestor)
  1954  	case errors.Is(err, consensus.ErrFutureBlock) || (errors.Is(err, consensus.ErrUnknownAncestor) && bc.futureBlocks.Contains(it.first().ParentHash())):
  1955  		for block != nil && (it.index == 0 || errors.Is(err, consensus.ErrUnknownAncestor)) {
  1956  			log.Debug("Future block, postponing import", "number", block.Number(), "hash", block.Hash())
  1957  			if err := bc.addFutureBlock(block); err != nil {
  1958  				return it.index, err
  1959  			}
  1960  			block, err = it.next()
  1961  		}
  1962  		stats.queued += it.processed()
  1963  		stats.ignored += it.remaining()
  1964  
  1965  		// If there are any still remaining, mark as ignored
  1966  		return it.index, err
  1967  
  1968  	// Some other error occurred, abort
  1969  	case err != nil:
  1970  		bc.futureBlocks.Remove(block.Hash())
  1971  		stats.ignored += len(it.chain)
  1972  		bc.reportBlock(block, nil, err)
  1973  		return it.index, err
  1974  	}
  1975  	// No validation errors for the first block (or chain prefix skipped)
  1976  	var activeState *state.StateDB
  1977  	defer func() {
  1978  		// The chain importer is starting and stopping trie prefetchers. If a bad
  1979  		// block or other error is hit however, an early return may not properly
  1980  		// terminate the background threads. This defer ensures that we clean up
  1981  		// and dangling prefetcher, without defering each and holding on live refs.
  1982  		if activeState != nil {
  1983  			activeState.StopPrefetcher()
  1984  		}
  1985  	}()
  1986  
  1987  	for ; block != nil && err == nil || err == ErrKnownBlock; block, err = it.next() {
  1988  		// If the chain is terminating, stop processing blocks
  1989  		if bc.insertStopped() {
  1990  			log.Debug("Abort during block processing")
  1991  			break
  1992  		}
  1993  		// If the header is a banned one, straight out abort
  1994  		if BadHashes[block.Hash()] {
  1995  			bc.reportBlock(block, nil, ErrBlacklistedHash)
  1996  			return it.index, ErrBlacklistedHash
  1997  		}
  1998  		// If the block is known (in the middle of the chain), it's a special case for
  1999  		// Clique blocks where they can share state among each other, so importing an
  2000  		// older block might complete the state of the subsequent one. In this case,
  2001  		// just skip the block (we already validated it once fully (and crashed), since
  2002  		// its header and body was already in the database).
  2003  		if err == ErrKnownBlock {
  2004  			logger := log.Debug
  2005  			if bc.chainConfig.Clique == nil {
  2006  				logger = log.Warn
  2007  			}
  2008  			logger("Inserted known block", "number", block.Number(), "hash", block.Hash(),
  2009  				"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(),
  2010  				"root", block.Root())
  2011  
  2012  			// Special case. Commit the empty receipt slice if we meet the known
  2013  			// block in the middle. It can only happen in the clique chain. Whenever
  2014  			// we insert blocks via `insertSideChain`, we only commit `td`, `header`
  2015  			// and `body` if it's non-existent. Since we don't have receipts without
  2016  			// reexecution, so nothing to commit. But if the sidechain will be adpoted
  2017  			// as the canonical chain eventually, it needs to be reexecuted for missing
  2018  			// state, but if it's this special case here(skip reexecution) we will lose
  2019  			// the empty receipt entry.
  2020  			if len(block.Transactions()) == 0 {
  2021  				rawdb.WriteReceipts(bc.db, block.Hash(), block.NumberU64(), nil)
  2022  			} else {
  2023  				log.Error("Please file an issue, skip known block execution without receipt",
  2024  					"hash", block.Hash(), "number", block.NumberU64())
  2025  			}
  2026  			if err := bc.writeKnownBlock(block); err != nil {
  2027  				return it.index, err
  2028  			}
  2029  			stats.processed++
  2030  
  2031  			// We can assume that logs are empty here, since the only way for consecutive
  2032  			// Clique blocks to have the same state is if there are no transactions.
  2033  			lastCanon = block
  2034  			continue
  2035  		}
  2036  		// Retrieve the parent block and it's state to execute on top
  2037  		start := time.Now()
  2038  
  2039  		parent := it.previous()
  2040  		if parent == nil {
  2041  			parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
  2042  		}
  2043  		statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
  2044  		if err != nil {
  2045  			return it.index, err
  2046  		}
  2047  		bc.updateHighestVerifiedHeader(block.Header())
  2048  
  2049  		// Enable prefetching to pull in trie node paths while processing transactions
  2050  		statedb.StartPrefetcher("chain")
  2051  
  2052  		//Process block using the parent state as reference point
  2053  		substart := time.Now()
  2054  		statedb, receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig)
  2055  		activeState = statedb
  2056  		if err != nil {
  2057  			bc.reportBlock(block, receipts, err)
  2058  			return it.index, err
  2059  		}
  2060  		// Update the metrics touched during block processing
  2061  		accountReadTimer.Update(statedb.AccountReads)                 // Account reads are complete, we can mark them
  2062  		storageReadTimer.Update(statedb.StorageReads)                 // Storage reads are complete, we can mark them
  2063  		accountUpdateTimer.Update(statedb.AccountUpdates)             // Account updates are complete, we can mark them
  2064  		storageUpdateTimer.Update(statedb.StorageUpdates)             // Storage updates are complete, we can mark them
  2065  		snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete, we can mark them
  2066  		snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete, we can mark them
  2067  
  2068  		blockExecutionTimer.Update(time.Since(substart))
  2069  
  2070  		// Validate the state using the default validator
  2071  		substart = time.Now()
  2072  		if !statedb.IsLightProcessed() {
  2073  			if err := bc.validator.ValidateState(block, statedb, receipts, usedGas); err != nil {
  2074  				log.Error("validate state failed", "error", err)
  2075  				bc.reportBlock(block, receipts, err)
  2076  				return it.index, err
  2077  			}
  2078  		}
  2079  		bc.cacheReceipts(block.Hash(), receipts)
  2080  		bc.cacheBlock(block.Hash(), block)
  2081  		proctime := time.Since(start)
  2082  
  2083  		// Update the metrics touched during block validation
  2084  		accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete, we can mark them
  2085  		storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete, we can mark them
  2086  
  2087  		blockValidationTimer.Update(time.Since(substart))
  2088  
  2089  		// Write the block to the chain and get the status.
  2090  		substart = time.Now()
  2091  		status, err := bc.writeBlockWithState(block, receipts, logs, statedb, false)
  2092  		if err != nil {
  2093  			return it.index, err
  2094  		}
  2095  		// Update the metrics touched during block commit
  2096  		accountCommitTimer.Update(statedb.AccountCommits)   // Account commits are complete, we can mark them
  2097  		storageCommitTimer.Update(statedb.StorageCommits)   // Storage commits are complete, we can mark them
  2098  		snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them
  2099  
  2100  		blockWriteTimer.Update(time.Since(substart))
  2101  		blockInsertTimer.UpdateSince(start)
  2102  
  2103  		switch status {
  2104  		case CanonStatTy:
  2105  			log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(),
  2106  				"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(),
  2107  				"elapsed", common.PrettyDuration(time.Since(start)),
  2108  				"root", block.Root())
  2109  
  2110  			lastCanon = block
  2111  
  2112  			// Only count canonical blocks for GC processing time
  2113  			bc.gcproc += proctime
  2114  
  2115  		case SideStatTy:
  2116  			log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(),
  2117  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  2118  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  2119  				"root", block.Root())
  2120  
  2121  		default:
  2122  			// This in theory is impossible, but lets be nice to our future selves and leave
  2123  			// a log, instead of trying to track down blocks imports that don't emit logs.
  2124  			log.Warn("Inserted block with unknown status", "number", block.Number(), "hash", block.Hash(),
  2125  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  2126  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  2127  				"root", block.Root())
  2128  		}
  2129  		stats.processed++
  2130  		stats.usedGas += usedGas
  2131  
  2132  		dirty, _ := bc.stateCache.TrieDB().Size()
  2133  		stats.report(chain, it.index, dirty)
  2134  	}
  2135  	// Any blocks remaining here? The only ones we care about are the future ones
  2136  	if block != nil && errors.Is(err, consensus.ErrFutureBlock) {
  2137  		if err := bc.addFutureBlock(block); err != nil {
  2138  			return it.index, err
  2139  		}
  2140  		block, err = it.next()
  2141  
  2142  		for ; block != nil && errors.Is(err, consensus.ErrUnknownAncestor); block, err = it.next() {
  2143  			if err := bc.addFutureBlock(block); err != nil {
  2144  				return it.index, err
  2145  			}
  2146  			stats.queued++
  2147  		}
  2148  	}
  2149  	stats.ignored += it.remaining()
  2150  
  2151  	return it.index, err
  2152  }
  2153  
  2154  func (bc *BlockChain) updateHighestVerifiedHeader(header *types.Header) {
  2155  	if header == nil || header.Number == nil {
  2156  		return
  2157  	}
  2158  	currentHeader := bc.highestVerifiedHeader.Load().(*types.Header)
  2159  	if currentHeader == nil {
  2160  		bc.highestVerifiedHeader.Store(types.CopyHeader(header))
  2161  		return
  2162  	}
  2163  
  2164  	newParentTD := bc.GetTdByHash(header.ParentHash)
  2165  	if newParentTD == nil {
  2166  		newParentTD = big.NewInt(0)
  2167  	}
  2168  	oldParentTD := bc.GetTdByHash(currentHeader.ParentHash)
  2169  	if oldParentTD == nil {
  2170  		oldParentTD = big.NewInt(0)
  2171  	}
  2172  	newTD := big.NewInt(0).Add(newParentTD, header.Difficulty)
  2173  	oldTD := big.NewInt(0).Add(oldParentTD, currentHeader.Difficulty)
  2174  
  2175  	if newTD.Cmp(oldTD) > 0 {
  2176  		bc.highestVerifiedHeader.Store(types.CopyHeader(header))
  2177  		return
  2178  	}
  2179  }
  2180  
  2181  func (bc *BlockChain) GetHighestVerifiedHeader() *types.Header {
  2182  	return bc.highestVerifiedHeader.Load().(*types.Header)
  2183  }
  2184  
  2185  // insertSideChain is called when an import batch hits upon a pruned ancestor
  2186  // error, which happens when a sidechain with a sufficiently old fork-block is
  2187  // found.
  2188  //
  2189  // The method writes all (header-and-body-valid) blocks to disk, then tries to
  2190  // switch over to the new chain if the TD exceeded the current chain.
  2191  func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (int, error) {
  2192  	var (
  2193  		externTd *big.Int
  2194  		current  = bc.CurrentBlock()
  2195  	)
  2196  	// The first sidechain block error is already verified to be ErrPrunedAncestor.
  2197  	// Since we don't import them here, we expect ErrUnknownAncestor for the remaining
  2198  	// ones. Any other errors means that the block is invalid, and should not be written
  2199  	// to disk.
  2200  	err := consensus.ErrPrunedAncestor
  2201  	for ; block != nil && errors.Is(err, consensus.ErrPrunedAncestor); block, err = it.next() {
  2202  		// Check the canonical state root for that number
  2203  		if number := block.NumberU64(); current.NumberU64() >= number {
  2204  			canonical := bc.GetBlockByNumber(number)
  2205  			if canonical != nil && canonical.Hash() == block.Hash() {
  2206  				// Not a sidechain block, this is a re-import of a canon block which has it's state pruned
  2207  
  2208  				// Collect the TD of the block. Since we know it's a canon one,
  2209  				// we can get it directly, and not (like further below) use
  2210  				// the parent and then add the block on top
  2211  				externTd = bc.GetTd(block.Hash(), block.NumberU64())
  2212  				continue
  2213  			}
  2214  			if canonical != nil && canonical.Root() == block.Root() {
  2215  				// This is most likely a shadow-state attack. When a fork is imported into the
  2216  				// database, and it eventually reaches a block height which is not pruned, we
  2217  				// just found that the state already exist! This means that the sidechain block
  2218  				// refers to a state which already exists in our canon chain.
  2219  				//
  2220  				// If left unchecked, we would now proceed importing the blocks, without actually
  2221  				// having verified the state of the previous blocks.
  2222  				log.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root())
  2223  
  2224  				// If someone legitimately side-mines blocks, they would still be imported as usual. However,
  2225  				// we cannot risk writing unverified blocks to disk when they obviously target the pruning
  2226  				// mechanism.
  2227  				return it.index, errors.New("sidechain ghost-state attack")
  2228  			}
  2229  		}
  2230  		if externTd == nil {
  2231  			externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1)
  2232  		}
  2233  		externTd = new(big.Int).Add(externTd, block.Difficulty())
  2234  
  2235  		if !bc.HasBlock(block.Hash(), block.NumberU64()) {
  2236  			start := time.Now()
  2237  			if err := bc.writeBlockWithoutState(block, externTd); err != nil {
  2238  				return it.index, err
  2239  			}
  2240  			log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(),
  2241  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  2242  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  2243  				"root", block.Root())
  2244  		}
  2245  	}
  2246  	// At this point, we've written all sidechain blocks to database. Loop ended
  2247  	// either on some other error or all were processed. If there was some other
  2248  	// error, we can ignore the rest of those blocks.
  2249  	//
  2250  	// If the externTd was larger than our local TD, we now need to reimport the previous
  2251  	// blocks to regenerate the required state
  2252  	localTd := bc.GetTd(current.Hash(), current.NumberU64())
  2253  	if localTd.Cmp(externTd) > 0 {
  2254  		log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd)
  2255  		return it.index, err
  2256  	}
  2257  	// Gather all the sidechain hashes (full blocks may be memory heavy)
  2258  	var (
  2259  		hashes  []common.Hash
  2260  		numbers []uint64
  2261  	)
  2262  	parent := it.previous()
  2263  	for parent != nil && !bc.HasState(parent.Root) {
  2264  		hashes = append(hashes, parent.Hash())
  2265  		numbers = append(numbers, parent.Number.Uint64())
  2266  
  2267  		parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1)
  2268  	}
  2269  	if parent == nil {
  2270  		return it.index, errors.New("missing parent")
  2271  	}
  2272  	// Import all the pruned blocks to make the state available
  2273  	var (
  2274  		blocks []*types.Block
  2275  		memory common.StorageSize
  2276  	)
  2277  	for i := len(hashes) - 1; i >= 0; i-- {
  2278  		// Append the next block to our batch
  2279  		block := bc.GetBlock(hashes[i], numbers[i])
  2280  
  2281  		blocks = append(blocks, block)
  2282  		memory += block.Size()
  2283  
  2284  		// If memory use grew too large, import and continue. Sadly we need to discard
  2285  		// all raised events and logs from notifications since we're too heavy on the
  2286  		// memory here.
  2287  		if len(blocks) >= 2048 || memory > 64*1024*1024 {
  2288  			log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64())
  2289  			if _, err := bc.insertChain(blocks, false); err != nil {
  2290  				return 0, err
  2291  			}
  2292  			blocks, memory = blocks[:0], 0
  2293  
  2294  			// If the chain is terminating, stop processing blocks
  2295  			if bc.insertStopped() {
  2296  				log.Debug("Abort during blocks processing")
  2297  				return 0, nil
  2298  			}
  2299  		}
  2300  	}
  2301  	if len(blocks) > 0 {
  2302  		log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64())
  2303  		return bc.insertChain(blocks, false)
  2304  	}
  2305  	return 0, nil
  2306  }
  2307  
  2308  // reorg takes two blocks, an old chain and a new chain and will reconstruct the
  2309  // blocks and inserts them to be part of the new canonical chain and accumulates
  2310  // potential missing transactions and post an event about them.
  2311  func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
  2312  	var (
  2313  		newChain    types.Blocks
  2314  		oldChain    types.Blocks
  2315  		commonBlock *types.Block
  2316  
  2317  		deletedTxs types.Transactions
  2318  		addedTxs   types.Transactions
  2319  
  2320  		deletedLogs [][]*types.Log
  2321  		rebirthLogs [][]*types.Log
  2322  
  2323  		// collectLogs collects the logs that were generated or removed during
  2324  		// the processing of the block that corresponds with the given hash.
  2325  		// These logs are later announced as deleted or reborn
  2326  		collectLogs = func(hash common.Hash, removed bool) {
  2327  			number := bc.hc.GetBlockNumber(hash)
  2328  			if number == nil {
  2329  				return
  2330  			}
  2331  			receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig)
  2332  
  2333  			var logs []*types.Log
  2334  			for _, receipt := range receipts {
  2335  				for _, log := range receipt.Logs {
  2336  					l := *log
  2337  					if removed {
  2338  						l.Removed = true
  2339  					}
  2340  					logs = append(logs, &l)
  2341  				}
  2342  			}
  2343  			if len(logs) > 0 {
  2344  				if removed {
  2345  					deletedLogs = append(deletedLogs, logs)
  2346  				} else {
  2347  					rebirthLogs = append(rebirthLogs, logs)
  2348  				}
  2349  			}
  2350  		}
  2351  		// mergeLogs returns a merged log slice with specified sort order.
  2352  		mergeLogs = func(logs [][]*types.Log, reverse bool) []*types.Log {
  2353  			var ret []*types.Log
  2354  			if reverse {
  2355  				for i := len(logs) - 1; i >= 0; i-- {
  2356  					ret = append(ret, logs[i]...)
  2357  				}
  2358  			} else {
  2359  				for i := 0; i < len(logs); i++ {
  2360  					ret = append(ret, logs[i]...)
  2361  				}
  2362  			}
  2363  			return ret
  2364  		}
  2365  	)
  2366  	// Reduce the longer chain to the same number as the shorter one
  2367  	if oldBlock.NumberU64() > newBlock.NumberU64() {
  2368  		// Old chain is longer, gather all transactions and logs as deleted ones
  2369  		for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
  2370  			oldChain = append(oldChain, oldBlock)
  2371  			deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
  2372  			collectLogs(oldBlock.Hash(), true)
  2373  		}
  2374  	} else {
  2375  		// New chain is longer, stash all blocks away for subsequent insertion
  2376  		for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) {
  2377  			newChain = append(newChain, newBlock)
  2378  		}
  2379  	}
  2380  	if oldBlock == nil {
  2381  		return fmt.Errorf("invalid old chain")
  2382  	}
  2383  	if newBlock == nil {
  2384  		return fmt.Errorf("invalid new chain")
  2385  	}
  2386  	// Both sides of the reorg are at the same number, reduce both until the common
  2387  	// ancestor is found
  2388  	for {
  2389  		// If the common ancestor was found, bail out
  2390  		if oldBlock.Hash() == newBlock.Hash() {
  2391  			commonBlock = oldBlock
  2392  			break
  2393  		}
  2394  		// Remove an old block as well as stash away a new block
  2395  		oldChain = append(oldChain, oldBlock)
  2396  		deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
  2397  		collectLogs(oldBlock.Hash(), true)
  2398  
  2399  		newChain = append(newChain, newBlock)
  2400  
  2401  		// Step back with both chains
  2402  		oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1)
  2403  		if oldBlock == nil {
  2404  			return fmt.Errorf("invalid old chain")
  2405  		}
  2406  		newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
  2407  		if newBlock == nil {
  2408  			return fmt.Errorf("invalid new chain")
  2409  		}
  2410  	}
  2411  	// Ensure the user sees large reorgs
  2412  	if len(oldChain) > 0 && len(newChain) > 0 {
  2413  		logFn := log.Info
  2414  		msg := "Chain reorg detected"
  2415  		if len(oldChain) > 63 {
  2416  			msg = "Large chain reorg detected"
  2417  			logFn = log.Warn
  2418  		}
  2419  		logFn(msg, "number", commonBlock.Number(), "hash", commonBlock.Hash(),
  2420  			"drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash())
  2421  		blockReorgAddMeter.Mark(int64(len(newChain)))
  2422  		blockReorgDropMeter.Mark(int64(len(oldChain)))
  2423  		blockReorgMeter.Mark(1)
  2424  	} else {
  2425  		log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash())
  2426  	}
  2427  	// Insert the new chain(except the head block(reverse order)),
  2428  	// taking care of the proper incremental order.
  2429  	for i := len(newChain) - 1; i >= 1; i-- {
  2430  		// Insert the block in the canonical way, re-writing history
  2431  		bc.writeHeadBlock(newChain[i])
  2432  
  2433  		// Collect reborn logs due to chain reorg
  2434  		collectLogs(newChain[i].Hash(), false)
  2435  
  2436  		// Collect the new added transactions.
  2437  		addedTxs = append(addedTxs, newChain[i].Transactions()...)
  2438  	}
  2439  	// Delete useless indexes right now which includes the non-canonical
  2440  	// transaction indexes, canonical chain indexes which above the head.
  2441  	indexesBatch := bc.db.NewBatch()
  2442  	for _, tx := range types.TxDifference(deletedTxs, addedTxs) {
  2443  		rawdb.DeleteTxLookupEntry(indexesBatch, tx.Hash())
  2444  	}
  2445  	// Delete any canonical number assignments above the new head
  2446  	number := bc.CurrentBlock().NumberU64()
  2447  	for i := number + 1; ; i++ {
  2448  		hash := rawdb.ReadCanonicalHash(bc.db, i)
  2449  		if hash == (common.Hash{}) {
  2450  			break
  2451  		}
  2452  		rawdb.DeleteCanonicalHash(indexesBatch, i)
  2453  	}
  2454  	if err := indexesBatch.Write(); err != nil {
  2455  		log.Crit("Failed to delete useless indexes", "err", err)
  2456  	}
  2457  	// If any logs need to be fired, do it now. In theory we could avoid creating
  2458  	// this goroutine if there are no events to fire, but realistcally that only
  2459  	// ever happens if we're reorging empty blocks, which will only happen on idle
  2460  	// networks where performance is not an issue either way.
  2461  	if len(deletedLogs) > 0 {
  2462  		bc.rmLogsFeed.Send(RemovedLogsEvent{mergeLogs(deletedLogs, true)})
  2463  	}
  2464  	if len(rebirthLogs) > 0 {
  2465  		bc.logsFeed.Send(mergeLogs(rebirthLogs, false))
  2466  	}
  2467  	if len(oldChain) > 0 {
  2468  		for i := len(oldChain) - 1; i >= 0; i-- {
  2469  			bc.chainSideFeed.Send(ChainSideEvent{Block: oldChain[i]})
  2470  		}
  2471  	}
  2472  	return nil
  2473  }
  2474  
  2475  func (bc *BlockChain) update() {
  2476  	futureTimer := time.NewTicker(5 * time.Second)
  2477  	defer futureTimer.Stop()
  2478  	for {
  2479  		select {
  2480  		case <-futureTimer.C:
  2481  			bc.procFutureBlocks()
  2482  		case <-bc.quit:
  2483  			return
  2484  		}
  2485  	}
  2486  }
  2487  
  2488  func (bc *BlockChain) trustedDiffLayerLoop() {
  2489  	recheck := time.Tick(diffLayerFreezerRecheckInterval)
  2490  	bc.wg.Add(1)
  2491  	defer bc.wg.Done()
  2492  	for {
  2493  		select {
  2494  		case diff := <-bc.diffQueueBuffer:
  2495  			bc.diffQueue.Push(diff, -(int64(diff.Number)))
  2496  		case <-bc.quit:
  2497  			// Persist all diffLayers when shutdown, it will introduce redundant storage, but it is acceptable.
  2498  			// If the client been ungracefully shutdown, it will missing all cached diff layers, it is acceptable as well.
  2499  			var batch ethdb.Batch
  2500  			for !bc.diffQueue.Empty() {
  2501  				diff, _ := bc.diffQueue.Pop()
  2502  				diffLayer := diff.(*types.DiffLayer)
  2503  				if batch == nil {
  2504  					batch = bc.db.DiffStore().NewBatch()
  2505  				}
  2506  				rawdb.WriteDiffLayer(batch, diffLayer.BlockHash, diffLayer)
  2507  				if batch.ValueSize() > ethdb.IdealBatchSize {
  2508  					if err := batch.Write(); err != nil {
  2509  						log.Error("Failed to write diff layer", "err", err)
  2510  						return
  2511  					}
  2512  					batch.Reset()
  2513  				}
  2514  			}
  2515  			if batch != nil {
  2516  				// flush data
  2517  				if err := batch.Write(); err != nil {
  2518  					log.Error("Failed to write diff layer", "err", err)
  2519  					return
  2520  				}
  2521  				batch.Reset()
  2522  			}
  2523  			return
  2524  		case <-recheck:
  2525  			currentHeight := bc.CurrentBlock().NumberU64()
  2526  			var batch ethdb.Batch
  2527  			for !bc.diffQueue.Empty() {
  2528  				diff, prio := bc.diffQueue.Pop()
  2529  				diffLayer := diff.(*types.DiffLayer)
  2530  
  2531  				// if the block old enough
  2532  				if int64(currentHeight)+prio >= int64(bc.triesInMemory) {
  2533  					canonicalHash := bc.GetCanonicalHash(uint64(-prio))
  2534  					// on the canonical chain
  2535  					if canonicalHash == diffLayer.BlockHash {
  2536  						if batch == nil {
  2537  							batch = bc.db.DiffStore().NewBatch()
  2538  						}
  2539  						rawdb.WriteDiffLayer(batch, diffLayer.BlockHash, diffLayer)
  2540  						staleHash := bc.GetCanonicalHash(uint64(-prio) - bc.diffLayerFreezerBlockLimit)
  2541  						rawdb.DeleteDiffLayer(batch, staleHash)
  2542  					}
  2543  				} else {
  2544  					bc.diffQueue.Push(diffLayer, prio)
  2545  					break
  2546  				}
  2547  				if batch != nil && batch.ValueSize() > ethdb.IdealBatchSize {
  2548  					if err := batch.Write(); err != nil {
  2549  						panic(fmt.Sprintf("Failed to write diff layer, error %v", err))
  2550  					}
  2551  					batch.Reset()
  2552  				}
  2553  			}
  2554  			if batch != nil {
  2555  				if err := batch.Write(); err != nil {
  2556  					panic(fmt.Sprintf("Failed to write diff layer, error %v", err))
  2557  				}
  2558  				batch.Reset()
  2559  			}
  2560  		}
  2561  	}
  2562  }
  2563  
  2564  func (bc *BlockChain) GetUnTrustedDiffLayer(blockHash common.Hash, pid string) *types.DiffLayer {
  2565  	bc.diffMux.RLock()
  2566  	defer bc.diffMux.RUnlock()
  2567  	if diffs, exist := bc.blockHashToDiffLayers[blockHash]; exist && len(diffs) != 0 {
  2568  		if len(diffs) == 1 {
  2569  			// return the only one diff layer
  2570  			for _, diff := range diffs {
  2571  				return diff
  2572  			}
  2573  		}
  2574  		// pick the one from exact same peer if we know where the block comes from
  2575  		if pid != "" {
  2576  			if diffHashes, exist := bc.diffPeersToDiffHashes[pid]; exist {
  2577  				for diff := range diffs {
  2578  					if _, overlap := diffHashes[diff]; overlap {
  2579  						return bc.blockHashToDiffLayers[blockHash][diff]
  2580  					}
  2581  				}
  2582  			}
  2583  		}
  2584  		// Do not find overlap, do random pick
  2585  		for _, diff := range diffs {
  2586  			return diff
  2587  		}
  2588  	}
  2589  	return nil
  2590  }
  2591  
  2592  func (bc *BlockChain) removeDiffLayers(diffHash common.Hash) {
  2593  	bc.diffMux.Lock()
  2594  	defer bc.diffMux.Unlock()
  2595  
  2596  	// Untrusted peers
  2597  	pids := bc.diffHashToPeers[diffHash]
  2598  	invalidDiffHashes := make(map[common.Hash]struct{})
  2599  	for pid := range pids {
  2600  		invaliDiffHashesPeer := bc.diffPeersToDiffHashes[pid]
  2601  		for invaliDiffHash := range invaliDiffHashesPeer {
  2602  			invalidDiffHashes[invaliDiffHash] = struct{}{}
  2603  		}
  2604  		delete(bc.diffPeersToDiffHashes, pid)
  2605  	}
  2606  	for invalidDiffHash := range invalidDiffHashes {
  2607  		delete(bc.diffHashToPeers, invalidDiffHash)
  2608  		affectedBlockHash := bc.diffHashToBlockHash[invalidDiffHash]
  2609  		if diffs, exist := bc.blockHashToDiffLayers[affectedBlockHash]; exist {
  2610  			delete(diffs, invalidDiffHash)
  2611  			if len(diffs) == 0 {
  2612  				delete(bc.blockHashToDiffLayers, affectedBlockHash)
  2613  			}
  2614  		}
  2615  		delete(bc.diffHashToBlockHash, invalidDiffHash)
  2616  	}
  2617  }
  2618  
  2619  func (bc *BlockChain) RemoveDiffPeer(pid string) {
  2620  	bc.diffMux.Lock()
  2621  	defer bc.diffMux.Unlock()
  2622  	if invaliDiffHashes := bc.diffPeersToDiffHashes[pid]; invaliDiffHashes != nil {
  2623  		for invalidDiffHash := range invaliDiffHashes {
  2624  			lastDiffHash := false
  2625  			if peers, ok := bc.diffHashToPeers[invalidDiffHash]; ok {
  2626  				delete(peers, pid)
  2627  				if len(peers) == 0 {
  2628  					lastDiffHash = true
  2629  					delete(bc.diffHashToPeers, invalidDiffHash)
  2630  				}
  2631  			}
  2632  			if lastDiffHash {
  2633  				affectedBlockHash := bc.diffHashToBlockHash[invalidDiffHash]
  2634  				if diffs, exist := bc.blockHashToDiffLayers[affectedBlockHash]; exist {
  2635  					delete(diffs, invalidDiffHash)
  2636  					if len(diffs) == 0 {
  2637  						delete(bc.blockHashToDiffLayers, affectedBlockHash)
  2638  					}
  2639  				}
  2640  				delete(bc.diffHashToBlockHash, invalidDiffHash)
  2641  			}
  2642  		}
  2643  		delete(bc.diffPeersToDiffHashes, pid)
  2644  	}
  2645  }
  2646  
  2647  func (bc *BlockChain) untrustedDiffLayerPruneLoop() {
  2648  	recheck := time.NewTicker(diffLayerPruneRecheckInterval)
  2649  	bc.wg.Add(1)
  2650  	defer func() {
  2651  		bc.wg.Done()
  2652  		recheck.Stop()
  2653  	}()
  2654  	for {
  2655  		select {
  2656  		case <-bc.quit:
  2657  			return
  2658  		case <-recheck.C:
  2659  			bc.pruneDiffLayer()
  2660  		}
  2661  	}
  2662  }
  2663  
  2664  func (bc *BlockChain) pruneDiffLayer() {
  2665  	currentHeight := bc.CurrentBlock().NumberU64()
  2666  	bc.diffMux.Lock()
  2667  	defer bc.diffMux.Unlock()
  2668  	sortNumbers := make([]uint64, 0, len(bc.diffNumToBlockHashes))
  2669  	for number := range bc.diffNumToBlockHashes {
  2670  		sortNumbers = append(sortNumbers, number)
  2671  	}
  2672  	sort.Slice(sortNumbers, func(i, j int) bool {
  2673  		return sortNumbers[i] <= sortNumbers[j]
  2674  	})
  2675  	staleBlockHashes := make(map[common.Hash]struct{})
  2676  	for _, number := range sortNumbers {
  2677  		if number >= currentHeight-maxDiffForkDist {
  2678  			break
  2679  		}
  2680  		affectedHashes := bc.diffNumToBlockHashes[number]
  2681  		if affectedHashes != nil {
  2682  			for affectedHash := range affectedHashes {
  2683  				staleBlockHashes[affectedHash] = struct{}{}
  2684  			}
  2685  			delete(bc.diffNumToBlockHashes, number)
  2686  		}
  2687  	}
  2688  	staleDiffHashes := make(map[common.Hash]struct{})
  2689  	for blockHash := range staleBlockHashes {
  2690  		if diffHashes, exist := bc.blockHashToDiffLayers[blockHash]; exist {
  2691  			for diffHash := range diffHashes {
  2692  				staleDiffHashes[diffHash] = struct{}{}
  2693  				delete(bc.diffHashToBlockHash, diffHash)
  2694  				delete(bc.diffHashToPeers, diffHash)
  2695  			}
  2696  		}
  2697  		delete(bc.blockHashToDiffLayers, blockHash)
  2698  	}
  2699  	for diffHash := range staleDiffHashes {
  2700  		for p, diffHashes := range bc.diffPeersToDiffHashes {
  2701  			delete(diffHashes, diffHash)
  2702  			if len(diffHashes) == 0 {
  2703  				delete(bc.diffPeersToDiffHashes, p)
  2704  			}
  2705  		}
  2706  	}
  2707  }
  2708  
  2709  // Process received diff layers
  2710  func (bc *BlockChain) HandleDiffLayer(diffLayer *types.DiffLayer, pid string, fulfilled bool) error {
  2711  	// Basic check
  2712  	currentHeight := bc.CurrentBlock().NumberU64()
  2713  	if diffLayer.Number > currentHeight && diffLayer.Number-currentHeight > maxDiffQueueDist {
  2714  		log.Error("diff layers too new from current", "pid", pid)
  2715  		return nil
  2716  	}
  2717  	if diffLayer.Number < currentHeight && currentHeight-diffLayer.Number > maxDiffForkDist {
  2718  		log.Error("diff layers too old from current", "pid", pid)
  2719  		return nil
  2720  	}
  2721  
  2722  	bc.diffMux.Lock()
  2723  	defer bc.diffMux.Unlock()
  2724  
  2725  	if !fulfilled && len(bc.diffPeersToDiffHashes[pid]) > maxDiffLimitForBroadcast {
  2726  		log.Error("too many accumulated diffLayers", "pid", pid)
  2727  		return nil
  2728  	}
  2729  
  2730  	if len(bc.diffPeersToDiffHashes[pid]) > maxDiffLimit {
  2731  		log.Error("too many accumulated diffLayers", "pid", pid)
  2732  		return nil
  2733  	}
  2734  	if _, exist := bc.diffPeersToDiffHashes[pid]; exist {
  2735  		if _, alreadyHas := bc.diffPeersToDiffHashes[pid][diffLayer.DiffHash]; alreadyHas {
  2736  			return nil
  2737  		}
  2738  	} else {
  2739  		bc.diffPeersToDiffHashes[pid] = make(map[common.Hash]struct{})
  2740  	}
  2741  	bc.diffPeersToDiffHashes[pid][diffLayer.DiffHash] = struct{}{}
  2742  	if _, exist := bc.diffNumToBlockHashes[diffLayer.Number]; !exist {
  2743  		bc.diffNumToBlockHashes[diffLayer.Number] = make(map[common.Hash]struct{})
  2744  	}
  2745  	bc.diffNumToBlockHashes[diffLayer.Number][diffLayer.BlockHash] = struct{}{}
  2746  
  2747  	if _, exist := bc.diffHashToPeers[diffLayer.DiffHash]; !exist {
  2748  		bc.diffHashToPeers[diffLayer.DiffHash] = make(map[string]struct{})
  2749  	}
  2750  	bc.diffHashToPeers[diffLayer.DiffHash][pid] = struct{}{}
  2751  
  2752  	if _, exist := bc.blockHashToDiffLayers[diffLayer.BlockHash]; !exist {
  2753  		bc.blockHashToDiffLayers[diffLayer.BlockHash] = make(map[common.Hash]*types.DiffLayer)
  2754  	}
  2755  	bc.blockHashToDiffLayers[diffLayer.BlockHash][diffLayer.DiffHash] = diffLayer
  2756  	bc.diffHashToBlockHash[diffLayer.DiffHash] = diffLayer.BlockHash
  2757  
  2758  	return nil
  2759  }
  2760  
  2761  // maintainTxIndex is responsible for the construction and deletion of the
  2762  // transaction index.
  2763  //
  2764  // User can use flag `txlookuplimit` to specify a "recentness" block, below
  2765  // which ancient tx indices get deleted. If `txlookuplimit` is 0, it means
  2766  // all tx indices will be reserved.
  2767  //
  2768  // The user can adjust the txlookuplimit value for each launch after fast
  2769  // sync, Geth will automatically construct the missing indices and delete
  2770  // the extra indices.
  2771  func (bc *BlockChain) maintainTxIndex(ancients uint64) {
  2772  	defer bc.wg.Done()
  2773  
  2774  	// Before starting the actual maintenance, we need to handle a special case,
  2775  	// where user might init Geth with an external ancient database. If so, we
  2776  	// need to reindex all necessary transactions before starting to process any
  2777  	// pruning requests.
  2778  	if ancients > 0 {
  2779  		var from = uint64(0)
  2780  		if bc.txLookupLimit != 0 && ancients > bc.txLookupLimit {
  2781  			from = ancients - bc.txLookupLimit
  2782  		}
  2783  		rawdb.IndexTransactions(bc.db, from, ancients, bc.quit)
  2784  	}
  2785  	// indexBlocks reindexes or unindexes transactions depending on user configuration
  2786  	indexBlocks := func(tail *uint64, head uint64, done chan struct{}) {
  2787  		defer func() { done <- struct{}{} }()
  2788  
  2789  		// If the user just upgraded Geth to a new version which supports transaction
  2790  		// index pruning, write the new tail and remove anything older.
  2791  		if tail == nil {
  2792  			if bc.txLookupLimit == 0 || head < bc.txLookupLimit {
  2793  				// Nothing to delete, write the tail and return
  2794  				rawdb.WriteTxIndexTail(bc.db, 0)
  2795  			} else {
  2796  				// Prune all stale tx indices and record the tx index tail
  2797  				rawdb.UnindexTransactions(bc.db, 0, head-bc.txLookupLimit+1, bc.quit)
  2798  			}
  2799  			return
  2800  		}
  2801  		// If a previous indexing existed, make sure that we fill in any missing entries
  2802  		if bc.txLookupLimit == 0 || head < bc.txLookupLimit {
  2803  			if *tail > 0 {
  2804  				rawdb.IndexTransactions(bc.db, 0, *tail, bc.quit)
  2805  			}
  2806  			return
  2807  		}
  2808  		// Update the transaction index to the new chain state
  2809  		if head-bc.txLookupLimit+1 < *tail {
  2810  			// Reindex a part of missing indices and rewind index tail to HEAD-limit
  2811  			rawdb.IndexTransactions(bc.db, head-bc.txLookupLimit+1, *tail, bc.quit)
  2812  		} else {
  2813  			// Unindex a part of stale indices and forward index tail to HEAD-limit
  2814  			rawdb.UnindexTransactions(bc.db, *tail, head-bc.txLookupLimit+1, bc.quit)
  2815  		}
  2816  	}
  2817  	// Any reindexing done, start listening to chain events and moving the index window
  2818  	var (
  2819  		done   chan struct{}                  // Non-nil if background unindexing or reindexing routine is active.
  2820  		headCh = make(chan ChainHeadEvent, 1) // Buffered to avoid locking up the event feed
  2821  	)
  2822  	sub := bc.SubscribeChainHeadEvent(headCh)
  2823  	if sub == nil {
  2824  		return
  2825  	}
  2826  	defer sub.Unsubscribe()
  2827  
  2828  	for {
  2829  		select {
  2830  		case head := <-headCh:
  2831  			if done == nil {
  2832  				done = make(chan struct{})
  2833  				go indexBlocks(rawdb.ReadTxIndexTail(bc.db), head.Block.NumberU64(), done)
  2834  			}
  2835  		case <-done:
  2836  			done = nil
  2837  		case <-bc.quit:
  2838  			if done != nil {
  2839  				log.Info("Waiting background transaction indexer to exit")
  2840  				<-done
  2841  			}
  2842  			return
  2843  		}
  2844  	}
  2845  }
  2846  
  2847  // reportBlock logs a bad block error.
  2848  func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) {
  2849  	rawdb.WriteBadBlock(bc.db, block)
  2850  
  2851  	var receiptString string
  2852  	for i, receipt := range receipts {
  2853  		receiptString += fmt.Sprintf("\t %d: cumulative: %v gas: %v contract: %v status: %v tx: %v logs: %v bloom: %x state: %x\n",
  2854  			i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(),
  2855  			receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState)
  2856  	}
  2857  	log.Error(fmt.Sprintf(`
  2858  ########## BAD BLOCK #########
  2859  Chain config: %v
  2860  
  2861  Number: %v
  2862  Hash: 0x%x
  2863  %v
  2864  
  2865  Error: %v
  2866  ##############################
  2867  `, bc.chainConfig, block.Number(), block.Hash(), receiptString, err))
  2868  }
  2869  
  2870  // InsertHeaderChain attempts to insert the given header chain in to the local
  2871  // chain, possibly creating a reorg. If an error is returned, it will return the
  2872  // index number of the failing header as well an error describing what went wrong.
  2873  //
  2874  // The verify parameter can be used to fine tune whether nonce verification
  2875  // should be done or not. The reason behind the optional check is because some
  2876  // of the header retrieval mechanisms already need to verify nonces, as well as
  2877  // because nonces can be verified sparsely, not needing to check each.
  2878  func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
  2879  	start := time.Now()
  2880  	if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil {
  2881  		return i, err
  2882  	}
  2883  
  2884  	// Make sure only one thread manipulates the chain at once
  2885  	bc.chainmu.Lock()
  2886  	defer bc.chainmu.Unlock()
  2887  
  2888  	bc.wg.Add(1)
  2889  	defer bc.wg.Done()
  2890  	_, err := bc.hc.InsertHeaderChain(chain, start)
  2891  	return 0, err
  2892  }
  2893  
  2894  // CurrentHeader retrieves the current head header of the canonical chain. The
  2895  // header is retrieved from the HeaderChain's internal cache.
  2896  func (bc *BlockChain) CurrentHeader() *types.Header {
  2897  	return bc.hc.CurrentHeader()
  2898  }
  2899  
  2900  // GetTd retrieves a block's total difficulty in the canonical chain from the
  2901  // database by hash and number, caching it if found.
  2902  func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
  2903  	return bc.hc.GetTd(hash, number)
  2904  }
  2905  
  2906  // GetTdByHash retrieves a block's total difficulty in the canonical chain from the
  2907  // database by hash, caching it if found.
  2908  func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int {
  2909  	return bc.hc.GetTdByHash(hash)
  2910  }
  2911  
  2912  // GetHeader retrieves a block header from the database by hash and number,
  2913  // caching it if found.
  2914  func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
  2915  	return bc.hc.GetHeader(hash, number)
  2916  }
  2917  
  2918  // GetHeaderByHash retrieves a block header from the database by hash, caching it if
  2919  // found.
  2920  func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
  2921  	return bc.hc.GetHeaderByHash(hash)
  2922  }
  2923  
  2924  // HasHeader checks if a block header is present in the database or not, caching
  2925  // it if present.
  2926  func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool {
  2927  	return bc.hc.HasHeader(hash, number)
  2928  }
  2929  
  2930  // GetCanonicalHash returns the canonical hash for a given block number
  2931  func (bc *BlockChain) GetCanonicalHash(number uint64) common.Hash {
  2932  	return bc.hc.GetCanonicalHash(number)
  2933  }
  2934  
  2935  // GetBlockHashesFromHash retrieves a number of block hashes starting at a given
  2936  // hash, fetching towards the genesis block.
  2937  func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash {
  2938  	return bc.hc.GetBlockHashesFromHash(hash, max)
  2939  }
  2940  
  2941  // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or
  2942  // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the
  2943  // number of blocks to be individually checked before we reach the canonical chain.
  2944  //
  2945  // Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
  2946  func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
  2947  	return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
  2948  }
  2949  
  2950  // GetHeaderByNumber retrieves a block header from the database by number,
  2951  // caching it (associated with its hash) if found.
  2952  func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
  2953  	return bc.hc.GetHeaderByNumber(number)
  2954  }
  2955  
  2956  // GetTransactionLookup retrieves the lookup associate with the given transaction
  2957  // hash from the cache or database.
  2958  func (bc *BlockChain) GetTransactionLookup(hash common.Hash) *rawdb.LegacyTxLookupEntry {
  2959  	// Short circuit if the txlookup already in the cache, retrieve otherwise
  2960  	if lookup, exist := bc.txLookupCache.Get(hash); exist {
  2961  		return lookup.(*rawdb.LegacyTxLookupEntry)
  2962  	}
  2963  	tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash)
  2964  	if tx == nil {
  2965  		return nil
  2966  	}
  2967  	lookup := &rawdb.LegacyTxLookupEntry{BlockHash: blockHash, BlockIndex: blockNumber, Index: txIndex}
  2968  	bc.txLookupCache.Add(hash, lookup)
  2969  	return lookup
  2970  }
  2971  
  2972  func (bc *BlockChain) TriesInMemory() uint64 { return bc.triesInMemory }
  2973  
  2974  // Config retrieves the chain's fork configuration.
  2975  func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
  2976  
  2977  // Engine retrieves the blockchain's consensus engine.
  2978  func (bc *BlockChain) Engine() consensus.Engine { return bc.engine }
  2979  
  2980  // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
  2981  func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
  2982  	return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))
  2983  }
  2984  
  2985  // SubscribeChainEvent registers a subscription of ChainEvent.
  2986  func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription {
  2987  	return bc.scope.Track(bc.chainFeed.Subscribe(ch))
  2988  }
  2989  
  2990  // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
  2991  func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
  2992  	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
  2993  }
  2994  
  2995  // SubscribeChainSideEvent registers a subscription of ChainSideEvent.
  2996  func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
  2997  	return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
  2998  }
  2999  
  3000  // SubscribeLogsEvent registers a subscription of []*types.Log.
  3001  func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
  3002  	return bc.scope.Track(bc.logsFeed.Subscribe(ch))
  3003  }
  3004  
  3005  // SubscribeBlockProcessingEvent registers a subscription of bool where true means
  3006  // block processing has started while false means it has stopped.
  3007  func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription {
  3008  	return bc.scope.Track(bc.blockProcFeed.Subscribe(ch))
  3009  }
  3010  
  3011  // Options
  3012  func EnableLightProcessor(bc *BlockChain) *BlockChain {
  3013  	bc.processor = NewLightStateProcessor(bc.Config(), bc, bc.engine)
  3014  	return bc
  3015  }
  3016  
  3017  func EnablePersistDiff(limit uint64) BlockChainOption {
  3018  	return func(chain *BlockChain) *BlockChain {
  3019  		chain.diffLayerFreezerBlockLimit = limit
  3020  		return chain
  3021  	}
  3022  }