github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/chain/core/blockchain.go (about)

     1  package core
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"math/big"
     8  	mrand "math/rand"
     9  	"sync"
    10  	"sync/atomic"
    11  	"time"
    12  
    13  	"github.com/neatio-net/neatio/chain/core/rawdb"
    14  
    15  	lru "github.com/hashicorp/golang-lru"
    16  	"github.com/neatio-net/neatio/chain/consensus"
    17  	"github.com/neatio-net/neatio/chain/core/state"
    18  	"github.com/neatio-net/neatio/chain/core/types"
    19  	"github.com/neatio-net/neatio/chain/core/vm"
    20  	"github.com/neatio-net/neatio/chain/log"
    21  	"github.com/neatio-net/neatio/chain/trie"
    22  	"github.com/neatio-net/neatio/neatdb"
    23  	"github.com/neatio-net/neatio/params"
    24  	"github.com/neatio-net/neatio/utilities/common"
    25  	"github.com/neatio-net/neatio/utilities/common/mclock"
    26  	"github.com/neatio-net/neatio/utilities/common/prque"
    27  	"github.com/neatio-net/neatio/utilities/crypto"
    28  	"github.com/neatio-net/neatio/utilities/event"
    29  	"github.com/neatio-net/neatio/utilities/metrics"
    30  	"github.com/neatio-net/neatio/utilities/rlp"
    31  )
    32  
    33  var (
    34  	blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil)
    35  
    36  	ErrNoGenesis = errors.New("Genesis not found in chain")
    37  )
    38  
    39  const (
    40  	bodyCacheLimit      = 256
    41  	blockCacheLimit     = 256
    42  	receiptsCacheLimit  = 32
    43  	maxFutureBlocks     = 256
    44  	maxTimeFutureBlocks = 30
    45  	badBlockLimit       = 10
    46  	triesInMemory       = 128
    47  
    48  	BlockChainVersion = 3
    49  
    50  	TimeForBanned  = 2 * time.Hour
    51  	BannedDuration = 24 * time.Hour
    52  )
    53  
    54  type CacheConfig struct {
    55  	TrieCleanLimit int
    56  
    57  	TrieDirtyLimit    int
    58  	TrieDirtyDisabled bool
    59  	TrieTimeLimit     time.Duration
    60  }
    61  
    62  type BlockChain struct {
    63  	chainConfig *params.ChainConfig
    64  	cacheConfig *CacheConfig
    65  
    66  	db     neatdb.Database
    67  	triegc *prque.Prque
    68  	gcproc time.Duration
    69  
    70  	hc                  *HeaderChain
    71  	rmLogsFeed          event.Feed
    72  	chainFeed           event.Feed
    73  	chainSideFeed       event.Feed
    74  	chainHeadFeed       event.Feed
    75  	logsFeed            event.Feed
    76  	createSideChainFeed event.Feed
    77  	startMiningFeed     event.Feed
    78  	stopMiningFeed      event.Feed
    79  
    80  	scope        event.SubscriptionScope
    81  	genesisBlock *types.Block
    82  
    83  	chainmu sync.RWMutex
    84  
    85  	currentBlock     atomic.Value
    86  	currentFastBlock atomic.Value
    87  
    88  	stateCache    state.Database
    89  	bodyCache     *lru.Cache
    90  	bodyRLPCache  *lru.Cache
    91  	receiptsCache *lru.Cache
    92  	blockCache    *lru.Cache
    93  	futureBlocks  *lru.Cache
    94  
    95  	quit    chan struct{}
    96  	running int32
    97  
    98  	procInterrupt int32
    99  	wg            sync.WaitGroup
   100  
   101  	engine    consensus.Engine
   102  	validator Validator
   103  	processor Processor
   104  	vmConfig  vm.Config
   105  
   106  	badBlocks *lru.Cache
   107  
   108  	cch    CrossChainHelper
   109  	logger log.Logger
   110  }
   111  
   112  func NewBlockChain(db neatdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, cch CrossChainHelper) (*BlockChain, error) {
   113  	if cacheConfig == nil {
   114  		cacheConfig = &CacheConfig{
   115  			TrieCleanLimit: 256,
   116  			TrieDirtyLimit: 256,
   117  			TrieTimeLimit:  5 * time.Minute,
   118  		}
   119  	}
   120  	bodyCache, _ := lru.New(bodyCacheLimit)
   121  	bodyRLPCache, _ := lru.New(bodyCacheLimit)
   122  	receiptsCache, _ := lru.New(receiptsCacheLimit)
   123  	blockCache, _ := lru.New(blockCacheLimit)
   124  	futureBlocks, _ := lru.New(maxFutureBlocks)
   125  	badBlocks, _ := lru.New(badBlockLimit)
   126  
   127  	bc := &BlockChain{
   128  		chainConfig:   chainConfig,
   129  		cacheConfig:   cacheConfig,
   130  		db:            db,
   131  		triegc:        prque.New(nil),
   132  		stateCache:    state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit),
   133  		quit:          make(chan struct{}),
   134  		bodyCache:     bodyCache,
   135  		bodyRLPCache:  bodyRLPCache,
   136  		receiptsCache: receiptsCache,
   137  		blockCache:    blockCache,
   138  		futureBlocks:  futureBlocks,
   139  		engine:        engine,
   140  		vmConfig:      vmConfig,
   141  		badBlocks:     badBlocks,
   142  		cch:           cch,
   143  		logger:        chainConfig.ChainLogger,
   144  	}
   145  	bc.validator = NewBlockValidator(chainConfig, bc, engine)
   146  	bc.processor = NewStateProcessor(chainConfig, bc, engine, cch)
   147  
   148  	var err error
   149  	bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt)
   150  	if err != nil {
   151  		return nil, err
   152  	}
   153  	bc.genesisBlock = bc.GetBlockByNumber(0)
   154  	if bc.genesisBlock == nil {
   155  		return nil, ErrNoGenesis
   156  	}
   157  	if err := bc.loadLastState(); err != nil {
   158  		return nil, err
   159  	}
   160  
   161  	for hash := range BadHashes {
   162  		if header := bc.GetHeaderByHash(hash); header != nil {
   163  
   164  			headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64())
   165  
   166  			if headerByNumber != nil && headerByNumber.Hash() == header.Hash() {
   167  				bc.logger.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash)
   168  				bc.SetHead(header.Number.Uint64() - 1)
   169  				bc.logger.Error("Chain rewind was successful, resuming normal operation")
   170  			}
   171  		}
   172  	}
   173  
   174  	go bc.update()
   175  	return bc, nil
   176  }
   177  
   178  func (bc *BlockChain) getProcInterrupt() bool {
   179  	return atomic.LoadInt32(&bc.procInterrupt) == 1
   180  }
   181  
   182  func (bc *BlockChain) loadLastState() error {
   183  
   184  	head := rawdb.ReadHeadBlockHash(bc.db)
   185  	if head == (common.Hash{}) {
   186  
   187  		bc.logger.Warn("Empty database, resetting chain")
   188  		return bc.Reset()
   189  	}
   190  
   191  	currentBlock := bc.GetBlockByHash(head)
   192  	if currentBlock == nil {
   193  
   194  		bc.logger.Warn("Head block missing, resetting chain", "hash", head)
   195  		return bc.Reset()
   196  	}
   197  
   198  	if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil {
   199  
   200  		bc.logger.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "err", err)
   201  		if err := bc.repair(&currentBlock); err != nil {
   202  			return err
   203  		}
   204  	}
   205  
   206  	bc.currentBlock.Store(currentBlock)
   207  
   208  	currentHeader := currentBlock.Header()
   209  	if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
   210  		if header := bc.GetHeaderByHash(head); header != nil {
   211  			currentHeader = header
   212  		}
   213  	}
   214  	bc.hc.SetCurrentHeader(currentHeader)
   215  
   216  	bc.currentFastBlock.Store(currentBlock)
   217  	if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) {
   218  		if block := bc.GetBlockByHash(head); block != nil {
   219  			bc.currentFastBlock.Store(block)
   220  		}
   221  	}
   222  
   223  	bc.logger.Info("Local chain block height is:", "Block", currentHeader.Number, "Hash", currentHeader.Hash())
   224  
   225  	return nil
   226  }
   227  
   228  func (bc *BlockChain) SetHead(head uint64) error {
   229  	bc.logger.Warn("Rewinding blockchain", "target", head)
   230  
   231  	bc.chainmu.Lock()
   232  	defer bc.chainmu.Unlock()
   233  
   234  	delFn := func(db neatdb.Writer, hash common.Hash, num uint64) {
   235  		rawdb.DeleteBody(db, hash, num)
   236  	}
   237  	bc.hc.SetHead(head, delFn)
   238  	currentHeader := bc.hc.CurrentHeader()
   239  
   240  	bc.bodyCache.Purge()
   241  	bc.bodyRLPCache.Purge()
   242  	bc.receiptsCache.Purge()
   243  	bc.blockCache.Purge()
   244  	bc.futureBlocks.Purge()
   245  
   246  	if currentBlock := bc.CurrentBlock(); currentBlock != nil && currentHeader.Number.Uint64() < currentBlock.NumberU64() {
   247  		bc.currentBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()))
   248  	}
   249  	if currentBlock := bc.CurrentBlock(); currentBlock != nil {
   250  		if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil {
   251  
   252  			bc.currentBlock.Store(bc.genesisBlock)
   253  		}
   254  	}
   255  
   256  	if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && currentHeader.Number.Uint64() < currentFastBlock.NumberU64() {
   257  		bc.currentFastBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()))
   258  	}
   259  
   260  	if currentBlock := bc.CurrentBlock(); currentBlock == nil {
   261  		bc.currentBlock.Store(bc.genesisBlock)
   262  	}
   263  	if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock == nil {
   264  		bc.currentFastBlock.Store(bc.genesisBlock)
   265  	}
   266  	currentBlock := bc.CurrentBlock()
   267  	currentFastBlock := bc.CurrentFastBlock()
   268  
   269  	rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash())
   270  	rawdb.WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash())
   271  
   272  	return bc.loadLastState()
   273  }
   274  
   275  func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
   276  
   277  	block := bc.GetBlockByHash(hash)
   278  	if block == nil {
   279  		return fmt.Errorf("non existent block [%x…]", hash[:4])
   280  	}
   281  	if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil {
   282  		return err
   283  	}
   284  
   285  	bc.chainmu.Lock()
   286  	bc.currentBlock.Store(block)
   287  	bc.chainmu.Unlock()
   288  
   289  	bc.logger.Info("Committed new head block", "number", block.Number(), "hash", hash)
   290  	return nil
   291  }
   292  
   293  func (bc *BlockChain) GasLimit() uint64 {
   294  	return bc.CurrentBlock().GasLimit()
   295  }
   296  
   297  func (bc *BlockChain) CurrentBlock() *types.Block {
   298  	return bc.currentBlock.Load().(*types.Block)
   299  }
   300  
   301  func (bc *BlockChain) CurrentFastBlock() *types.Block {
   302  	return bc.currentFastBlock.Load().(*types.Block)
   303  }
   304  
   305  func (bc *BlockChain) Validator() Validator {
   306  	return bc.validator
   307  }
   308  
   309  func (bc *BlockChain) Processor() Processor {
   310  	return bc.processor
   311  }
   312  
   313  func (bc *BlockChain) State() (*state.StateDB, error) {
   314  	return bc.StateAt(bc.CurrentBlock().Root())
   315  }
   316  
   317  func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
   318  	return state.New(root, bc.stateCache)
   319  }
   320  
   321  func (bc *BlockChain) StateCache() state.Database {
   322  	return bc.stateCache
   323  }
   324  
   325  func (bc *BlockChain) Reset() error {
   326  	return bc.ResetWithGenesisBlock(bc.genesisBlock)
   327  }
   328  
   329  func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
   330  
   331  	if err := bc.SetHead(0); err != nil {
   332  		return err
   333  	}
   334  	bc.chainmu.Lock()
   335  	defer bc.chainmu.Unlock()
   336  
   337  	if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil {
   338  		bc.logger.Crit("Failed to write genesis block TD", "err", err)
   339  	}
   340  	rawdb.WriteBlock(bc.db, genesis)
   341  
   342  	bc.genesisBlock = genesis
   343  	bc.insert(bc.genesisBlock)
   344  	bc.currentBlock.Store(bc.genesisBlock)
   345  	bc.hc.SetGenesis(bc.genesisBlock.Header())
   346  	bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
   347  	bc.currentFastBlock.Store(bc.genesisBlock)
   348  
   349  	return nil
   350  }
   351  
   352  func (bc *BlockChain) repair(head **types.Block) error {
   353  	for {
   354  
   355  		if _, err := state.New((*head).Root(), bc.stateCache); err == nil {
   356  			bc.logger.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash())
   357  			return nil
   358  		}
   359  
   360  		block := bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1)
   361  		if block == nil {
   362  			return fmt.Errorf("missing block %d [%x]", (*head).NumberU64()-1, (*head).ParentHash())
   363  		}
   364  		*head = block
   365  	}
   366  }
   367  
   368  func (bc *BlockChain) Export(w io.Writer) error {
   369  	return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64())
   370  }
   371  
   372  func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
   373  	bc.chainmu.RLock()
   374  	defer bc.chainmu.RUnlock()
   375  
   376  	if first > last {
   377  		return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last)
   378  	}
   379  	bc.logger.Info("Exporting batch of blocks", "count", last-first+1)
   380  
   381  	for nr := first; nr <= last; nr++ {
   382  		block := bc.GetBlockByNumber(nr)
   383  		if block == nil {
   384  			return fmt.Errorf("export failed on #%d: not found", nr)
   385  		}
   386  
   387  		if err := block.EncodeRLP(w); err != nil {
   388  			return err
   389  		}
   390  	}
   391  
   392  	return nil
   393  }
   394  
   395  func (bc *BlockChain) insert(block *types.Block) {
   396  
   397  	updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash()
   398  
   399  	rawdb.WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64())
   400  	rawdb.WriteHeadBlockHash(bc.db, block.Hash())
   401  
   402  	bc.currentBlock.Store(block)
   403  
   404  	if updateHeads {
   405  		bc.hc.SetCurrentHeader(block.Header())
   406  		rawdb.WriteHeadFastBlockHash(bc.db, block.Hash())
   407  
   408  		bc.currentFastBlock.Store(block)
   409  	}
   410  
   411  	ibCbMap := GetInsertBlockCbMap()
   412  	for _, cb := range ibCbMap {
   413  		cb(bc, block)
   414  	}
   415  }
   416  
   417  func (bc *BlockChain) Genesis() *types.Block {
   418  	return bc.genesisBlock
   419  }
   420  
   421  func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
   422  
   423  	if cached, ok := bc.bodyCache.Get(hash); ok {
   424  		body := cached.(*types.Body)
   425  		return body
   426  	}
   427  	number := bc.hc.GetBlockNumber(hash)
   428  	if number == nil {
   429  		return nil
   430  	}
   431  	body := rawdb.ReadBody(bc.db, hash, *number)
   432  	if body == nil {
   433  		return nil
   434  	}
   435  
   436  	bc.bodyCache.Add(hash, body)
   437  	return body
   438  }
   439  
   440  func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
   441  
   442  	if cached, ok := bc.bodyRLPCache.Get(hash); ok {
   443  		return cached.(rlp.RawValue)
   444  	}
   445  	number := bc.hc.GetBlockNumber(hash)
   446  	if number == nil {
   447  		return nil
   448  	}
   449  	body := rawdb.ReadBodyRLP(bc.db, hash, *number)
   450  	if len(body) == 0 {
   451  		return nil
   452  	}
   453  
   454  	bc.bodyRLPCache.Add(hash, body)
   455  	return body
   456  }
   457  
   458  func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
   459  	if bc.blockCache.Contains(hash) {
   460  		return true
   461  	}
   462  	return rawdb.HasBody(bc.db, hash, number)
   463  }
   464  
   465  func (bc *BlockChain) HasState(hash common.Hash) bool {
   466  	_, err := bc.stateCache.OpenTrie(hash)
   467  	return err == nil
   468  }
   469  
   470  func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
   471  
   472  	block := bc.GetBlock(hash, number)
   473  	if block == nil {
   474  		return false
   475  	}
   476  	return bc.HasState(block.Root())
   477  }
   478  
   479  func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
   480  
   481  	if block, ok := bc.blockCache.Get(hash); ok {
   482  		return block.(*types.Block)
   483  	}
   484  	block := rawdb.ReadBlock(bc.db, hash, number)
   485  	if block == nil {
   486  		return nil
   487  	}
   488  
   489  	bc.blockCache.Add(block.Hash(), block)
   490  	return block
   491  }
   492  
   493  func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
   494  	number := bc.hc.GetBlockNumber(hash)
   495  	if number == nil {
   496  		return nil
   497  	}
   498  	return bc.GetBlock(hash, *number)
   499  }
   500  
   501  func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
   502  	hash := rawdb.ReadCanonicalHash(bc.db, number)
   503  	if hash == (common.Hash{}) {
   504  		return nil
   505  	}
   506  	return bc.GetBlock(hash, number)
   507  }
   508  
   509  func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
   510  	if receipts, ok := bc.receiptsCache.Get(hash); ok {
   511  		return receipts.(types.Receipts)
   512  	}
   513  	number := rawdb.ReadHeaderNumber(bc.db, hash)
   514  	if number == nil {
   515  		return nil
   516  	}
   517  	receipts := rawdb.ReadReceipts(bc.db, hash, *number)
   518  	if receipts == nil {
   519  		return nil
   520  	}
   521  	bc.receiptsCache.Add(hash, receipts)
   522  	return receipts
   523  }
   524  
   525  func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
   526  	number := bc.hc.GetBlockNumber(hash)
   527  	if number == nil {
   528  		return nil
   529  	}
   530  	for i := 0; i < n; i++ {
   531  		block := bc.GetBlock(hash, *number)
   532  		if block == nil {
   533  			break
   534  		}
   535  		blocks = append(blocks, block)
   536  		hash = block.ParentHash()
   537  		*number--
   538  	}
   539  	return
   540  }
   541  
   542  func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header {
   543  	uncles := []*types.Header{}
   544  	for i := 0; block != nil && i < length; i++ {
   545  		uncles = append(uncles, block.Uncles()...)
   546  		block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
   547  	}
   548  	return uncles
   549  }
   550  
   551  func (bc *BlockChain) ValidateBlock(block *types.Block) (*state.StateDB, types.Receipts, *types.PendingOps, error) {
   552  
   553  	if BadHashes[block.Hash()] {
   554  		return nil, nil, nil, ErrBlacklistedHash
   555  	}
   556  
   557  	if err := bc.engine.(consensus.NeatCon).VerifyHeaderBeforeConsensus(bc, block.Header(), true); err != nil {
   558  		return nil, nil, nil, err
   559  	}
   560  
   561  	if err := bc.Validator().ValidateBody(block); err != nil {
   562  		log.Debugf("ValidateBlock-ValidateBody return with error: %v", err)
   563  		return nil, nil, nil, err
   564  	}
   565  
   566  	var parent *types.Block
   567  	parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
   568  	state, err := state.New(parent.Root(), bc.stateCache)
   569  	if err != nil {
   570  		log.Debugf("ValidateBlock-state.New return with error: %v", err)
   571  		return nil, nil, nil, err
   572  	}
   573  
   574  	receipts, _, usedGas, ops, err := bc.processor.Process(block, state, bc.vmConfig)
   575  	if err != nil {
   576  		log.Debugf("ValidateBlock-Process return with error: %v", err)
   577  		return nil, nil, nil, err
   578  	}
   579  
   580  	err = bc.Validator().ValidateState(block, state, receipts, usedGas)
   581  	if err != nil {
   582  		log.Debugf("ValidateBlock-ValidateState return with error: %v", err)
   583  		return nil, nil, nil, err
   584  	}
   585  
   586  	return state, receipts, ops, nil
   587  }
   588  
   589  func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) {
   590  	return bc.stateCache.TrieDB().Node(hash)
   591  }
   592  
   593  func (bc *BlockChain) Stop() {
   594  	if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
   595  		return
   596  	}
   597  
   598  	bc.scope.Close()
   599  	close(bc.quit)
   600  	atomic.StoreInt32(&bc.procInterrupt, 1)
   601  
   602  	bc.wg.Wait()
   603  
   604  	if !bc.cacheConfig.TrieDirtyDisabled {
   605  		triedb := bc.stateCache.TrieDB()
   606  
   607  		for _, offset := range []uint64{0, 1, triesInMemory - 1} {
   608  			if number := bc.CurrentBlock().NumberU64(); number > offset {
   609  				recent := bc.GetBlockByNumber(number - offset)
   610  
   611  				bc.logger.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
   612  				if err := triedb.Commit(recent.Root(), true); err != nil {
   613  					bc.logger.Error("Failed to commit recent state trie", "err", err)
   614  				}
   615  			}
   616  		}
   617  		for !bc.triegc.Empty() {
   618  			triedb.Dereference(bc.triegc.PopItem().(common.Hash))
   619  		}
   620  		if size, _ := triedb.Size(); size != 0 {
   621  			bc.logger.Error("Dangling trie nodes after full cleanup")
   622  		}
   623  	}
   624  	bc.logger.Info("Blockchain manager stopped")
   625  }
   626  
   627  func (bc *BlockChain) procFutureBlocks() {
   628  	blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
   629  	for _, hash := range bc.futureBlocks.Keys() {
   630  		if block, exist := bc.futureBlocks.Peek(hash); exist {
   631  			blocks = append(blocks, block.(*types.Block))
   632  		}
   633  	}
   634  	if len(blocks) > 0 {
   635  		types.BlockBy(types.Number).Sort(blocks)
   636  
   637  		for i := range blocks {
   638  			bc.InsertChain(blocks[i : i+1])
   639  		}
   640  	}
   641  }
   642  
   643  type WriteStatus byte
   644  
   645  const (
   646  	NonStatTy WriteStatus = iota
   647  	CanonStatTy
   648  	SideStatTy
   649  )
   650  
   651  func (bc *BlockChain) Rollback(chain []common.Hash) {
   652  	bc.chainmu.Lock()
   653  	defer bc.chainmu.Unlock()
   654  
   655  	for i := len(chain) - 1; i >= 0; i-- {
   656  		hash := chain[i]
   657  
   658  		currentHeader := bc.hc.CurrentHeader()
   659  		if currentHeader.Hash() == hash {
   660  			bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1))
   661  		}
   662  		if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash {
   663  			newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1)
   664  			bc.currentFastBlock.Store(newFastBlock)
   665  			rawdb.WriteHeadFastBlockHash(bc.db, newFastBlock.Hash())
   666  		}
   667  		if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash {
   668  			newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1)
   669  			bc.currentBlock.Store(newBlock)
   670  			rawdb.WriteHeadBlockHash(bc.db, newBlock.Hash())
   671  		}
   672  	}
   673  }
   674  
   675  func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) error {
   676  	signer := types.MakeSigner(config, block.Number())
   677  
   678  	transactions, logIndex := block.Transactions(), uint(0)
   679  	if len(transactions) != len(receipts) {
   680  		return errors.New("transaction and receipt count mismatch")
   681  	}
   682  
   683  	for j := 0; j < len(receipts); j++ {
   684  
   685  		receipts[j].TxHash = transactions[j].Hash()
   686  
   687  		receipts[j].BlockHash = block.Hash()
   688  		receipts[j].BlockNumber = block.Number()
   689  		receipts[j].TransactionIndex = uint(j)
   690  
   691  		if transactions[j].To() == nil {
   692  
   693  			from, _ := types.Sender(signer, transactions[j])
   694  			receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce())
   695  		}
   696  
   697  		if j == 0 {
   698  			receipts[j].GasUsed = receipts[j].CumulativeGasUsed
   699  		} else {
   700  			receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed
   701  		}
   702  
   703  		for k := 0; k < len(receipts[j].Logs); k++ {
   704  			receipts[j].Logs[k].BlockNumber = block.NumberU64()
   705  			receipts[j].Logs[k].BlockHash = block.Hash()
   706  			receipts[j].Logs[k].TxHash = receipts[j].TxHash
   707  			receipts[j].Logs[k].TxIndex = uint(j)
   708  			receipts[j].Logs[k].Index = logIndex
   709  			logIndex++
   710  		}
   711  	}
   712  	return nil
   713  }
   714  
   715  func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) {
   716  	bc.wg.Add(1)
   717  	defer bc.wg.Done()
   718  
   719  	for i := 1; i < len(blockChain); i++ {
   720  		if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() {
   721  			bc.logger.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(),
   722  				"prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash())
   723  			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(),
   724  				blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4])
   725  		}
   726  	}
   727  
   728  	var (
   729  		stats = struct{ processed, ignored int32 }{}
   730  		start = time.Now()
   731  		bytes = 0
   732  		batch = bc.db.NewBatch()
   733  	)
   734  	for i, block := range blockChain {
   735  		receipts := receiptChain[i]
   736  
   737  		if atomic.LoadInt32(&bc.procInterrupt) == 1 {
   738  			return 0, nil
   739  		}
   740  
   741  		if !bc.HasHeader(block.Hash(), block.NumberU64()) {
   742  			return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
   743  		}
   744  
   745  		if bc.HasBlock(block.Hash(), block.NumberU64()) {
   746  			stats.ignored++
   747  			continue
   748  		}
   749  
   750  		if err := SetReceiptsData(bc.chainConfig, block, receipts); err != nil {
   751  			return i, fmt.Errorf("failed to set receipts data: %v", err)
   752  		}
   753  
   754  		rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
   755  		rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts)
   756  		rawdb.WriteTxLookupEntries(batch, block)
   757  
   758  		stats.processed++
   759  
   760  		if batch.ValueSize() >= neatdb.IdealBatchSize {
   761  			if err := batch.Write(); err != nil {
   762  				return 0, err
   763  			}
   764  			bytes += batch.ValueSize()
   765  			batch.Reset()
   766  		}
   767  	}
   768  	if batch.ValueSize() > 0 {
   769  		bytes += batch.ValueSize()
   770  		if err := batch.Write(); err != nil {
   771  			return 0, err
   772  		}
   773  	}
   774  
   775  	bc.chainmu.Lock()
   776  	head := blockChain[len(blockChain)-1]
   777  	if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil {
   778  		currentFastBlock := bc.CurrentFastBlock()
   779  		if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 {
   780  			rawdb.WriteHeadFastBlockHash(bc.db, head.Hash())
   781  			bc.currentFastBlock.Store(head)
   782  		}
   783  	}
   784  	bc.chainmu.Unlock()
   785  
   786  	bc.logger.Info("Imported new block receipts",
   787  		"count", stats.processed,
   788  		"elapsed", common.PrettyDuration(time.Since(start)),
   789  		"number", head.Number(),
   790  		"hash", head.Hash(),
   791  		"size", common.StorageSize(bytes),
   792  		"ignored", stats.ignored)
   793  	return 0, nil
   794  }
   795  
   796  var lastWrite uint64
   797  
   798  func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (err error) {
   799  	bc.wg.Add(1)
   800  	defer bc.wg.Done()
   801  
   802  	if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), td); err != nil {
   803  		return err
   804  	}
   805  	rawdb.WriteBlock(bc.db, block)
   806  
   807  	return nil
   808  }
   809  
   810  func (bc *BlockChain) MuLock() {
   811  	bc.chainmu.Lock()
   812  }
   813  
   814  func (bc *BlockChain) MuUnLock() {
   815  	bc.chainmu.Unlock()
   816  }
   817  
   818  func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) {
   819  
   820  	return bc.writeBlockWithState(block, receipts, state)
   821  }
   822  
   823  func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) {
   824  	bc.wg.Add(1)
   825  	defer bc.wg.Done()
   826  
   827  	if bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
   828  		bc.insert(block)
   829  		bc.futureBlocks.Remove(block.Hash())
   830  		return CanonStatTy, nil
   831  	}
   832  
   833  	ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
   834  	if ptd == nil {
   835  		return NonStatTy, consensus.ErrUnknownAncestor
   836  	}
   837  
   838  	currentBlock := bc.CurrentBlock()
   839  	localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
   840  	externTd := new(big.Int).Add(block.Difficulty(), ptd)
   841  
   842  	if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil {
   843  		return NonStatTy, err
   844  	}
   845  	rawdb.WriteBlock(bc.db, block)
   846  
   847  	root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number()))
   848  	if err != nil {
   849  		return NonStatTy, err
   850  	}
   851  	triedb := bc.stateCache.TrieDB()
   852  
   853  	nc := bc.Engine().(consensus.NeatCon)
   854  	FORCEFULSHWINDOW := uint64(5)
   855  	curBlockNumber := block.NumberU64()
   856  	curEpoch := nc.GetEpoch().GetEpochByBlockNumber(curBlockNumber)
   857  	withinEpochSwitchWindow := curBlockNumber < curEpoch.StartBlock+FORCEFULSHWINDOW || curBlockNumber > curEpoch.EndBlock-FORCEFULSHWINDOW
   858  
   859  	FLUSHBLOCKSINTERVAL := uint64(5000)
   860  	meetFlushBlockInterval := curBlockNumber%FLUSHBLOCKSINTERVAL == 0
   861  
   862  	if withinEpochSwitchWindow || bc.cacheConfig.TrieDirtyDisabled || meetFlushBlockInterval {
   863  		if err := triedb.Commit(root, false); err != nil {
   864  			return NonStatTy, err
   865  		}
   866  	} else {
   867  
   868  		triedb.Reference(root, common.Hash{})
   869  		bc.triegc.Push(root, -int64(block.NumberU64()))
   870  
   871  		if current := block.NumberU64(); current > triesInMemory {
   872  
   873  			var (
   874  				nodes, imgs = triedb.Size()
   875  				limit       = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
   876  			)
   877  			if nodes > limit || imgs > 4*1024*1024 {
   878  				triedb.Cap(limit - neatdb.IdealBatchSize)
   879  			}
   880  
   881  			chosen := current - triesInMemory
   882  
   883  			if bc.gcproc > bc.cacheConfig.TrieTimeLimit {
   884  
   885  				header := bc.GetHeaderByNumber(chosen)
   886  				if header == nil {
   887  					log.Warn("Reorg in progress, trie commit postponed", "number", chosen)
   888  				} else {
   889  
   890  					if chosen < lastWrite+triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit {
   891  						log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory)
   892  					}
   893  
   894  					triedb.Commit(header.Root, true)
   895  					lastWrite = chosen
   896  					bc.gcproc = 0
   897  				}
   898  			}
   899  
   900  			for !bc.triegc.Empty() {
   901  				root, number := bc.triegc.Pop()
   902  				if uint64(-number) > chosen {
   903  					bc.triegc.Push(root, number)
   904  					break
   905  				}
   906  				triedb.Dereference(root.(common.Hash))
   907  			}
   908  		}
   909  	}
   910  
   911  	batch := bc.db.NewBatch()
   912  	rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts)
   913  
   914  	var reorg bool
   915  	if _, ok := bc.engine.(consensus.NeatCon); ok {
   916  
   917  		reorg = true
   918  	} else {
   919  
   920  		reorg := externTd.Cmp(localTd) > 0
   921  		currentBlock = bc.CurrentBlock()
   922  		if !reorg && externTd.Cmp(localTd) == 0 {
   923  
   924  			reorg = block.NumberU64() < currentBlock.NumberU64() || (block.NumberU64() == currentBlock.NumberU64() && mrand.Float64() < 0.5)
   925  		}
   926  	}
   927  	if reorg {
   928  
   929  		if block.ParentHash() != currentBlock.Hash() {
   930  			if err := bc.reorg(currentBlock, block); err != nil {
   931  				return NonStatTy, err
   932  			}
   933  		}
   934  
   935  		rawdb.WriteTxLookupEntries(batch, block)
   936  		rawdb.WritePreimages(batch, state.Preimages())
   937  
   938  		status = CanonStatTy
   939  	} else {
   940  		status = SideStatTy
   941  	}
   942  	if err := batch.Write(); err != nil {
   943  		return NonStatTy, err
   944  	}
   945  
   946  	if status == CanonStatTy {
   947  		bc.insert(block)
   948  	}
   949  	bc.futureBlocks.Remove(block.Hash())
   950  	return status, nil
   951  }
   952  
   953  func (bc *BlockChain) addFutureBlock(block *types.Block) error {
   954  	max := uint64(time.Now().Unix() + maxTimeFutureBlocks)
   955  	if block.Time() > max {
   956  		return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max)
   957  	}
   958  	bc.futureBlocks.Add(block.Hash(), block)
   959  	return nil
   960  }
   961  
   962  func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
   963  
   964  	if len(chain) == 0 {
   965  		return 0, nil
   966  	}
   967  
   968  	var (
   969  		block, prev *types.Block
   970  	)
   971  
   972  	for i := 1; i < len(chain); i++ {
   973  		block = chain[i]
   974  		prev = chain[i-1]
   975  		if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() {
   976  
   977  			log.Error("Non contiguous block insert", "number", block.Number(), "hash", block.Hash(),
   978  				"parent", block.ParentHash(), "prevnumber", prev.Number(), "prevhash", prev.Hash())
   979  
   980  			return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, prev.NumberU64(),
   981  				prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4])
   982  		}
   983  	}
   984  
   985  	bc.wg.Add(1)
   986  	bc.chainmu.Lock()
   987  	n, events, logs, err := bc.insertChain(chain, true)
   988  	bc.chainmu.Unlock()
   989  	bc.wg.Done()
   990  
   991  	bc.PostChainEvents(events, logs)
   992  	return n, err
   993  }
   994  
   995  func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []interface{}, []*types.Log, error) {
   996  
   997  	if atomic.LoadInt32(&bc.procInterrupt) == 1 {
   998  		return 0, nil, nil, nil
   999  	}
  1000  
  1001  	var (
  1002  		stats         = insertStats{startTime: mclock.Now()}
  1003  		events        = make([]interface{}, 0, len(chain))
  1004  		lastCanon     *types.Block
  1005  		coalescedLogs []*types.Log
  1006  	)
  1007  
  1008  	headers := make([]*types.Header, len(chain))
  1009  	seals := make([]bool, len(chain))
  1010  
  1011  	for i, block := range chain {
  1012  		headers[i] = block.Header()
  1013  		seals[i] = verifySeals
  1014  	}
  1015  
  1016  	abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
  1017  	defer close(abort)
  1018  
  1019  	it := newInsertIterator(chain, results, bc.validator)
  1020  
  1021  	block, err := it.next()
  1022  
  1023  	if err == ErrKnownBlock {
  1024  
  1025  		current := bc.CurrentBlock().NumberU64()
  1026  		for block != nil && err == ErrKnownBlock {
  1027  			if current >= block.NumberU64() {
  1028  				stats.ignored++
  1029  				block, err = it.next()
  1030  			} else {
  1031  				log.Infof("this block has been written, but head not refreshed. hash %x, number %v\n",
  1032  					block.Hash(), block.NumberU64())
  1033  
  1034  				err = nil
  1035  				break
  1036  			}
  1037  		}
  1038  
  1039  	}
  1040  
  1041  	switch {
  1042  
  1043  	case err == consensus.ErrPrunedAncestor:
  1044  		return bc.insertSidechain(block, it)
  1045  
  1046  	case err == consensus.ErrFutureBlock || (err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(it.first().ParentHash())):
  1047  		for block != nil && (it.index == 0 || err == consensus.ErrUnknownAncestor) {
  1048  			if err := bc.addFutureBlock(block); err != nil {
  1049  				return it.index, events, coalescedLogs, err
  1050  			}
  1051  			block, err = it.next()
  1052  		}
  1053  		stats.queued += it.processed()
  1054  		stats.ignored += it.remaining()
  1055  
  1056  		return it.index, events, coalescedLogs, err
  1057  
  1058  	case err != nil:
  1059  		stats.ignored += len(it.chain)
  1060  		bc.reportBlock(block, nil, err)
  1061  		return it.index, events, coalescedLogs, err
  1062  	}
  1063  
  1064  	for ; block != nil && err == nil; block, err = it.next() {
  1065  
  1066  		if atomic.LoadInt32(&bc.procInterrupt) == 1 {
  1067  			bc.logger.Debug("Premature abort during blocks processing")
  1068  			break
  1069  		}
  1070  
  1071  		if BadHashes[block.Hash()] {
  1072  			bc.reportBlock(block, nil, ErrBlacklistedHash)
  1073  			return it.index, events, coalescedLogs, ErrBlacklistedHash
  1074  		}
  1075  
  1076  		start := time.Now()
  1077  
  1078  		parent := it.previous()
  1079  		if parent == nil {
  1080  			parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
  1081  		}
  1082  		statedb, err := state.New(parent.Root, bc.stateCache)
  1083  		if err != nil {
  1084  			return it.index, events, coalescedLogs, err
  1085  		}
  1086  
  1087  		receipts, logs, usedGas, ops, err := bc.processor.Process(block, statedb, bc.vmConfig)
  1088  		if err != nil {
  1089  			bc.reportBlock(block, receipts, err)
  1090  			return it.index, events, coalescedLogs, err
  1091  		}
  1092  
  1093  		err = bc.Validator().ValidateState(block, statedb, receipts, usedGas)
  1094  		if err != nil {
  1095  			bc.reportBlock(block, receipts, err)
  1096  			return it.index, events, coalescedLogs, err
  1097  		}
  1098  		proctime := time.Since(start)
  1099  
  1100  		status, err := bc.writeBlockWithState(block, receipts, statedb)
  1101  		if err != nil {
  1102  			return it.index, events, coalescedLogs, err
  1103  		}
  1104  
  1105  		for _, op := range ops.Ops() {
  1106  			if err := ApplyOp(op, bc, bc.cch); err != nil {
  1107  				bc.logger.Error("Failed executing op", op, "err", err)
  1108  			}
  1109  		}
  1110  
  1111  		blockInsertTimer.UpdateSince(start)
  1112  
  1113  		switch status {
  1114  		case CanonStatTy:
  1115  			bc.logger.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(),
  1116  				"uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(),
  1117  				"elapsed", common.PrettyDuration(time.Since(start)),
  1118  				"root", block.Root())
  1119  
  1120  			coalescedLogs = append(coalescedLogs, logs...)
  1121  			events = append(events, ChainEvent{block, block.Hash(), logs})
  1122  			lastCanon = block
  1123  
  1124  			bc.gcproc += proctime
  1125  
  1126  		case SideStatTy:
  1127  			bc.logger.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(),
  1128  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  1129  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  1130  				"root", block.Root())
  1131  			events = append(events, ChainSideEvent{block})
  1132  		}
  1133  		stats.processed++
  1134  		stats.usedGas += usedGas
  1135  
  1136  		dirty, _ := bc.stateCache.TrieDB().Size()
  1137  		stats.report(chain, it.index, dirty)
  1138  	}
  1139  
  1140  	if block != nil && err == consensus.ErrFutureBlock {
  1141  		if err := bc.addFutureBlock(block); err != nil {
  1142  			return it.index, events, coalescedLogs, err
  1143  		}
  1144  		block, err = it.next()
  1145  
  1146  		for ; block != nil && err == consensus.ErrUnknownAncestor; block, err = it.next() {
  1147  			if err := bc.addFutureBlock(block); err != nil {
  1148  				return it.index, events, coalescedLogs, err
  1149  			}
  1150  			stats.queued++
  1151  		}
  1152  	}
  1153  	stats.ignored += it.remaining()
  1154  
  1155  	if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
  1156  		events = append(events, ChainHeadEvent{lastCanon})
  1157  	}
  1158  
  1159  	return it.index, events, coalescedLogs, err
  1160  }
  1161  
  1162  func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (int, []interface{}, []*types.Log, error) {
  1163  	var (
  1164  		externTd *big.Int
  1165  		current  = bc.CurrentBlock()
  1166  	)
  1167  
  1168  	err := consensus.ErrPrunedAncestor
  1169  	for ; block != nil && (err == consensus.ErrPrunedAncestor); block, err = it.next() {
  1170  
  1171  		if number := block.NumberU64(); current.NumberU64() >= number {
  1172  			canonical := bc.GetBlockByNumber(number)
  1173  			if canonical != nil && canonical.Hash() == block.Hash() {
  1174  
  1175  				continue
  1176  			}
  1177  			if canonical != nil && canonical.Root() == block.Root() {
  1178  
  1179  				bc.logger.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root())
  1180  
  1181  				return it.index, nil, nil, errors.New("sidechain ghost-state attack")
  1182  			}
  1183  		}
  1184  		if externTd == nil {
  1185  			externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1)
  1186  		}
  1187  		externTd = new(big.Int).Add(externTd, block.Difficulty())
  1188  
  1189  		if !bc.HasBlock(block.Hash(), block.NumberU64()) {
  1190  			start := time.Now()
  1191  			if err := bc.WriteBlockWithoutState(block, externTd); err != nil {
  1192  				return it.index, nil, nil, err
  1193  			}
  1194  			bc.logger.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(),
  1195  				"diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)),
  1196  				"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
  1197  				"root", block.Root())
  1198  		}
  1199  	}
  1200  
  1201  	localTd := bc.GetTd(current.Hash(), current.NumberU64())
  1202  	if localTd.Cmp(externTd) > 0 {
  1203  		bc.logger.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd)
  1204  		return it.index, nil, nil, err
  1205  	}
  1206  
  1207  	var (
  1208  		hashes  []common.Hash
  1209  		numbers []uint64
  1210  	)
  1211  	parent := it.previous()
  1212  	for parent != nil && !bc.HasState(parent.Root) {
  1213  		hashes = append(hashes, parent.Hash())
  1214  		numbers = append(numbers, parent.Number.Uint64())
  1215  
  1216  		parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1)
  1217  	}
  1218  	if parent == nil {
  1219  		return it.index, nil, nil, errors.New("missing parent")
  1220  	}
  1221  
  1222  	var (
  1223  		blocks []*types.Block
  1224  		memory common.StorageSize
  1225  	)
  1226  	for i := len(hashes) - 1; i >= 0; i-- {
  1227  
  1228  		block := bc.GetBlock(hashes[i], numbers[i])
  1229  
  1230  		blocks = append(blocks, block)
  1231  		memory += block.Size()
  1232  
  1233  		if len(blocks) >= 2048 || memory > 64*1024*1024 {
  1234  			bc.logger.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64())
  1235  			if _, _, _, err := bc.insertChain(blocks, false); err != nil {
  1236  				return 0, nil, nil, err
  1237  			}
  1238  			blocks, memory = blocks[:0], 0
  1239  
  1240  			if atomic.LoadInt32(&bc.procInterrupt) == 1 {
  1241  				bc.logger.Debug("Premature abort during blocks processing")
  1242  				return 0, nil, nil, nil
  1243  			}
  1244  		}
  1245  	}
  1246  	if len(blocks) > 0 {
  1247  		bc.logger.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64())
  1248  		return bc.insertChain(blocks, false)
  1249  	}
  1250  	return 0, nil, nil, nil
  1251  }
  1252  
  1253  func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
  1254  	var (
  1255  		newChain    types.Blocks
  1256  		oldChain    types.Blocks
  1257  		commonBlock *types.Block
  1258  
  1259  		deletedTxs types.Transactions
  1260  
  1261  		deletedLogs []*types.Log
  1262  
  1263  		collectLogs = func(hash common.Hash) {
  1264  			number := bc.hc.GetBlockNumber(hash)
  1265  			if number == nil {
  1266  				return
  1267  			}
  1268  
  1269  			receipts := rawdb.ReadReceipts(bc.db, hash, *number)
  1270  			for _, receipt := range receipts {
  1271  				for _, log := range receipt.Logs {
  1272  					del := *log
  1273  					del.Removed = true
  1274  					deletedLogs = append(deletedLogs, &del)
  1275  				}
  1276  			}
  1277  		}
  1278  	)
  1279  
  1280  	if oldBlock.NumberU64() > newBlock.NumberU64() {
  1281  
  1282  		for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) {
  1283  			oldChain = append(oldChain, oldBlock)
  1284  			deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
  1285  			collectLogs(oldBlock.Hash())
  1286  		}
  1287  	} else {
  1288  
  1289  		for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) {
  1290  			newChain = append(newChain, newBlock)
  1291  		}
  1292  	}
  1293  	if oldBlock == nil {
  1294  		return fmt.Errorf("Invalid old chain")
  1295  	}
  1296  	if newBlock == nil {
  1297  		return fmt.Errorf("Invalid new chain")
  1298  	}
  1299  
  1300  	for {
  1301  		if oldBlock.Hash() == newBlock.Hash() {
  1302  			commonBlock = oldBlock
  1303  			break
  1304  		}
  1305  
  1306  		oldChain = append(oldChain, oldBlock)
  1307  		newChain = append(newChain, newBlock)
  1308  		deletedTxs = append(deletedTxs, oldBlock.Transactions()...)
  1309  		collectLogs(oldBlock.Hash())
  1310  
  1311  		oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
  1312  		if oldBlock == nil {
  1313  			return fmt.Errorf("Invalid old chain")
  1314  		}
  1315  		if newBlock == nil {
  1316  			return fmt.Errorf("Invalid new chain")
  1317  		}
  1318  	}
  1319  
  1320  	if len(oldChain) > 0 && len(newChain) > 0 {
  1321  		logFn := log.Debug
  1322  		if len(oldChain) > 63 {
  1323  			logFn = log.Warn
  1324  		}
  1325  		logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(),
  1326  			"drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash())
  1327  	} else {
  1328  		bc.logger.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash())
  1329  	}
  1330  
  1331  	var addedTxs types.Transactions
  1332  	for i := len(newChain) - 1; i >= 0; i-- {
  1333  
  1334  		bc.insert(newChain[i])
  1335  
  1336  		rawdb.WriteTxLookupEntries(bc.db, newChain[i])
  1337  		addedTxs = append(addedTxs, newChain[i].Transactions()...)
  1338  	}
  1339  
  1340  	batch := bc.db.NewBatch()
  1341  	for _, tx := range types.TxDifference(deletedTxs, addedTxs) {
  1342  		rawdb.DeleteTxLookupEntry(batch, tx.Hash())
  1343  	}
  1344  	batch.Write()
  1345  
  1346  	if len(deletedLogs) > 0 {
  1347  		go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs})
  1348  	}
  1349  	if len(oldChain) > 0 {
  1350  		go func() {
  1351  			for _, block := range oldChain {
  1352  				bc.chainSideFeed.Send(ChainSideEvent{Block: block})
  1353  			}
  1354  		}()
  1355  	}
  1356  
  1357  	return nil
  1358  }
  1359  
  1360  func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) {
  1361  
  1362  	if logs != nil {
  1363  		bc.logsFeed.Send(logs)
  1364  	}
  1365  	for _, event := range events {
  1366  		switch ev := event.(type) {
  1367  		case ChainEvent:
  1368  			bc.chainFeed.Send(ev)
  1369  
  1370  		case ChainHeadEvent:
  1371  			bc.chainHeadFeed.Send(ev)
  1372  
  1373  		case ChainSideEvent:
  1374  			bc.chainSideFeed.Send(ev)
  1375  
  1376  		case CreateSideChainEvent:
  1377  			bc.createSideChainFeed.Send(ev)
  1378  
  1379  		case StartMiningEvent:
  1380  			bc.startMiningFeed.Send(ev)
  1381  
  1382  		case StopMiningEvent:
  1383  			bc.stopMiningFeed.Send(ev)
  1384  		}
  1385  	}
  1386  }
  1387  
  1388  func (bc *BlockChain) update() {
  1389  	futureTimer := time.NewTicker(5 * time.Second)
  1390  	defer futureTimer.Stop()
  1391  	for {
  1392  		select {
  1393  		case <-futureTimer.C:
  1394  			bc.procFutureBlocks()
  1395  		case <-bc.quit:
  1396  			return
  1397  		}
  1398  	}
  1399  }
  1400  
  1401  type BadBlockArgs struct {
  1402  	Hash   common.Hash   `json:"hash"`
  1403  	Header *types.Header `json:"header"`
  1404  }
  1405  
  1406  func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) {
  1407  	headers := make([]BadBlockArgs, 0, bc.badBlocks.Len())
  1408  	for _, hash := range bc.badBlocks.Keys() {
  1409  		if hdr, exist := bc.badBlocks.Peek(hash); exist {
  1410  			header := hdr.(*types.Header)
  1411  			headers = append(headers, BadBlockArgs{header.Hash(), header})
  1412  		}
  1413  	}
  1414  	return headers, nil
  1415  }
  1416  
  1417  func (bc *BlockChain) HasBadBlock(hash common.Hash) bool {
  1418  	return bc.badBlocks.Contains(hash)
  1419  }
  1420  
  1421  func (bc *BlockChain) addBadBlock(block *types.Block) {
  1422  	bc.badBlocks.Add(block.Header().Hash(), block.Header())
  1423  }
  1424  
  1425  func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) {
  1426  	bc.addBadBlock(block)
  1427  
  1428  	var receiptString string
  1429  	for _, receipt := range receipts {
  1430  		receiptString += fmt.Sprintf("\t%v\n", receipt)
  1431  	}
  1432  	bc.logger.Error(fmt.Sprintf(`
  1433  ########## BAD BLOCK #########
  1434  Chain config: %v
  1435  
  1436  Number: %v
  1437  Hash: 0x%x
  1438  %v
  1439  
  1440  Error: %v
  1441  ##############################
  1442  `, bc.chainConfig, block.Number(), block.Hash(), receiptString, err))
  1443  }
  1444  
  1445  func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
  1446  	start := time.Now()
  1447  	if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil {
  1448  		return i, err
  1449  	}
  1450  
  1451  	bc.chainmu.Lock()
  1452  	defer bc.chainmu.Unlock()
  1453  
  1454  	bc.wg.Add(1)
  1455  	defer bc.wg.Done()
  1456  
  1457  	whFunc := func(header *types.Header) error {
  1458  		_, err := bc.hc.WriteHeader(header)
  1459  		return err
  1460  	}
  1461  
  1462  	return bc.hc.InsertHeaderChain(chain, whFunc, start)
  1463  }
  1464  
  1465  func (bc *BlockChain) CurrentHeader() *types.Header {
  1466  	return bc.hc.CurrentHeader()
  1467  }
  1468  
  1469  func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
  1470  	return bc.hc.GetTd(hash, number)
  1471  }
  1472  
  1473  func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int {
  1474  	return bc.hc.GetTdByHash(hash)
  1475  }
  1476  
  1477  func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header {
  1478  	return bc.hc.GetHeader(hash, number)
  1479  }
  1480  
  1481  func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header {
  1482  	return bc.hc.GetHeaderByHash(hash)
  1483  }
  1484  
  1485  func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool {
  1486  	return bc.hc.HasHeader(hash, number)
  1487  }
  1488  
  1489  func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash {
  1490  	return bc.hc.GetBlockHashesFromHash(hash, max)
  1491  }
  1492  
  1493  func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
  1494  	return bc.hc.GetHeaderByNumber(number)
  1495  }
  1496  
  1497  func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
  1498  
  1499  func (bc *BlockChain) Engine() consensus.Engine { return bc.engine }
  1500  
  1501  func (bc *BlockChain) GetCrossChainHelper() CrossChainHelper { return bc.cch }
  1502  
  1503  func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
  1504  	return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))
  1505  }
  1506  
  1507  func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription {
  1508  	return bc.scope.Track(bc.chainFeed.Subscribe(ch))
  1509  }
  1510  
  1511  func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription {
  1512  	return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
  1513  }
  1514  
  1515  func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
  1516  	return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
  1517  }
  1518  
  1519  func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
  1520  	return bc.scope.Track(bc.logsFeed.Subscribe(ch))
  1521  }
  1522  
  1523  func (bc *BlockChain) SubscribeCreateSideChainEvent(ch chan<- CreateSideChainEvent) event.Subscription {
  1524  	return bc.scope.Track(bc.createSideChainFeed.Subscribe(ch))
  1525  }
  1526  
  1527  func (bc *BlockChain) SubscribeStartMiningEvent(ch chan<- StartMiningEvent) event.Subscription {
  1528  	return bc.scope.Track(bc.startMiningFeed.Subscribe(ch))
  1529  }
  1530  
  1531  func (bc *BlockChain) SubscribeStopMiningEvent(ch chan<- StopMiningEvent) event.Subscription {
  1532  	return bc.scope.Track(bc.stopMiningFeed.Subscribe(ch))
  1533  }