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