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