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