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