github.com/klaytn/klaytn@v1.10.2/blockchain/blockchain.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2015 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from core/blockchain.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package blockchain
    22  
    23  import (
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  	"math/big"
    28  	mrand "math/rand"
    29  	"reflect"
    30  	"runtime"
    31  	"strconv"
    32  	"sync"
    33  	"sync/atomic"
    34  	"time"
    35  
    36  	"github.com/klaytn/klaytn/snapshot"
    37  
    38  	"github.com/go-redis/redis/v7"
    39  	lru "github.com/hashicorp/golang-lru"
    40  	"github.com/klaytn/klaytn/blockchain/state"
    41  	"github.com/klaytn/klaytn/blockchain/types"
    42  	"github.com/klaytn/klaytn/blockchain/vm"
    43  	"github.com/klaytn/klaytn/common"
    44  	"github.com/klaytn/klaytn/common/hexutil"
    45  	"github.com/klaytn/klaytn/common/mclock"
    46  	"github.com/klaytn/klaytn/common/prque"
    47  	"github.com/klaytn/klaytn/consensus"
    48  	"github.com/klaytn/klaytn/crypto"
    49  	"github.com/klaytn/klaytn/event"
    50  	"github.com/klaytn/klaytn/fork"
    51  	"github.com/klaytn/klaytn/log"
    52  	klaytnmetrics "github.com/klaytn/klaytn/metrics"
    53  	"github.com/klaytn/klaytn/params"
    54  	"github.com/klaytn/klaytn/rlp"
    55  	"github.com/klaytn/klaytn/storage/database"
    56  	"github.com/klaytn/klaytn/storage/statedb"
    57  	"github.com/rcrowley/go-metrics"
    58  )
    59  
    60  // If total insertion time of a block exceeds insertTimeLimit,
    61  // that time will be logged by blockLongInsertTimeGauge.
    62  const insertTimeLimit = common.PrettyDuration(time.Second)
    63  
    64  var (
    65  	accountReadTimer   = klaytnmetrics.NewRegisteredHybridTimer("state/account/reads", nil)
    66  	accountHashTimer   = klaytnmetrics.NewRegisteredHybridTimer("state/account/hashes", nil)
    67  	accountUpdateTimer = klaytnmetrics.NewRegisteredHybridTimer("state/account/updates", nil)
    68  	accountCommitTimer = klaytnmetrics.NewRegisteredHybridTimer("state/account/commits", nil)
    69  
    70  	storageReadTimer   = klaytnmetrics.NewRegisteredHybridTimer("state/storage/reads", nil)
    71  	storageHashTimer   = klaytnmetrics.NewRegisteredHybridTimer("state/storage/hashes", nil)
    72  	storageUpdateTimer = klaytnmetrics.NewRegisteredHybridTimer("state/storage/updates", nil)
    73  	storageCommitTimer = klaytnmetrics.NewRegisteredHybridTimer("state/storage/commits", nil)
    74  
    75  	snapshotAccountReadTimer = metrics.NewRegisteredTimer("state/snapshot/account/reads", nil)
    76  	snapshotStorageReadTimer = metrics.NewRegisteredTimer("state/snapshot/storage/reads", nil)
    77  	snapshotCommitTimer      = metrics.NewRegisteredTimer("state/snapshot/commits", nil)
    78  
    79  	blockBaseFee        = metrics.NewRegisteredGauge("chain/basefee", nil)
    80  	blockInsertTimer    = klaytnmetrics.NewRegisteredHybridTimer("chain/inserts", nil)
    81  	blockProcessTimer   = klaytnmetrics.NewRegisteredHybridTimer("chain/process", nil)
    82  	blockExecutionTimer = klaytnmetrics.NewRegisteredHybridTimer("chain/execution", nil)
    83  	blockFinalizeTimer  = klaytnmetrics.NewRegisteredHybridTimer("chain/finalize", nil)
    84  	blockValidateTimer  = klaytnmetrics.NewRegisteredHybridTimer("chain/validate", nil)
    85  	blockAgeTimer       = klaytnmetrics.NewRegisteredHybridTimer("chain/age", nil)
    86  
    87  	blockPrefetchExecuteTimer   = klaytnmetrics.NewRegisteredHybridTimer("chain/prefetch/executes", nil)
    88  	blockPrefetchInterruptMeter = metrics.NewRegisteredMeter("chain/prefetch/interrupts", nil)
    89  
    90  	ErrNoGenesis            = errors.New("genesis not found in chain")
    91  	ErrNotExistNode         = errors.New("the node does not exist in cached node")
    92  	ErrQuitBySignal         = errors.New("quit by signal")
    93  	ErrNotInWarmUp          = errors.New("not in warm up")
    94  	logger                  = log.NewModuleLogger(log.Blockchain)
    95  	kesCachePrefixBlockLogs = []byte("blockLogs")
    96  )
    97  
    98  // Below is the list of the constants for cache size.
    99  // TODO-Klaytn: Below should be handled by ini or other configurations.
   100  const (
   101  	maxFutureBlocks     = 256
   102  	maxTimeFutureBlocks = 30
   103  	// TODO-Klaytn-Issue1911  This flag needs to be adjusted to the appropriate value.
   104  	//  Currently, this value is taken to cache all 10 million accounts
   105  	//  and should be optimized considering memory size and performance.
   106  	maxAccountForCache = 10000000
   107  )
   108  
   109  const (
   110  	DefaultTriesInMemory = 128
   111  	DefaultBlockInterval = 128
   112  	MaxPrefetchTxs       = 20000
   113  
   114  	// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
   115  	// Changelog:
   116  	// - Version 4
   117  	// The following incompatible database changes were added:
   118  	//   * New scheme for contract code in order to separate the codes and trie nodes
   119  	BlockChainVersion = 4
   120  )
   121  
   122  // CacheConfig contains the configuration values for the 1) stateDB caching and
   123  // 2) trie caching/pruning resident in a blockchain.
   124  type CacheConfig struct {
   125  	// TODO-Klaytn-Issue1666 Need to check the benefit of trie caching.
   126  	ArchiveMode          bool                         // If true, state trie is not pruned and always written to database
   127  	CacheSize            int                          // Size of in-memory cache of a trie (MiB) to flush matured singleton trie nodes to disk
   128  	BlockInterval        uint                         // Block interval to flush the trie. Each interval state trie will be flushed into disk
   129  	TriesInMemory        uint64                       // Maximum number of recent state tries according to its block number
   130  	SenderTxHashIndexing bool                         // Enables saving senderTxHash to txHash mapping information to database and cache
   131  	TrieNodeCacheConfig  *statedb.TrieNodeCacheConfig // Configures trie node cache
   132  	SnapshotCacheSize    int                          // Memory allowance (MB) to use for caching snapshot entries in memory
   133  	SnapshotAsyncGen     bool                         // Enables snapshot data generation asynchronously
   134  }
   135  
   136  // gcBlock is used for priority queue for GC.
   137  type gcBlock struct {
   138  	root     common.Hash
   139  	blockNum uint64
   140  }
   141  
   142  // BlockChain represents the canonical chain given a database with a genesis
   143  // block. The Blockchain manages chain imports, reverts, chain reorganisations.
   144  //
   145  // Importing blocks in to the block chain happens according to the set of rules
   146  // defined by the two stage Validator. Processing of blocks is done using the
   147  // Processor which processes the included transaction. The validation of the state
   148  // is done in the second part of the Validator. Failing results in aborting of
   149  // the import.
   150  //
   151  // The BlockChain also helps in returning blocks from **any** chain included
   152  // in the database as well as blocks that represents the canonical chain. It's
   153  // important to note that GetBlock can return any block and does not need to be
   154  // included in the canonical one where as GetBlockByNumber always represents the
   155  // canonical chain.
   156  type BlockChain struct {
   157  	chainConfig *params.ChainConfig // Chain & network configuration
   158  	cacheConfig *CacheConfig        // stateDB caching and trie caching/pruning configuration
   159  
   160  	db      database.DBManager // Low level persistent database to store final content in
   161  	snaps   *snapshot.Tree     // Snapshot tree for fast trie leaf access
   162  	triegc  *prque.Prque       // Priority queue mapping block numbers to tries to gc
   163  	chBlock chan gcBlock       // chPushBlockGCPrque is a channel for delivering the gc item to gc loop.
   164  
   165  	hc            *HeaderChain
   166  	rmLogsFeed    event.Feed
   167  	chainFeed     event.Feed
   168  	chainSideFeed event.Feed
   169  	chainHeadFeed event.Feed
   170  	logsFeed      event.Feed
   171  	scope         event.SubscriptionScope
   172  	genesisBlock  *types.Block
   173  
   174  	mu sync.RWMutex // global mutex for locking chain operations
   175  
   176  	checkpoint       int          // checkpoint counts towards the new checkpoint
   177  	currentBlock     atomic.Value // Current head of the block chain
   178  	currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
   179  
   180  	stateCache   state.Database // State database to reuse between imports (contains state cache)
   181  	futureBlocks *lru.Cache     // future blocks are blocks added for later processing
   182  
   183  	quit    chan struct{} // blockchain quit channel
   184  	running int32         // running must be called atomically
   185  	// procInterrupt must be atomically called
   186  	procInterrupt int32          // interrupt signaler for block processing
   187  	wg            sync.WaitGroup // chain processing wait group for shutting down
   188  
   189  	engine     consensus.Engine
   190  	processor  Processor  // block processor interface
   191  	prefetcher Prefetcher // Block state prefetcher interface
   192  	validator  Validator  // block and state validator interface
   193  	vmConfig   vm.Config
   194  
   195  	parallelDBWrite bool // TODO-Klaytn-Storage parallelDBWrite will be replaced by number of goroutines when worker pool pattern is introduced.
   196  
   197  	// State migration
   198  	prepareStateMigration bool
   199  	stopStateMigration    chan struct{}
   200  	readCnt               int
   201  	committedCnt          int
   202  	pendingCnt            int
   203  	progress              float64
   204  	migrationErr          error
   205  	testMigrationHook     func()
   206  
   207  	// Warm up
   208  	lastCommittedBlock uint64
   209  	quitWarmUp         chan struct{}
   210  
   211  	prefetchTxCh chan prefetchTx
   212  }
   213  
   214  // prefetchTx is used to prefetch transactions, when fetcher works.
   215  type prefetchTx struct {
   216  	ti                int
   217  	block             *types.Block
   218  	followupInterrupt *uint32
   219  }
   220  
   221  // NewBlockChain returns a fully initialised block chain using information
   222  // available in the database. It initialises the default Klaytn validator and
   223  // Processor.
   224  func NewBlockChain(db database.DBManager, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
   225  	if cacheConfig == nil {
   226  		cacheConfig = &CacheConfig{
   227  			ArchiveMode:         false,
   228  			CacheSize:           512,
   229  			BlockInterval:       DefaultBlockInterval,
   230  			TriesInMemory:       DefaultTriesInMemory,
   231  			TrieNodeCacheConfig: statedb.GetEmptyTrieNodeCacheConfig(),
   232  			SnapshotCacheSize:   512,
   233  			SnapshotAsyncGen:    true,
   234  		}
   235  	}
   236  
   237  	if cacheConfig.TrieNodeCacheConfig == nil {
   238  		cacheConfig.TrieNodeCacheConfig = statedb.GetEmptyTrieNodeCacheConfig()
   239  	}
   240  
   241  	state.EnabledExpensive = db.GetDBConfig().EnableDBPerfMetrics
   242  
   243  	futureBlocks, _ := lru.New(maxFutureBlocks)
   244  
   245  	bc := &BlockChain{
   246  		chainConfig:        chainConfig,
   247  		cacheConfig:        cacheConfig,
   248  		db:                 db,
   249  		triegc:             prque.New(),
   250  		chBlock:            make(chan gcBlock, 1000),
   251  		stateCache:         state.NewDatabaseWithNewCache(db, cacheConfig.TrieNodeCacheConfig),
   252  		quit:               make(chan struct{}),
   253  		futureBlocks:       futureBlocks,
   254  		engine:             engine,
   255  		vmConfig:           vmConfig,
   256  		parallelDBWrite:    db.IsParallelDBWrite(),
   257  		stopStateMigration: make(chan struct{}),
   258  		prefetchTxCh:       make(chan prefetchTx, MaxPrefetchTxs),
   259  	}
   260  
   261  	// set hardForkBlockNumberConfig which will be used as a global variable
   262  	if err := fork.SetHardForkBlockNumberConfig(bc.chainConfig); err != nil {
   263  		return nil, err
   264  	}
   265  
   266  	bc.validator = NewBlockValidator(chainConfig, bc, engine)
   267  	bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine)
   268  	bc.processor = NewStateProcessor(chainConfig, bc, engine)
   269  
   270  	var err error
   271  	bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt)
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  	bc.genesisBlock = bc.GetBlockByNumber(0)
   276  	if bc.genesisBlock == nil {
   277  		return nil, ErrNoGenesis
   278  	}
   279  	var nilBlock *types.Block
   280  	bc.currentBlock.Store(nilBlock)
   281  	bc.currentFastBlock.Store(nilBlock)
   282  
   283  	if err := bc.loadLastState(); err != nil {
   284  		return nil, err
   285  	}
   286  	// Make sure the state associated with the block is available
   287  	head := bc.CurrentBlock()
   288  	if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil {
   289  		// Head state is missing, before the state recovery, find out the
   290  		// disk layer point of snapshot(if it's enabled). Make sure the
   291  		// rewound point is lower than disk layer.
   292  		var diskRoot common.Hash
   293  		if bc.cacheConfig.SnapshotCacheSize > 0 {
   294  			diskRoot = bc.db.ReadSnapshotRoot()
   295  		}
   296  		if diskRoot != (common.Hash{}) {
   297  			logger.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot)
   298  
   299  			snapDisk, err := bc.setHeadBeyondRoot(head.NumberU64(), diskRoot, true)
   300  			if err != nil {
   301  				return nil, err
   302  			}
   303  
   304  			// Chain rewound, persist old snapshot number to indicate recovery procedure
   305  			if snapDisk != 0 {
   306  				bc.db.WriteSnapshotRecoveryNumber(snapDisk)
   307  			}
   308  		} else {
   309  			// Dangling block without a state associated, init from scratch
   310  			logger.Warn("Head state missing, repairing chain",
   311  				"number", head.NumberU64(), "hash", head.Hash().String())
   312  			if _, err := bc.setHeadBeyondRoot(head.NumberU64(), common.Hash{}, true); err != nil {
   313  				return nil, err
   314  			}
   315  		}
   316  	}
   317  	// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
   318  	for hash := range BadHashes {
   319  		if header := bc.GetHeaderByHash(hash); header != nil {
   320  			// get the canonical block corresponding to the offending header's number
   321  			headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64())
   322  			// make sure the headerByNumber (if present) is in our current canonical chain
   323  			if headerByNumber != nil && headerByNumber.Hash() == header.Hash() {
   324  				logger.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash)
   325  				bc.SetHead(header.Number.Uint64() - 1)
   326  				logger.Error("Chain rewind was successful, resuming normal operation")
   327  			}
   328  		}
   329  	}
   330  
   331  	// Load any existing snapshot, regenerating it if loading failed
   332  	if bc.cacheConfig.SnapshotCacheSize > 0 {
   333  		// If the chain was rewound past the snapshot persistent layer (causing
   334  		// a recovery block number to be persisted to disk), check if we're still
   335  		// in recovery mode and in that case, don't invalidate the snapshot on a
   336  		// head mismatch.
   337  		var recover bool
   338  
   339  		head := bc.CurrentBlock()
   340  		if layer := bc.db.ReadSnapshotRecoveryNumber(); layer != nil && *layer > head.NumberU64() {
   341  			logger.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer)
   342  			recover = true
   343  		}
   344  		bc.snaps, _ = snapshot.New(bc.db, bc.stateCache.TrieDB(), bc.cacheConfig.SnapshotCacheSize, head.Root(), bc.cacheConfig.SnapshotAsyncGen, true, recover)
   345  	}
   346  
   347  	for i := 1; i <= bc.cacheConfig.TrieNodeCacheConfig.NumFetcherPrefetchWorker; i++ {
   348  		bc.wg.Add(1)
   349  		go bc.prefetchTxWorker(i)
   350  	}
   351  	logger.Info("prefetchTxWorkers are started", "num", bc.cacheConfig.TrieNodeCacheConfig.NumFetcherPrefetchWorker)
   352  
   353  	// Take ownership of this particular state
   354  	go bc.update()
   355  	bc.gcCachedNodeLoop()
   356  	bc.restartStateMigration()
   357  
   358  	if cacheConfig.TrieNodeCacheConfig.DumpPeriodically() {
   359  		logger.Info("LocalCache is used for trie node cache, start saving cache to file periodically",
   360  			"dir", bc.cacheConfig.TrieNodeCacheConfig.FastCacheFileDir,
   361  			"period", bc.cacheConfig.TrieNodeCacheConfig.FastCacheSavePeriod)
   362  		trieDB := bc.stateCache.TrieDB()
   363  		bc.wg.Add(1)
   364  		go func() {
   365  			defer bc.wg.Done()
   366  			trieDB.SaveCachePeriodically(bc.cacheConfig.TrieNodeCacheConfig, bc.quit)
   367  		}()
   368  	}
   369  
   370  	return bc, nil
   371  }
   372  
   373  // prefetchTxWorker receives a block and a transaction index, which it pre-executes
   374  // to retrieve and cache the data for the actual block processing.
   375  func (bc *BlockChain) prefetchTxWorker(index int) {
   376  	defer bc.wg.Done()
   377  
   378  	logger.Debug("prefetchTxWorker is started", "index", index)
   379  	var snaps *snapshot.Tree
   380  	if bc.cacheConfig.TrieNodeCacheConfig.UseSnapshotForPrefetch {
   381  		snaps = bc.snaps
   382  	}
   383  	for followup := range bc.prefetchTxCh {
   384  		stateDB, err := state.NewForPrefetching(bc.CurrentBlock().Root(), bc.stateCache, snaps)
   385  		if err != nil {
   386  			logger.Debug("failed to retrieve stateDB for prefetchTxWorker", "err", err)
   387  			continue
   388  		}
   389  		vmCfg := bc.vmConfig
   390  		vmCfg.Prefetching = true
   391  		bc.prefetcher.PrefetchTx(followup.block, followup.ti, stateDB, vmCfg, followup.followupInterrupt)
   392  	}
   393  	logger.Debug("prefetchTxWorker is terminated", "index", index)
   394  }
   395  
   396  // SetCanonicalBlock resets the canonical as the block with the given block number.
   397  // It works as rewinding the head block to the previous one, but does not delete the data.
   398  func (bc *BlockChain) SetCanonicalBlock(blockNum uint64) {
   399  	// If the given block number is zero (it is zero by default), it does nothing
   400  	if blockNum == 0 {
   401  		return
   402  	}
   403  	// Read the block with the given block number and set it as canonical block
   404  	targetBlock := bc.db.ReadBlockByNumber(blockNum)
   405  	if targetBlock == nil {
   406  		logger.Error("failed to retrieve the block", "blockNum", blockNum)
   407  		return
   408  	}
   409  	bc.insert(targetBlock)
   410  	if err := bc.loadLastState(); err != nil {
   411  		logger.Error("failed to load last state after setting the canonical block", "err", err)
   412  		return
   413  	}
   414  	// Make sure the state associated with the block is available
   415  	head := bc.CurrentBlock()
   416  	if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil {
   417  		// Dangling block without a state associated, init from scratch
   418  		logger.Warn("Head state missing, repairing chain",
   419  			"number", head.NumberU64(), "hash", head.Hash().String())
   420  		if _, err := bc.setHeadBeyondRoot(head.NumberU64(), common.Hash{}, true); err != nil {
   421  			logger.Error("Repairing chain is failed", "number", head.NumberU64(), "hash", head.Hash().String(), "err", err)
   422  			return
   423  		}
   424  	}
   425  	logger.Info("successfully set the canonical block", "blockNum", blockNum)
   426  }
   427  
   428  func (bc *BlockChain) UseGiniCoeff() bool {
   429  	return bc.chainConfig.Governance.Reward.UseGiniCoeff
   430  }
   431  
   432  func (bc *BlockChain) ProposerPolicy() uint64 {
   433  	return bc.chainConfig.Istanbul.ProposerPolicy
   434  }
   435  
   436  func (bc *BlockChain) getProcInterrupt() bool {
   437  	return atomic.LoadInt32(&bc.procInterrupt) == 1
   438  }
   439  
   440  // loadLastState loads the last known chain state from the database. This method
   441  // assumes that the chain manager mutex is held.
   442  func (bc *BlockChain) loadLastState() error {
   443  	// Restore the last known head block
   444  	head := bc.db.ReadHeadBlockHash()
   445  	if head == (common.Hash{}) {
   446  		// Corrupt or empty database, init from scratch
   447  		logger.Info("Empty database, resetting chain")
   448  		return bc.Reset()
   449  	}
   450  	// Make sure the entire head block is available
   451  	currentBlock := bc.GetBlockByHash(head)
   452  	if currentBlock == nil {
   453  		head = bc.db.ReadHeadBlockBackupHash()
   454  		if head == (common.Hash{}) {
   455  			// Corrupt or empty database, init from scratch
   456  			logger.Info("Empty database, resetting chain")
   457  			return bc.Reset()
   458  		}
   459  
   460  		currentBlock = bc.GetBlockByHash(head)
   461  		if currentBlock == nil {
   462  			// Corrupt or empty database, init from scratch
   463  			logger.Error("Head block missing, resetting chain", "hash", head.String())
   464  			return bc.Reset()
   465  		}
   466  	}
   467  	// Everything seems to be fine, set as the head block
   468  	bc.currentBlock.Store(currentBlock)
   469  	bc.lastCommittedBlock = currentBlock.NumberU64()
   470  
   471  	// Restore the last known head header
   472  	currentHeader := currentBlock.Header()
   473  	if head := bc.db.ReadHeadHeaderHash(); head != (common.Hash{}) {
   474  		if header := bc.GetHeaderByHash(head); header != nil {
   475  			currentHeader = header
   476  		}
   477  	}
   478  	bc.hc.SetCurrentHeader(currentHeader)
   479  
   480  	// Restore the last known head fast block
   481  	bc.currentFastBlock.Store(currentBlock)
   482  	if head := bc.db.ReadHeadFastBlockHash(); head != (common.Hash{}) {
   483  		if block := bc.GetBlockByHash(head); block != nil {
   484  			bc.currentFastBlock.Store(block)
   485  		} else if head := bc.db.ReadHeadFastBlockBackupHash(); head != (common.Hash{}) {
   486  			if block := bc.GetBlockByHash(head); block != nil {
   487  				bc.currentFastBlock.Store(block)
   488  			}
   489  		}
   490  	}
   491  
   492  	// Issue a status log for the user
   493  	currentFastBlock := bc.CurrentFastBlock()
   494  
   495  	headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
   496  	blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
   497  	fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64())
   498  
   499  	logger.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time.Uint64()), 0)))
   500  	logger.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time.Uint64()), 0)))
   501  	logger.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time.Uint64()), 0)))
   502  
   503  	return nil
   504  }
   505  
   506  // SetHead rewinds the local chain to a new head with the extra condition
   507  // that the rewind must pass the specified state root. The method will try to
   508  // delete minimal data from disk whilst retaining chain consistency.
   509  func (bc *BlockChain) SetHead(head uint64) error {
   510  	_, err := bc.setHeadBeyondRoot(head, common.Hash{}, false)
   511  	return err
   512  }
   513  
   514  // setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
   515  // that the rewind must pass the specified state root. This method is meant to be
   516  // used when rewinding with snapshots enabled to ensure that we go back further than
   517  // persistent disk layer. Depending on whether the node was fast synced or full, and
   518  // in which state, the method will try to delete minimal data from disk whilst
   519  // retaining chain consistency.
   520  //
   521  // The method returns the block number where the requested root cap was found.
   522  func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bool) (uint64, error) {
   523  	bc.mu.Lock()
   524  	defer bc.mu.Unlock()
   525  
   526  	// Track the block number of the requested root hash
   527  	var rootNumber uint64 // (no root == always 0)
   528  
   529  	updateFn := func(header *types.Header) error {
   530  		// Rewind the block chain, ensuring we don't end up with a stateless head block
   531  		if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() {
   532  			newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
   533  			if newHeadBlock == nil {
   534  				logger.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash())
   535  				newHeadBlock = bc.genesisBlock
   536  			} else {
   537  				// Block exists, keep rewinding until we find one with state,
   538  				// keeping rewinding until we exceed the optional threshold
   539  				// root hash
   540  				beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true)
   541  
   542  				for {
   543  					// If a root threshold was requested but not yet crossed, check
   544  					if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root {
   545  						beyondRoot, rootNumber = true, newHeadBlock.NumberU64()
   546  					}
   547  					if _, err := state.New(newHeadBlock.Root(), bc.stateCache, bc.snaps); err != nil {
   548  						// Rewound state missing, rolled back to the parent block, reset to genesis
   549  						logger.Trace("Block state missing, rewinding further", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
   550  						parent := bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1)
   551  						if parent != nil {
   552  							newHeadBlock = parent
   553  							continue
   554  						}
   555  						logger.Error("Missing block in the middle, aiming genesis", "number", newHeadBlock.NumberU64()-1, "hash", newHeadBlock.ParentHash())
   556  						newHeadBlock = bc.genesisBlock
   557  					}
   558  					if beyondRoot || newHeadBlock.NumberU64() == 0 {
   559  						logger.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash().String())
   560  						break
   561  					}
   562  					// if newHeadBlock has state, then rewind first
   563  					logger.Debug("Skipping block with threshold state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash().String(), "root", newHeadBlock.Root().String())
   564  					newHeadBlock = bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) // Keep rewinding
   565  				}
   566  
   567  			}
   568  			if newHeadBlock.NumberU64() == 0 {
   569  				return errors.New("rewound to block number 0, but repair failed")
   570  			}
   571  			bc.db.WriteHeadBlockHash(newHeadBlock.Hash())
   572  
   573  			// Degrade the chain markers if they are explicitly reverted.
   574  			// In theory we should update all in-memory markers in the
   575  			// last step, however the direction of SetHead is from high
   576  			// to low, so it's safe the update in-memory markers directly.
   577  			bc.currentBlock.Store(newHeadBlock)
   578  			headBlockNumberGauge.Update(int64(newHeadBlock.NumberU64()))
   579  		}
   580  
   581  		// Rewind the fast block in a simpleton way to the target head
   582  		if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() {
   583  			newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64())
   584  			// If either blocks reached nil, reset to the genesis state
   585  			if newHeadFastBlock == nil {
   586  				newHeadFastBlock = bc.genesisBlock
   587  			}
   588  			bc.db.WriteHeadFastBlockHash(newHeadFastBlock.Hash())
   589  
   590  			// Degrade the chain markers if they are explicitly reverted.
   591  			// In theory we should update all in-memory markers in the
   592  			// last step, however the direction of SetHead is from high
   593  			// to low, so it's safe the update in-memory markers directly.
   594  			bc.currentFastBlock.Store(newHeadFastBlock)
   595  		}
   596  		return nil
   597  	}
   598  
   599  	// Rewind the header chain, deleting all block bodies until then
   600  	delFn := func(hash common.Hash, num uint64) {
   601  		// Remove relative body and receipts from the active store.
   602  		// The header, total difficulty and canonical hash will be
   603  		// removed in the hc.SetHead function.
   604  		bc.db.DeleteBody(hash, num)
   605  		bc.db.DeleteReceipts(hash, num)
   606  	}
   607  
   608  	// If SetHead was only called as a chain reparation method, try to skip
   609  	// touching the header chain altogether
   610  	if repair {
   611  		if err := updateFn(bc.CurrentBlock().Header()); err != nil {
   612  			return 0, err
   613  		}
   614  	} else {
   615  		// Rewind the chain to the requested head and keep going backwards until a
   616  		// block with a state is found
   617  		logger.Warn("Rewinding blockchain", "target", head)
   618  		if err := bc.hc.SetHead(head, updateFn, delFn); err != nil {
   619  			return 0, err
   620  		}
   621  	}
   622  
   623  	// Clear out any stale content from the caches
   624  	bc.futureBlocks.Purge()
   625  	bc.db.ClearBlockChainCache()
   626  	// TODO-Klaytn add governance DB deletion logic.
   627  
   628  	return rootNumber, bc.loadLastState()
   629  }
   630  
   631  // FastSyncCommitHead sets the current head block to the one defined by the hash
   632  // irrelevant what the chain contents were prior.
   633  func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
   634  	// Make sure that both the block as well at its state trie exists
   635  	block := bc.GetBlockByHash(hash)
   636  	if block == nil {
   637  		return fmt.Errorf("non existent block [%x…]", hash[:4])
   638  	}
   639  	if _, err := statedb.NewSecureTrie(block.Root(), bc.stateCache.TrieDB()); err != nil {
   640  		return err
   641  	}
   642  	// If all checks out, manually set the head block
   643  	bc.mu.Lock()
   644  	bc.currentBlock.Store(block)
   645  	bc.lastCommittedBlock = block.NumberU64()
   646  	bc.mu.Unlock()
   647  
   648  	// Destroy any existing state snapshot and regenerate it in the background,
   649  	// also resuming the normal maintenance of any previously paused snapshot.
   650  	if bc.snaps != nil {
   651  		bc.snaps.Rebuild(block.Root())
   652  	}
   653  	logger.Info("Committed new head block", "number", block.Number(), "hash", hash)
   654  	return nil
   655  }
   656  
   657  // CurrentBlock retrieves the current head block of the canonical chain. The
   658  // block is retrieved from the blockchain's internal cache.
   659  func (bc *BlockChain) CurrentBlock() *types.Block {
   660  	return bc.currentBlock.Load().(*types.Block)
   661  }
   662  
   663  // CurrentFastBlock retrieves the current fast-sync head block of the canonical
   664  // chain. The block is retrieved from the blockchain's internal cache.
   665  func (bc *BlockChain) CurrentFastBlock() *types.Block {
   666  	return bc.currentFastBlock.Load().(*types.Block)
   667  }
   668  
   669  // Validator returns the current validator.
   670  func (bc *BlockChain) Validator() Validator {
   671  	return bc.validator
   672  }
   673  
   674  // Processor returns the current processor.
   675  func (bc *BlockChain) Processor() Processor {
   676  	return bc.processor
   677  }
   678  
   679  // State returns a new mutable state based on the current HEAD block.
   680  func (bc *BlockChain) State() (*state.StateDB, error) {
   681  	return bc.StateAt(bc.CurrentBlock().Root())
   682  }
   683  
   684  // StateAt returns a new mutable state based on a particular point in time.
   685  func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
   686  	return state.New(root, bc.stateCache, bc.snaps)
   687  }
   688  
   689  // StateAtWithPersistent returns a new mutable state based on a particular point in time with persistent trie nodes.
   690  func (bc *BlockChain) StateAtWithPersistent(root common.Hash) (*state.StateDB, error) {
   691  	exist := bc.stateCache.TrieDB().DoesExistNodeInPersistent(root)
   692  	if !exist {
   693  		return nil, ErrNotExistNode
   694  	}
   695  	return state.New(root, bc.stateCache, bc.snaps)
   696  }
   697  
   698  // StateAtWithGCLock returns a new mutable state based on a particular point in time with read lock of the state nodes.
   699  func (bc *BlockChain) StateAtWithGCLock(root common.Hash) (*state.StateDB, error) {
   700  	bc.RLockGCCachedNode()
   701  
   702  	exist := bc.stateCache.TrieDB().DoesExistCachedNode(root)
   703  	if !exist {
   704  		bc.RUnlockGCCachedNode()
   705  		return nil, ErrNotExistNode
   706  	}
   707  
   708  	stateDB, err := state.New(root, bc.stateCache, bc.snaps)
   709  	if err != nil {
   710  		bc.RUnlockGCCachedNode()
   711  		return nil, err
   712  	}
   713  
   714  	return stateDB, nil
   715  }
   716  
   717  // StateCache returns the caching database underpinning the blockchain instance.
   718  func (bc *BlockChain) StateCache() state.Database {
   719  	return bc.stateCache
   720  }
   721  
   722  // Reset purges the entire blockchain, restoring it to its genesis state.
   723  func (bc *BlockChain) Reset() error {
   724  	return bc.ResetWithGenesisBlock(bc.genesisBlock)
   725  }
   726  
   727  // ResetWithGenesisBlock purges the entire blockchain, restoring it to the
   728  // specified genesis state.
   729  func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
   730  	// Dump the entire block chain and purge the caches
   731  	if err := bc.SetHead(0); err != nil {
   732  		return err
   733  	}
   734  	bc.mu.Lock()
   735  	defer bc.mu.Unlock()
   736  
   737  	// Prepare the genesis block and reinitialise the chain
   738  	bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.BlockScore())
   739  	bc.db.WriteBlock(genesis)
   740  
   741  	bc.genesisBlock = genesis
   742  	bc.insert(bc.genesisBlock)
   743  	bc.currentBlock.Store(bc.genesisBlock)
   744  	bc.hc.SetGenesis(bc.genesisBlock.Header())
   745  	bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
   746  	bc.currentFastBlock.Store(bc.genesisBlock)
   747  
   748  	return nil
   749  }
   750  
   751  // repair tries to repair the current blockchain by rolling back the current block
   752  // until one with associated state is found. This is needed to fix incomplete db
   753  // writes caused either by crashes/power outages, or simply non-committed tries.
   754  //
   755  // This method only rolls back the current block. The current header and current
   756  // fast block are left intact.
   757  // Deprecated: in order to repair chain, please use SetHead or setHeadBeyondRoot methods
   758  func (bc *BlockChain) repair(head **types.Block) error {
   759  	for {
   760  		// Abort if we've rewound to a head block that does have associated state
   761  		if _, err := state.New((*head).Root(), bc.stateCache, bc.snaps); err == nil {
   762  			logger.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash())
   763  			return nil
   764  		} else {
   765  			// Should abort and return error, otherwise it will fall into infinite loop
   766  			if (*head).NumberU64() == 0 {
   767  				return errors.New("rewound to block number 0, but repair failed")
   768  			} else {
   769  				// If headBlockNumber > 0, rewind one block and recheck state availability there
   770  				block := bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1)
   771  				if block == nil {
   772  					return fmt.Errorf("missing block %d [%x]", (*head).NumberU64()-1, (*head).ParentHash())
   773  				}
   774  				*head = block
   775  			}
   776  		}
   777  	}
   778  }
   779  
   780  // Export writes the active chain to the given writer.
   781  func (bc *BlockChain) Export(w io.Writer) error {
   782  	return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64())
   783  }
   784  
   785  // ExportN writes a subset of the active chain to the given writer.
   786  func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
   787  	bc.mu.RLock()
   788  	defer bc.mu.RUnlock()
   789  
   790  	if first > last {
   791  		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
   792  	}
   793  	logger.Info("Exporting batch of blocks", "count", last-first+1)
   794  
   795  	start, reported := time.Now(), time.Now()
   796  	for nr := first; nr <= last; nr++ {
   797  		block := bc.GetBlockByNumber(nr)
   798  		if block == nil {
   799  			return fmt.Errorf("export failed on #%d: not found", nr)
   800  		}
   801  		if err := block.EncodeRLP(w); err != nil {
   802  			return err
   803  		}
   804  		if time.Since(reported) >= log.StatsReportLimit {
   805  			logger.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start)))
   806  			reported = time.Now()
   807  		}
   808  	}
   809  
   810  	return nil
   811  }
   812  
   813  // insert injects a new head block into the current block chain. This method
   814  // assumes that the block is indeed a true head. It will also reset the head
   815  // header and the head fast sync block to this very same block if they are older
   816  // or if they are on a different side chain.
   817  //
   818  // Note, this function assumes that the `mu` mutex is held!
   819  func (bc *BlockChain) insert(block *types.Block) {
   820  	// If the block is on a side chain or an unknown one, force other heads onto it too
   821  	updateHeads := bc.db.ReadCanonicalHash(block.NumberU64()) != block.Hash()
   822  
   823  	// Add the block to the canonical chain number scheme and mark as the head
   824  	bc.db.WriteCanonicalHash(block.Hash(), block.NumberU64())
   825  	bc.db.WriteHeadBlockHash(block.Hash())
   826  
   827  	bc.currentBlock.Store(block)
   828  
   829  	// If the block is better than our head or is on a different chain, force update heads
   830  	if updateHeads {
   831  		bc.hc.SetCurrentHeader(block.Header())
   832  		bc.db.WriteHeadFastBlockHash(block.Hash())
   833  
   834  		bc.currentFastBlock.Store(block)
   835  	}
   836  }
   837  
   838  // Genesis retrieves the chain's genesis block.
   839  func (bc *BlockChain) Genesis() *types.Block {
   840  	return bc.genesisBlock
   841  }
   842  
   843  // GetBodyRLP retrieves a block body in RLP encoding from the database by hash,
   844  // caching it if found.
   845  func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
   846  	return bc.db.ReadBodyRLPByHash(hash)
   847  }
   848  
   849  // HasBlock checks if a block is fully present in the database or not.
   850  func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
   851  	return bc.db.HasBlock(hash, number)
   852  }
   853  
   854  // HasState checks if state trie is fully present in the database or not.
   855  func (bc *BlockChain) HasState(hash common.Hash) bool {
   856  	_, err := bc.stateCache.OpenTrie(hash)
   857  	return err == nil
   858  }
   859  
   860  // HasBlockAndState checks if a block and associated state trie is fully present
   861  // in the database or not, caching it if present.
   862  func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
   863  	// Check first that the block itself is known
   864  	block := bc.GetBlock(hash, number)
   865  	if block == nil {
   866  		return false
   867  	}
   868  	return bc.HasState(block.Root())
   869  }
   870  
   871  // ShouldTryInserting returns the state whether the block should be inserted.
   872  // If a node doesn't have the given block or the block number of given block is higher than the node's head block, it can try inserting the block.
   873  func (bc *BlockChain) ShouldTryInserting(block *types.Block) bool {
   874  	return !bc.HasBlockAndState(block.Hash(), block.NumberU64()) || bc.CurrentBlock().NumberU64() < block.NumberU64()
   875  }
   876  
   877  // GetBlock retrieves a block from the database by hash and number,
   878  // caching it if found.
   879  func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
   880  	return bc.db.ReadBlock(hash, number)
   881  }
   882  
   883  // GetBlockByHash retrieves a block from the database by hash, caching it if found.
   884  func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
   885  	return bc.db.ReadBlockByHash(hash)
   886  }
   887  
   888  // GetBlockNumber retrieves a blockNumber from the database by hash, caching it if found.
   889  func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 {
   890  	return bc.hc.GetBlockNumber(hash)
   891  }
   892  
   893  // GetBlockByNumber retrieves a block from the database by number, caching it
   894  // (associated with its hash) if found.
   895  func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
   896  	return bc.db.ReadBlockByNumber(number)
   897  }
   898  
   899  // GetTxAndLookupInfo retrieves a tx and lookup info for a given transaction hash.
   900  func (bc *BlockChain) GetTxAndLookupInfo(txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
   901  	tx, blockHash, blockNumber, index := bc.GetTxAndLookupInfoInCache(txHash)
   902  	if tx == nil {
   903  		tx, blockHash, blockNumber, index = bc.db.ReadTxAndLookupInfo(txHash)
   904  	}
   905  	return tx, blockHash, blockNumber, index
   906  }
   907  
   908  // GetTxLookupInfoAndReceipt retrieves a tx and lookup info and receipt for a given transaction hash.
   909  func (bc *BlockChain) GetTxLookupInfoAndReceipt(txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, *types.Receipt) {
   910  	tx, blockHash, blockNumber, index := bc.GetTxAndLookupInfo(txHash)
   911  	if tx == nil {
   912  		return nil, common.Hash{}, 0, 0, nil
   913  	}
   914  
   915  	receipt := bc.GetReceiptByTxHash(txHash)
   916  	if receipt == nil {
   917  		return nil, common.Hash{}, 0, 0, nil
   918  	}
   919  
   920  	return tx, blockHash, blockNumber, index, receipt
   921  }
   922  
   923  // GetTxLookupInfoAndReceiptInCache retrieves a tx and lookup info and receipt for a given transaction hash in cache.
   924  func (bc *BlockChain) GetTxLookupInfoAndReceiptInCache(txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, *types.Receipt) {
   925  	tx, blockHash, blockNumber, index := bc.GetTxAndLookupInfoInCache(txHash)
   926  	if tx == nil {
   927  		return nil, common.Hash{}, 0, 0, nil
   928  	}
   929  
   930  	receipt := bc.GetTxReceiptInCache(txHash)
   931  	if receipt == nil {
   932  		return nil, common.Hash{}, 0, 0, nil
   933  	}
   934  
   935  	return tx, blockHash, blockNumber, index, receipt
   936  }
   937  
   938  // GetReceiptsByBlockHash retrieves the receipts for all transactions with given block hash.
   939  func (bc *BlockChain) GetReceiptsByBlockHash(blockHash common.Hash) types.Receipts {
   940  	return bc.db.ReadReceiptsByBlockHash(blockHash)
   941  }
   942  
   943  // GetReceiptByTxHash retrieves a receipt for a given transaction hash.
   944  func (bc *BlockChain) GetReceiptByTxHash(txHash common.Hash) *types.Receipt {
   945  	receipt := bc.GetTxReceiptInCache(txHash)
   946  	if receipt != nil {
   947  		return receipt
   948  	}
   949  
   950  	tx, blockHash, _, index := bc.GetTxAndLookupInfo(txHash)
   951  	if tx == nil {
   952  		return nil
   953  	}
   954  
   955  	receipts := bc.GetReceiptsByBlockHash(blockHash)
   956  	if len(receipts) <= int(index) {
   957  		logger.Error("receipt index exceeds the size of receipts", "receiptIndex", index, "receiptsSize", len(receipts))
   958  		return nil
   959  	}
   960  	return receipts[index]
   961  }
   962  
   963  // GetLogsByHash retrieves the logs for all receipts in a given block.
   964  func (bc *BlockChain) GetLogsByHash(hash common.Hash) [][]*types.Log {
   965  	receipts := bc.GetReceiptsByBlockHash(hash)
   966  	if receipts == nil {
   967  		return nil
   968  	}
   969  
   970  	logs := make([][]*types.Log, len(receipts))
   971  	for i, receipt := range receipts {
   972  		logs[i] = receipt.Logs
   973  	}
   974  	return logs
   975  }
   976  
   977  // TrieNode retrieves a blob of data associated with a trie node
   978  // either from ephemeral in-memory cache, or from persistent storage.
   979  func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) {
   980  	return bc.stateCache.TrieDB().Node(hash)
   981  }
   982  
   983  // ContractCode retrieves a blob of data associated with a contract hash
   984  // either from ephemeral in-memory cache, or from persistent storage.
   985  func (bc *BlockChain) ContractCode(hash common.Hash) ([]byte, error) {
   986  	return bc.stateCache.ContractCode(hash)
   987  }
   988  
   989  // ContractCodeWithPrefix retrieves a blob of data associated with a contract
   990  // hash either from ephemeral in-memory cache, or from persistent storage.
   991  //
   992  // If the code doesn't exist in the in-memory cache, check the storage with
   993  // new code scheme.
   994  func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
   995  	type codeReader interface {
   996  		ContractCodeWithPrefix(codeHash common.Hash) ([]byte, error)
   997  	}
   998  	return bc.stateCache.(codeReader).ContractCodeWithPrefix(hash)
   999  }
  1000  
  1001  // Stop stops the blockchain service. If any imports are currently in progress
  1002  // it will abort them using the procInterrupt.
  1003  func (bc *BlockChain) Stop() {
  1004  	if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
  1005  		return
  1006  	}
  1007  	// Unsubscribe all subscriptions registered from blockchain
  1008  	bc.scope.Close()
  1009  	if bc.cacheConfig.TrieNodeCacheConfig.RedisSubscribeBlockEnable {
  1010  		bc.CloseBlockSubscriptionLoop()
  1011  	}
  1012  
  1013  	close(bc.prefetchTxCh)
  1014  	close(bc.quit)
  1015  	atomic.StoreInt32(&bc.procInterrupt, 1)
  1016  
  1017  	bc.wg.Wait()
  1018  
  1019  	// Ensure that the entirety of the state snapshot is journalled to disk.
  1020  	var snapBase common.Hash
  1021  	if bc.snaps != nil {
  1022  		var err error
  1023  		if snapBase, err = bc.snaps.Journal(bc.CurrentBlock().Root()); err != nil {
  1024  			logger.Error("Failed to journal state snapshot", "err", err)
  1025  		}
  1026  	}
  1027  
  1028  	triedb := bc.stateCache.TrieDB()
  1029  	if !bc.isArchiveMode() {
  1030  		number := bc.CurrentBlock().NumberU64()
  1031  		recent := bc.GetBlockByNumber(number)
  1032  		if recent == nil {
  1033  			logger.Error("Failed to find recent block from persistent", "blockNumber", number)
  1034  			return
  1035  		}
  1036  
  1037  		logger.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
  1038  		if err := triedb.Commit(recent.Root(), true, number); err != nil {
  1039  			logger.Error("Failed to commit recent state trie", "err", err)
  1040  		}
  1041  		if snapBase != (common.Hash{}) {
  1042  			logger.Info("Writing snapshot state to disk", "root", snapBase)
  1043  			if err := triedb.Commit(snapBase, true, number); err != nil {
  1044  				logger.Error("Failed to commit recent state trie", "err", err)
  1045  			}
  1046  		}
  1047  		for !bc.triegc.Empty() {
  1048  			triedb.Dereference(bc.triegc.PopItem().(common.Hash))
  1049  		}
  1050  		if size, _, _ := triedb.Size(); size != 0 {
  1051  			logger.Error("Dangling trie nodes after full cleanup")
  1052  		}
  1053  	}
  1054  	if triedb.TrieNodeCache() != nil {
  1055  		_ = triedb.TrieNodeCache().Close()
  1056  	}
  1057  
  1058  	logger.Info("Blockchain manager stopped")
  1059  }
  1060  
  1061  func (bc *BlockChain) procFutureBlocks() {
  1062  	blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
  1063  	for _, hash := range bc.futureBlocks.Keys() {
  1064  		hashKey, ok := hash.(common.CacheKey)
  1065  		if !ok {
  1066  			logger.Error("invalid key type", "expect", "common.CacheKey", "actual", reflect.TypeOf(hash))
  1067  			continue
  1068  		}
  1069  
  1070  		if block, exist := bc.futureBlocks.Peek(hashKey); exist {
  1071  			cacheGetFutureBlockHitMeter.Mark(1)
  1072  			blocks = append(blocks, block.(*types.Block))
  1073  		} else {
  1074  			cacheGetFutureBlockMissMeter.Mark(1)
  1075  		}
  1076  	}
  1077  	if len(blocks) > 0 {
  1078  		types.BlockBy(types.Number).Sort(blocks)
  1079  
  1080  		// Insert one by one as chain insertion needs contiguous ancestry between blocks
  1081  		for i := range blocks {
  1082  			bc.InsertChain(blocks[i : i+1])
  1083  		}
  1084  	}
  1085  }
  1086  
  1087  // WriteStatus status of write
  1088  type WriteStatus byte
  1089  
  1090  // TODO-Klaytn-Issue264 If we are using istanbul BFT, then we always have a canonical chain.
  1091  //
  1092  //	Later we may be able to remove SideStatTy.
  1093  const (
  1094  	NonStatTy WriteStatus = iota
  1095  	CanonStatTy
  1096  	SideStatTy
  1097  )
  1098  
  1099  // WriteResult includes the block write status and related statistics.
  1100  type WriteResult struct {
  1101  	Status         WriteStatus
  1102  	TotalWriteTime time.Duration
  1103  	TrieWriteTime  time.Duration
  1104  }
  1105  
  1106  // Rollback is designed to remove a chain of links from the database that aren't
  1107  // certain enough to be valid.
  1108  func (bc *BlockChain) Rollback(chain []common.Hash) {
  1109  	bc.mu.Lock()
  1110  	defer bc.mu.Unlock()
  1111  
  1112  	for i := len(chain) - 1; i >= 0; i-- {
  1113  		hash := chain[i]
  1114  
  1115  		currentHeader := bc.CurrentHeader()
  1116  		if currentHeader.Hash() == hash {
  1117  			bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1))
  1118  		}
  1119  		if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
  1120  			newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
  1121  			bc.currentFastBlock.Store(newFastBlock)
  1122  			bc.db.WriteHeadFastBlockHash(newFastBlock.Hash())
  1123  		}
  1124  		if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash {
  1125  			newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1)
  1126  			bc.currentBlock.Store(newBlock)
  1127  			bc.db.WriteHeadBlockHash(newBlock.Hash())
  1128  		}
  1129  	}
  1130  }
  1131  
  1132  // SetReceiptsData computes all the non-consensus fields of the receipts
  1133  func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) error {
  1134  	signer := types.MakeSigner(config, block.Number())
  1135  
  1136  	transactions, logIndex := block.Transactions(), uint(0)
  1137  	if len(transactions) != len(receipts) {
  1138  		return errors.New("transaction and receipt count mismatch")
  1139  	}
  1140  
  1141  	for j := 0; j < len(receipts); j++ {
  1142  		// The transaction hash can be retrieved from the transaction itself
  1143  		receipts[j].TxHash = transactions[j].Hash()
  1144  
  1145  		// The contract address can be derived from the transaction itself
  1146  		if transactions[j].To() == nil {
  1147  			// Deriving the signer is expensive, only do if it's actually needed
  1148  			from, _ := types.Sender(signer, transactions[j])
  1149  			receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce())
  1150  		}
  1151  		// The derived log fields can simply be set from the block and transaction
  1152  		for k := 0; k < len(receipts[j].Logs); k++ {
  1153  			receipts[j].Logs[k].BlockNumber = block.NumberU64()
  1154  			receipts[j].Logs[k].BlockHash = block.Hash()
  1155  			receipts[j].Logs[k].TxHash = receipts[j].TxHash
  1156  			receipts[j].Logs[k].TxIndex = uint(j)
  1157  			receipts[j].Logs[k].Index = logIndex
  1158  			logIndex++
  1159  		}
  1160  	}
  1161  	return nil
  1162  }
  1163  
  1164  // InsertReceiptChain attempts to complete an already existing header chain with
  1165  // transaction and receipt data.
  1166  func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
  1167  	bc.wg.Add(1)
  1168  	defer bc.wg.Done()
  1169  
  1170  	// Do a sanity check that the provided chain is actually ordered and linked
  1171  	for i := 1; i < len(blockChain); i++ {
  1172  		if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() {
  1173  			logger.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(),
  1174  				"prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash())
  1175  			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(),
  1176  				blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4])
  1177  		}
  1178  	}
  1179  
  1180  	var (
  1181  		stats = struct{ processed, ignored int32 }{}
  1182  		start = time.Now()
  1183  		bytes = 0
  1184  
  1185  		// TODO-Klaytn Needs to roll back if any one of batches fails
  1186  		bodyBatch            = bc.db.NewBatch(database.BodyDB)
  1187  		receiptsBatch        = bc.db.NewBatch(database.ReceiptsDB)
  1188  		txLookupEntriesBatch = bc.db.NewBatch(database.TxLookUpEntryDB)
  1189  	)
  1190  	for i, block := range blockChain {
  1191  		receipts := receiptChain[i]
  1192  		// Short circuit insertion if shutting down or processing failed
  1193  		if atomic.LoadInt32(&bc.procInterrupt) == 1 {
  1194  			return 0, nil
  1195  		}
  1196  		// Short circuit if the owner header is unknown
  1197  		if !bc.HasHeader(block.Hash(), block.NumberU64()) {
  1198  			return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
  1199  		}
  1200  		// Skip if the entire data is already known
  1201  		if bc.HasBlock(block.Hash(), block.NumberU64()) {
  1202  			stats.ignored++
  1203  			continue
  1204  		}
  1205  		// Compute all the non-consensus fields of the receipts
  1206  		if err := SetReceiptsData(bc.chainConfig, block, receipts); err != nil {
  1207  			return i, fmt.Errorf("failed to set receipts data: %v", err)
  1208  		}
  1209  		// Write all the data out into the database
  1210  		bc.db.PutBodyToBatch(bodyBatch, block.Hash(), block.NumberU64(), block.Body())
  1211  		bc.db.PutReceiptsToBatch(receiptsBatch, block.Hash(), block.NumberU64(), receipts)
  1212  		bc.db.PutTxLookupEntriesToBatch(txLookupEntriesBatch, block)
  1213  
  1214  		stats.processed++
  1215  
  1216  		totalBytes, err := database.WriteBatchesOverThreshold(bodyBatch, receiptsBatch, txLookupEntriesBatch)
  1217  		if err != nil {
  1218  			return 0, err
  1219  		} else {
  1220  			bytes += totalBytes
  1221  		}
  1222  	}
  1223  
  1224  	totalBytes, err := database.WriteBatches(bodyBatch, receiptsBatch, txLookupEntriesBatch)
  1225  	if err != nil {
  1226  		return 0, err
  1227  	} else {
  1228  		bytes += totalBytes
  1229  	}
  1230  
  1231  	// Update the head fast sync block if better
  1232  	bc.mu.Lock()
  1233  	head := blockChain[len(blockChain)-1]
  1234  	if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case
  1235  		currentFastBlock := bc.CurrentFastBlock()
  1236  		if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 {
  1237  			bc.db.WriteHeadFastBlockHash(head.Hash())
  1238  			bc.currentFastBlock.Store(head)
  1239  		}
  1240  	}
  1241  	bc.mu.Unlock()
  1242  
  1243  	logger.Info("Imported new block receipts",
  1244  		"count", stats.processed,
  1245  		"elapsed", common.PrettyDuration(time.Since(start)),
  1246  		"number", head.Number(),
  1247  		"hash", head.Hash(),
  1248  		"size", common.StorageSize(bytes),
  1249  		"ignored", stats.ignored)
  1250  	return 0, nil
  1251  }
  1252  
  1253  // WriteBlockWithoutState writes only the block and its metadata to the database,
  1254  // but does not write any state. This is used to construct competing side forks
  1255  // up to the point where they exceed the canonical total blockscore.
  1256  func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) {
  1257  	bc.wg.Add(1)
  1258  	defer bc.wg.Done()
  1259  
  1260  	bc.hc.WriteTd(block.Hash(), block.NumberU64(), td)
  1261  	bc.writeBlock(block)
  1262  }
  1263  
  1264  type TransactionLookup struct {
  1265  	Tx *types.Transaction
  1266  	*database.TxLookupEntry
  1267  }
  1268  
  1269  // writeBlock writes block to persistent database.
  1270  // If write through caching is enabled, it also writes block to the cache.
  1271  func (bc *BlockChain) writeBlock(block *types.Block) {
  1272  	bc.db.WriteBlock(block)
  1273  }
  1274  
  1275  // writeReceipts writes receipts to persistent database.
  1276  // If write through caching is enabled, it also writes blockReceipts to the cache.
  1277  func (bc *BlockChain) writeReceipts(hash common.Hash, number uint64, receipts types.Receipts) {
  1278  	bc.db.WriteReceipts(hash, number, receipts)
  1279  }
  1280  
  1281  // writeStateTrie writes state trie to database if possible.
  1282  // If an archiving node is running, it always flushes state trie to DB.
  1283  // If not, it flushes state trie to DB periodically. (period = bc.cacheConfig.BlockInterval)
  1284  func (bc *BlockChain) writeStateTrie(block *types.Block, state *state.StateDB) error {
  1285  	state.LockGCCachedNode()
  1286  	defer state.UnlockGCCachedNode()
  1287  
  1288  	root, err := state.Commit(true)
  1289  	if err != nil {
  1290  		return err
  1291  	}
  1292  	trieDB := bc.stateCache.TrieDB()
  1293  	trieDB.UpdateMetricNodes()
  1294  
  1295  	// If we're running an archive node, always flush
  1296  	if bc.isArchiveMode() {
  1297  		if err := trieDB.Commit(root, false, block.NumberU64()); err != nil {
  1298  			return err
  1299  		}
  1300  
  1301  		bc.checkStartStateMigration(block.NumberU64(), root)
  1302  		bc.lastCommittedBlock = block.NumberU64()
  1303  	} else {
  1304  		// Full but not archive node, do proper garbage collection
  1305  		trieDB.Reference(root, common.Hash{}) // metadata reference to keep trie alive
  1306  
  1307  		// If we exceeded our memory allowance, flush matured singleton nodes to disk
  1308  		var (
  1309  			nodesSize, _, preimagesSize = trieDB.Size()
  1310  			nodesSizeLimit              = common.StorageSize(bc.cacheConfig.CacheSize) * 1024 * 1024
  1311  		)
  1312  
  1313  		trieDBNodesSizeBytesGauge.Update(int64(nodesSize))
  1314  		trieDBPreimagesSizeGauge.Update(int64(preimagesSize))
  1315  
  1316  		if nodesSize > nodesSizeLimit || preimagesSize > 4*1024*1024 {
  1317  			// NOTE-Klaytn Not to change the original behavior, error is not returned.
  1318  			// Error should be returned if it is thought to be safe in the future.
  1319  			if err := trieDB.Cap(nodesSizeLimit - database.IdealBatchSize); err != nil {
  1320  				logger.Error("Error from trieDB.Cap", "err", err, "limit", nodesSizeLimit-database.IdealBatchSize)
  1321  			}
  1322  		}
  1323  
  1324  		if isCommitTrieRequired(bc, block.NumberU64()) {
  1325  			logger.Trace("Commit the state trie into the disk", "blocknum", block.NumberU64())
  1326  			if err := trieDB.Commit(block.Header().Root, true, block.NumberU64()); err != nil {
  1327  				return err
  1328  			}
  1329  
  1330  			if bc.checkStartStateMigration(block.NumberU64(), root) {
  1331  				// flush referenced trie nodes out to new stateTrieDB
  1332  				if err := trieDB.Cap(0); err != nil {
  1333  					logger.Error("Error from trieDB.Cap by state migration", "err", err)
  1334  				}
  1335  			}
  1336  
  1337  			bc.lastCommittedBlock = block.NumberU64()
  1338  		}
  1339  
  1340  		bc.chBlock <- gcBlock{root, block.NumberU64()}
  1341  	}
  1342  	return nil
  1343  }
  1344  
  1345  // RLockGCCachedNode locks the GC lock of CachedNode.
  1346  func (bc *BlockChain) RLockGCCachedNode() {
  1347  	bc.stateCache.RLockGCCachedNode()
  1348  }
  1349  
  1350  // RUnlockGCCachedNode unlocks the GC lock of CachedNode.
  1351  func (bc *BlockChain) RUnlockGCCachedNode() {
  1352  	bc.stateCache.RUnlockGCCachedNode()
  1353  }
  1354  
  1355  // DefaultTriesInMemory returns the number of tries residing in the memory.
  1356  func (bc *BlockChain) triesInMemory() uint64 {
  1357  	return bc.cacheConfig.TriesInMemory
  1358  }
  1359  
  1360  // gcCachedNodeLoop runs a loop to gc.
  1361  func (bc *BlockChain) gcCachedNodeLoop() {
  1362  	trieDB := bc.stateCache.TrieDB()
  1363  
  1364  	bc.wg.Add(1)
  1365  	go func() {
  1366  		defer bc.wg.Done()
  1367  		for {
  1368  			select {
  1369  			case block := <-bc.chBlock:
  1370  				bc.triegc.Push(block.root, -int64(block.blockNum))
  1371  				logger.Trace("Push GC block", "blkNum", block.blockNum, "hash", block.root.String())
  1372  
  1373  				blkNum := block.blockNum
  1374  				if blkNum <= bc.triesInMemory() {
  1375  					continue
  1376  				}
  1377  
  1378  				// Garbage collect anything below our required write retention
  1379  				chosen := blkNum - bc.triesInMemory()
  1380  				cnt := 0
  1381  				for !bc.triegc.Empty() {
  1382  					root, number := bc.triegc.Pop()
  1383  					if uint64(-number) > chosen {
  1384  						bc.triegc.Push(root, number)
  1385  						break
  1386  					}
  1387  					trieDB.Dereference(root.(common.Hash))
  1388  					cnt++
  1389  				}
  1390  				logger.Debug("GC cached node", "currentBlk", blkNum, "chosenBlk", chosen, "deferenceCnt", cnt)
  1391  			case <-bc.quit:
  1392  				return
  1393  			}
  1394  		}
  1395  	}()
  1396  }
  1397  
  1398  func isCommitTrieRequired(bc *BlockChain, blockNum uint64) bool {
  1399  	if bc.prepareStateMigration {
  1400  		return true
  1401  	}
  1402  
  1403  	// TODO-Klaytn-Issue1602 Introduce a simple and more concise way to determine commit trie requirements from governance
  1404  	if blockNum%uint64(bc.cacheConfig.BlockInterval) == 0 {
  1405  		return true
  1406  	}
  1407  
  1408  	if bc.chainConfig.Istanbul != nil {
  1409  		return bc.ProposerPolicy() == params.WeightedRandom &&
  1410  			params.IsStakingUpdateInterval(blockNum)
  1411  	}
  1412  	return false
  1413  }
  1414  
  1415  // isReorganizationRequired returns if reorganization is required or not based on total blockscore.
  1416  func isReorganizationRequired(localTd, externTd *big.Int, currentBlock, block *types.Block) bool {
  1417  	reorg := externTd.Cmp(localTd) > 0
  1418  	if !reorg && externTd.Cmp(localTd) == 0 {
  1419  		// Split same-blockscore blocks by number, then at random
  1420  		reorg = block.NumberU64() < currentBlock.NumberU64() || (block.NumberU64() == currentBlock.NumberU64() && mrand.Float64() < 0.5)
  1421  	}
  1422  	return reorg
  1423  }
  1424  
  1425  // WriteBlockWithState writes the block and all associated state to the database.
  1426  // If we are to use writeBlockWithState alone, we should use mutex to protect internal state.
  1427  func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, stateDB *state.StateDB) (WriteResult, error) {
  1428  	bc.mu.Lock()
  1429  	defer bc.mu.Unlock()
  1430  
  1431  	return bc.writeBlockWithState(block, receipts, stateDB)
  1432  }
  1433  
  1434  // writeBlockWithState writes the block and all associated state to the database.
  1435  // If BlockChain.parallelDBWrite is true, it calls writeBlockWithStateParallel.
  1436  // If not, it calls writeBlockWithStateSerial.
  1437  func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, stateDB *state.StateDB) (WriteResult, error) {
  1438  	var status WriteResult
  1439  	var err error
  1440  	if bc.parallelDBWrite {
  1441  		status, err = bc.writeBlockWithStateParallel(block, receipts, stateDB)
  1442  	} else {
  1443  		status, err = bc.writeBlockWithStateSerial(block, receipts, stateDB)
  1444  	}
  1445  
  1446  	if err != nil {
  1447  		return status, err
  1448  	}
  1449  
  1450  	// Publish the committed block to the redis cache of stateDB.
  1451  	// The cache uses the block to distinguish the latest state.
  1452  	if bc.cacheConfig.TrieNodeCacheConfig.RedisPublishBlockEnable {
  1453  		blockLogsKey := append(kesCachePrefixBlockLogs, block.Number().Bytes()...)
  1454  		bc.writeBlockLogsToRemoteCache(blockLogsKey, receipts)
  1455  
  1456  		blockRlp, err := rlp.EncodeToBytes(block)
  1457  		if err != nil {
  1458  			logger.Error("failed to encode lastCommittedBlock", "blockNumber", block.NumberU64(), "err", err)
  1459  		}
  1460  
  1461  		pubSub, ok := bc.stateCache.TrieDB().TrieNodeCache().(statedb.BlockPubSub)
  1462  		if ok {
  1463  			if err := pubSub.PublishBlock(hexutil.Encode(blockRlp)); err != nil {
  1464  				logger.Error("failed to publish block to redis", "blockNumber", block.NumberU64(), "err", err)
  1465  			}
  1466  		} else {
  1467  			logger.Error("invalid TrieNodeCache type", "trieNodeCacheConfig", bc.cacheConfig.TrieNodeCacheConfig)
  1468  		}
  1469  	}
  1470  
  1471  	return status, err
  1472  }
  1473  
  1474  // writeBlockLogsToRemoteCache writes block logs to remote cache.
  1475  // The stored logs will be used by KES service nodes to subscribe log events.
  1476  // This method is only for KES nodes.
  1477  func (bc *BlockChain) writeBlockLogsToRemoteCache(blockLogsKey []byte, receipts []*types.Receipt) {
  1478  	var entireBlockLogs []*types.LogForStorage
  1479  	for _, receipt := range receipts {
  1480  		for _, log := range receipt.Logs {
  1481  			// convert Log to LogForStorage to encode entire data
  1482  			entireBlockLogs = append(entireBlockLogs, (*types.LogForStorage)(log))
  1483  		}
  1484  	}
  1485  	encodedBlockLogs, err := rlp.EncodeToBytes(entireBlockLogs)
  1486  	if err != nil {
  1487  		logger.Error("rlp encoding error", "err", err)
  1488  		return
  1489  	}
  1490  	// TODO-Klaytn-KES: refine this not to use trieNodeCache
  1491  	cache, ok := bc.stateCache.TrieDB().TrieNodeCache().(*statedb.HybridCache)
  1492  	if !ok {
  1493  		logger.Error("only HybridCache supports block logs writing",
  1494  			"TrieNodeCacheType", reflect.TypeOf(bc.stateCache.TrieDB().TrieNodeCache()))
  1495  	} else {
  1496  		cache.Remote().Set(blockLogsKey, encodedBlockLogs)
  1497  	}
  1498  }
  1499  
  1500  // writeBlockWithStateSerial writes the block and all associated state to the database in serial manner.
  1501  func (bc *BlockChain) writeBlockWithStateSerial(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (WriteResult, error) {
  1502  	start := time.Now()
  1503  	bc.wg.Add(1)
  1504  	defer bc.wg.Done()
  1505  
  1506  	var status WriteStatus
  1507  	// Calculate the total blockscore of the block
  1508  	ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
  1509  	if ptd == nil {
  1510  		logger.Error("unknown ancestor (writeBlockWithStateSerial)", "num", block.NumberU64(),
  1511  			"hash", block.Hash(), "parentHash", block.ParentHash())
  1512  		return WriteResult{Status: NonStatTy}, consensus.ErrUnknownAncestor
  1513  	}
  1514  
  1515  	if !bc.ShouldTryInserting(block) {
  1516  		return WriteResult{Status: NonStatTy}, ErrKnownBlock
  1517  	}
  1518  
  1519  	currentBlock := bc.CurrentBlock()
  1520  	localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
  1521  	externTd := new(big.Int).Add(block.BlockScore(), ptd)
  1522  
  1523  	// Irrelevant of the canonical status, write the block itself to the database
  1524  	bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd)
  1525  
  1526  	// Write other block data.
  1527  	bc.writeBlock(block)
  1528  
  1529  	trieWriteStart := time.Now()
  1530  	if err := bc.writeStateTrie(block, state); err != nil {
  1531  		return WriteResult{Status: NonStatTy}, err
  1532  	}
  1533  	trieWriteTime := time.Since(trieWriteStart)
  1534  
  1535  	bc.writeReceipts(block.Hash(), block.NumberU64(), receipts)
  1536  
  1537  	// TODO-Klaytn-Issue264 If we are using istanbul BFT, then we always have a canonical chain.
  1538  	//         Later we may be able to refine below code.
  1539  
  1540  	// If the total blockscore is higher than our known, add it to the canonical chain
  1541  	// Second clause in the if statement reduces the vulnerability to selfish mining.
  1542  	// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
  1543  	currentBlock = bc.CurrentBlock()
  1544  	reorg := isReorganizationRequired(localTd, externTd, currentBlock, block)
  1545  	if reorg {
  1546  		// Reorganise the chain if the parent is not the head block
  1547  		if block.ParentHash() != currentBlock.Hash() {
  1548  			if err := bc.reorg(currentBlock, block); err != nil {
  1549  				return WriteResult{Status: NonStatTy}, err
  1550  			}
  1551  		}
  1552  		// Write the positional metadata for transaction/receipt lookups and preimages
  1553  		if err := bc.writeTxLookupEntries(block); err != nil {
  1554  			return WriteResult{Status: NonStatTy}, err
  1555  		}
  1556  		bc.db.WritePreimages(block.NumberU64(), state.Preimages())
  1557  		status = CanonStatTy
  1558  	} else {
  1559  		status = SideStatTy
  1560  	}
  1561  
  1562  	return bc.finalizeWriteBlockWithState(block, status, start, trieWriteTime)
  1563  }
  1564  
  1565  // writeBlockWithStateParallel writes the block and all associated state to the database using goroutines.
  1566  func (bc *BlockChain) writeBlockWithStateParallel(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (WriteResult, error) {
  1567  	start := time.Now()
  1568  	bc.wg.Add(1)
  1569  	defer bc.wg.Done()
  1570  
  1571  	var status WriteStatus
  1572  	// Calculate the total blockscore of the block
  1573  	ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
  1574  	if ptd == nil {
  1575  		logger.Error("unknown ancestor (writeBlockWithStateParallel)", "num", block.NumberU64(),
  1576  			"hash", block.Hash(), "parentHash", block.ParentHash())
  1577  		return WriteResult{Status: NonStatTy}, consensus.ErrUnknownAncestor
  1578  	}
  1579  
  1580  	if !bc.ShouldTryInserting(block) {
  1581  		return WriteResult{Status: NonStatTy}, ErrKnownBlock
  1582  	}
  1583  
  1584  	currentBlock := bc.CurrentBlock()
  1585  	localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
  1586  	externTd := new(big.Int).Add(block.BlockScore(), ptd)
  1587  
  1588  	parallelDBWriteWG := sync.WaitGroup{}
  1589  	parallelDBWriteErrCh := make(chan error, 2)
  1590  	// Irrelevant of the canonical status, write the block itself to the database
  1591  	// TODO-Klaytn-Storage Implementing worker pool pattern instead of generating goroutines every time.
  1592  	parallelDBWriteWG.Add(4)
  1593  	go func() {
  1594  		defer parallelDBWriteWG.Done()
  1595  		bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd)
  1596  	}()
  1597  
  1598  	// Write other block data.
  1599  	go func() {
  1600  		defer parallelDBWriteWG.Done()
  1601  		bc.writeBlock(block)
  1602  	}()
  1603  
  1604  	var trieWriteTime time.Duration
  1605  	trieWriteStart := time.Now()
  1606  	go func() {
  1607  		defer parallelDBWriteWG.Done()
  1608  		if err := bc.writeStateTrie(block, state); err != nil {
  1609  			parallelDBWriteErrCh <- err
  1610  		}
  1611  		trieWriteTime = time.Since(trieWriteStart)
  1612  	}()
  1613  
  1614  	go func() {
  1615  		defer parallelDBWriteWG.Done()
  1616  		bc.writeReceipts(block.Hash(), block.NumberU64(), receipts)
  1617  	}()
  1618  
  1619  	// Wait until all writing goroutines are terminated.
  1620  	parallelDBWriteWG.Wait()
  1621  	select {
  1622  	case err := <-parallelDBWriteErrCh:
  1623  		return WriteResult{Status: NonStatTy}, err
  1624  	default:
  1625  	}
  1626  
  1627  	// TODO-Klaytn-Issue264 If we are using istanbul BFT, then we always have a canonical chain.
  1628  	//         Later we may be able to refine below code.
  1629  
  1630  	// If the total blockscore is higher than our known, add it to the canonical chain
  1631  	// Second clause in the if statement reduces the vulnerability to selfish mining.
  1632  	// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
  1633  	currentBlock = bc.CurrentBlock()
  1634  	reorg := isReorganizationRequired(localTd, externTd, currentBlock, block)
  1635  	if reorg {
  1636  		// Reorganise the chain if the parent is not the head block
  1637  		if block.ParentHash() != currentBlock.Hash() {
  1638  			if err := bc.reorg(currentBlock, block); err != nil {
  1639  				return WriteResult{Status: NonStatTy}, err
  1640  			}
  1641  		}
  1642  
  1643  		parallelDBWriteWG.Add(2)
  1644  
  1645  		go func() {
  1646  			defer parallelDBWriteWG.Done()
  1647  			// Write the positional metadata for transaction/receipt lookups
  1648  			if err := bc.writeTxLookupEntries(block); err != nil {
  1649  				parallelDBWriteErrCh <- err
  1650  			}
  1651  		}()
  1652  
  1653  		go func() {
  1654  			defer parallelDBWriteWG.Done()
  1655  			bc.db.WritePreimages(block.NumberU64(), state.Preimages())
  1656  		}()
  1657  
  1658  		// Wait until all writing goroutines are terminated.
  1659  		parallelDBWriteWG.Wait()
  1660  
  1661  		status = CanonStatTy
  1662  	} else {
  1663  		status = SideStatTy
  1664  	}
  1665  
  1666  	select {
  1667  	case err := <-parallelDBWriteErrCh:
  1668  		return WriteResult{Status: NonStatTy}, err
  1669  	default:
  1670  	}
  1671  
  1672  	return bc.finalizeWriteBlockWithState(block, status, start, trieWriteTime)
  1673  }
  1674  
  1675  // finalizeWriteBlockWithState updates metrics and inserts block when status is CanonStatTy.
  1676  func (bc *BlockChain) finalizeWriteBlockWithState(block *types.Block, status WriteStatus, startTime time.Time, trieWriteTime time.Duration) (WriteResult, error) {
  1677  	// Set new head.
  1678  	if status == CanonStatTy {
  1679  		bc.insert(block)
  1680  		headBlockNumberGauge.Update(block.Number().Int64())
  1681  		blockTxCountsGauge.Update(int64(block.Transactions().Len()))
  1682  		blockTxCountsCounter.Inc(int64(block.Transactions().Len()))
  1683  	}
  1684  	bc.futureBlocks.Remove(block.Hash())
  1685  	return WriteResult{status, time.Since(startTime), trieWriteTime}, nil
  1686  }
  1687  
  1688  func (bc *BlockChain) writeTxLookupEntries(block *types.Block) error {
  1689  	return bc.db.WriteAndCacheTxLookupEntries(block)
  1690  }
  1691  
  1692  // GetTxAndLookupInfoInCache retrieves a tx and lookup info for a given transaction hash in cache.
  1693  func (bc *BlockChain) GetTxAndLookupInfoInCache(hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
  1694  	return bc.db.ReadTxAndLookupInfoInCache(hash)
  1695  }
  1696  
  1697  // GetBlockReceiptsInCache returns receipt of txHash in cache.
  1698  func (bc *BlockChain) GetBlockReceiptsInCache(blockHash common.Hash) types.Receipts {
  1699  	return bc.db.ReadBlockReceiptsInCache(blockHash)
  1700  }
  1701  
  1702  // GetTxReceiptInCache returns receipt of txHash in cache.
  1703  func (bc *BlockChain) GetTxReceiptInCache(txHash common.Hash) *types.Receipt {
  1704  	return bc.db.ReadTxReceiptInCache(txHash)
  1705  }
  1706  
  1707  // InsertChain attempts to insert the given batch of blocks in to the canonical
  1708  // chain or, otherwise, create a fork. If an error is returned it will return
  1709  // the index number of the failing block as well an error describing what went
  1710  // wrong.
  1711  //
  1712  // After insertion is done, all accumulated events will be fired.
  1713  func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
  1714  	n, events, logs, err := bc.insertChain(chain)
  1715  	bc.PostChainEvents(events, logs)
  1716  	return n, err
  1717  }
  1718  
  1719  // insertChain will execute the actual chain insertion and event aggregation. The
  1720  // only reason this method exists as a separate one is to make locking cleaner
  1721  // with deferred statements.
  1722  func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*types.Log, error) {
  1723  	// Sanity check that we have something meaningful to import
  1724  	if len(chain) == 0 {
  1725  		return 0, nil, nil, nil
  1726  	}
  1727  	// Do a sanity check that the provided chain is actually ordered and linked
  1728  	for i := 1; i < len(chain); i++ {
  1729  		if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() {
  1730  			// Chain broke ancestry, log a messge (programming error) and skip insertion
  1731  			logger.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(),
  1732  				"parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash())
  1733  
  1734  			return 0, nil, nil, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(),
  1735  				chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4])
  1736  		}
  1737  	}
  1738  
  1739  	// Pre-checks passed, start the full block imports
  1740  	bc.wg.Add(1)
  1741  	defer bc.wg.Done()
  1742  
  1743  	bc.mu.Lock()
  1744  	defer bc.mu.Unlock()
  1745  
  1746  	// A queued approach to delivering events. This is generally
  1747  	// faster than direct delivery and requires much less mutex
  1748  	// acquiring.
  1749  	var (
  1750  		stats         = insertStats{startTime: mclock.Now()}
  1751  		events        = make([]interface{}, 0, len(chain))
  1752  		lastCanon     *types.Block
  1753  		coalescedLogs []*types.Log
  1754  	)
  1755  	// Start the parallel header verifier
  1756  	headers := make([]*types.Header, len(chain))
  1757  	seals := make([]bool, len(chain))
  1758  
  1759  	for i, block := range chain {
  1760  		headers[i] = block.Header()
  1761  		seals[i] = true
  1762  	}
  1763  
  1764  	var (
  1765  		abort   chan<- struct{}
  1766  		results <-chan error
  1767  	)
  1768  	if bc.engine.CanVerifyHeadersConcurrently() {
  1769  		abort, results = bc.engine.VerifyHeaders(bc, headers, seals)
  1770  	} else {
  1771  		abort, results = bc.engine.PreprocessHeaderVerification(headers)
  1772  	}
  1773  	defer close(abort)
  1774  
  1775  	// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
  1776  	senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)
  1777  
  1778  	// Iterate over the blocks and insert when the verifier permits
  1779  	for i, block := range chain {
  1780  		// If the chain is terminating, stop processing blocks
  1781  		if atomic.LoadInt32(&bc.procInterrupt) == 1 {
  1782  			logger.Debug("Premature abort during blocks processing")
  1783  			break
  1784  		}
  1785  		// Create a new trie using the parent block and report an
  1786  		// error if it fails.
  1787  		var parent *types.Block
  1788  		if i == 0 {
  1789  			parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
  1790  		} else {
  1791  			parent = chain[i-1]
  1792  		}
  1793  
  1794  		// If we have a followup block, run that against the current state to pre-cache
  1795  		// transactions and probabilistically some of the account/storage trie nodes.
  1796  		var followupInterrupt uint32
  1797  
  1798  		if bc.cacheConfig.TrieNodeCacheConfig.NumFetcherPrefetchWorker > 0 && parent != nil {
  1799  			var snaps *snapshot.Tree
  1800  			if bc.cacheConfig.TrieNodeCacheConfig.UseSnapshotForPrefetch {
  1801  				snaps = bc.snaps
  1802  			}
  1803  
  1804  			// Tx prefetcher is enabled for all cases (both single and multiple block insertion).
  1805  			for ti := range block.Transactions() {
  1806  				select {
  1807  				case bc.prefetchTxCh <- prefetchTx{ti, block, &followupInterrupt}:
  1808  				default:
  1809  				}
  1810  			}
  1811  			if i < len(chain)-1 {
  1812  				// current block is not the last one, so prefetch the right next block
  1813  				followup := chain[i+1]
  1814  				go func(start time.Time) {
  1815  					defer func() {
  1816  						if err := recover(); err != nil {
  1817  							logger.Error("Got panic and recovered from prefetcher", "err", err)
  1818  						}
  1819  					}()
  1820  
  1821  					throwaway, err := state.NewForPrefetching(parent.Root(), bc.stateCache, snaps)
  1822  					if throwaway == nil || err != nil {
  1823  						logger.Warn("failed to get StateDB for prefetcher", "err", err,
  1824  							"parentBlockNum", parent.NumberU64(), "currBlockNum", bc.CurrentBlock().NumberU64())
  1825  						return
  1826  					}
  1827  
  1828  					vmCfg := bc.vmConfig
  1829  					vmCfg.Prefetching = true
  1830  					bc.prefetcher.Prefetch(followup, throwaway, vmCfg, &followupInterrupt)
  1831  
  1832  					blockPrefetchExecuteTimer.Update(time.Since(start))
  1833  					if atomic.LoadUint32(&followupInterrupt) == 1 {
  1834  						blockPrefetchInterruptMeter.Mark(1)
  1835  					}
  1836  				}(time.Now())
  1837  			}
  1838  		}
  1839  		// If the header is a banned one, straight out abort
  1840  		if BadHashes[block.Hash()] {
  1841  			bc.reportBlock(block, nil, ErrBlacklistedHash)
  1842  			return i, events, coalescedLogs, ErrBlacklistedHash
  1843  		}
  1844  		// Wait for the block's verification to complete
  1845  		bstart := time.Now()
  1846  
  1847  		err := <-results
  1848  		if !bc.engine.CanVerifyHeadersConcurrently() && err == nil {
  1849  			err = bc.engine.VerifyHeader(bc, block.Header(), true)
  1850  		}
  1851  
  1852  		if err == nil {
  1853  			err = bc.validator.ValidateBody(block)
  1854  		}
  1855  
  1856  		switch {
  1857  		case err == ErrKnownBlock:
  1858  			// Block and state both already known. However if the current block is below
  1859  			// this number we did a rollback and we should reimport it nonetheless.
  1860  			if bc.CurrentBlock().NumberU64() >= block.NumberU64() {
  1861  				stats.ignored++
  1862  				continue
  1863  			}
  1864  
  1865  		case err == consensus.ErrFutureBlock:
  1866  			// Allow up to MaxFuture second in the future blocks. If this limit is exceeded
  1867  			// the chain is discarded and processed at a later time if given.
  1868  			max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks)
  1869  			if block.Time().Cmp(max) > 0 {
  1870  				return i, events, coalescedLogs, fmt.Errorf("future block: %v > %v", block.Time(), max)
  1871  			}
  1872  			bc.futureBlocks.Add(block.Hash(), block)
  1873  			stats.queued++
  1874  			continue
  1875  
  1876  		case err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(block.ParentHash()):
  1877  			bc.futureBlocks.Add(block.Hash(), block)
  1878  			stats.queued++
  1879  			continue
  1880  
  1881  		case err == consensus.ErrPrunedAncestor:
  1882  			// Block competing with the canonical chain, store in the db, but don't process
  1883  			// until the competitor TD goes above the canonical TD
  1884  			currentBlock := bc.CurrentBlock()
  1885  			localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
  1886  			externTd := new(big.Int).Add(bc.GetTd(block.ParentHash(), block.NumberU64()-1), block.BlockScore())
  1887  			if localTd.Cmp(externTd) > 0 {
  1888  				bc.WriteBlockWithoutState(block, externTd)
  1889  				continue
  1890  			}
  1891  			// Competitor chain beat canonical, gather all blocks from the common ancestor
  1892  			var winner []*types.Block
  1893  
  1894  			parent := bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
  1895  			for !bc.HasState(parent.Root()) {
  1896  				winner = append(winner, parent)
  1897  				parent = bc.GetBlock(parent.ParentHash(), parent.NumberU64()-1)
  1898  			}
  1899  			for j := 0; j < len(winner)/2; j++ {
  1900  				winner[j], winner[len(winner)-1-j] = winner[len(winner)-1-j], winner[j]
  1901  			}
  1902  			// Import all the pruned blocks to make the state available
  1903  			bc.mu.Unlock()
  1904  			_, evs, logs, err := bc.insertChain(winner)
  1905  			bc.mu.Lock()
  1906  			events, coalescedLogs = evs, logs
  1907  
  1908  			if err != nil {
  1909  				return i, events, coalescedLogs, err
  1910  			}
  1911  
  1912  		case err != nil:
  1913  			bc.futureBlocks.Remove(block.Hash())
  1914  			bc.reportBlock(block, nil, err)
  1915  			return i, events, coalescedLogs, err
  1916  		}
  1917  
  1918  		stateDB, err := bc.StateAt(parent.Root())
  1919  		if err != nil {
  1920  			return i, events, coalescedLogs, err
  1921  		}
  1922  
  1923  		// Process block using the parent state as reference point.
  1924  		receipts, logs, usedGas, internalTxTraces, procStats, err := bc.processor.Process(block, stateDB, bc.vmConfig)
  1925  		if err != nil {
  1926  			bc.reportBlock(block, receipts, err)
  1927  			atomic.StoreUint32(&followupInterrupt, 1)
  1928  			return i, events, coalescedLogs, err
  1929  		}
  1930  
  1931  		// Validate the state using the default validator
  1932  		err = bc.validator.ValidateState(block, parent, stateDB, receipts, usedGas)
  1933  		if err != nil {
  1934  			bc.reportBlock(block, receipts, err)
  1935  			atomic.StoreUint32(&followupInterrupt, 1)
  1936  			return i, events, coalescedLogs, err
  1937  		}
  1938  		afterValidate := time.Now()
  1939  
  1940  		// Write the block to the chain and get the writeResult.
  1941  		writeResult, err := bc.writeBlockWithState(block, receipts, stateDB)
  1942  		if err != nil {
  1943  			atomic.StoreUint32(&followupInterrupt, 1)
  1944  			if err == ErrKnownBlock {
  1945  				logger.Debug("Tried to insert already known block", "num", block.NumberU64(), "hash", block.Hash().String())
  1946  				continue
  1947  			}
  1948  			return i, events, coalescedLogs, err
  1949  		}
  1950  		atomic.StoreUint32(&followupInterrupt, 1)
  1951  
  1952  		// Update to-address based spam throttler when spamThrottler is enabled and a single block is fetched.
  1953  		spamThrottler := GetSpamThrottler()
  1954  		if spamThrottler != nil && len(chain) == 1 {
  1955  			spamThrottler.updateThrottlerState(block.Transactions(), receipts)
  1956  		}
  1957  
  1958  		// Update the metrics subsystem with all the measurements
  1959  		accountReadTimer.Update(stateDB.AccountReads)
  1960  		accountHashTimer.Update(stateDB.AccountHashes)
  1961  		accountUpdateTimer.Update(stateDB.AccountUpdates)
  1962  		accountCommitTimer.Update(stateDB.AccountCommits)
  1963  
  1964  		storageReadTimer.Update(stateDB.StorageReads)
  1965  		storageHashTimer.Update(stateDB.StorageHashes)
  1966  		storageUpdateTimer.Update(stateDB.StorageUpdates)
  1967  		storageCommitTimer.Update(stateDB.StorageCommits)
  1968  
  1969  		snapshotAccountReadTimer.Update(stateDB.SnapshotAccountReads)
  1970  		snapshotStorageReadTimer.Update(stateDB.SnapshotStorageReads)
  1971  		snapshotCommitTimer.Update(stateDB.SnapshotCommits)
  1972  
  1973  		trieAccess := stateDB.AccountReads + stateDB.AccountHashes + stateDB.AccountUpdates + stateDB.AccountCommits
  1974  		trieAccess += stateDB.StorageReads + stateDB.StorageHashes + stateDB.StorageUpdates + stateDB.StorageCommits
  1975  
  1976  		blockAgeTimer.Update(time.Since(time.Unix(int64(block.Time().Uint64()), 0)))
  1977  
  1978  		switch writeResult.Status {
  1979  		case CanonStatTy:
  1980  			processTxsTime := common.PrettyDuration(procStats.AfterApplyTxs.Sub(procStats.BeforeApplyTxs))
  1981  			processFinalizeTime := common.PrettyDuration(procStats.AfterFinalize.Sub(procStats.AfterApplyTxs))
  1982  			validateTime := common.PrettyDuration(afterValidate.Sub(procStats.AfterFinalize))
  1983  			totalTime := common.PrettyDuration(time.Since(bstart))
  1984  			logger.Info("Inserted a new block", "number", block.Number(), "hash", block.Hash(),
  1985  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", totalTime,
  1986  				"processTxs", processTxsTime, "finalize", processFinalizeTime, "validateState", validateTime,
  1987  				"totalWrite", writeResult.TotalWriteTime, "trieWrite", writeResult.TrieWriteTime)
  1988  
  1989  			if block.Header().BaseFee != nil {
  1990  				blockBaseFee.Update(block.Header().BaseFee.Int64() / int64(params.Ston))
  1991  			}
  1992  			blockProcessTimer.Update(time.Duration(processTxsTime))
  1993  			blockExecutionTimer.Update(time.Duration(processTxsTime) - trieAccess)
  1994  			blockFinalizeTimer.Update(time.Duration(processFinalizeTime))
  1995  			blockValidateTimer.Update(time.Duration(validateTime))
  1996  			blockInsertTimer.Update(time.Duration(totalTime))
  1997  
  1998  			coalescedLogs = append(coalescedLogs, logs...)
  1999  			events = append(events, ChainEvent{
  2000  				Block:            block,
  2001  				Hash:             block.Hash(),
  2002  				Logs:             logs,
  2003  				Receipts:         receipts,
  2004  				InternalTxTraces: internalTxTraces,
  2005  			})
  2006  			lastCanon = block
  2007  
  2008  		case SideStatTy:
  2009  			logger.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), "diff", block.BlockScore(), "elapsed",
  2010  				common.PrettyDuration(time.Since(bstart)), "txs", len(block.Transactions()), "gas", block.GasUsed())
  2011  
  2012  			events = append(events, ChainSideEvent{block})
  2013  		}
  2014  		stats.processed++
  2015  		stats.usedGas += usedGas
  2016  
  2017  		cache, _, _ := bc.stateCache.TrieDB().Size()
  2018  		stats.report(chain, i, cache)
  2019  
  2020  		// update governance CurrentSet if it is at an epoch block
  2021  		if bc.engine.CreateSnapshot(bc, block.NumberU64(), block.Hash(), nil) != nil {
  2022  			return i, events, coalescedLogs, err
  2023  		}
  2024  	}
  2025  	// Append a single chain head event if we've progressed the chain
  2026  	if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
  2027  		events = append(events, ChainHeadEvent{lastCanon})
  2028  	}
  2029  	return 0, events, coalescedLogs, nil
  2030  }
  2031  
  2032  // BlockSubscriptionLoop subscribes blocks from a redis server and processes them.
  2033  // This method is only for KES nodes.
  2034  func (bc *BlockChain) BlockSubscriptionLoop(pool *TxPool) {
  2035  	var ch <-chan *redis.Message
  2036  	logger.Info("subscribe blocks from redis cache")
  2037  
  2038  	pubSub, ok := bc.stateCache.TrieDB().TrieNodeCache().(statedb.BlockPubSub)
  2039  	if !ok || pubSub == nil {
  2040  		logger.Crit("invalid block pub/sub configure", "trieNodeCacheConfig",
  2041  			bc.stateCache.TrieDB().GetTrieNodeCacheConfig())
  2042  	}
  2043  
  2044  	ch = pubSub.SubscribeBlockCh()
  2045  	if ch == nil {
  2046  		logger.Crit("failed to create redis subscription channel")
  2047  	}
  2048  
  2049  	for msg := range ch {
  2050  		logger.Debug("msg from redis subscription channel", "msg", msg.Payload)
  2051  
  2052  		blockRlp, err := hexutil.Decode(msg.Payload)
  2053  		if err != nil {
  2054  			logger.Error("failed to decode redis subscription msg", "msg", msg.Payload)
  2055  			continue
  2056  		}
  2057  
  2058  		block := &types.Block{}
  2059  		if err := rlp.DecodeBytes(blockRlp, block); err != nil {
  2060  			logger.Error("failed to rlp decode block", "msg", msg.Payload, "block", string(blockRlp))
  2061  			continue
  2062  		}
  2063  
  2064  		oldHead := bc.CurrentHeader()
  2065  		bc.replaceCurrentBlock(block)
  2066  		pool.lockedReset(oldHead, bc.CurrentHeader())
  2067  
  2068  		// just in case the block number jumps up more than one, iterates all missed blocks
  2069  		for blockNum := oldHead.Number.Uint64() + 1; blockNum < block.Number().Uint64(); blockNum++ {
  2070  			retrievedBlock := bc.GetBlockByNumber(blockNum)
  2071  			bc.sendKESSubscriptionData(retrievedBlock)
  2072  		}
  2073  		bc.sendKESSubscriptionData(block)
  2074  	}
  2075  
  2076  	logger.Info("closed the block subscription loop")
  2077  }
  2078  
  2079  // sendKESSubscriptionData sends data to chainFeed and logsFeed.
  2080  // ChainEvent containing only Block and Hash is sent to chainFeed.
  2081  // []*types.Log containing entire logs of a block is set to logsFeed.
  2082  // The logs are expected to be delivered from remote cache.
  2083  // If it failed to read log data from remote cache, it will read the data from database.
  2084  // This method is only for KES nodes.
  2085  func (bc *BlockChain) sendKESSubscriptionData(block *types.Block) {
  2086  	bc.chainFeed.Send(ChainEvent{
  2087  		Block: block,
  2088  		Hash:  block.Hash(),
  2089  		// TODO-Klaytn-KES: fill the following data if needed
  2090  		Receipts:         types.Receipts{},
  2091  		Logs:             []*types.Log{},
  2092  		InternalTxTraces: []*vm.InternalTxTrace{},
  2093  	})
  2094  
  2095  	// TODO-Klaytn-KES: refine this not to use trieNodeCache
  2096  	logKey := append(kesCachePrefixBlockLogs, block.Number().Bytes()...)
  2097  	encodedLogs := bc.stateCache.TrieDB().TrieNodeCache().Get(logKey)
  2098  	if encodedLogs == nil {
  2099  		logger.Warn("cannot get a block log from the remote cache", "blockNum", block.NumberU64())
  2100  
  2101  		// read log data from database and send it
  2102  		logsList := bc.GetLogsByHash(block.Header().Hash())
  2103  		var logs []*types.Log
  2104  		for _, list := range logsList {
  2105  			logs = append(logs, list...)
  2106  		}
  2107  		bc.logsFeed.Send(logs)
  2108  		return
  2109  	}
  2110  
  2111  	entireLogs := []*types.LogForStorage{}
  2112  	if err := rlp.DecodeBytes(encodedLogs, &entireLogs); err != nil {
  2113  		logger.Warn("failed to decode a block log", "blockNum", block.NumberU64(), "err", err)
  2114  
  2115  		// read log data from database and send it
  2116  		logsList := bc.GetLogsByHash(block.Header().Hash())
  2117  		var logs []*types.Log
  2118  		for _, list := range logsList {
  2119  			logs = append(logs, list...)
  2120  		}
  2121  		bc.logsFeed.Send(logs)
  2122  		return
  2123  	}
  2124  
  2125  	// convert LogForStorage to Log
  2126  	logs := make([]*types.Log, len(entireLogs))
  2127  	for i, log := range entireLogs {
  2128  		logs[i] = (*types.Log)(log)
  2129  	}
  2130  	bc.logsFeed.Send(logs)
  2131  }
  2132  
  2133  // CloseBlockSubscriptionLoop closes BlockSubscriptionLoop.
  2134  func (bc *BlockChain) CloseBlockSubscriptionLoop() {
  2135  	pubSub, ok := bc.stateCache.TrieDB().TrieNodeCache().(statedb.BlockPubSub)
  2136  	if ok {
  2137  		if err := pubSub.UnsubscribeBlock(); err != nil {
  2138  			logger.Error("failed to unsubscribe blocks", "err", err, "trieNodeCacheConfig",
  2139  				bc.stateCache.TrieDB().GetTrieNodeCacheConfig())
  2140  		}
  2141  	}
  2142  }
  2143  
  2144  // replaceCurrentBlock replaces bc.currentBlock to the given block.
  2145  func (bc *BlockChain) replaceCurrentBlock(latestBlock *types.Block) {
  2146  	bc.mu.Lock()
  2147  	defer bc.mu.Unlock()
  2148  
  2149  	if latestBlock == nil {
  2150  		logger.Error("no latest block")
  2151  		return
  2152  	}
  2153  
  2154  	// Don't update current block if the latest block is not newer than current block.
  2155  	currentBlock := bc.CurrentBlock()
  2156  	if currentBlock.NumberU64() >= latestBlock.NumberU64() {
  2157  		logger.Debug("ignore an old block", "currentBlockNumber", currentBlock.NumberU64(), "oldBlockNumber",
  2158  			latestBlock.NumberU64())
  2159  		return
  2160  	}
  2161  
  2162  	// Insert a new block and update metrics
  2163  	bc.insert(latestBlock)
  2164  	bc.hc.SetCurrentHeader(latestBlock.Header())
  2165  
  2166  	headBlockNumberGauge.Update(latestBlock.Number().Int64())
  2167  	blockTxCountsGauge.Update(int64(latestBlock.Transactions().Len()))
  2168  	blockTxCountsCounter.Inc(int64(latestBlock.Transactions().Len()))
  2169  	bc.stateCache.TrieDB().UpdateMetricNodes()
  2170  
  2171  	logger.Info("Replaced the current block",
  2172  		"blkNum", latestBlock.NumberU64(), "blkHash", latestBlock.Hash().String())
  2173  }
  2174  
  2175  // insertStats tracks and reports on block insertion.
  2176  type insertStats struct {
  2177  	queued, processed, ignored int
  2178  	usedGas                    uint64
  2179  	lastIndex                  int
  2180  	startTime                  mclock.AbsTime
  2181  }
  2182  
  2183  // report prints statistics if some number of blocks have been processed
  2184  // or more than a few seconds have passed since the last message.
  2185  func (st *insertStats) report(chain []*types.Block, index int, cache common.StorageSize) {
  2186  	// report will leave a log only if inserting two or more blocks at once
  2187  	if len(chain) <= 1 {
  2188  		return
  2189  	}
  2190  	// Fetch the timings for the batch
  2191  	var (
  2192  		now     = mclock.Now()
  2193  		elapsed = time.Duration(now) - time.Duration(st.startTime)
  2194  	)
  2195  	// If we're at the last block of the batch or report period reached, log
  2196  	if index == len(chain)-1 || elapsed >= log.StatsReportLimit {
  2197  		var (
  2198  			end = chain[index]
  2199  			txs = countTransactions(chain[st.lastIndex : index+1])
  2200  		)
  2201  		context := []interface{}{
  2202  			"number", end.Number(), "hash", end.Hash(), "blocks", st.processed, "txs", txs, "elapsed", common.PrettyDuration(elapsed),
  2203  			"trieDBSize", cache, "mgas", float64(st.usedGas) / 1000000, "mgasps", float64(st.usedGas) * 1000 / float64(elapsed),
  2204  		}
  2205  
  2206  		timestamp := time.Unix(int64(end.Time().Uint64()), 0)
  2207  		context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
  2208  
  2209  		if st.queued > 0 {
  2210  			context = append(context, []interface{}{"queued", st.queued}...)
  2211  		}
  2212  		if st.ignored > 0 {
  2213  			context = append(context, []interface{}{"ignored", st.ignored}...)
  2214  		}
  2215  		logger.Info("Imported new chain segment", context...)
  2216  
  2217  		*st = insertStats{startTime: now, lastIndex: index + 1}
  2218  	}
  2219  }
  2220  
  2221  func countTransactions(chain []*types.Block) (c int) {
  2222  	for _, b := range chain {
  2223  		c += len(b.Transactions())
  2224  	}
  2225  	return c
  2226  }
  2227  
  2228  // reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them
  2229  // to be part of the new canonical chain and accumulates potential missing transactions and post an
  2230  // event about them
  2231  func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
  2232  	var (
  2233  		newChain    types.Blocks
  2234  		oldChain    types.Blocks
  2235  		commonBlock *types.Block
  2236  		deletedTxs  types.Transactions
  2237  		deletedLogs []*types.Log
  2238  		// collectLogs collects the logs that were generated during the
  2239  		// processing of the block that corresponds with the given hash.
  2240  		// These logs are later announced as deleted.
  2241  		collectLogs = func(hash common.Hash) {
  2242  			// Coalesce logs and set 'Removed'.
  2243  			number := bc.GetBlockNumber(hash)
  2244  			if number == nil {
  2245  				return
  2246  			}
  2247  			receipts := bc.db.ReadReceipts(hash, *number)
  2248  			for _, receipt := range receipts {
  2249  				for _, log := range receipt.Logs {
  2250  					del := *log
  2251  					del.Removed = true
  2252  					deletedLogs = append(deletedLogs, &del)
  2253  				}
  2254  			}
  2255  		}
  2256  	)
  2257  
  2258  	// first reduce whoever is higher bound
  2259  	if oldBlock.NumberU64() > newBlock.NumberU64() {
  2260  		// reduce old chain
  2261  		for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
  2262  			oldChain = append(oldChain, oldBlock)
  2263  			deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
  2264  
  2265  			collectLogs(oldBlock.Hash())
  2266  		}
  2267  	} else {
  2268  		// reduce new chain and append new chain blocks for inserting later on
  2269  		for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) {
  2270  			newChain = append(newChain, newBlock)
  2271  		}
  2272  	}
  2273  	if oldBlock == nil {
  2274  		return fmt.Errorf("Invalid old chain")
  2275  	}
  2276  	if newBlock == nil {
  2277  		return fmt.Errorf("Invalid new chain")
  2278  	}
  2279  
  2280  	for {
  2281  		if oldBlock.Hash() == newBlock.Hash() {
  2282  			commonBlock = oldBlock
  2283  			break
  2284  		}
  2285  
  2286  		oldChain = append(oldChain, oldBlock)
  2287  		newChain = append(newChain, newBlock)
  2288  		deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
  2289  		collectLogs(oldBlock.Hash())
  2290  
  2291  		oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
  2292  		if oldBlock == nil {
  2293  			return fmt.Errorf("Invalid old chain")
  2294  		}
  2295  		if newBlock == nil {
  2296  			return fmt.Errorf("Invalid new chain")
  2297  		}
  2298  	}
  2299  	// Ensure the user sees large reorgs
  2300  	if len(oldChain) > 0 && len(newChain) > 0 {
  2301  		logFn := logger.Debug
  2302  		if len(oldChain) > 63 {
  2303  			logFn = logger.Warn
  2304  		}
  2305  		logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(),
  2306  			"drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash())
  2307  	} else {
  2308  		logger.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash())
  2309  	}
  2310  	// Insert the new chain, taking care of the proper incremental order
  2311  	var addedTxs types.Transactions
  2312  	for i := len(newChain) - 1; i >= 0; i-- {
  2313  		// insert the block in the canonical way, re-writing history
  2314  		bc.insert(newChain[i])
  2315  		// write lookup entries for hash based transaction/receipt searches
  2316  		bc.db.WriteTxLookupEntries(newChain[i])
  2317  		addedTxs = append(addedTxs, newChain[i].Transactions()...)
  2318  	}
  2319  	// calculate the difference between deleted and added transactions
  2320  	diff := types.TxDifference(deletedTxs, addedTxs)
  2321  	// When transactions get deleted from the database that means the
  2322  	// receipts that were created in the fork must also be deleted
  2323  	for _, tx := range diff {
  2324  		bc.db.DeleteTxLookupEntry(tx.Hash())
  2325  	}
  2326  	if len(deletedLogs) > 0 {
  2327  		go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
  2328  	}
  2329  	if len(oldChain) > 0 {
  2330  		go func() {
  2331  			for _, block := range oldChain {
  2332  				bc.chainSideFeed.Send(ChainSideEvent{Block: block})
  2333  			}
  2334  		}()
  2335  	}
  2336  
  2337  	return nil
  2338  }
  2339  
  2340  // PostChainEvents iterates over the events generated by a chain insertion and
  2341  // posts them into the event feed.
  2342  // TODO: Should not expose PostChainEvents. The chain events should be posted in WriteBlock.
  2343  func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) {
  2344  	// post event logs for further processing
  2345  	if logs != nil {
  2346  		bc.logsFeed.Send(logs)
  2347  	}
  2348  	for _, event := range events {
  2349  		switch ev := event.(type) {
  2350  		case ChainEvent:
  2351  			bc.chainFeed.Send(ev)
  2352  
  2353  		case ChainHeadEvent:
  2354  			bc.chainHeadFeed.Send(ev)
  2355  
  2356  		case ChainSideEvent:
  2357  			bc.chainSideFeed.Send(ev)
  2358  		}
  2359  	}
  2360  }
  2361  
  2362  func (bc *BlockChain) update() {
  2363  	futureTimer := time.NewTicker(5 * time.Second)
  2364  	defer futureTimer.Stop()
  2365  	for {
  2366  		select {
  2367  		case <-futureTimer.C:
  2368  			bc.procFutureBlocks()
  2369  		case <-bc.quit:
  2370  			return
  2371  		}
  2372  	}
  2373  }
  2374  
  2375  // BadBlockArgs represents the entries in the list returned when bad blocks are queried.
  2376  type BadBlockArgs struct {
  2377  	Hash  common.Hash  `json:"hash"`
  2378  	Block *types.Block `json:"block"`
  2379  }
  2380  
  2381  // BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network
  2382  func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) {
  2383  	blocks, err := bc.db.ReadAllBadBlocks()
  2384  	if err != nil {
  2385  		return nil, err
  2386  	}
  2387  	badBlockArgs := make([]BadBlockArgs, len(blocks))
  2388  	for i, block := range blocks {
  2389  		hash := block.Hash()
  2390  		badBlockArgs[i] = BadBlockArgs{Hash: hash, Block: block}
  2391  	}
  2392  	return badBlockArgs, err
  2393  }
  2394  
  2395  // istanbul BFT
  2396  func (bc *BlockChain) HasBadBlock(hash common.Hash) bool {
  2397  	badBlock := bc.db.ReadBadBlock(hash)
  2398  	if badBlock != nil {
  2399  		return true
  2400  	}
  2401  	return false
  2402  }
  2403  
  2404  // reportBlock logs a bad block error.
  2405  func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) {
  2406  	badBlockCounter.Inc(1)
  2407  	bc.db.WriteBadBlock(block)
  2408  
  2409  	var receiptString string
  2410  	for i, receipt := range receipts {
  2411  		receiptString += fmt.Sprintf("\t %d: tx: %v status: %v gas: %v contract: %v bloom: %x logs: %v\n",
  2412  			i, receipt.TxHash.Hex(), receipt.Status, receipt.GasUsed, receipt.ContractAddress.Hex(),
  2413  			receipt.Bloom, receipt.Logs)
  2414  	}
  2415  	logger.Error(fmt.Sprintf(`########## BAD BLOCK ######### Chain config: %v Number: %v Hash: 0x%x Receipt: %v Error: %v`, bc.chainConfig, block.Number(), block.Hash(), receiptString, err))
  2416  }
  2417  
  2418  // InsertHeaderChain attempts to insert the given header chain in to the local
  2419  // chain, possibly creating a reorg. If an error is returned, it will return the
  2420  // index number of the failing header as well an error describing what went wrong.
  2421  //
  2422  // The verify parameter can be used to fine tune whether nonce verification
  2423  // should be done or not. The reason behind the optional check is because some
  2424  // of the header retrieval mechanisms already need to verify nonces, as well as
  2425  // because nonces can be verified sparsely, not needing to check each.
  2426  func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
  2427  	start := time.Now()
  2428  	if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil {
  2429  		return i, err
  2430  	}
  2431  
  2432  	// Make sure only one thread manipulates the chain at once
  2433  	bc.mu.Lock()
  2434  	defer bc.mu.Unlock()
  2435  
  2436  	bc.wg.Add(1)
  2437  	defer bc.wg.Done()
  2438  
  2439  	whFunc := func(header *types.Header) error {
  2440  		_, err := bc.hc.WriteHeader(header)
  2441  		return err
  2442  	}
  2443  
  2444  	return bc.hc.InsertHeaderChain(chain, whFunc, start)
  2445  }
  2446  
  2447  // CurrentHeader retrieves the current head header of the canonical chain. The
  2448  // header is retrieved from the HeaderChain's internal cache.
  2449  func (bc *BlockChain) CurrentHeader() *types.Header {
  2450  	return bc.hc.CurrentHeader()
  2451  }
  2452  
  2453  // GetTd retrieves a block's total blockscore in the canonical chain from the
  2454  // database by hash and number, caching it if found.
  2455  func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
  2456  	return bc.hc.GetTd(hash, number)
  2457  }
  2458  
  2459  // GetTdByHash retrieves a block's total blockscore in the canonical chain from the
  2460  // database by hash, caching it if found.
  2461  func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int {
  2462  	return bc.hc.GetTdByHash(hash)
  2463  }
  2464  
  2465  // GetHeader retrieves a block header from the database by hash and number,
  2466  // caching it if found.
  2467  func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
  2468  	return bc.hc.GetHeader(hash, number)
  2469  }
  2470  
  2471  // GetHeaderByHash retrieves a block header from the database by hash, caching it if
  2472  // found.
  2473  func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
  2474  	return bc.hc.GetHeaderByHash(hash)
  2475  }
  2476  
  2477  // HasHeader checks if a block header is present in the database or not, caching
  2478  // it if present.
  2479  func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool {
  2480  	return bc.hc.HasHeader(hash, number)
  2481  }
  2482  
  2483  // GetBlockHashesFromHash retrieves a number of block hashes starting at a given
  2484  // hash, fetching towards the genesis block.
  2485  func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash {
  2486  	return bc.hc.GetBlockHashesFromHash(hash, max)
  2487  }
  2488  
  2489  // GetHeaderByNumber retrieves a block header from the database by number,
  2490  // caching it (associated with its hash) if found.
  2491  func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
  2492  	return bc.hc.GetHeaderByNumber(number)
  2493  }
  2494  
  2495  // Config retrieves the blockchain's chain configuration.
  2496  func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
  2497  
  2498  // Engine retrieves the blockchain's consensus engine.
  2499  func (bc *BlockChain) Engine() consensus.Engine { return bc.engine }
  2500  
  2501  // Snapshots returns the blockchain snapshot tree.
  2502  func (bc *BlockChain) Snapshots() *snapshot.Tree {
  2503  	return bc.snaps
  2504  }
  2505  
  2506  // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
  2507  func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
  2508  	return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))
  2509  }
  2510  
  2511  // SubscribeChainEvent registers a subscription of ChainEvent.
  2512  func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription {
  2513  	return bc.scope.Track(bc.chainFeed.Subscribe(ch))
  2514  }
  2515  
  2516  // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent.
  2517  func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
  2518  	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
  2519  }
  2520  
  2521  // SubscribeChainSideEvent registers a subscription of ChainSideEvent.
  2522  func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
  2523  	return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
  2524  }
  2525  
  2526  // SubscribeLogsEvent registers a subscription of []*types.Log.
  2527  func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
  2528  	return bc.scope.Track(bc.logsFeed.Subscribe(ch))
  2529  }
  2530  
  2531  // isArchiveMode returns whether current blockchain is in archiving mode or not.
  2532  // cacheConfig.ArchiveMode means trie caching is disabled.
  2533  func (bc *BlockChain) isArchiveMode() bool {
  2534  	return bc.cacheConfig.ArchiveMode
  2535  }
  2536  
  2537  // IsParallelDBWrite returns if parallel write is enabled or not.
  2538  // If enabled, data written in WriteBlockWithState is being written in parallel manner.
  2539  func (bc *BlockChain) IsParallelDBWrite() bool {
  2540  	return bc.parallelDBWrite
  2541  }
  2542  
  2543  // IsSenderTxHashIndexingEnabled returns if storing senderTxHash to txHash mapping information
  2544  // is enabled or not.
  2545  func (bc *BlockChain) IsSenderTxHashIndexingEnabled() bool {
  2546  	return bc.cacheConfig.SenderTxHashIndexing
  2547  }
  2548  
  2549  func (bc *BlockChain) SaveTrieNodeCacheToDisk() error {
  2550  	if err := bc.stateCache.TrieDB().CanSaveTrieNodeCacheToFile(); err != nil {
  2551  		return err
  2552  	}
  2553  	go bc.stateCache.TrieDB().SaveTrieNodeCacheToFile(bc.cacheConfig.TrieNodeCacheConfig.FastCacheFileDir, runtime.NumCPU()/2)
  2554  	return nil
  2555  }
  2556  
  2557  // ApplyTransaction attempts to apply a transaction to the given state database
  2558  // and uses the input parameters for its environment. It returns the receipt
  2559  // for the transaction, gas used and an error if the transaction failed,
  2560  // indicating the block was invalid.
  2561  func (bc *BlockChain) ApplyTransaction(chainConfig *params.ChainConfig, author *common.Address, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, vmConfig *vm.Config) (*types.Receipt, *vm.InternalTxTrace, error) {
  2562  	// TODO-Klaytn We reject transactions with unexpected gasPrice and do not put the transaction into TxPool.
  2563  	//         And we run transactions regardless of gasPrice if we push transactions in the TxPool.
  2564  	/*
  2565  		// istanbul BFT
  2566  		if tx.GasPrice() != nil && tx.GasPrice().Cmp(common.Big0) > 0 {
  2567  			return nil, uint64(0), ErrInvalidGasPrice
  2568  		}
  2569  	*/
  2570  
  2571  	blockNumber := header.Number.Uint64()
  2572  
  2573  	// validation for each transaction before execution
  2574  	if err := tx.Validate(statedb, blockNumber); err != nil {
  2575  		return nil, nil, err
  2576  	}
  2577  
  2578  	msg, err := tx.AsMessageWithAccountKeyPicker(types.MakeSigner(chainConfig, header.Number), statedb, blockNumber)
  2579  	if err != nil {
  2580  		return nil, nil, err
  2581  	}
  2582  	// Create a new context to be used in the EVM environment
  2583  	context := NewEVMContext(msg, header, bc, author)
  2584  	// Create a new environment which holds all relevant information
  2585  	// about the transaction and calling mechanisms.
  2586  	vmenv := vm.NewEVM(context, statedb, chainConfig, vmConfig)
  2587  	// Apply the transaction to the current state (included in the env)
  2588  	_, gas, kerr := ApplyMessage(vmenv, msg)
  2589  	err = kerr.ErrTxInvalid
  2590  	if err != nil {
  2591  		return nil, nil, err
  2592  	}
  2593  
  2594  	var internalTrace *vm.InternalTxTrace
  2595  	if vmConfig.EnableInternalTxTracing {
  2596  		internalTrace, err = GetInternalTxTrace(vmConfig.Tracer)
  2597  		if err != nil {
  2598  			logger.Error("failed to get tracing result from a transaction", "txHash", tx.Hash().String(), "err", err)
  2599  		}
  2600  	}
  2601  	// Update the state with pending changes
  2602  	statedb.Finalise(true, false)
  2603  	*usedGas += gas
  2604  
  2605  	receipt := types.NewReceipt(kerr.Status, tx.Hash(), gas)
  2606  	// if the transaction created a contract, store the creation address in the receipt.
  2607  	msg.FillContractAddress(vmenv.Context.Origin, receipt)
  2608  	// Set the receipt logs and create a bloom for filtering
  2609  	receipt.Logs = statedb.GetLogs(tx.Hash())
  2610  	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
  2611  
  2612  	return receipt, internalTrace, err
  2613  }
  2614  
  2615  func GetInternalTxTrace(tracer vm.Tracer) (*vm.InternalTxTrace, error) {
  2616  	var (
  2617  		internalTxTrace *vm.InternalTxTrace
  2618  		err             error
  2619  	)
  2620  	switch tracer := tracer.(type) {
  2621  	case *vm.InternalTxTracer:
  2622  		internalTxTrace, err = tracer.GetResult()
  2623  		if err != nil {
  2624  			return nil, err
  2625  		}
  2626  	default:
  2627  		logger.Error("To trace internal transactions, VM tracer type should be vm.InternalTxTracer", "actualType", reflect.TypeOf(tracer).String())
  2628  		return nil, ErrInvalidTracer
  2629  	}
  2630  	return internalTxTrace, nil
  2631  }
  2632  
  2633  // CheckBlockChainVersion checks the version of the current database and upgrade if possible.
  2634  func CheckBlockChainVersion(chainDB database.DBManager) error {
  2635  	bcVersion := chainDB.ReadDatabaseVersion()
  2636  	if bcVersion != nil && *bcVersion > BlockChainVersion {
  2637  		return fmt.Errorf("database version is v%d, Klaytn %s only supports v%d", *bcVersion, params.Version, BlockChainVersion)
  2638  	} else if bcVersion == nil || *bcVersion < BlockChainVersion {
  2639  		bcVersionStr := "N/A"
  2640  		if bcVersion != nil {
  2641  			bcVersionStr = strconv.Itoa(int(*bcVersion))
  2642  		}
  2643  		logger.Warn("Upgrade database version", "from", bcVersionStr, "to", BlockChainVersion)
  2644  		chainDB.WriteDatabaseVersion(BlockChainVersion)
  2645  	}
  2646  	return nil
  2647  }