github.com/phillinzzz/newBsc@v1.1.6/core/blockchain.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package core implements the Ethereum consensus protocol. 18 package core 19 20 import ( 21 "errors" 22 "fmt" 23 "io" 24 "math/big" 25 mrand "math/rand" 26 "sort" 27 "sync" 28 "sync/atomic" 29 "time" 30 31 lru "github.com/hashicorp/golang-lru" 32 33 "github.com/phillinzzz/newBsc/common" 34 "github.com/phillinzzz/newBsc/common/mclock" 35 "github.com/phillinzzz/newBsc/common/prque" 36 "github.com/phillinzzz/newBsc/consensus" 37 "github.com/phillinzzz/newBsc/core/rawdb" 38 "github.com/phillinzzz/newBsc/core/state" 39 "github.com/phillinzzz/newBsc/core/state/snapshot" 40 "github.com/phillinzzz/newBsc/core/types" 41 "github.com/phillinzzz/newBsc/core/vm" 42 "github.com/phillinzzz/newBsc/ethdb" 43 "github.com/phillinzzz/newBsc/event" 44 "github.com/phillinzzz/newBsc/log" 45 "github.com/phillinzzz/newBsc/metrics" 46 "github.com/phillinzzz/newBsc/params" 47 "github.com/phillinzzz/newBsc/rlp" 48 "github.com/phillinzzz/newBsc/trie" 49 ) 50 51 var ( 52 headBlockGauge = metrics.NewRegisteredGauge("chain/head/block", nil) 53 headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil) 54 headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil) 55 56 accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil) 57 accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil) 58 accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil) 59 accountCommitTimer = metrics.NewRegisteredTimer("chain/account/commits", nil) 60 61 storageReadTimer = metrics.NewRegisteredTimer("chain/storage/reads", nil) 62 storageHashTimer = metrics.NewRegisteredTimer("chain/storage/hashes", nil) 63 storageUpdateTimer = metrics.NewRegisteredTimer("chain/storage/updates", nil) 64 storageCommitTimer = metrics.NewRegisteredTimer("chain/storage/commits", nil) 65 66 snapshotAccountReadTimer = metrics.NewRegisteredTimer("chain/snapshot/account/reads", nil) 67 snapshotStorageReadTimer = metrics.NewRegisteredTimer("chain/snapshot/storage/reads", nil) 68 snapshotCommitTimer = metrics.NewRegisteredTimer("chain/snapshot/commits", nil) 69 70 blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) 71 blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil) 72 blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil) 73 blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil) 74 75 blockReorgMeter = metrics.NewRegisteredMeter("chain/reorg/executes", nil) 76 blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil) 77 blockReorgDropMeter = metrics.NewRegisteredMeter("chain/reorg/drop", nil) 78 blockReorgInvalidatedTx = metrics.NewRegisteredMeter("chain/reorg/invalidTx", nil) 79 80 errInsertionInterrupted = errors.New("insertion is interrupted") 81 ) 82 83 const ( 84 bodyCacheLimit = 256 85 blockCacheLimit = 256 86 diffLayerCacheLimit = 1024 87 diffLayerRLPCacheLimit = 256 88 receiptsCacheLimit = 10000 89 txLookupCacheLimit = 1024 90 maxFutureBlocks = 256 91 maxTimeFutureBlocks = 30 92 maxBeyondBlocks = 2048 93 94 diffLayerFreezerRecheckInterval = 3 * time.Second 95 diffLayerPruneRecheckInterval = 1 * time.Second // The interval to prune unverified diff layers 96 maxDiffQueueDist = 2048 // Maximum allowed distance from the chain head to queue diffLayers 97 maxDiffLimit = 2048 // Maximum number of unique diff layers a peer may have responded 98 maxDiffForkDist = 11 // Maximum allowed backward distance from the chain head 99 maxDiffLimitForBroadcast = 128 // Maximum number of unique diff layers a peer may have broadcasted 100 101 // BlockChainVersion ensures that an incompatible database forces a resync from scratch. 102 // 103 // Changelog: 104 // 105 // - Version 4 106 // The following incompatible database changes were added: 107 // * the `BlockNumber`, `TxHash`, `TxIndex`, `BlockHash` and `Index` fields of log are deleted 108 // * the `Bloom` field of receipt is deleted 109 // * the `BlockIndex` and `TxIndex` fields of txlookup are deleted 110 // - Version 5 111 // The following incompatible database changes were added: 112 // * the `TxHash`, `GasCost`, and `ContractAddress` fields are no longer stored for a receipt 113 // * the `TxHash`, `GasCost`, and `ContractAddress` fields are computed by looking up the 114 // receipts' corresponding block 115 // - Version 6 116 // The following incompatible database changes were added: 117 // * Transaction lookup information stores the corresponding block number instead of block hash 118 // - Version 7 119 // The following incompatible database changes were added: 120 // * Use freezer as the ancient database to maintain all ancient data 121 // - Version 8 122 // The following incompatible database changes were added: 123 // * New scheme for contract code in order to separate the codes and trie nodes 124 BlockChainVersion uint64 = 8 125 ) 126 127 // CacheConfig contains the configuration values for the trie caching/pruning 128 // that's resident in a blockchain. 129 type CacheConfig struct { 130 TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory 131 TrieCleanJournal string // Disk journal for saving clean cache entries. 132 TrieCleanRejournal time.Duration // Time interval to dump clean cache to disk periodically 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 TriesInMemory uint64 // How many tries keeps in memory 139 140 SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it 141 } 142 143 // To avoid cycle import 144 type PeerIDer interface { 145 ID() string 146 } 147 148 // defaultCacheConfig are the default caching values if none are specified by the 149 // user (also used during testing). 150 var defaultCacheConfig = &CacheConfig{ 151 TrieCleanLimit: 256, 152 TrieDirtyLimit: 256, 153 TrieTimeLimit: 5 * time.Minute, 154 SnapshotLimit: 256, 155 TriesInMemory: 128, 156 SnapshotWait: true, 157 } 158 159 type BlockChainOption func(*BlockChain) *BlockChain 160 161 // BlockChain represents the canonical chain given a database with a genesis 162 // block. The Blockchain manages chain imports, reverts, chain reorganisations. 163 // 164 // Importing blocks in to the block chain happens according to the set of rules 165 // defined by the two stage Validator. Processing of blocks is done using the 166 // Processor which processes the included transaction. The validation of the state 167 // is done in the second part of the Validator. Failing results in aborting of 168 // the import. 169 // 170 // The BlockChain also helps in returning blocks from **any** chain included 171 // in the database as well as blocks that represents the canonical chain. It's 172 // important to note that GetBlock can return any block and does not need to be 173 // included in the canonical one where as GetBlockByNumber always represents the 174 // canonical chain. 175 type BlockChain struct { 176 chainConfig *params.ChainConfig // Chain & network configuration 177 cacheConfig *CacheConfig // Cache configuration for pruning 178 179 db ethdb.Database // Low level persistent database to store final content in 180 snaps *snapshot.Tree // Snapshot tree for fast trie leaf access 181 triegc *prque.Prque // Priority queue mapping block numbers to tries to gc 182 gcproc time.Duration // Accumulates canonical block processing for trie dumping 183 184 // txLookupLimit is the maximum number of blocks from head whose tx indices 185 // are reserved: 186 // * 0: means no limit and regenerate any missing indexes 187 // * N: means N block limit [HEAD-N+1, HEAD] and delete extra indexes 188 // * nil: disable tx reindexer/deleter, but still index new blocks 189 txLookupLimit uint64 190 triesInMemory uint64 191 192 hc *HeaderChain 193 rmLogsFeed event.Feed 194 chainFeed event.Feed 195 chainSideFeed event.Feed 196 chainHeadFeed event.Feed 197 logsFeed event.Feed 198 blockProcFeed event.Feed 199 scope event.SubscriptionScope 200 genesisBlock *types.Block 201 202 chainmu sync.RWMutex // blockchain insertion lock 203 204 currentBlock atomic.Value // Current head of the block chain 205 currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!) 206 highestVerifiedHeader atomic.Value 207 208 stateCache state.Database // State database to reuse between imports (contains state cache) 209 bodyCache *lru.Cache // Cache for the most recent block bodies 210 bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format 211 receiptsCache *lru.Cache // Cache for the most recent receipts per block 212 blockCache *lru.Cache // Cache for the most recent entire blocks 213 txLookupCache *lru.Cache // Cache for the most recent transaction lookup data. 214 futureBlocks *lru.Cache // future blocks are blocks added for later processing 215 216 // trusted diff layers 217 diffLayerCache *lru.Cache // Cache for the diffLayers 218 diffLayerRLPCache *lru.Cache // Cache for the rlp encoded diffLayers 219 diffQueue *prque.Prque // A Priority queue to store recent diff layer 220 diffQueueBuffer chan *types.DiffLayer 221 diffLayerFreezerBlockLimit uint64 222 223 // untrusted diff layers 224 diffMux sync.RWMutex 225 blockHashToDiffLayers map[common.Hash]map[common.Hash]*types.DiffLayer // map[blockHash] map[DiffHash]Diff 226 diffHashToBlockHash map[common.Hash]common.Hash // map[diffHash]blockHash 227 diffHashToPeers map[common.Hash]map[string]struct{} // map[diffHash]map[pid] 228 diffNumToBlockHashes map[uint64]map[common.Hash]struct{} // map[number]map[blockHash] 229 diffPeersToDiffHashes map[string]map[common.Hash]struct{} // map[pid]map[diffHash] 230 231 quit chan struct{} // blockchain quit channel 232 wg sync.WaitGroup // chain processing wait group for shutting down 233 running int32 // 0 if chain is running, 1 when stopped 234 procInterrupt int32 // interrupt signaler for block processing 235 236 engine consensus.Engine 237 validator Validator // Block and state validator interface 238 processor Processor // Block transaction processor interface 239 vmConfig vm.Config 240 241 shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block. 242 terminateInsert func(common.Hash, uint64) bool // Testing hook used to terminate ancient receipt chain insertion. 243 } 244 245 // NewBlockChain returns a fully initialised block chain using information 246 // available in the database. It initialises the default Ethereum Validator and 247 // Processor. 248 func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, 249 vmConfig vm.Config, shouldPreserve func(block *types.Block) bool, txLookupLimit *uint64, 250 options ...BlockChainOption) (*BlockChain, error) { 251 if cacheConfig == nil { 252 cacheConfig = defaultCacheConfig 253 } 254 if cacheConfig.TriesInMemory != 128 { 255 log.Warn("TriesInMemory isn't the default value(128), you need specify exact same TriesInMemory when prune data", 256 "triesInMemory", cacheConfig.TriesInMemory) 257 } 258 bodyCache, _ := lru.New(bodyCacheLimit) 259 bodyRLPCache, _ := lru.New(bodyCacheLimit) 260 receiptsCache, _ := lru.New(receiptsCacheLimit) 261 blockCache, _ := lru.New(blockCacheLimit) 262 txLookupCache, _ := lru.New(txLookupCacheLimit) 263 futureBlocks, _ := lru.New(maxFutureBlocks) 264 diffLayerCache, _ := lru.New(diffLayerCacheLimit) 265 diffLayerRLPCache, _ := lru.New(diffLayerRLPCacheLimit) 266 267 bc := &BlockChain{ 268 chainConfig: chainConfig, 269 cacheConfig: cacheConfig, 270 db: db, 271 triegc: prque.New(nil), 272 stateCache: state.NewDatabaseWithConfigAndCache(db, &trie.Config{ 273 Cache: cacheConfig.TrieCleanLimit, 274 Journal: cacheConfig.TrieCleanJournal, 275 Preimages: cacheConfig.Preimages, 276 }), 277 triesInMemory: cacheConfig.TriesInMemory, 278 quit: make(chan struct{}), 279 shouldPreserve: shouldPreserve, 280 bodyCache: bodyCache, 281 bodyRLPCache: bodyRLPCache, 282 receiptsCache: receiptsCache, 283 blockCache: blockCache, 284 diffLayerCache: diffLayerCache, 285 diffLayerRLPCache: diffLayerRLPCache, 286 txLookupCache: txLookupCache, 287 futureBlocks: futureBlocks, 288 engine: engine, 289 vmConfig: vmConfig, 290 diffQueue: prque.New(nil), 291 diffQueueBuffer: make(chan *types.DiffLayer), 292 blockHashToDiffLayers: make(map[common.Hash]map[common.Hash]*types.DiffLayer), 293 diffHashToBlockHash: make(map[common.Hash]common.Hash), 294 diffHashToPeers: make(map[common.Hash]map[string]struct{}), 295 diffNumToBlockHashes: make(map[uint64]map[common.Hash]struct{}), 296 diffPeersToDiffHashes: make(map[string]map[common.Hash]struct{}), 297 } 298 bc.validator = NewBlockValidator(chainConfig, bc, engine) 299 bc.processor = NewStateProcessor(chainConfig, bc, engine) 300 301 var err error 302 bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped) 303 if err != nil { 304 return nil, err 305 } 306 bc.genesisBlock = bc.GetBlockByNumber(0) 307 if bc.genesisBlock == nil { 308 return nil, ErrNoGenesis 309 } 310 311 var nilBlock *types.Block 312 bc.currentBlock.Store(nilBlock) 313 bc.currentFastBlock.Store(nilBlock) 314 315 var nilHeader *types.Header 316 bc.highestVerifiedHeader.Store(nilHeader) 317 318 // Initialize the chain with ancient data if it isn't empty. 319 var txIndexBlock uint64 320 321 if bc.empty() { 322 rawdb.InitDatabaseFromFreezer(bc.db) 323 // If ancient database is not empty, reconstruct all missing 324 // indices in the background. 325 frozen, _ := bc.db.Ancients() 326 if frozen > 0 { 327 txIndexBlock = frozen 328 } 329 } 330 if err := bc.loadLastState(); err != nil { 331 return nil, err 332 } 333 // Make sure the state associated with the block is available 334 head := bc.CurrentBlock() 335 if _, err := state.New(head.Root(), bc.stateCache, bc.snaps); err != nil { 336 // Head state is missing, before the state recovery, find out the 337 // disk layer point of snapshot(if it's enabled). Make sure the 338 // rewound point is lower than disk layer. 339 var diskRoot common.Hash 340 if bc.cacheConfig.SnapshotLimit > 0 { 341 diskRoot = rawdb.ReadSnapshotRoot(bc.db) 342 } 343 if diskRoot != (common.Hash{}) { 344 log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash(), "snaproot", diskRoot) 345 346 snapDisk, err := bc.SetHeadBeyondRoot(head.NumberU64(), diskRoot) 347 if err != nil { 348 return nil, err 349 } 350 // Chain rewound, persist old snapshot number to indicate recovery procedure 351 if snapDisk != 0 { 352 rawdb.WriteSnapshotRecoveryNumber(bc.db, snapDisk) 353 } 354 } else { 355 log.Warn("Head state missing, repairing", "number", head.Number(), "hash", head.Hash()) 356 if err := bc.SetHead(head.NumberU64()); err != nil { 357 return nil, err 358 } 359 } 360 } 361 // Ensure that a previous crash in SetHead doesn't leave extra ancients 362 if frozen, err := bc.db.Ancients(); err == nil && frozen > 0 { 363 var ( 364 needRewind bool 365 low uint64 366 ) 367 // The head full block may be rolled back to a very low height due to 368 // blockchain repair. If the head full block is even lower than the ancient 369 // chain, truncate the ancient store. 370 fullBlock := bc.CurrentBlock() 371 if fullBlock != nil && fullBlock.Hash() != bc.genesisBlock.Hash() && fullBlock.NumberU64() < frozen-1 { 372 needRewind = true 373 low = fullBlock.NumberU64() 374 } 375 // In fast sync, it may happen that ancient data has been written to the 376 // ancient store, but the LastFastBlock has not been updated, truncate the 377 // extra data here. 378 fastBlock := bc.CurrentFastBlock() 379 if fastBlock != nil && fastBlock.NumberU64() < frozen-1 { 380 needRewind = true 381 if fastBlock.NumberU64() < low || low == 0 { 382 low = fastBlock.NumberU64() 383 } 384 } 385 if needRewind { 386 log.Error("Truncating ancient chain", "from", bc.CurrentHeader().Number.Uint64(), "to", low) 387 if err := bc.SetHead(low); err != nil { 388 return nil, err 389 } 390 } 391 } 392 // The first thing the node will do is reconstruct the verification data for 393 // the head block (ethash cache or clique voting snapshot). Might as well do 394 // it in advance. 395 bc.engine.VerifyHeader(bc, bc.CurrentHeader(), true) 396 397 // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain 398 for hash := range BadHashes { 399 if header := bc.GetHeaderByHash(hash); header != nil { 400 // get the canonical block corresponding to the offending header's number 401 headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64()) 402 // make sure the headerByNumber (if present) is in our current canonical chain 403 if headerByNumber != nil && headerByNumber.Hash() == header.Hash() { 404 log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) 405 if err := bc.SetHead(header.Number.Uint64() - 1); err != nil { 406 return nil, err 407 } 408 log.Error("Chain rewind was successful, resuming normal operation") 409 } 410 } 411 } 412 // Load any existing snapshot, regenerating it if loading failed 413 if bc.cacheConfig.SnapshotLimit > 0 { 414 // If the chain was rewound past the snapshot persistent layer (causing 415 // a recovery block number to be persisted to disk), check if we're still 416 // in recovery mode and in that case, don't invalidate the snapshot on a 417 // head mismatch. 418 var recover bool 419 420 head := bc.CurrentBlock() 421 if layer := rawdb.ReadSnapshotRecoveryNumber(bc.db); layer != nil && *layer > head.NumberU64() { 422 log.Warn("Enabling snapshot recovery", "chainhead", head.NumberU64(), "diskbase", *layer) 423 recover = true 424 } 425 bc.snaps, _ = snapshot.New(bc.db, bc.stateCache.TrieDB(), bc.cacheConfig.SnapshotLimit, int(bc.cacheConfig.TriesInMemory), head.Root(), !bc.cacheConfig.SnapshotWait, true, recover) 426 } 427 // do options before start any routine 428 for _, option := range options { 429 bc = option(bc) 430 } 431 // Take ownership of this particular state 432 go bc.update() 433 if txLookupLimit != nil { 434 bc.txLookupLimit = *txLookupLimit 435 436 bc.wg.Add(1) 437 go bc.maintainTxIndex(txIndexBlock) 438 } 439 // If periodic cache journal is required, spin it up. 440 if bc.cacheConfig.TrieCleanRejournal > 0 { 441 if bc.cacheConfig.TrieCleanRejournal < time.Minute { 442 log.Warn("Sanitizing invalid trie cache journal time", "provided", bc.cacheConfig.TrieCleanRejournal, "updated", time.Minute) 443 bc.cacheConfig.TrieCleanRejournal = time.Minute 444 } 445 triedb := bc.stateCache.TrieDB() 446 bc.wg.Add(1) 447 go func() { 448 defer bc.wg.Done() 449 triedb.SaveCachePeriodically(bc.cacheConfig.TrieCleanJournal, bc.cacheConfig.TrieCleanRejournal, bc.quit) 450 }() 451 } 452 // Need persist and prune diff layer 453 if bc.db.DiffStore() != nil { 454 go bc.trustedDiffLayerLoop() 455 } 456 go bc.untrustedDiffLayerPruneLoop() 457 458 return bc, nil 459 } 460 461 // GetVMConfig returns the block chain VM config. 462 func (bc *BlockChain) GetVMConfig() *vm.Config { 463 return &bc.vmConfig 464 } 465 466 func (bc *BlockChain) cacheReceipts(hash common.Hash, receipts types.Receipts) { 467 // TODO, This is a hot fix for the block hash of logs is `0x0000000000000000000000000000000000000000000000000000000000000000` for system tx 468 // Please check details in https://github.com/binance-chain/bsc/issues/443 469 // This is a temporary fix, the official fix should be a hard fork. 470 const possibleSystemReceipts = 3 // One slash tx, two reward distribute txs. 471 numOfReceipts := len(receipts) 472 for i := numOfReceipts - 1; i >= 0 && i >= numOfReceipts-possibleSystemReceipts; i-- { 473 for j := 0; j < len(receipts[i].Logs); j++ { 474 receipts[i].Logs[j].BlockHash = hash 475 } 476 } 477 bc.receiptsCache.Add(hash, receipts) 478 } 479 480 func (bc *BlockChain) cacheDiffLayer(diffLayer *types.DiffLayer) { 481 bc.diffLayerCache.Add(diffLayer.BlockHash, diffLayer) 482 if bc.db.DiffStore() != nil { 483 // push to priority queue before persisting 484 bc.diffQueueBuffer <- diffLayer 485 } 486 } 487 488 func (bc *BlockChain) cacheBlock(hash common.Hash, block *types.Block) { 489 bc.blockCache.Add(hash, block) 490 } 491 492 // empty returns an indicator whether the blockchain is empty. 493 // Note, it's a special case that we connect a non-empty ancient 494 // database with an empty node, so that we can plugin the ancient 495 // into node seamlessly. 496 func (bc *BlockChain) empty() bool { 497 genesis := bc.genesisBlock.Hash() 498 for _, hash := range []common.Hash{rawdb.ReadHeadBlockHash(bc.db), rawdb.ReadHeadHeaderHash(bc.db), rawdb.ReadHeadFastBlockHash(bc.db)} { 499 if hash != genesis { 500 return false 501 } 502 } 503 return true 504 } 505 506 // loadLastState loads the last known chain state from the database. This method 507 // assumes that the chain manager mutex is held. 508 func (bc *BlockChain) loadLastState() error { 509 // Restore the last known head block 510 head := rawdb.ReadHeadBlockHash(bc.db) 511 if head == (common.Hash{}) { 512 // Corrupt or empty database, init from scratch 513 log.Warn("Empty database, resetting chain") 514 return bc.Reset() 515 } 516 // Make sure the entire head block is available 517 currentBlock := bc.GetBlockByHash(head) 518 if currentBlock == nil { 519 // Corrupt or empty database, init from scratch 520 log.Warn("Head block missing, resetting chain", "hash", head) 521 return bc.Reset() 522 } 523 // Everything seems to be fine, set as the head block 524 bc.currentBlock.Store(currentBlock) 525 headBlockGauge.Update(int64(currentBlock.NumberU64())) 526 527 // Restore the last known head header 528 currentHeader := currentBlock.Header() 529 if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) { 530 if header := bc.GetHeaderByHash(head); header != nil { 531 currentHeader = header 532 } 533 } 534 bc.hc.SetCurrentHeader(currentHeader) 535 536 // Restore the last known head fast block 537 bc.currentFastBlock.Store(currentBlock) 538 headFastBlockGauge.Update(int64(currentBlock.NumberU64())) 539 540 if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) { 541 if block := bc.GetBlockByHash(head); block != nil { 542 bc.currentFastBlock.Store(block) 543 headFastBlockGauge.Update(int64(block.NumberU64())) 544 } 545 } 546 // Issue a status log for the user 547 currentFastBlock := bc.CurrentFastBlock() 548 549 headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) 550 blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 551 fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()) 552 553 log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(currentHeader.Time), 0))) 554 log.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(currentBlock.Time()), 0))) 555 log.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd, "age", common.PrettyAge(time.Unix(int64(currentFastBlock.Time()), 0))) 556 if pivot := rawdb.ReadLastPivotNumber(bc.db); pivot != nil { 557 log.Info("Loaded last fast-sync pivot marker", "number", *pivot) 558 } 559 return nil 560 } 561 562 // SetHead rewinds the local chain to a new head. Depending on whether the node 563 // was fast synced or full synced and in which state, the method will try to 564 // delete minimal data from disk whilst retaining chain consistency. 565 func (bc *BlockChain) SetHead(head uint64) error { 566 _, err := bc.SetHeadBeyondRoot(head, common.Hash{}) 567 return err 568 } 569 570 // SetHeadBeyondRoot rewinds the local chain to a new head with the extra condition 571 // that the rewind must pass the specified state root. This method is meant to be 572 // used when rewinding with snapshots enabled to ensure that we go back further than 573 // persistent disk layer. Depending on whether the node was fast synced or full, and 574 // in which state, the method will try to delete minimal data from disk whilst 575 // retaining chain consistency. 576 // 577 // The method returns the block number where the requested root cap was found. 578 func (bc *BlockChain) SetHeadBeyondRoot(head uint64, root common.Hash) (uint64, error) { 579 bc.chainmu.Lock() 580 defer bc.chainmu.Unlock() 581 582 // Track the block number of the requested root hash 583 var rootNumber uint64 // (no root == always 0) 584 585 // Retrieve the last pivot block to short circuit rollbacks beyond it and the 586 // current freezer limit to start nuking id underflown 587 pivot := rawdb.ReadLastPivotNumber(bc.db) 588 frozen, _ := bc.db.Ancients() 589 590 updateFn := func(db ethdb.KeyValueWriter, header *types.Header) (uint64, bool) { 591 // Rewind the block chain, ensuring we don't end up with a stateless head 592 // block. Note, depth equality is permitted to allow using SetHead as a 593 // chain reparation mechanism without deleting any data! 594 if currentBlock := bc.CurrentBlock(); currentBlock != nil && header.Number.Uint64() <= currentBlock.NumberU64() { 595 newHeadBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) 596 lastBlockNum := header.Number.Uint64() 597 if newHeadBlock == nil { 598 log.Error("Gap in the chain, rewinding to genesis", "number", header.Number, "hash", header.Hash()) 599 newHeadBlock = bc.genesisBlock 600 } else { 601 // Block exists, keep rewinding until we find one with state, 602 // keeping rewinding until we exceed the optional threshold 603 // root hash 604 beyondRoot := (root == common.Hash{}) // Flag whether we're beyond the requested root (no root, always true) 605 enoughBeyondCount := false 606 beyondCount := 0 607 for { 608 beyondCount++ 609 // If a root threshold was requested but not yet crossed, check 610 if root != (common.Hash{}) && !beyondRoot && newHeadBlock.Root() == root { 611 beyondRoot, rootNumber = true, newHeadBlock.NumberU64() 612 } 613 614 enoughBeyondCount = beyondCount > maxBeyondBlocks 615 616 if _, err := state.New(newHeadBlock.Root(), bc.stateCache, bc.snaps); err != nil { 617 log.Trace("Block state missing, rewinding further", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash()) 618 if pivot == nil || newHeadBlock.NumberU64() > *pivot { 619 parent := bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) 620 if parent != nil { 621 newHeadBlock = parent 622 continue 623 } 624 log.Error("Missing block in the middle, aiming genesis", "number", newHeadBlock.NumberU64()-1, "hash", newHeadBlock.ParentHash()) 625 newHeadBlock = bc.genesisBlock 626 } else { 627 log.Trace("Rewind passed pivot, aiming genesis", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "pivot", *pivot) 628 newHeadBlock = bc.genesisBlock 629 } 630 } 631 if beyondRoot || (enoughBeyondCount && root != common.Hash{}) || newHeadBlock.NumberU64() == 0 { 632 if enoughBeyondCount && (root != common.Hash{}) && rootNumber == 0 { 633 for { 634 lastBlockNum++ 635 block := bc.GetBlockByNumber(lastBlockNum) 636 if block == nil { 637 break 638 } 639 if block.Root() == root { 640 rootNumber = block.NumberU64() 641 break 642 } 643 } 644 } 645 log.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash()) 646 break 647 } 648 log.Debug("Skipping block with threshold state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash(), "root", newHeadBlock.Root()) 649 newHeadBlock = bc.GetBlock(newHeadBlock.ParentHash(), newHeadBlock.NumberU64()-1) // Keep rewinding 650 } 651 } 652 rawdb.WriteHeadBlockHash(db, newHeadBlock.Hash()) 653 654 // Degrade the chain markers if they are explicitly reverted. 655 // In theory we should update all in-memory markers in the 656 // last step, however the direction of SetHead is from high 657 // to low, so it's safe the update in-memory markers directly. 658 bc.currentBlock.Store(newHeadBlock) 659 headBlockGauge.Update(int64(newHeadBlock.NumberU64())) 660 } 661 // Rewind the fast block in a simpleton way to the target head 662 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() { 663 newHeadFastBlock := bc.GetBlock(header.Hash(), header.Number.Uint64()) 664 // If either blocks reached nil, reset to the genesis state 665 if newHeadFastBlock == nil { 666 newHeadFastBlock = bc.genesisBlock 667 } 668 rawdb.WriteHeadFastBlockHash(db, newHeadFastBlock.Hash()) 669 670 // Degrade the chain markers if they are explicitly reverted. 671 // In theory we should update all in-memory markers in the 672 // last step, however the direction of SetHead is from high 673 // to low, so it's safe the update in-memory markers directly. 674 bc.currentFastBlock.Store(newHeadFastBlock) 675 headFastBlockGauge.Update(int64(newHeadFastBlock.NumberU64())) 676 } 677 head := bc.CurrentBlock().NumberU64() 678 679 // If setHead underflown the freezer threshold and the block processing 680 // intent afterwards is full block importing, delete the chain segment 681 // between the stateful-block and the sethead target. 682 var wipe bool 683 if head+1 < frozen { 684 wipe = pivot == nil || head >= *pivot 685 } 686 return head, wipe // Only force wipe if full synced 687 } 688 // Rewind the header chain, deleting all block bodies until then 689 delFn := func(db ethdb.KeyValueWriter, hash common.Hash, num uint64) { 690 // Ignore the error here since light client won't hit this path 691 frozen, _ := bc.db.Ancients() 692 if num+1 <= frozen { 693 // Truncate all relative data(header, total difficulty, body, receipt 694 // and canonical hash) from ancient store. 695 if err := bc.db.TruncateAncients(num); err != nil { 696 log.Crit("Failed to truncate ancient data", "number", num, "err", err) 697 } 698 // Remove the hash <-> number mapping from the active store. 699 rawdb.DeleteHeaderNumber(db, hash) 700 } else { 701 // Remove relative body and receipts from the active store. 702 // The header, total difficulty and canonical hash will be 703 // removed in the hc.SetHead function. 704 rawdb.DeleteBody(db, hash, num) 705 rawdb.DeleteReceipts(db, hash, num) 706 } 707 // Todo(rjl493456442) txlookup, bloombits, etc 708 } 709 // If SetHead was only called as a chain reparation method, try to skip 710 // touching the header chain altogether, unless the freezer is broken 711 if block := bc.CurrentBlock(); block.NumberU64() == head { 712 if target, force := updateFn(bc.db, block.Header()); force { 713 bc.hc.SetHead(target, updateFn, delFn) 714 } 715 } else { 716 // Rewind the chain to the requested head and keep going backwards until a 717 // block with a state is found or fast sync pivot is passed 718 log.Warn("Rewinding blockchain", "target", head) 719 bc.hc.SetHead(head, updateFn, delFn) 720 } 721 // Clear out any stale content from the caches 722 bc.bodyCache.Purge() 723 bc.bodyRLPCache.Purge() 724 bc.receiptsCache.Purge() 725 bc.blockCache.Purge() 726 bc.txLookupCache.Purge() 727 bc.futureBlocks.Purge() 728 729 return rootNumber, bc.loadLastState() 730 } 731 732 // FastSyncCommitHead sets the current head block to the one defined by the hash 733 // irrelevant what the chain contents were prior. 734 func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { 735 // Make sure that both the block as well at its state trie exists 736 block := bc.GetBlockByHash(hash) 737 if block == nil { 738 return fmt.Errorf("non existent block [%x..]", hash[:4]) 739 } 740 if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil { 741 return err 742 } 743 // If all checks out, manually set the head block 744 bc.chainmu.Lock() 745 bc.currentBlock.Store(block) 746 headBlockGauge.Update(int64(block.NumberU64())) 747 bc.chainmu.Unlock() 748 749 // Destroy any existing state snapshot and regenerate it in the background, 750 // also resuming the normal maintenance of any previously paused snapshot. 751 if bc.snaps != nil { 752 bc.snaps.Rebuild(block.Root()) 753 } 754 log.Info("Committed new head block", "number", block.Number(), "hash", hash) 755 return nil 756 } 757 758 // GasLimit returns the gas limit of the current HEAD block. 759 func (bc *BlockChain) GasLimit() uint64 { 760 return bc.CurrentBlock().GasLimit() 761 } 762 763 // CurrentBlock retrieves the current head block of the canonical chain. The 764 // block is retrieved from the blockchain's internal cache. 765 func (bc *BlockChain) CurrentBlock() *types.Block { 766 return bc.currentBlock.Load().(*types.Block) 767 } 768 769 // Snapshots returns the blockchain snapshot tree. 770 func (bc *BlockChain) Snapshots() *snapshot.Tree { 771 return bc.snaps 772 } 773 774 // CurrentFastBlock retrieves the current fast-sync head block of the canonical 775 // chain. The block is retrieved from the blockchain's internal cache. 776 func (bc *BlockChain) CurrentFastBlock() *types.Block { 777 return bc.currentFastBlock.Load().(*types.Block) 778 } 779 780 // Validator returns the current validator. 781 func (bc *BlockChain) Validator() Validator { 782 return bc.validator 783 } 784 785 // Processor returns the current processor. 786 func (bc *BlockChain) Processor() Processor { 787 return bc.processor 788 } 789 790 // State returns a new mutable state based on the current HEAD block. 791 func (bc *BlockChain) State() (*state.StateDB, error) { 792 return bc.StateAt(bc.CurrentBlock().Root()) 793 } 794 795 // StateAt returns a new mutable state based on a particular point in time. 796 func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { 797 return state.New(root, bc.stateCache, bc.snaps) 798 } 799 800 // StateCache returns the caching database underpinning the blockchain instance. 801 func (bc *BlockChain) StateCache() state.Database { 802 return bc.stateCache 803 } 804 805 // Reset purges the entire blockchain, restoring it to its genesis state. 806 func (bc *BlockChain) Reset() error { 807 return bc.ResetWithGenesisBlock(bc.genesisBlock) 808 } 809 810 // ResetWithGenesisBlock purges the entire blockchain, restoring it to the 811 // specified genesis state. 812 func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { 813 // Dump the entire block chain and purge the caches 814 if err := bc.SetHead(0); err != nil { 815 return err 816 } 817 bc.chainmu.Lock() 818 defer bc.chainmu.Unlock() 819 820 // Prepare the genesis block and reinitialise the chain 821 batch := bc.db.NewBatch() 822 rawdb.WriteTd(batch, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()) 823 rawdb.WriteBlock(batch, genesis) 824 if err := batch.Write(); err != nil { 825 log.Crit("Failed to write genesis block", "err", err) 826 } 827 bc.writeHeadBlock(genesis) 828 829 // Last update all in-memory chain markers 830 bc.genesisBlock = genesis 831 bc.currentBlock.Store(bc.genesisBlock) 832 headBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) 833 bc.hc.SetGenesis(bc.genesisBlock.Header()) 834 bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) 835 bc.currentFastBlock.Store(bc.genesisBlock) 836 headFastBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) 837 return nil 838 } 839 840 // Export writes the active chain to the given writer. 841 func (bc *BlockChain) Export(w io.Writer) error { 842 return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64()) 843 } 844 845 // ExportN writes a subset of the active chain to the given writer. 846 func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { 847 bc.chainmu.RLock() 848 defer bc.chainmu.RUnlock() 849 850 if first > last { 851 return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) 852 } 853 log.Info("Exporting batch of blocks", "count", last-first+1) 854 855 start, reported := time.Now(), time.Now() 856 for nr := first; nr <= last; nr++ { 857 block := bc.GetBlockByNumber(nr) 858 if block == nil { 859 return fmt.Errorf("export failed on #%d: not found", nr) 860 } 861 if err := block.EncodeRLP(w); err != nil { 862 return err 863 } 864 if time.Since(reported) >= statsReportLimit { 865 log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start))) 866 reported = time.Now() 867 } 868 } 869 return nil 870 } 871 872 // writeHeadBlock injects a new head block into the current block chain. This method 873 // assumes that the block is indeed a true head. It will also reset the head 874 // header and the head fast sync block to this very same block if they are older 875 // or if they are on a different side chain. 876 // 877 // Note, this function assumes that the `mu` mutex is held! 878 func (bc *BlockChain) writeHeadBlock(block *types.Block) { 879 // If the block is on a side chain or an unknown one, force other heads onto it too 880 updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash() 881 882 // Add the block to the canonical chain number scheme and mark as the head 883 batch := bc.db.NewBatch() 884 rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64()) 885 rawdb.WriteTxLookupEntriesByBlock(batch, block) 886 rawdb.WriteHeadBlockHash(batch, block.Hash()) 887 888 // If the block is better than our head or is on a different chain, force update heads 889 if updateHeads { 890 rawdb.WriteHeadHeaderHash(batch, block.Hash()) 891 rawdb.WriteHeadFastBlockHash(batch, block.Hash()) 892 } 893 // Flush the whole batch into the disk, exit the node if failed 894 if err := batch.Write(); err != nil { 895 log.Crit("Failed to update chain indexes and markers", "err", err) 896 } 897 // Update all in-memory chain markers in the last step 898 if updateHeads { 899 bc.hc.SetCurrentHeader(block.Header()) 900 bc.currentFastBlock.Store(block) 901 headFastBlockGauge.Update(int64(block.NumberU64())) 902 } 903 bc.currentBlock.Store(block) 904 headBlockGauge.Update(int64(block.NumberU64())) 905 } 906 907 // Genesis retrieves the chain's genesis block. 908 func (bc *BlockChain) Genesis() *types.Block { 909 return bc.genesisBlock 910 } 911 912 // GetBody retrieves a block body (transactions and uncles) from the database by 913 // hash, caching it if found. 914 func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { 915 // Short circuit if the body's already in the cache, retrieve otherwise 916 if cached, ok := bc.bodyCache.Get(hash); ok { 917 body := cached.(*types.Body) 918 return body 919 } 920 number := bc.hc.GetBlockNumber(hash) 921 if number == nil { 922 return nil 923 } 924 body := rawdb.ReadBody(bc.db, hash, *number) 925 if body == nil { 926 return nil 927 } 928 // Cache the found body for next time and return 929 bc.bodyCache.Add(hash, body) 930 return body 931 } 932 933 // GetBodyRLP retrieves a block body in RLP encoding from the database by hash, 934 // caching it if found. 935 func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { 936 // Short circuit if the body's already in the cache, retrieve otherwise 937 if cached, ok := bc.bodyRLPCache.Get(hash); ok { 938 return cached.(rlp.RawValue) 939 } 940 number := bc.hc.GetBlockNumber(hash) 941 if number == nil { 942 return nil 943 } 944 body := rawdb.ReadBodyRLP(bc.db, hash, *number) 945 if len(body) == 0 { 946 return nil 947 } 948 // Cache the found body for next time and return 949 bc.bodyRLPCache.Add(hash, body) 950 return body 951 } 952 953 // GetDiffLayerRLP retrieves a diff layer in RLP encoding from the cache or database by blockHash 954 func (bc *BlockChain) GetDiffLayerRLP(blockHash common.Hash) rlp.RawValue { 955 // Short circuit if the diffLayer's already in the cache, retrieve otherwise 956 if cached, ok := bc.diffLayerRLPCache.Get(blockHash); ok { 957 return cached.(rlp.RawValue) 958 } 959 if cached, ok := bc.diffLayerCache.Get(blockHash); ok { 960 diff := cached.(*types.DiffLayer) 961 bz, err := rlp.EncodeToBytes(diff) 962 if err != nil { 963 return nil 964 } 965 bc.diffLayerRLPCache.Add(blockHash, rlp.RawValue(bz)) 966 return bz 967 } 968 969 // fallback to untrusted sources. 970 diff := bc.GetUnTrustedDiffLayer(blockHash, "") 971 if diff != nil { 972 bz, err := rlp.EncodeToBytes(diff) 973 if err != nil { 974 return nil 975 } 976 // No need to cache untrusted data 977 return bz 978 } 979 980 // fallback to disk 981 diffStore := bc.db.DiffStore() 982 if diffStore == nil { 983 return nil 984 } 985 rawData := rawdb.ReadDiffLayerRLP(diffStore, blockHash) 986 if len(rawData) != 0 { 987 bc.diffLayerRLPCache.Add(blockHash, rawData) 988 } 989 return rawData 990 } 991 992 func (bc *BlockChain) GetDiffAccounts(blockHash common.Hash) ([]common.Address, error) { 993 var ( 994 accounts []common.Address 995 diffLayer *types.DiffLayer 996 ) 997 998 header := bc.GetHeaderByHash(blockHash) 999 if header == nil { 1000 return nil, fmt.Errorf("no block found") 1001 } 1002 1003 if cached, ok := bc.diffLayerCache.Get(blockHash); ok { 1004 diffLayer = cached.(*types.DiffLayer) 1005 } else if diffStore := bc.db.DiffStore(); diffStore != nil { 1006 diffLayer = rawdb.ReadDiffLayer(diffStore, blockHash) 1007 } 1008 1009 if diffLayer == nil { 1010 if header.TxHash != types.EmptyRootHash { 1011 return nil, fmt.Errorf("no diff layer found") 1012 } 1013 1014 return nil, nil 1015 } 1016 1017 for _, diffAccounts := range diffLayer.Accounts { 1018 accounts = append(accounts, diffAccounts.Account) 1019 } 1020 1021 if header.TxHash != types.EmptyRootHash && len(accounts) == 0 { 1022 return nil, fmt.Errorf("no diff account in block, maybe bad diff layer") 1023 } 1024 1025 return accounts, nil 1026 } 1027 1028 // HasBlock checks if a block is fully present in the database or not. 1029 func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool { 1030 if bc.blockCache.Contains(hash) { 1031 return true 1032 } 1033 return rawdb.HasBody(bc.db, hash, number) 1034 } 1035 1036 // HasFastBlock checks if a fast block is fully present in the database or not. 1037 func (bc *BlockChain) HasFastBlock(hash common.Hash, number uint64) bool { 1038 if !bc.HasBlock(hash, number) { 1039 return false 1040 } 1041 if bc.receiptsCache.Contains(hash) { 1042 return true 1043 } 1044 return rawdb.HasReceipts(bc.db, hash, number) 1045 } 1046 1047 // HasState checks if state trie is fully present in the database or not. 1048 func (bc *BlockChain) HasState(hash common.Hash) bool { 1049 _, err := bc.stateCache.OpenTrie(hash) 1050 return err == nil 1051 } 1052 1053 // HasBlockAndState checks if a block and associated state trie is fully present 1054 // in the database or not, caching it if present. 1055 func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool { 1056 // Check first that the block itself is known 1057 block := bc.GetBlock(hash, number) 1058 if block == nil { 1059 return false 1060 } 1061 return bc.HasState(block.Root()) 1062 } 1063 1064 // GetBlock retrieves a block from the database by hash and number, 1065 // caching it if found. 1066 func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 1067 // Short circuit if the block's already in the cache, retrieve otherwise 1068 if block, ok := bc.blockCache.Get(hash); ok { 1069 return block.(*types.Block) 1070 } 1071 block := rawdb.ReadBlock(bc.db, hash, number) 1072 if block == nil { 1073 return nil 1074 } 1075 // Cache the found block for next time and return 1076 bc.blockCache.Add(block.Hash(), block) 1077 return block 1078 } 1079 1080 // GetBlockByHash retrieves a block from the database by hash, caching it if found. 1081 func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { 1082 number := bc.hc.GetBlockNumber(hash) 1083 if number == nil { 1084 return nil 1085 } 1086 return bc.GetBlock(hash, *number) 1087 } 1088 1089 // GetBlockByNumber retrieves a block from the database by number, caching it 1090 // (associated with its hash) if found. 1091 func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { 1092 hash := rawdb.ReadCanonicalHash(bc.db, number) 1093 if hash == (common.Hash{}) { 1094 return nil 1095 } 1096 return bc.GetBlock(hash, number) 1097 } 1098 1099 // GetReceiptsByHash retrieves the receipts for all transactions in a given block. 1100 func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { 1101 if receipts, ok := bc.receiptsCache.Get(hash); ok { 1102 return receipts.(types.Receipts) 1103 } 1104 number := rawdb.ReadHeaderNumber(bc.db, hash) 1105 if number == nil { 1106 return nil 1107 } 1108 receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig) 1109 if receipts == nil { 1110 return nil 1111 } 1112 bc.receiptsCache.Add(hash, receipts) 1113 return receipts 1114 } 1115 1116 // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. 1117 // [deprecated by eth/62] 1118 func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { 1119 number := bc.hc.GetBlockNumber(hash) 1120 if number == nil { 1121 return nil 1122 } 1123 for i := 0; i < n; i++ { 1124 block := bc.GetBlock(hash, *number) 1125 if block == nil { 1126 break 1127 } 1128 blocks = append(blocks, block) 1129 hash = block.ParentHash() 1130 *number-- 1131 } 1132 return 1133 } 1134 1135 // GetUnclesInChain retrieves all the uncles from a given block backwards until 1136 // a specific distance is reached. 1137 func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { 1138 uncles := []*types.Header{} 1139 for i := 0; block != nil && i < length; i++ { 1140 uncles = append(uncles, block.Uncles()...) 1141 block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 1142 } 1143 return uncles 1144 } 1145 1146 // TrieNode retrieves a blob of data associated with a trie node 1147 // either from ephemeral in-memory cache, or from persistent storage. 1148 func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) { 1149 return bc.stateCache.TrieDB().Node(hash) 1150 } 1151 1152 // ContractCode retrieves a blob of data associated with a contract hash 1153 // either from ephemeral in-memory cache, or from persistent storage. 1154 func (bc *BlockChain) ContractCode(hash common.Hash) ([]byte, error) { 1155 return bc.stateCache.ContractCode(common.Hash{}, hash) 1156 } 1157 1158 // ContractCodeWithPrefix retrieves a blob of data associated with a contract 1159 // hash either from ephemeral in-memory cache, or from persistent storage. 1160 // 1161 // If the code doesn't exist in the in-memory cache, check the storage with 1162 // new code scheme. 1163 func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) { 1164 type codeReader interface { 1165 ContractCodeWithPrefix(addrHash, codeHash common.Hash) ([]byte, error) 1166 } 1167 return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Hash{}, hash) 1168 } 1169 1170 // Stop stops the blockchain service. If any imports are currently in progress 1171 // it will abort them using the procInterrupt. 1172 func (bc *BlockChain) Stop() { 1173 if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { 1174 return 1175 } 1176 // Unsubscribe all subscriptions registered from blockchain 1177 bc.scope.Close() 1178 close(bc.quit) 1179 bc.StopInsert() 1180 bc.wg.Wait() 1181 1182 // Ensure that the entirety of the state snapshot is journalled to disk. 1183 var snapBase common.Hash 1184 if bc.snaps != nil { 1185 var err error 1186 if snapBase, err = bc.snaps.Journal(bc.CurrentBlock().Root()); err != nil { 1187 log.Error("Failed to journal state snapshot", "err", err) 1188 } 1189 } 1190 // Ensure the state of a recent block is also stored to disk before exiting. 1191 // We're writing three different states to catch different restart scenarios: 1192 // - HEAD: So we don't need to reprocess any blocks in the general case 1193 // - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle 1194 // - HEAD-127: So we have a hard limit on the number of blocks reexecuted 1195 if !bc.cacheConfig.TrieDirtyDisabled { 1196 triedb := bc.stateCache.TrieDB() 1197 1198 for _, offset := range []uint64{0, 1, bc.triesInMemory - 1} { 1199 if number := bc.CurrentBlock().NumberU64(); number > offset { 1200 recent := bc.GetBlockByNumber(number - offset) 1201 1202 log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root()) 1203 if err := triedb.Commit(recent.Root(), true, nil); err != nil { 1204 log.Error("Failed to commit recent state trie", "err", err) 1205 } 1206 } 1207 } 1208 if snapBase != (common.Hash{}) { 1209 log.Info("Writing snapshot state to disk", "root", snapBase) 1210 if err := triedb.Commit(snapBase, true, nil); err != nil { 1211 log.Error("Failed to commit recent state trie", "err", err) 1212 } 1213 } 1214 for !bc.triegc.Empty() { 1215 go triedb.Dereference(bc.triegc.PopItem().(common.Hash)) 1216 } 1217 if size, _ := triedb.Size(); size != 0 { 1218 log.Error("Dangling trie nodes after full cleanup") 1219 } 1220 } 1221 // Ensure all live cached entries be saved into disk, so that we can skip 1222 // cache warmup when node restarts. 1223 if bc.cacheConfig.TrieCleanJournal != "" { 1224 triedb := bc.stateCache.TrieDB() 1225 triedb.SaveCache(bc.cacheConfig.TrieCleanJournal) 1226 } 1227 log.Info("Blockchain stopped") 1228 } 1229 1230 // StopInsert interrupts all insertion methods, causing them to return 1231 // errInsertionInterrupted as soon as possible. Insertion is permanently disabled after 1232 // calling this method. 1233 func (bc *BlockChain) StopInsert() { 1234 atomic.StoreInt32(&bc.procInterrupt, 1) 1235 } 1236 1237 // insertStopped returns true after StopInsert has been called. 1238 func (bc *BlockChain) insertStopped() bool { 1239 return atomic.LoadInt32(&bc.procInterrupt) == 1 1240 } 1241 1242 func (bc *BlockChain) procFutureBlocks() { 1243 blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) 1244 for _, hash := range bc.futureBlocks.Keys() { 1245 if block, exist := bc.futureBlocks.Peek(hash); exist { 1246 blocks = append(blocks, block.(*types.Block)) 1247 } 1248 } 1249 if len(blocks) > 0 { 1250 sort.Slice(blocks, func(i, j int) bool { 1251 return blocks[i].NumberU64() < blocks[j].NumberU64() 1252 }) 1253 // Insert one by one as chain insertion needs contiguous ancestry between blocks 1254 for i := range blocks { 1255 bc.InsertChain(blocks[i : i+1]) 1256 } 1257 } 1258 } 1259 1260 // WriteStatus status of write 1261 type WriteStatus byte 1262 1263 const ( 1264 NonStatTy WriteStatus = iota 1265 CanonStatTy 1266 SideStatTy 1267 ) 1268 1269 // truncateAncient rewinds the blockchain to the specified header and deletes all 1270 // data in the ancient store that exceeds the specified header. 1271 func (bc *BlockChain) truncateAncient(head uint64) error { 1272 frozen, err := bc.db.Ancients() 1273 if err != nil { 1274 return err 1275 } 1276 // Short circuit if there is no data to truncate in ancient store. 1277 if frozen <= head+1 { 1278 return nil 1279 } 1280 // Truncate all the data in the freezer beyond the specified head 1281 if err := bc.db.TruncateAncients(head + 1); err != nil { 1282 return err 1283 } 1284 // Clear out any stale content from the caches 1285 bc.hc.headerCache.Purge() 1286 bc.hc.tdCache.Purge() 1287 bc.hc.numberCache.Purge() 1288 1289 // Clear out any stale content from the caches 1290 bc.bodyCache.Purge() 1291 bc.bodyRLPCache.Purge() 1292 bc.receiptsCache.Purge() 1293 bc.blockCache.Purge() 1294 bc.txLookupCache.Purge() 1295 bc.futureBlocks.Purge() 1296 1297 log.Info("Rewind ancient data", "number", head) 1298 return nil 1299 } 1300 1301 // numberHash is just a container for a number and a hash, to represent a block 1302 type numberHash struct { 1303 number uint64 1304 hash common.Hash 1305 } 1306 1307 // InsertReceiptChain attempts to complete an already existing header chain with 1308 // transaction and receipt data. 1309 func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error) { 1310 // We don't require the chainMu here since we want to maximize the 1311 // concurrency of header insertion and receipt insertion. 1312 bc.wg.Add(1) 1313 defer bc.wg.Done() 1314 1315 var ( 1316 ancientBlocks, liveBlocks types.Blocks 1317 ancientReceipts, liveReceipts []types.Receipts 1318 ) 1319 // Do a sanity check that the provided chain is actually ordered and linked 1320 for i := 0; i < len(blockChain); i++ { 1321 if i != 0 { 1322 if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { 1323 log.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(), 1324 "prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash()) 1325 return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, blockChain[i-1].NumberU64(), 1326 blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4]) 1327 } 1328 } 1329 if blockChain[i].NumberU64() <= ancientLimit { 1330 ancientBlocks, ancientReceipts = append(ancientBlocks, blockChain[i]), append(ancientReceipts, receiptChain[i]) 1331 } else { 1332 liveBlocks, liveReceipts = append(liveBlocks, blockChain[i]), append(liveReceipts, receiptChain[i]) 1333 } 1334 } 1335 1336 var ( 1337 stats = struct{ processed, ignored int32 }{} 1338 start = time.Now() 1339 size = 0 1340 ) 1341 // updateHead updates the head fast sync block if the inserted blocks are better 1342 // and returns an indicator whether the inserted blocks are canonical. 1343 updateHead := func(head *types.Block) bool { 1344 bc.chainmu.Lock() 1345 1346 // Rewind may have occurred, skip in that case. 1347 if bc.CurrentHeader().Number.Cmp(head.Number()) >= 0 { 1348 currentFastBlock, td := bc.CurrentFastBlock(), bc.GetTd(head.Hash(), head.NumberU64()) 1349 if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 { 1350 rawdb.WriteHeadFastBlockHash(bc.db, head.Hash()) 1351 bc.currentFastBlock.Store(head) 1352 headFastBlockGauge.Update(int64(head.NumberU64())) 1353 bc.chainmu.Unlock() 1354 return true 1355 } 1356 } 1357 bc.chainmu.Unlock() 1358 return false 1359 } 1360 // writeAncient writes blockchain and corresponding receipt chain into ancient store. 1361 // 1362 // this function only accepts canonical chain data. All side chain will be reverted 1363 // eventually. 1364 writeAncient := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { 1365 var ( 1366 previous = bc.CurrentFastBlock() 1367 batch = bc.db.NewBatch() 1368 ) 1369 // If any error occurs before updating the head or we are inserting a side chain, 1370 // all the data written this time wll be rolled back. 1371 defer func() { 1372 if previous != nil { 1373 if err := bc.truncateAncient(previous.NumberU64()); err != nil { 1374 log.Crit("Truncate ancient store failed", "err", err) 1375 } 1376 } 1377 }() 1378 var deleted []*numberHash 1379 for i, block := range blockChain { 1380 // Short circuit insertion if shutting down or processing failed 1381 if bc.insertStopped() { 1382 return 0, errInsertionInterrupted 1383 } 1384 // Short circuit insertion if it is required(used in testing only) 1385 if bc.terminateInsert != nil && bc.terminateInsert(block.Hash(), block.NumberU64()) { 1386 return i, errors.New("insertion is terminated for testing purpose") 1387 } 1388 // Short circuit if the owner header is unknown 1389 if !bc.HasHeader(block.Hash(), block.NumberU64()) { 1390 return i, fmt.Errorf("containing header #%d [%x..] unknown", block.Number(), block.Hash().Bytes()[:4]) 1391 } 1392 if block.NumberU64() == 1 { 1393 // Make sure to write the genesis into the freezer 1394 if frozen, _ := bc.db.Ancients(); frozen == 0 { 1395 h := rawdb.ReadCanonicalHash(bc.db, 0) 1396 b := rawdb.ReadBlock(bc.db, h, 0) 1397 size += rawdb.WriteAncientBlock(bc.db, b, rawdb.ReadReceipts(bc.db, h, 0, bc.chainConfig), rawdb.ReadTd(bc.db, h, 0)) 1398 log.Info("Wrote genesis to ancients") 1399 } 1400 } 1401 // Flush data into ancient database. 1402 size += rawdb.WriteAncientBlock(bc.db, block, receiptChain[i], bc.GetTd(block.Hash(), block.NumberU64())) 1403 1404 // Write tx indices if any condition is satisfied: 1405 // * If user requires to reserve all tx indices(txlookuplimit=0) 1406 // * If all ancient tx indices are required to be reserved(txlookuplimit is even higher than ancientlimit) 1407 // * If block number is large enough to be regarded as a recent block 1408 // It means blocks below the ancientLimit-txlookupLimit won't be indexed. 1409 // 1410 // But if the `TxIndexTail` is not nil, e.g. Geth is initialized with 1411 // an external ancient database, during the setup, blockchain will start 1412 // a background routine to re-indexed all indices in [ancients - txlookupLimit, ancients) 1413 // range. In this case, all tx indices of newly imported blocks should be 1414 // generated. 1415 if bc.txLookupLimit == 0 || ancientLimit <= bc.txLookupLimit || block.NumberU64() >= ancientLimit-bc.txLookupLimit { 1416 rawdb.WriteTxLookupEntriesByBlock(batch, block) 1417 } else if rawdb.ReadTxIndexTail(bc.db) != nil { 1418 rawdb.WriteTxLookupEntriesByBlock(batch, block) 1419 } 1420 stats.processed++ 1421 } 1422 // Flush all tx-lookup index data. 1423 size += batch.ValueSize() 1424 if err := batch.Write(); err != nil { 1425 return 0, err 1426 } 1427 batch.Reset() 1428 1429 // Sync the ancient store explicitly to ensure all data has been flushed to disk. 1430 if err := bc.db.Sync(); err != nil { 1431 return 0, err 1432 } 1433 if !updateHead(blockChain[len(blockChain)-1]) { 1434 return 0, errors.New("side blocks can't be accepted as the ancient chain data") 1435 } 1436 previous = nil // disable rollback explicitly 1437 1438 // Wipe out canonical block data. 1439 for _, nh := range deleted { 1440 rawdb.DeleteBlockWithoutNumber(batch, nh.hash, nh.number) 1441 rawdb.DeleteCanonicalHash(batch, nh.number) 1442 } 1443 for _, block := range blockChain { 1444 // Always keep genesis block in active database. 1445 if block.NumberU64() != 0 { 1446 rawdb.DeleteBlockWithoutNumber(batch, block.Hash(), block.NumberU64()) 1447 rawdb.DeleteCanonicalHash(batch, block.NumberU64()) 1448 } 1449 } 1450 if err := batch.Write(); err != nil { 1451 return 0, err 1452 } 1453 batch.Reset() 1454 1455 // Wipe out side chain too. 1456 for _, nh := range deleted { 1457 for _, hash := range rawdb.ReadAllHashes(bc.db, nh.number) { 1458 rawdb.DeleteBlock(batch, hash, nh.number) 1459 } 1460 } 1461 for _, block := range blockChain { 1462 // Always keep genesis block in active database. 1463 if block.NumberU64() != 0 { 1464 for _, hash := range rawdb.ReadAllHashes(bc.db, block.NumberU64()) { 1465 rawdb.DeleteBlock(batch, hash, block.NumberU64()) 1466 } 1467 } 1468 } 1469 if err := batch.Write(); err != nil { 1470 return 0, err 1471 } 1472 return 0, nil 1473 } 1474 // writeLive writes blockchain and corresponding receipt chain into active store. 1475 writeLive := func(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { 1476 skipPresenceCheck := false 1477 batch := bc.db.NewBatch() 1478 for i, block := range blockChain { 1479 // Short circuit insertion if shutting down or processing failed 1480 if bc.insertStopped() { 1481 return 0, errInsertionInterrupted 1482 } 1483 // Short circuit if the owner header is unknown 1484 if !bc.HasHeader(block.Hash(), block.NumberU64()) { 1485 return i, fmt.Errorf("containing header #%d [%x..] unknown", block.Number(), block.Hash().Bytes()[:4]) 1486 } 1487 if !skipPresenceCheck { 1488 // Ignore if the entire data is already known 1489 if bc.HasBlock(block.Hash(), block.NumberU64()) { 1490 stats.ignored++ 1491 continue 1492 } else { 1493 // If block N is not present, neither are the later blocks. 1494 // This should be true, but if we are mistaken, the shortcut 1495 // here will only cause overwriting of some existing data 1496 skipPresenceCheck = true 1497 } 1498 } 1499 // Write all the data out into the database 1500 rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()) 1501 rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i]) 1502 rawdb.WriteTxLookupEntriesByBlock(batch, block) // Always write tx indices for live blocks, we assume they are needed 1503 1504 // Write everything belongs to the blocks into the database. So that 1505 // we can ensure all components of body is completed(body, receipts, 1506 // tx indexes) 1507 if batch.ValueSize() >= ethdb.IdealBatchSize { 1508 if err := batch.Write(); err != nil { 1509 return 0, err 1510 } 1511 size += batch.ValueSize() 1512 batch.Reset() 1513 } 1514 stats.processed++ 1515 } 1516 // Write everything belongs to the blocks into the database. So that 1517 // we can ensure all components of body is completed(body, receipts, 1518 // tx indexes) 1519 if batch.ValueSize() > 0 { 1520 size += batch.ValueSize() 1521 if err := batch.Write(); err != nil { 1522 return 0, err 1523 } 1524 } 1525 updateHead(blockChain[len(blockChain)-1]) 1526 return 0, nil 1527 } 1528 // Write downloaded chain data and corresponding receipt chain data 1529 if len(ancientBlocks) > 0 { 1530 if n, err := writeAncient(ancientBlocks, ancientReceipts); err != nil { 1531 if err == errInsertionInterrupted { 1532 return 0, nil 1533 } 1534 return n, err 1535 } 1536 } 1537 // Write the tx index tail (block number from where we index) before write any live blocks 1538 if len(liveBlocks) > 0 && liveBlocks[0].NumberU64() == ancientLimit+1 { 1539 // The tx index tail can only be one of the following two options: 1540 // * 0: all ancient blocks have been indexed 1541 // * ancient-limit: the indices of blocks before ancient-limit are ignored 1542 if tail := rawdb.ReadTxIndexTail(bc.db); tail == nil { 1543 if bc.txLookupLimit == 0 || ancientLimit <= bc.txLookupLimit { 1544 rawdb.WriteTxIndexTail(bc.db, 0) 1545 } else { 1546 rawdb.WriteTxIndexTail(bc.db, ancientLimit-bc.txLookupLimit) 1547 } 1548 } 1549 } 1550 if len(liveBlocks) > 0 { 1551 if n, err := writeLive(liveBlocks, liveReceipts); err != nil { 1552 if err == errInsertionInterrupted { 1553 return 0, nil 1554 } 1555 return n, err 1556 } 1557 } 1558 1559 head := blockChain[len(blockChain)-1] 1560 context := []interface{}{ 1561 "count", stats.processed, "elapsed", common.PrettyDuration(time.Since(start)), 1562 "number", head.Number(), "hash", head.Hash(), "age", common.PrettyAge(time.Unix(int64(head.Time()), 0)), 1563 "size", common.StorageSize(size), 1564 } 1565 if stats.ignored > 0 { 1566 context = append(context, []interface{}{"ignored", stats.ignored}...) 1567 } 1568 log.Info("Imported new block receipts", context...) 1569 1570 return 0, nil 1571 } 1572 1573 // SetTxLookupLimit is responsible for updating the txlookup limit to the 1574 // original one stored in db if the new mismatches with the old one. 1575 func (bc *BlockChain) SetTxLookupLimit(limit uint64) { 1576 bc.txLookupLimit = limit 1577 } 1578 1579 // TxLookupLimit retrieves the txlookup limit used by blockchain to prune 1580 // stale transaction indices. 1581 func (bc *BlockChain) TxLookupLimit() uint64 { 1582 return bc.txLookupLimit 1583 } 1584 1585 var lastWrite uint64 1586 1587 // writeBlockWithoutState writes only the block and its metadata to the database, 1588 // but does not write any state. This is used to construct competing side forks 1589 // up to the point where they exceed the canonical total difficulty. 1590 func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (err error) { 1591 bc.wg.Add(1) 1592 defer bc.wg.Done() 1593 1594 batch := bc.db.NewBatch() 1595 rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td) 1596 rawdb.WriteBlock(batch, block) 1597 if err := batch.Write(); err != nil { 1598 log.Crit("Failed to write block into disk", "err", err) 1599 } 1600 return nil 1601 } 1602 1603 // writeKnownBlock updates the head block flag with a known block 1604 // and introduces chain reorg if necessary. 1605 func (bc *BlockChain) writeKnownBlock(block *types.Block) error { 1606 bc.wg.Add(1) 1607 defer bc.wg.Done() 1608 1609 current := bc.CurrentBlock() 1610 if block.ParentHash() != current.Hash() { 1611 if err := bc.reorg(current, block); err != nil { 1612 return err 1613 } 1614 } 1615 bc.writeHeadBlock(block) 1616 return nil 1617 } 1618 1619 // WriteBlockWithState writes the block and all associated state to the database. 1620 func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { 1621 bc.chainmu.Lock() 1622 defer bc.chainmu.Unlock() 1623 1624 return bc.writeBlockWithState(block, receipts, logs, state, emitHeadEvent) 1625 } 1626 1627 // writeBlockWithState writes the block and all associated state to the database, 1628 // but is expects the chain mutex to be held. 1629 func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { 1630 bc.wg.Add(1) 1631 defer bc.wg.Done() 1632 1633 // Calculate the total difficulty of the block 1634 ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) 1635 if ptd == nil { 1636 return NonStatTy, consensus.ErrUnknownAncestor 1637 } 1638 // Make sure no inconsistent state is leaked during insertion 1639 currentBlock := bc.CurrentBlock() 1640 localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 1641 externTd := new(big.Int).Add(block.Difficulty(), ptd) 1642 1643 // Irrelevant of the canonical status, write the block itself to the database. 1644 // 1645 // Note all the components of block(td, hash->number map, header, body, receipts) 1646 // should be written atomically. BlockBatch is used for containing all components. 1647 wg := sync.WaitGroup{} 1648 wg.Add(1) 1649 go func() { 1650 blockBatch := bc.db.NewBatch() 1651 rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd) 1652 rawdb.WriteBlock(blockBatch, block) 1653 rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts) 1654 rawdb.WritePreimages(blockBatch, state.Preimages()) 1655 if err := blockBatch.Write(); err != nil { 1656 log.Crit("Failed to write block into disk", "err", err) 1657 } 1658 wg.Done() 1659 }() 1660 // Commit all cached state changes into underlying memory database. 1661 root, diffLayer, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) 1662 if err != nil { 1663 return NonStatTy, err 1664 } 1665 1666 // Ensure no empty block body 1667 if diffLayer != nil && block.Header().TxHash != types.EmptyRootHash { 1668 // Filling necessary field 1669 diffLayer.Receipts = receipts 1670 diffLayer.BlockHash = block.Hash() 1671 diffLayer.Number = block.NumberU64() 1672 bc.cacheDiffLayer(diffLayer) 1673 } 1674 triedb := bc.stateCache.TrieDB() 1675 1676 // If we're running an archive node, always flush 1677 if bc.cacheConfig.TrieDirtyDisabled { 1678 if err := triedb.Commit(root, false, nil); err != nil { 1679 return NonStatTy, err 1680 } 1681 } else { 1682 // Full but not archive node, do proper garbage collection 1683 triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive 1684 bc.triegc.Push(root, -int64(block.NumberU64())) 1685 1686 if current := block.NumberU64(); current > bc.triesInMemory { 1687 // If we exceeded our memory allowance, flush matured singleton nodes to disk 1688 var ( 1689 nodes, imgs = triedb.Size() 1690 limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024 1691 ) 1692 if nodes > limit || imgs > 4*1024*1024 { 1693 triedb.Cap(limit - ethdb.IdealBatchSize) 1694 } 1695 // Find the next state trie we need to commit 1696 chosen := current - bc.triesInMemory 1697 1698 // If we exceeded out time allowance, flush an entire trie to disk 1699 if bc.gcproc > bc.cacheConfig.TrieTimeLimit { 1700 canWrite := true 1701 if posa, ok := bc.engine.(consensus.PoSA); ok { 1702 if !posa.EnoughDistance(bc, block.Header()) { 1703 canWrite = false 1704 } 1705 } 1706 if canWrite { 1707 // If the header is missing (canonical chain behind), we're reorging a low 1708 // diff sidechain. Suspend committing until this operation is completed. 1709 header := bc.GetHeaderByNumber(chosen) 1710 if header == nil { 1711 log.Warn("Reorg in progress, trie commit postponed", "number", chosen) 1712 } else { 1713 // If we're exceeding limits but haven't reached a large enough memory gap, 1714 // warn the user that the system is becoming unstable. 1715 if chosen < lastWrite+bc.triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { 1716 log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/float64(bc.triesInMemory)) 1717 } 1718 // Flush an entire trie and restart the counters 1719 triedb.Commit(header.Root, true, nil) 1720 lastWrite = chosen 1721 bc.gcproc = 0 1722 } 1723 } 1724 } 1725 // Garbage collect anything below our required write retention 1726 for !bc.triegc.Empty() { 1727 root, number := bc.triegc.Pop() 1728 if uint64(-number) > chosen { 1729 bc.triegc.Push(root, number) 1730 break 1731 } 1732 go triedb.Dereference(root.(common.Hash)) 1733 } 1734 } 1735 } 1736 wg.Wait() 1737 // If the total difficulty is higher than our known, add it to the canonical chain 1738 // Second clause in the if statement reduces the vulnerability to selfish mining. 1739 // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf 1740 reorg := externTd.Cmp(localTd) > 0 1741 currentBlock = bc.CurrentBlock() 1742 if !reorg && externTd.Cmp(localTd) == 0 { 1743 // Split same-difficulty blocks by number, then preferentially select 1744 // the block generated by the local miner as the canonical block. 1745 if block.NumberU64() < currentBlock.NumberU64() || block.Time() < currentBlock.Time() { 1746 reorg = true 1747 } else if p, ok := bc.engine.(consensus.PoSA); ok && p.IsLocalBlock(currentBlock.Header()) { 1748 reorg = true 1749 } else if block.NumberU64() == currentBlock.NumberU64() { 1750 var currentPreserve, blockPreserve bool 1751 if bc.shouldPreserve != nil { 1752 currentPreserve, blockPreserve = bc.shouldPreserve(currentBlock), bc.shouldPreserve(block) 1753 } 1754 reorg = !currentPreserve && (blockPreserve || mrand.Float64() < 0.5) 1755 } 1756 } 1757 if reorg { 1758 // Reorganise the chain if the parent is not the head block 1759 if block.ParentHash() != currentBlock.Hash() { 1760 if err := bc.reorg(currentBlock, block); err != nil { 1761 return NonStatTy, err 1762 } 1763 } 1764 status = CanonStatTy 1765 } else { 1766 status = SideStatTy 1767 } 1768 // Set new head. 1769 if status == CanonStatTy { 1770 bc.writeHeadBlock(block) 1771 } 1772 bc.futureBlocks.Remove(block.Hash()) 1773 1774 if status == CanonStatTy { 1775 bc.chainFeed.Send(ChainEvent{Block: block, Hash: block.Hash(), Logs: logs}) 1776 if len(logs) > 0 { 1777 bc.logsFeed.Send(logs) 1778 } 1779 // In theory we should fire a ChainHeadEvent when we inject 1780 // a canonical block, but sometimes we can insert a batch of 1781 // canonicial blocks. Avoid firing too much ChainHeadEvents, 1782 // we will fire an accumulated ChainHeadEvent and disable fire 1783 // event here. 1784 if emitHeadEvent { 1785 bc.chainHeadFeed.Send(ChainHeadEvent{Block: block}) 1786 } 1787 } else { 1788 bc.chainSideFeed.Send(ChainSideEvent{Block: block}) 1789 } 1790 return status, nil 1791 } 1792 1793 // addFutureBlock checks if the block is within the max allowed window to get 1794 // accepted for future processing, and returns an error if the block is too far 1795 // ahead and was not added. 1796 func (bc *BlockChain) addFutureBlock(block *types.Block) error { 1797 max := uint64(time.Now().Unix() + maxTimeFutureBlocks) 1798 if block.Time() > max { 1799 return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max) 1800 } 1801 bc.futureBlocks.Add(block.Hash(), block) 1802 return nil 1803 } 1804 1805 // InsertChain attempts to insert the given batch of blocks in to the canonical 1806 // chain or, otherwise, create a fork. If an error is returned it will return 1807 // the index number of the failing block as well an error describing what went 1808 // wrong. 1809 // 1810 // After insertion is done, all accumulated events will be fired. 1811 func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { 1812 // Sanity check that we have something meaningful to import 1813 if len(chain) == 0 { 1814 return 0, nil 1815 } 1816 1817 bc.blockProcFeed.Send(true) 1818 defer bc.blockProcFeed.Send(false) 1819 1820 // Remove already known canon-blocks 1821 var ( 1822 block, prev *types.Block 1823 ) 1824 // Do a sanity check that the provided chain is actually ordered and linked 1825 for i := 1; i < len(chain); i++ { 1826 block = chain[i] 1827 prev = chain[i-1] 1828 if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() { 1829 // Chain broke ancestry, log a message (programming error) and skip insertion 1830 log.Error("Non contiguous block insert", "number", block.Number(), "hash", block.Hash(), 1831 "parent", block.ParentHash(), "prevnumber", prev.Number(), "prevhash", prev.Hash()) 1832 1833 return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, prev.NumberU64(), 1834 prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4]) 1835 } 1836 } 1837 // Pre-checks passed, start the full block imports 1838 bc.wg.Add(1) 1839 bc.chainmu.Lock() 1840 n, err := bc.insertChain(chain, true) 1841 bc.chainmu.Unlock() 1842 bc.wg.Done() 1843 1844 return n, err 1845 } 1846 1847 // InsertChainWithoutSealVerification works exactly the same 1848 // except for seal verification, seal verification is omitted 1849 func (bc *BlockChain) InsertChainWithoutSealVerification(block *types.Block) (int, error) { 1850 bc.blockProcFeed.Send(true) 1851 defer bc.blockProcFeed.Send(false) 1852 1853 // Pre-checks passed, start the full block imports 1854 bc.wg.Add(1) 1855 bc.chainmu.Lock() 1856 n, err := bc.insertChain(types.Blocks([]*types.Block{block}), false) 1857 bc.chainmu.Unlock() 1858 bc.wg.Done() 1859 1860 return n, err 1861 } 1862 1863 // insertChain is the internal implementation of InsertChain, which assumes that 1864 // 1) chains are contiguous, and 2) The chain mutex is held. 1865 // 1866 // This method is split out so that import batches that require re-injecting 1867 // historical blocks can do so without releasing the lock, which could lead to 1868 // racey behaviour. If a sidechain import is in progress, and the historic state 1869 // is imported, but then new canon-head is added before the actual sidechain 1870 // completes, then the historic state could be pruned again 1871 func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, error) { 1872 // If the chain is terminating, don't even bother starting up 1873 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1874 return 0, nil 1875 } 1876 // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) 1877 signer := types.MakeSigner(bc.chainConfig, chain[0].Number()) 1878 go senderCacher.recoverFromBlocks(signer, chain) 1879 1880 var ( 1881 stats = insertStats{startTime: mclock.Now()} 1882 lastCanon *types.Block 1883 ) 1884 // Fire a single chain head event if we've progressed the chain 1885 defer func() { 1886 if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { 1887 bc.chainHeadFeed.Send(ChainHeadEvent{lastCanon}) 1888 } 1889 }() 1890 // Start the parallel header verifier 1891 headers := make([]*types.Header, len(chain)) 1892 seals := make([]bool, len(chain)) 1893 1894 for i, block := range chain { 1895 headers[i] = block.Header() 1896 seals[i] = verifySeals 1897 } 1898 abort, results := bc.engine.VerifyHeaders(bc, headers, seals) 1899 defer close(abort) 1900 1901 // Peek the error for the first block to decide the directing import logic 1902 it := newInsertIterator(chain, results, bc.validator) 1903 1904 block, err := it.next() 1905 1906 // Left-trim all the known blocks 1907 if err == ErrKnownBlock { 1908 // First block (and state) is known 1909 // 1. We did a roll-back, and should now do a re-import 1910 // 2. The block is stored as a sidechain, and is lying about it's stateroot, and passes a stateroot 1911 // from the canonical chain, which has not been verified. 1912 // Skip all known blocks that are behind us 1913 var ( 1914 current = bc.CurrentBlock() 1915 localTd = bc.GetTd(current.Hash(), current.NumberU64()) 1916 externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) // The first block can't be nil 1917 ) 1918 for block != nil && err == ErrKnownBlock { 1919 externTd = new(big.Int).Add(externTd, block.Difficulty()) 1920 if localTd.Cmp(externTd) < 0 { 1921 break 1922 } 1923 log.Debug("Ignoring already known block", "number", block.Number(), "hash", block.Hash()) 1924 stats.ignored++ 1925 1926 block, err = it.next() 1927 } 1928 // The remaining blocks are still known blocks, the only scenario here is: 1929 // During the fast sync, the pivot point is already submitted but rollback 1930 // happens. Then node resets the head full block to a lower height via `rollback` 1931 // and leaves a few known blocks in the database. 1932 // 1933 // When node runs a fast sync again, it can re-import a batch of known blocks via 1934 // `insertChain` while a part of them have higher total difficulty than current 1935 // head full block(new pivot point). 1936 for block != nil && err == ErrKnownBlock { 1937 log.Debug("Writing previously known block", "number", block.Number(), "hash", block.Hash()) 1938 if err := bc.writeKnownBlock(block); err != nil { 1939 return it.index, err 1940 } 1941 lastCanon = block 1942 1943 block, err = it.next() 1944 } 1945 // Falls through to the block import 1946 } 1947 switch { 1948 // First block is pruned, insert as sidechain and reorg only if TD grows enough 1949 case errors.Is(err, consensus.ErrPrunedAncestor): 1950 log.Debug("Pruned ancestor, inserting as sidechain", "number", block.Number(), "hash", block.Hash()) 1951 return bc.insertSideChain(block, it) 1952 1953 // First block is future, shove it (and all children) to the future queue (unknown ancestor) 1954 case errors.Is(err, consensus.ErrFutureBlock) || (errors.Is(err, consensus.ErrUnknownAncestor) && bc.futureBlocks.Contains(it.first().ParentHash())): 1955 for block != nil && (it.index == 0 || errors.Is(err, consensus.ErrUnknownAncestor)) { 1956 log.Debug("Future block, postponing import", "number", block.Number(), "hash", block.Hash()) 1957 if err := bc.addFutureBlock(block); err != nil { 1958 return it.index, err 1959 } 1960 block, err = it.next() 1961 } 1962 stats.queued += it.processed() 1963 stats.ignored += it.remaining() 1964 1965 // If there are any still remaining, mark as ignored 1966 return it.index, err 1967 1968 // Some other error occurred, abort 1969 case err != nil: 1970 bc.futureBlocks.Remove(block.Hash()) 1971 stats.ignored += len(it.chain) 1972 bc.reportBlock(block, nil, err) 1973 return it.index, err 1974 } 1975 // No validation errors for the first block (or chain prefix skipped) 1976 var activeState *state.StateDB 1977 defer func() { 1978 // The chain importer is starting and stopping trie prefetchers. If a bad 1979 // block or other error is hit however, an early return may not properly 1980 // terminate the background threads. This defer ensures that we clean up 1981 // and dangling prefetcher, without defering each and holding on live refs. 1982 if activeState != nil { 1983 activeState.StopPrefetcher() 1984 } 1985 }() 1986 1987 for ; block != nil && err == nil || err == ErrKnownBlock; block, err = it.next() { 1988 // If the chain is terminating, stop processing blocks 1989 if bc.insertStopped() { 1990 log.Debug("Abort during block processing") 1991 break 1992 } 1993 // If the header is a banned one, straight out abort 1994 if BadHashes[block.Hash()] { 1995 bc.reportBlock(block, nil, ErrBlacklistedHash) 1996 return it.index, ErrBlacklistedHash 1997 } 1998 // If the block is known (in the middle of the chain), it's a special case for 1999 // Clique blocks where they can share state among each other, so importing an 2000 // older block might complete the state of the subsequent one. In this case, 2001 // just skip the block (we already validated it once fully (and crashed), since 2002 // its header and body was already in the database). 2003 if err == ErrKnownBlock { 2004 logger := log.Debug 2005 if bc.chainConfig.Clique == nil { 2006 logger = log.Warn 2007 } 2008 logger("Inserted known block", "number", block.Number(), "hash", block.Hash(), 2009 "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), 2010 "root", block.Root()) 2011 2012 // Special case. Commit the empty receipt slice if we meet the known 2013 // block in the middle. It can only happen in the clique chain. Whenever 2014 // we insert blocks via `insertSideChain`, we only commit `td`, `header` 2015 // and `body` if it's non-existent. Since we don't have receipts without 2016 // reexecution, so nothing to commit. But if the sidechain will be adpoted 2017 // as the canonical chain eventually, it needs to be reexecuted for missing 2018 // state, but if it's this special case here(skip reexecution) we will lose 2019 // the empty receipt entry. 2020 if len(block.Transactions()) == 0 { 2021 rawdb.WriteReceipts(bc.db, block.Hash(), block.NumberU64(), nil) 2022 } else { 2023 log.Error("Please file an issue, skip known block execution without receipt", 2024 "hash", block.Hash(), "number", block.NumberU64()) 2025 } 2026 if err := bc.writeKnownBlock(block); err != nil { 2027 return it.index, err 2028 } 2029 stats.processed++ 2030 2031 // We can assume that logs are empty here, since the only way for consecutive 2032 // Clique blocks to have the same state is if there are no transactions. 2033 lastCanon = block 2034 continue 2035 } 2036 // Retrieve the parent block and it's state to execute on top 2037 start := time.Now() 2038 2039 parent := it.previous() 2040 if parent == nil { 2041 parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) 2042 } 2043 statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps) 2044 if err != nil { 2045 return it.index, err 2046 } 2047 bc.updateHighestVerifiedHeader(block.Header()) 2048 2049 // Enable prefetching to pull in trie node paths while processing transactions 2050 statedb.StartPrefetcher("chain") 2051 2052 //Process block using the parent state as reference point 2053 substart := time.Now() 2054 statedb, receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig) 2055 activeState = statedb 2056 if err != nil { 2057 bc.reportBlock(block, receipts, err) 2058 return it.index, err 2059 } 2060 // Update the metrics touched during block processing 2061 accountReadTimer.Update(statedb.AccountReads) // Account reads are complete, we can mark them 2062 storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete, we can mark them 2063 accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete, we can mark them 2064 storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete, we can mark them 2065 snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete, we can mark them 2066 snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete, we can mark them 2067 2068 blockExecutionTimer.Update(time.Since(substart)) 2069 2070 // Validate the state using the default validator 2071 substart = time.Now() 2072 if !statedb.IsLightProcessed() { 2073 if err := bc.validator.ValidateState(block, statedb, receipts, usedGas); err != nil { 2074 log.Error("validate state failed", "error", err) 2075 bc.reportBlock(block, receipts, err) 2076 return it.index, err 2077 } 2078 } 2079 bc.cacheReceipts(block.Hash(), receipts) 2080 bc.cacheBlock(block.Hash(), block) 2081 proctime := time.Since(start) 2082 2083 // Update the metrics touched during block validation 2084 accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete, we can mark them 2085 storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete, we can mark them 2086 2087 blockValidationTimer.Update(time.Since(substart)) 2088 2089 // Write the block to the chain and get the status. 2090 substart = time.Now() 2091 status, err := bc.writeBlockWithState(block, receipts, logs, statedb, false) 2092 if err != nil { 2093 return it.index, err 2094 } 2095 // Update the metrics touched during block commit 2096 accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them 2097 storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them 2098 snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them 2099 2100 blockWriteTimer.Update(time.Since(substart)) 2101 blockInsertTimer.UpdateSince(start) 2102 2103 switch status { 2104 case CanonStatTy: 2105 log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), 2106 "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), 2107 "elapsed", common.PrettyDuration(time.Since(start)), 2108 "root", block.Root()) 2109 2110 lastCanon = block 2111 2112 // Only count canonical blocks for GC processing time 2113 bc.gcproc += proctime 2114 2115 case SideStatTy: 2116 log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), 2117 "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), 2118 "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), 2119 "root", block.Root()) 2120 2121 default: 2122 // This in theory is impossible, but lets be nice to our future selves and leave 2123 // a log, instead of trying to track down blocks imports that don't emit logs. 2124 log.Warn("Inserted block with unknown status", "number", block.Number(), "hash", block.Hash(), 2125 "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), 2126 "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), 2127 "root", block.Root()) 2128 } 2129 stats.processed++ 2130 stats.usedGas += usedGas 2131 2132 dirty, _ := bc.stateCache.TrieDB().Size() 2133 stats.report(chain, it.index, dirty) 2134 } 2135 // Any blocks remaining here? The only ones we care about are the future ones 2136 if block != nil && errors.Is(err, consensus.ErrFutureBlock) { 2137 if err := bc.addFutureBlock(block); err != nil { 2138 return it.index, err 2139 } 2140 block, err = it.next() 2141 2142 for ; block != nil && errors.Is(err, consensus.ErrUnknownAncestor); block, err = it.next() { 2143 if err := bc.addFutureBlock(block); err != nil { 2144 return it.index, err 2145 } 2146 stats.queued++ 2147 } 2148 } 2149 stats.ignored += it.remaining() 2150 2151 return it.index, err 2152 } 2153 2154 func (bc *BlockChain) updateHighestVerifiedHeader(header *types.Header) { 2155 if header == nil || header.Number == nil { 2156 return 2157 } 2158 currentHeader := bc.highestVerifiedHeader.Load().(*types.Header) 2159 if currentHeader == nil { 2160 bc.highestVerifiedHeader.Store(types.CopyHeader(header)) 2161 return 2162 } 2163 2164 newParentTD := bc.GetTdByHash(header.ParentHash) 2165 if newParentTD == nil { 2166 newParentTD = big.NewInt(0) 2167 } 2168 oldParentTD := bc.GetTdByHash(currentHeader.ParentHash) 2169 if oldParentTD == nil { 2170 oldParentTD = big.NewInt(0) 2171 } 2172 newTD := big.NewInt(0).Add(newParentTD, header.Difficulty) 2173 oldTD := big.NewInt(0).Add(oldParentTD, currentHeader.Difficulty) 2174 2175 if newTD.Cmp(oldTD) > 0 { 2176 bc.highestVerifiedHeader.Store(types.CopyHeader(header)) 2177 return 2178 } 2179 } 2180 2181 func (bc *BlockChain) GetHighestVerifiedHeader() *types.Header { 2182 return bc.highestVerifiedHeader.Load().(*types.Header) 2183 } 2184 2185 // insertSideChain is called when an import batch hits upon a pruned ancestor 2186 // error, which happens when a sidechain with a sufficiently old fork-block is 2187 // found. 2188 // 2189 // The method writes all (header-and-body-valid) blocks to disk, then tries to 2190 // switch over to the new chain if the TD exceeded the current chain. 2191 func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (int, error) { 2192 var ( 2193 externTd *big.Int 2194 current = bc.CurrentBlock() 2195 ) 2196 // The first sidechain block error is already verified to be ErrPrunedAncestor. 2197 // Since we don't import them here, we expect ErrUnknownAncestor for the remaining 2198 // ones. Any other errors means that the block is invalid, and should not be written 2199 // to disk. 2200 err := consensus.ErrPrunedAncestor 2201 for ; block != nil && errors.Is(err, consensus.ErrPrunedAncestor); block, err = it.next() { 2202 // Check the canonical state root for that number 2203 if number := block.NumberU64(); current.NumberU64() >= number { 2204 canonical := bc.GetBlockByNumber(number) 2205 if canonical != nil && canonical.Hash() == block.Hash() { 2206 // Not a sidechain block, this is a re-import of a canon block which has it's state pruned 2207 2208 // Collect the TD of the block. Since we know it's a canon one, 2209 // we can get it directly, and not (like further below) use 2210 // the parent and then add the block on top 2211 externTd = bc.GetTd(block.Hash(), block.NumberU64()) 2212 continue 2213 } 2214 if canonical != nil && canonical.Root() == block.Root() { 2215 // This is most likely a shadow-state attack. When a fork is imported into the 2216 // database, and it eventually reaches a block height which is not pruned, we 2217 // just found that the state already exist! This means that the sidechain block 2218 // refers to a state which already exists in our canon chain. 2219 // 2220 // If left unchecked, we would now proceed importing the blocks, without actually 2221 // having verified the state of the previous blocks. 2222 log.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root()) 2223 2224 // If someone legitimately side-mines blocks, they would still be imported as usual. However, 2225 // we cannot risk writing unverified blocks to disk when they obviously target the pruning 2226 // mechanism. 2227 return it.index, errors.New("sidechain ghost-state attack") 2228 } 2229 } 2230 if externTd == nil { 2231 externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) 2232 } 2233 externTd = new(big.Int).Add(externTd, block.Difficulty()) 2234 2235 if !bc.HasBlock(block.Hash(), block.NumberU64()) { 2236 start := time.Now() 2237 if err := bc.writeBlockWithoutState(block, externTd); err != nil { 2238 return it.index, err 2239 } 2240 log.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(), 2241 "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), 2242 "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), 2243 "root", block.Root()) 2244 } 2245 } 2246 // At this point, we've written all sidechain blocks to database. Loop ended 2247 // either on some other error or all were processed. If there was some other 2248 // error, we can ignore the rest of those blocks. 2249 // 2250 // If the externTd was larger than our local TD, we now need to reimport the previous 2251 // blocks to regenerate the required state 2252 localTd := bc.GetTd(current.Hash(), current.NumberU64()) 2253 if localTd.Cmp(externTd) > 0 { 2254 log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd) 2255 return it.index, err 2256 } 2257 // Gather all the sidechain hashes (full blocks may be memory heavy) 2258 var ( 2259 hashes []common.Hash 2260 numbers []uint64 2261 ) 2262 parent := it.previous() 2263 for parent != nil && !bc.HasState(parent.Root) { 2264 hashes = append(hashes, parent.Hash()) 2265 numbers = append(numbers, parent.Number.Uint64()) 2266 2267 parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1) 2268 } 2269 if parent == nil { 2270 return it.index, errors.New("missing parent") 2271 } 2272 // Import all the pruned blocks to make the state available 2273 var ( 2274 blocks []*types.Block 2275 memory common.StorageSize 2276 ) 2277 for i := len(hashes) - 1; i >= 0; i-- { 2278 // Append the next block to our batch 2279 block := bc.GetBlock(hashes[i], numbers[i]) 2280 2281 blocks = append(blocks, block) 2282 memory += block.Size() 2283 2284 // If memory use grew too large, import and continue. Sadly we need to discard 2285 // all raised events and logs from notifications since we're too heavy on the 2286 // memory here. 2287 if len(blocks) >= 2048 || memory > 64*1024*1024 { 2288 log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64()) 2289 if _, err := bc.insertChain(blocks, false); err != nil { 2290 return 0, err 2291 } 2292 blocks, memory = blocks[:0], 0 2293 2294 // If the chain is terminating, stop processing blocks 2295 if bc.insertStopped() { 2296 log.Debug("Abort during blocks processing") 2297 return 0, nil 2298 } 2299 } 2300 } 2301 if len(blocks) > 0 { 2302 log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64()) 2303 return bc.insertChain(blocks, false) 2304 } 2305 return 0, nil 2306 } 2307 2308 // reorg takes two blocks, an old chain and a new chain and will reconstruct the 2309 // blocks and inserts them to be part of the new canonical chain and accumulates 2310 // potential missing transactions and post an event about them. 2311 func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { 2312 var ( 2313 newChain types.Blocks 2314 oldChain types.Blocks 2315 commonBlock *types.Block 2316 2317 deletedTxs types.Transactions 2318 addedTxs types.Transactions 2319 2320 deletedLogs [][]*types.Log 2321 rebirthLogs [][]*types.Log 2322 2323 // collectLogs collects the logs that were generated or removed during 2324 // the processing of the block that corresponds with the given hash. 2325 // These logs are later announced as deleted or reborn 2326 collectLogs = func(hash common.Hash, removed bool) { 2327 number := bc.hc.GetBlockNumber(hash) 2328 if number == nil { 2329 return 2330 } 2331 receipts := rawdb.ReadReceipts(bc.db, hash, *number, bc.chainConfig) 2332 2333 var logs []*types.Log 2334 for _, receipt := range receipts { 2335 for _, log := range receipt.Logs { 2336 l := *log 2337 if removed { 2338 l.Removed = true 2339 } 2340 logs = append(logs, &l) 2341 } 2342 } 2343 if len(logs) > 0 { 2344 if removed { 2345 deletedLogs = append(deletedLogs, logs) 2346 } else { 2347 rebirthLogs = append(rebirthLogs, logs) 2348 } 2349 } 2350 } 2351 // mergeLogs returns a merged log slice with specified sort order. 2352 mergeLogs = func(logs [][]*types.Log, reverse bool) []*types.Log { 2353 var ret []*types.Log 2354 if reverse { 2355 for i := len(logs) - 1; i >= 0; i-- { 2356 ret = append(ret, logs[i]...) 2357 } 2358 } else { 2359 for i := 0; i < len(logs); i++ { 2360 ret = append(ret, logs[i]...) 2361 } 2362 } 2363 return ret 2364 } 2365 ) 2366 // Reduce the longer chain to the same number as the shorter one 2367 if oldBlock.NumberU64() > newBlock.NumberU64() { 2368 // Old chain is longer, gather all transactions and logs as deleted ones 2369 for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { 2370 oldChain = append(oldChain, oldBlock) 2371 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 2372 collectLogs(oldBlock.Hash(), true) 2373 } 2374 } else { 2375 // New chain is longer, stash all blocks away for subsequent insertion 2376 for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { 2377 newChain = append(newChain, newBlock) 2378 } 2379 } 2380 if oldBlock == nil { 2381 return fmt.Errorf("invalid old chain") 2382 } 2383 if newBlock == nil { 2384 return fmt.Errorf("invalid new chain") 2385 } 2386 // Both sides of the reorg are at the same number, reduce both until the common 2387 // ancestor is found 2388 for { 2389 // If the common ancestor was found, bail out 2390 if oldBlock.Hash() == newBlock.Hash() { 2391 commonBlock = oldBlock 2392 break 2393 } 2394 // Remove an old block as well as stash away a new block 2395 oldChain = append(oldChain, oldBlock) 2396 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 2397 collectLogs(oldBlock.Hash(), true) 2398 2399 newChain = append(newChain, newBlock) 2400 2401 // Step back with both chains 2402 oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) 2403 if oldBlock == nil { 2404 return fmt.Errorf("invalid old chain") 2405 } 2406 newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) 2407 if newBlock == nil { 2408 return fmt.Errorf("invalid new chain") 2409 } 2410 } 2411 // Ensure the user sees large reorgs 2412 if len(oldChain) > 0 && len(newChain) > 0 { 2413 logFn := log.Info 2414 msg := "Chain reorg detected" 2415 if len(oldChain) > 63 { 2416 msg = "Large chain reorg detected" 2417 logFn = log.Warn 2418 } 2419 logFn(msg, "number", commonBlock.Number(), "hash", commonBlock.Hash(), 2420 "drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash()) 2421 blockReorgAddMeter.Mark(int64(len(newChain))) 2422 blockReorgDropMeter.Mark(int64(len(oldChain))) 2423 blockReorgMeter.Mark(1) 2424 } else { 2425 log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) 2426 } 2427 // Insert the new chain(except the head block(reverse order)), 2428 // taking care of the proper incremental order. 2429 for i := len(newChain) - 1; i >= 1; i-- { 2430 // Insert the block in the canonical way, re-writing history 2431 bc.writeHeadBlock(newChain[i]) 2432 2433 // Collect reborn logs due to chain reorg 2434 collectLogs(newChain[i].Hash(), false) 2435 2436 // Collect the new added transactions. 2437 addedTxs = append(addedTxs, newChain[i].Transactions()...) 2438 } 2439 // Delete useless indexes right now which includes the non-canonical 2440 // transaction indexes, canonical chain indexes which above the head. 2441 indexesBatch := bc.db.NewBatch() 2442 for _, tx := range types.TxDifference(deletedTxs, addedTxs) { 2443 rawdb.DeleteTxLookupEntry(indexesBatch, tx.Hash()) 2444 } 2445 // Delete any canonical number assignments above the new head 2446 number := bc.CurrentBlock().NumberU64() 2447 for i := number + 1; ; i++ { 2448 hash := rawdb.ReadCanonicalHash(bc.db, i) 2449 if hash == (common.Hash{}) { 2450 break 2451 } 2452 rawdb.DeleteCanonicalHash(indexesBatch, i) 2453 } 2454 if err := indexesBatch.Write(); err != nil { 2455 log.Crit("Failed to delete useless indexes", "err", err) 2456 } 2457 // If any logs need to be fired, do it now. In theory we could avoid creating 2458 // this goroutine if there are no events to fire, but realistcally that only 2459 // ever happens if we're reorging empty blocks, which will only happen on idle 2460 // networks where performance is not an issue either way. 2461 if len(deletedLogs) > 0 { 2462 bc.rmLogsFeed.Send(RemovedLogsEvent{mergeLogs(deletedLogs, true)}) 2463 } 2464 if len(rebirthLogs) > 0 { 2465 bc.logsFeed.Send(mergeLogs(rebirthLogs, false)) 2466 } 2467 if len(oldChain) > 0 { 2468 for i := len(oldChain) - 1; i >= 0; i-- { 2469 bc.chainSideFeed.Send(ChainSideEvent{Block: oldChain[i]}) 2470 } 2471 } 2472 return nil 2473 } 2474 2475 func (bc *BlockChain) update() { 2476 futureTimer := time.NewTicker(5 * time.Second) 2477 defer futureTimer.Stop() 2478 for { 2479 select { 2480 case <-futureTimer.C: 2481 bc.procFutureBlocks() 2482 case <-bc.quit: 2483 return 2484 } 2485 } 2486 } 2487 2488 func (bc *BlockChain) trustedDiffLayerLoop() { 2489 recheck := time.Tick(diffLayerFreezerRecheckInterval) 2490 bc.wg.Add(1) 2491 defer bc.wg.Done() 2492 for { 2493 select { 2494 case diff := <-bc.diffQueueBuffer: 2495 bc.diffQueue.Push(diff, -(int64(diff.Number))) 2496 case <-bc.quit: 2497 // Persist all diffLayers when shutdown, it will introduce redundant storage, but it is acceptable. 2498 // If the client been ungracefully shutdown, it will missing all cached diff layers, it is acceptable as well. 2499 var batch ethdb.Batch 2500 for !bc.diffQueue.Empty() { 2501 diff, _ := bc.diffQueue.Pop() 2502 diffLayer := diff.(*types.DiffLayer) 2503 if batch == nil { 2504 batch = bc.db.DiffStore().NewBatch() 2505 } 2506 rawdb.WriteDiffLayer(batch, diffLayer.BlockHash, diffLayer) 2507 if batch.ValueSize() > ethdb.IdealBatchSize { 2508 if err := batch.Write(); err != nil { 2509 log.Error("Failed to write diff layer", "err", err) 2510 return 2511 } 2512 batch.Reset() 2513 } 2514 } 2515 if batch != nil { 2516 // flush data 2517 if err := batch.Write(); err != nil { 2518 log.Error("Failed to write diff layer", "err", err) 2519 return 2520 } 2521 batch.Reset() 2522 } 2523 return 2524 case <-recheck: 2525 currentHeight := bc.CurrentBlock().NumberU64() 2526 var batch ethdb.Batch 2527 for !bc.diffQueue.Empty() { 2528 diff, prio := bc.diffQueue.Pop() 2529 diffLayer := diff.(*types.DiffLayer) 2530 2531 // if the block old enough 2532 if int64(currentHeight)+prio >= int64(bc.triesInMemory) { 2533 canonicalHash := bc.GetCanonicalHash(uint64(-prio)) 2534 // on the canonical chain 2535 if canonicalHash == diffLayer.BlockHash { 2536 if batch == nil { 2537 batch = bc.db.DiffStore().NewBatch() 2538 } 2539 rawdb.WriteDiffLayer(batch, diffLayer.BlockHash, diffLayer) 2540 staleHash := bc.GetCanonicalHash(uint64(-prio) - bc.diffLayerFreezerBlockLimit) 2541 rawdb.DeleteDiffLayer(batch, staleHash) 2542 } 2543 } else { 2544 bc.diffQueue.Push(diffLayer, prio) 2545 break 2546 } 2547 if batch != nil && batch.ValueSize() > ethdb.IdealBatchSize { 2548 if err := batch.Write(); err != nil { 2549 panic(fmt.Sprintf("Failed to write diff layer, error %v", err)) 2550 } 2551 batch.Reset() 2552 } 2553 } 2554 if batch != nil { 2555 if err := batch.Write(); err != nil { 2556 panic(fmt.Sprintf("Failed to write diff layer, error %v", err)) 2557 } 2558 batch.Reset() 2559 } 2560 } 2561 } 2562 } 2563 2564 func (bc *BlockChain) GetUnTrustedDiffLayer(blockHash common.Hash, pid string) *types.DiffLayer { 2565 bc.diffMux.RLock() 2566 defer bc.diffMux.RUnlock() 2567 if diffs, exist := bc.blockHashToDiffLayers[blockHash]; exist && len(diffs) != 0 { 2568 if len(diffs) == 1 { 2569 // return the only one diff layer 2570 for _, diff := range diffs { 2571 return diff 2572 } 2573 } 2574 // pick the one from exact same peer if we know where the block comes from 2575 if pid != "" { 2576 if diffHashes, exist := bc.diffPeersToDiffHashes[pid]; exist { 2577 for diff := range diffs { 2578 if _, overlap := diffHashes[diff]; overlap { 2579 return bc.blockHashToDiffLayers[blockHash][diff] 2580 } 2581 } 2582 } 2583 } 2584 // Do not find overlap, do random pick 2585 for _, diff := range diffs { 2586 return diff 2587 } 2588 } 2589 return nil 2590 } 2591 2592 func (bc *BlockChain) removeDiffLayers(diffHash common.Hash) { 2593 bc.diffMux.Lock() 2594 defer bc.diffMux.Unlock() 2595 2596 // Untrusted peers 2597 pids := bc.diffHashToPeers[diffHash] 2598 invalidDiffHashes := make(map[common.Hash]struct{}) 2599 for pid := range pids { 2600 invaliDiffHashesPeer := bc.diffPeersToDiffHashes[pid] 2601 for invaliDiffHash := range invaliDiffHashesPeer { 2602 invalidDiffHashes[invaliDiffHash] = struct{}{} 2603 } 2604 delete(bc.diffPeersToDiffHashes, pid) 2605 } 2606 for invalidDiffHash := range invalidDiffHashes { 2607 delete(bc.diffHashToPeers, invalidDiffHash) 2608 affectedBlockHash := bc.diffHashToBlockHash[invalidDiffHash] 2609 if diffs, exist := bc.blockHashToDiffLayers[affectedBlockHash]; exist { 2610 delete(diffs, invalidDiffHash) 2611 if len(diffs) == 0 { 2612 delete(bc.blockHashToDiffLayers, affectedBlockHash) 2613 } 2614 } 2615 delete(bc.diffHashToBlockHash, invalidDiffHash) 2616 } 2617 } 2618 2619 func (bc *BlockChain) RemoveDiffPeer(pid string) { 2620 bc.diffMux.Lock() 2621 defer bc.diffMux.Unlock() 2622 if invaliDiffHashes := bc.diffPeersToDiffHashes[pid]; invaliDiffHashes != nil { 2623 for invalidDiffHash := range invaliDiffHashes { 2624 lastDiffHash := false 2625 if peers, ok := bc.diffHashToPeers[invalidDiffHash]; ok { 2626 delete(peers, pid) 2627 if len(peers) == 0 { 2628 lastDiffHash = true 2629 delete(bc.diffHashToPeers, invalidDiffHash) 2630 } 2631 } 2632 if lastDiffHash { 2633 affectedBlockHash := bc.diffHashToBlockHash[invalidDiffHash] 2634 if diffs, exist := bc.blockHashToDiffLayers[affectedBlockHash]; exist { 2635 delete(diffs, invalidDiffHash) 2636 if len(diffs) == 0 { 2637 delete(bc.blockHashToDiffLayers, affectedBlockHash) 2638 } 2639 } 2640 delete(bc.diffHashToBlockHash, invalidDiffHash) 2641 } 2642 } 2643 delete(bc.diffPeersToDiffHashes, pid) 2644 } 2645 } 2646 2647 func (bc *BlockChain) untrustedDiffLayerPruneLoop() { 2648 recheck := time.NewTicker(diffLayerPruneRecheckInterval) 2649 bc.wg.Add(1) 2650 defer func() { 2651 bc.wg.Done() 2652 recheck.Stop() 2653 }() 2654 for { 2655 select { 2656 case <-bc.quit: 2657 return 2658 case <-recheck.C: 2659 bc.pruneDiffLayer() 2660 } 2661 } 2662 } 2663 2664 func (bc *BlockChain) pruneDiffLayer() { 2665 currentHeight := bc.CurrentBlock().NumberU64() 2666 bc.diffMux.Lock() 2667 defer bc.diffMux.Unlock() 2668 sortNumbers := make([]uint64, 0, len(bc.diffNumToBlockHashes)) 2669 for number := range bc.diffNumToBlockHashes { 2670 sortNumbers = append(sortNumbers, number) 2671 } 2672 sort.Slice(sortNumbers, func(i, j int) bool { 2673 return sortNumbers[i] <= sortNumbers[j] 2674 }) 2675 staleBlockHashes := make(map[common.Hash]struct{}) 2676 for _, number := range sortNumbers { 2677 if number >= currentHeight-maxDiffForkDist { 2678 break 2679 } 2680 affectedHashes := bc.diffNumToBlockHashes[number] 2681 if affectedHashes != nil { 2682 for affectedHash := range affectedHashes { 2683 staleBlockHashes[affectedHash] = struct{}{} 2684 } 2685 delete(bc.diffNumToBlockHashes, number) 2686 } 2687 } 2688 staleDiffHashes := make(map[common.Hash]struct{}) 2689 for blockHash := range staleBlockHashes { 2690 if diffHashes, exist := bc.blockHashToDiffLayers[blockHash]; exist { 2691 for diffHash := range diffHashes { 2692 staleDiffHashes[diffHash] = struct{}{} 2693 delete(bc.diffHashToBlockHash, diffHash) 2694 delete(bc.diffHashToPeers, diffHash) 2695 } 2696 } 2697 delete(bc.blockHashToDiffLayers, blockHash) 2698 } 2699 for diffHash := range staleDiffHashes { 2700 for p, diffHashes := range bc.diffPeersToDiffHashes { 2701 delete(diffHashes, diffHash) 2702 if len(diffHashes) == 0 { 2703 delete(bc.diffPeersToDiffHashes, p) 2704 } 2705 } 2706 } 2707 } 2708 2709 // Process received diff layers 2710 func (bc *BlockChain) HandleDiffLayer(diffLayer *types.DiffLayer, pid string, fulfilled bool) error { 2711 // Basic check 2712 currentHeight := bc.CurrentBlock().NumberU64() 2713 if diffLayer.Number > currentHeight && diffLayer.Number-currentHeight > maxDiffQueueDist { 2714 log.Error("diff layers too new from current", "pid", pid) 2715 return nil 2716 } 2717 if diffLayer.Number < currentHeight && currentHeight-diffLayer.Number > maxDiffForkDist { 2718 log.Error("diff layers too old from current", "pid", pid) 2719 return nil 2720 } 2721 2722 bc.diffMux.Lock() 2723 defer bc.diffMux.Unlock() 2724 2725 if !fulfilled && len(bc.diffPeersToDiffHashes[pid]) > maxDiffLimitForBroadcast { 2726 log.Error("too many accumulated diffLayers", "pid", pid) 2727 return nil 2728 } 2729 2730 if len(bc.diffPeersToDiffHashes[pid]) > maxDiffLimit { 2731 log.Error("too many accumulated diffLayers", "pid", pid) 2732 return nil 2733 } 2734 if _, exist := bc.diffPeersToDiffHashes[pid]; exist { 2735 if _, alreadyHas := bc.diffPeersToDiffHashes[pid][diffLayer.DiffHash]; alreadyHas { 2736 return nil 2737 } 2738 } else { 2739 bc.diffPeersToDiffHashes[pid] = make(map[common.Hash]struct{}) 2740 } 2741 bc.diffPeersToDiffHashes[pid][diffLayer.DiffHash] = struct{}{} 2742 if _, exist := bc.diffNumToBlockHashes[diffLayer.Number]; !exist { 2743 bc.diffNumToBlockHashes[diffLayer.Number] = make(map[common.Hash]struct{}) 2744 } 2745 bc.diffNumToBlockHashes[diffLayer.Number][diffLayer.BlockHash] = struct{}{} 2746 2747 if _, exist := bc.diffHashToPeers[diffLayer.DiffHash]; !exist { 2748 bc.diffHashToPeers[diffLayer.DiffHash] = make(map[string]struct{}) 2749 } 2750 bc.diffHashToPeers[diffLayer.DiffHash][pid] = struct{}{} 2751 2752 if _, exist := bc.blockHashToDiffLayers[diffLayer.BlockHash]; !exist { 2753 bc.blockHashToDiffLayers[diffLayer.BlockHash] = make(map[common.Hash]*types.DiffLayer) 2754 } 2755 bc.blockHashToDiffLayers[diffLayer.BlockHash][diffLayer.DiffHash] = diffLayer 2756 bc.diffHashToBlockHash[diffLayer.DiffHash] = diffLayer.BlockHash 2757 2758 return nil 2759 } 2760 2761 // maintainTxIndex is responsible for the construction and deletion of the 2762 // transaction index. 2763 // 2764 // User can use flag `txlookuplimit` to specify a "recentness" block, below 2765 // which ancient tx indices get deleted. If `txlookuplimit` is 0, it means 2766 // all tx indices will be reserved. 2767 // 2768 // The user can adjust the txlookuplimit value for each launch after fast 2769 // sync, Geth will automatically construct the missing indices and delete 2770 // the extra indices. 2771 func (bc *BlockChain) maintainTxIndex(ancients uint64) { 2772 defer bc.wg.Done() 2773 2774 // Before starting the actual maintenance, we need to handle a special case, 2775 // where user might init Geth with an external ancient database. If so, we 2776 // need to reindex all necessary transactions before starting to process any 2777 // pruning requests. 2778 if ancients > 0 { 2779 var from = uint64(0) 2780 if bc.txLookupLimit != 0 && ancients > bc.txLookupLimit { 2781 from = ancients - bc.txLookupLimit 2782 } 2783 rawdb.IndexTransactions(bc.db, from, ancients, bc.quit) 2784 } 2785 // indexBlocks reindexes or unindexes transactions depending on user configuration 2786 indexBlocks := func(tail *uint64, head uint64, done chan struct{}) { 2787 defer func() { done <- struct{}{} }() 2788 2789 // If the user just upgraded Geth to a new version which supports transaction 2790 // index pruning, write the new tail and remove anything older. 2791 if tail == nil { 2792 if bc.txLookupLimit == 0 || head < bc.txLookupLimit { 2793 // Nothing to delete, write the tail and return 2794 rawdb.WriteTxIndexTail(bc.db, 0) 2795 } else { 2796 // Prune all stale tx indices and record the tx index tail 2797 rawdb.UnindexTransactions(bc.db, 0, head-bc.txLookupLimit+1, bc.quit) 2798 } 2799 return 2800 } 2801 // If a previous indexing existed, make sure that we fill in any missing entries 2802 if bc.txLookupLimit == 0 || head < bc.txLookupLimit { 2803 if *tail > 0 { 2804 rawdb.IndexTransactions(bc.db, 0, *tail, bc.quit) 2805 } 2806 return 2807 } 2808 // Update the transaction index to the new chain state 2809 if head-bc.txLookupLimit+1 < *tail { 2810 // Reindex a part of missing indices and rewind index tail to HEAD-limit 2811 rawdb.IndexTransactions(bc.db, head-bc.txLookupLimit+1, *tail, bc.quit) 2812 } else { 2813 // Unindex a part of stale indices and forward index tail to HEAD-limit 2814 rawdb.UnindexTransactions(bc.db, *tail, head-bc.txLookupLimit+1, bc.quit) 2815 } 2816 } 2817 // Any reindexing done, start listening to chain events and moving the index window 2818 var ( 2819 done chan struct{} // Non-nil if background unindexing or reindexing routine is active. 2820 headCh = make(chan ChainHeadEvent, 1) // Buffered to avoid locking up the event feed 2821 ) 2822 sub := bc.SubscribeChainHeadEvent(headCh) 2823 if sub == nil { 2824 return 2825 } 2826 defer sub.Unsubscribe() 2827 2828 for { 2829 select { 2830 case head := <-headCh: 2831 if done == nil { 2832 done = make(chan struct{}) 2833 go indexBlocks(rawdb.ReadTxIndexTail(bc.db), head.Block.NumberU64(), done) 2834 } 2835 case <-done: 2836 done = nil 2837 case <-bc.quit: 2838 if done != nil { 2839 log.Info("Waiting background transaction indexer to exit") 2840 <-done 2841 } 2842 return 2843 } 2844 } 2845 } 2846 2847 // reportBlock logs a bad block error. 2848 func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { 2849 rawdb.WriteBadBlock(bc.db, block) 2850 2851 var receiptString string 2852 for i, receipt := range receipts { 2853 receiptString += fmt.Sprintf("\t %d: cumulative: %v gas: %v contract: %v status: %v tx: %v logs: %v bloom: %x state: %x\n", 2854 i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(), 2855 receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState) 2856 } 2857 log.Error(fmt.Sprintf(` 2858 ########## BAD BLOCK ######### 2859 Chain config: %v 2860 2861 Number: %v 2862 Hash: 0x%x 2863 %v 2864 2865 Error: %v 2866 ############################## 2867 `, bc.chainConfig, block.Number(), block.Hash(), receiptString, err)) 2868 } 2869 2870 // InsertHeaderChain attempts to insert the given header chain in to the local 2871 // chain, possibly creating a reorg. If an error is returned, it will return the 2872 // index number of the failing header as well an error describing what went wrong. 2873 // 2874 // The verify parameter can be used to fine tune whether nonce verification 2875 // should be done or not. The reason behind the optional check is because some 2876 // of the header retrieval mechanisms already need to verify nonces, as well as 2877 // because nonces can be verified sparsely, not needing to check each. 2878 func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { 2879 start := time.Now() 2880 if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { 2881 return i, err 2882 } 2883 2884 // Make sure only one thread manipulates the chain at once 2885 bc.chainmu.Lock() 2886 defer bc.chainmu.Unlock() 2887 2888 bc.wg.Add(1) 2889 defer bc.wg.Done() 2890 _, err := bc.hc.InsertHeaderChain(chain, start) 2891 return 0, err 2892 } 2893 2894 // CurrentHeader retrieves the current head header of the canonical chain. The 2895 // header is retrieved from the HeaderChain's internal cache. 2896 func (bc *BlockChain) CurrentHeader() *types.Header { 2897 return bc.hc.CurrentHeader() 2898 } 2899 2900 // GetTd retrieves a block's total difficulty in the canonical chain from the 2901 // database by hash and number, caching it if found. 2902 func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { 2903 return bc.hc.GetTd(hash, number) 2904 } 2905 2906 // GetTdByHash retrieves a block's total difficulty in the canonical chain from the 2907 // database by hash, caching it if found. 2908 func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { 2909 return bc.hc.GetTdByHash(hash) 2910 } 2911 2912 // GetHeader retrieves a block header from the database by hash and number, 2913 // caching it if found. 2914 func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { 2915 return bc.hc.GetHeader(hash, number) 2916 } 2917 2918 // GetHeaderByHash retrieves a block header from the database by hash, caching it if 2919 // found. 2920 func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { 2921 return bc.hc.GetHeaderByHash(hash) 2922 } 2923 2924 // HasHeader checks if a block header is present in the database or not, caching 2925 // it if present. 2926 func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool { 2927 return bc.hc.HasHeader(hash, number) 2928 } 2929 2930 // GetCanonicalHash returns the canonical hash for a given block number 2931 func (bc *BlockChain) GetCanonicalHash(number uint64) common.Hash { 2932 return bc.hc.GetCanonicalHash(number) 2933 } 2934 2935 // GetBlockHashesFromHash retrieves a number of block hashes starting at a given 2936 // hash, fetching towards the genesis block. 2937 func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { 2938 return bc.hc.GetBlockHashesFromHash(hash, max) 2939 } 2940 2941 // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or 2942 // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the 2943 // number of blocks to be individually checked before we reach the canonical chain. 2944 // 2945 // Note: ancestor == 0 returns the same block, 1 returns its parent and so on. 2946 func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { 2947 return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical) 2948 } 2949 2950 // GetHeaderByNumber retrieves a block header from the database by number, 2951 // caching it (associated with its hash) if found. 2952 func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { 2953 return bc.hc.GetHeaderByNumber(number) 2954 } 2955 2956 // GetTransactionLookup retrieves the lookup associate with the given transaction 2957 // hash from the cache or database. 2958 func (bc *BlockChain) GetTransactionLookup(hash common.Hash) *rawdb.LegacyTxLookupEntry { 2959 // Short circuit if the txlookup already in the cache, retrieve otherwise 2960 if lookup, exist := bc.txLookupCache.Get(hash); exist { 2961 return lookup.(*rawdb.LegacyTxLookupEntry) 2962 } 2963 tx, blockHash, blockNumber, txIndex := rawdb.ReadTransaction(bc.db, hash) 2964 if tx == nil { 2965 return nil 2966 } 2967 lookup := &rawdb.LegacyTxLookupEntry{BlockHash: blockHash, BlockIndex: blockNumber, Index: txIndex} 2968 bc.txLookupCache.Add(hash, lookup) 2969 return lookup 2970 } 2971 2972 func (bc *BlockChain) TriesInMemory() uint64 { return bc.triesInMemory } 2973 2974 // Config retrieves the chain's fork configuration. 2975 func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig } 2976 2977 // Engine retrieves the blockchain's consensus engine. 2978 func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } 2979 2980 // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent. 2981 func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { 2982 return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch)) 2983 } 2984 2985 // SubscribeChainEvent registers a subscription of ChainEvent. 2986 func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription { 2987 return bc.scope.Track(bc.chainFeed.Subscribe(ch)) 2988 } 2989 2990 // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. 2991 func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 2992 return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch)) 2993 } 2994 2995 // SubscribeChainSideEvent registers a subscription of ChainSideEvent. 2996 func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription { 2997 return bc.scope.Track(bc.chainSideFeed.Subscribe(ch)) 2998 } 2999 3000 // SubscribeLogsEvent registers a subscription of []*types.Log. 3001 func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { 3002 return bc.scope.Track(bc.logsFeed.Subscribe(ch)) 3003 } 3004 3005 // SubscribeBlockProcessingEvent registers a subscription of bool where true means 3006 // block processing has started while false means it has stopped. 3007 func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription { 3008 return bc.scope.Track(bc.blockProcFeed.Subscribe(ch)) 3009 } 3010 3011 // Options 3012 func EnableLightProcessor(bc *BlockChain) *BlockChain { 3013 bc.processor = NewLightStateProcessor(bc.Config(), bc, bc.engine) 3014 return bc 3015 } 3016 3017 func EnablePersistDiff(limit uint64) BlockChainOption { 3018 return func(chain *BlockChain) *BlockChain { 3019 chain.diffLayerFreezerBlockLimit = limit 3020 return chain 3021 } 3022 }