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