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