github.com/m3shine/gochain@v2.2.26+incompatible/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 "context" 22 "errors" 23 "fmt" 24 "io" 25 "math/big" 26 "math/rand" 27 "runtime" 28 "sync" 29 "sync/atomic" 30 "time" 31 32 "github.com/hashicorp/golang-lru" 33 "go.opencensus.io/trace" 34 35 "github.com/gochain-io/gochain/common" 36 "github.com/gochain-io/gochain/common/mclock" 37 "github.com/gochain-io/gochain/common/prque" 38 "github.com/gochain-io/gochain/consensus" 39 "github.com/gochain-io/gochain/core/rawdb" 40 "github.com/gochain-io/gochain/core/state" 41 "github.com/gochain-io/gochain/core/types" 42 "github.com/gochain-io/gochain/core/vm" 43 "github.com/gochain-io/gochain/crypto" 44 "github.com/gochain-io/gochain/ethdb" 45 "github.com/gochain-io/gochain/log" 46 "github.com/gochain-io/gochain/metrics" 47 "github.com/gochain-io/gochain/params" 48 "github.com/gochain-io/gochain/rlp" 49 "github.com/gochain-io/gochain/trie" 50 ) 51 52 var ( 53 blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) 54 blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil) 55 blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil) 56 blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil) 57 58 ErrNoGenesis = errors.New("Genesis not found in chain") 59 ErrStopping = errors.New("stopping") 60 ) 61 62 const ( 63 bodyCacheLimit = 256 64 blockCacheLimit = 256 65 receiptsCacheLimit = 32 66 maxFutureBlocks = 256 67 maxTimeFutureBlocks = 30 68 badBlockLimit = 10 69 triesInMemory = 128 70 71 // BlockChainVersion ensures that an incompatible database forces a resync from scratch. 72 BlockChainVersion = 3 73 ) 74 75 // CacheConfig contains the configuration values for the trie caching/pruning 76 // that's resident in a blockchain. 77 type CacheConfig struct { 78 Disabled bool // Whether to disable trie write caching (archive node) 79 TrieNodeLimit int // Memory limit (MB) at which to flush the current in-memory trie to disk 80 TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk 81 } 82 83 // BlockChain represents the canonical chain given a database with a genesis 84 // block. The Blockchain manages chain imports, reverts, chain reorganisations. 85 // 86 // Importing blocks in to the block chain happens according to the set of rules 87 // defined by the two stage Validator. Processing of blocks is done using the 88 // Processor which processes the included transaction. The validation of the state 89 // is done in the second part of the Validator. Failing results in aborting of 90 // the import. 91 // 92 // The BlockChain also helps in returning blocks from **any** chain included 93 // in the database as well as blocks that represents the canonical chain. It's 94 // important to note that GetBlock can return any block and does not need to be 95 // included in the canonical one where as GetBlockByNumber always represents the 96 // canonical chain. 97 type BlockChain struct { 98 chainConfig *params.ChainConfig // Chain & network configuration 99 cacheConfig *CacheConfig // Cache configuration for pruning 100 101 db common.Database // Low level persistent database to store final content in 102 triegc *prque.Prque // Priority queue mapping block numbers to tries to gc 103 gcproc time.Duration // Accumulates canonical block processing for trie dumping 104 105 hc *HeaderChain 106 107 rmLogsFeed RemovedLogsFeed 108 chainFeed ChainFeed 109 chainSideFeed ChainSideFeed 110 chainHeadFeed ChainHeadFeed 111 logsFeed LogsFeed 112 113 genesisBlock *types.Block 114 115 mu sync.RWMutex // global mutex for locking chain operations 116 chainmu sync.RWMutex // blockchain insertion lock 117 procmu sync.RWMutex // block processor lock 118 119 checkpoint int // checkpoint counts towards the new checkpoint 120 currentBlock atomic.Value // Current head of the block chain 121 currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!) 122 123 stateCache state.Database // State database to reuse between imports (contains state cache) 124 bodyCache *lru.Cache // Cache for the most recent block bodies 125 bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format 126 receiptsCache *lru.Cache // Cache for the most recent receipts per block 127 blockCache *lru.Cache // Cache for the most recent entire blocks 128 futureBlocks *lru.Cache // future blocks are blocks added for later processing 129 130 quit chan struct{} // blockchain quit channel. Must hold write lock on wgQuitMu to close. 131 running int32 // running must be called atomically 132 // procInterrupt must be atomically called 133 procInterrupt int32 // interrupt signaler for block processing 134 wg sync.WaitGroup // chain processing wait group for shutting down. Must hold read lock on wgQuitMu to Add. 135 wgQuitMu sync.RWMutex // Lock to ensure wg.Add is not called after quit is closed. Write locked when closing quit, read locked when checking quit and adding to wg. 136 137 engine consensus.Engine 138 processor Processor // block processor interface 139 validator Validator // block and state validator interface 140 vmConfig vm.Config 141 parWorkers int // Number of workers to spawn for parallel tasks. 142 143 badBlocks *lru.Cache // Bad block cache 144 } 145 146 // NewBlockChain returns a fully initialised block chain using information 147 // available in the database. It initialises the default Ethereum Validator and 148 // Processor. 149 func NewBlockChain(ctx context.Context, db common.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) { 150 if cacheConfig == nil { 151 cacheConfig = &CacheConfig{ 152 TrieNodeLimit: 256 * 1024 * 1024, 153 TrieTimeLimit: 5 * time.Minute, 154 } 155 } 156 bodyCache, _ := lru.New(bodyCacheLimit) 157 bodyRLPCache, _ := lru.New(bodyCacheLimit) 158 receiptsCache, _ := lru.New(receiptsCacheLimit) 159 blockCache, _ := lru.New(blockCacheLimit) 160 futureBlocks, _ := lru.New(maxFutureBlocks) 161 badBlocks, _ := lru.New(badBlockLimit) 162 163 bc := &BlockChain{ 164 chainConfig: chainConfig, 165 cacheConfig: cacheConfig, 166 db: db, 167 triegc: prque.New(nil), 168 stateCache: state.NewDatabase(db), 169 quit: make(chan struct{}), 170 bodyCache: bodyCache, 171 bodyRLPCache: bodyRLPCache, 172 receiptsCache: receiptsCache, 173 blockCache: blockCache, 174 futureBlocks: futureBlocks, 175 engine: engine, 176 vmConfig: vmConfig, 177 parWorkers: runtime.GOMAXPROCS(0), 178 badBlocks: badBlocks, 179 } 180 bc.SetValidator(NewBlockValidator(chainConfig, bc, engine)) 181 bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine)) 182 183 var err error 184 bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt) 185 if err != nil { 186 return nil, err 187 } 188 bc.genesisBlock = bc.GetBlockByNumber(0) 189 if bc.genesisBlock == nil { 190 return nil, ErrNoGenesis 191 } 192 if err := bc.loadLastState(); err != nil { 193 return nil, err 194 } 195 // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain 196 for hash := range BadHashes { 197 if header := bc.GetHeaderByHash(hash); header != nil { 198 // get the canonical block corresponding to the offending header's number 199 headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64()) 200 // make sure the headerByNumber (if present) is in our current canonical chain 201 if headerByNumber != nil && headerByNumber.Hash() == header.Hash() { 202 log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) 203 if err := bc.SetHead(header.Number.Uint64() - 1); err != nil { 204 log.Error("Cannot set blockchain head", "err", err) 205 } 206 log.Error("Chain rewind was successful, resuming normal operation") 207 } 208 } 209 } 210 // Take ownership of this particular state 211 go bc.update() 212 return bc, nil 213 } 214 215 func (bc *BlockChain) getProcInterrupt() bool { 216 return atomic.LoadInt32(&bc.procInterrupt) == 1 217 } 218 219 // loadLastState loads the last known chain state from the database. This method 220 // assumes that the chain manager mutex is held. 221 func (bc *BlockChain) loadLastState() error { 222 // Restore the last known head block 223 head := rawdb.ReadHeadBlockHash(bc.db.GlobalTable()) 224 if head == (common.Hash{}) { 225 // Corrupt or empty database, init from scratch 226 log.Warn("Empty database, resetting chain") 227 return bc.Reset() 228 } 229 // Make sure the entire head block is available 230 currentBlock := bc.GetBlockByHash(head) 231 if currentBlock == nil { 232 // Corrupt or empty database, init from scratch 233 log.Warn("Head block missing, resetting chain", "hash", head) 234 return bc.Reset() 235 } 236 // Make sure the state associated with the block is available 237 if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil { 238 // Dangling block without a state associated, init from scratch 239 log.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash()) 240 if err := bc.repair(¤tBlock); err != nil { 241 return err 242 } 243 } 244 // Everything seems to be fine, set as the head block 245 bc.currentBlock.Store(currentBlock) 246 247 // Restore the last known head header 248 currentHeader := currentBlock.Header() 249 if head := rawdb.ReadHeadHeaderHash(bc.db.GlobalTable()); head != (common.Hash{}) { 250 if header := bc.GetHeaderByHash(head); header != nil { 251 currentHeader = header 252 } 253 } 254 bc.hc.SetCurrentHeader(currentHeader) 255 256 // Restore the last known head fast block 257 bc.currentFastBlock.Store(currentBlock) 258 if head := rawdb.ReadHeadFastBlockHash(bc.db.GlobalTable()); head != (common.Hash{}) { 259 if block := bc.GetBlockByHash(head); block != nil { 260 bc.currentFastBlock.Store(block) 261 } 262 } 263 264 // Issue a status log for the user 265 currentFastBlock := bc.CurrentFastBlock() 266 267 headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) 268 blockTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 269 fastTd := bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()) 270 271 log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd) 272 log.Info("Loaded most recent local full block", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "td", blockTd) 273 log.Info("Loaded most recent local fast block", "number", currentFastBlock.Number(), "hash", currentFastBlock.Hash(), "td", fastTd) 274 275 return nil 276 } 277 278 // SetHead rewinds the local chain to a new head. In the case of headers, everything 279 // above the new head will be deleted and the new one set. In the case of blocks 280 // though, the head may be further rewound if block bodies are missing (non-archive 281 // nodes after a fast sync). 282 func (bc *BlockChain) SetHead(head uint64) error { 283 log.Warn("Rewinding blockchain", "target", head) 284 285 bc.mu.Lock() 286 defer bc.mu.Unlock() 287 288 // Rewind the header chain, deleting all block bodies until then 289 bc.hc.SetHead(head, rawdb.DeleteBody) 290 currentHeader := bc.hc.CurrentHeader() 291 292 // Clear out any stale content from the caches 293 bc.bodyCache.Purge() 294 bc.bodyRLPCache.Purge() 295 bc.receiptsCache.Purge() 296 bc.blockCache.Purge() 297 bc.futureBlocks.Purge() 298 299 currentBlock := bc.CurrentBlock() 300 currentFastBlock := bc.CurrentFastBlock() 301 302 // Rewind the block chain, ensuring we don't end up with a stateless head block 303 if currentBlock != nil && currentHeader.Number.Uint64() < currentBlock.NumberU64() { 304 currentBlock = bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()) 305 bc.currentBlock.Store(currentBlock) 306 } 307 if currentBlock != nil { 308 if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil { 309 // Rewound state missing, rolled back to before pivot, reset to genesis 310 currentBlock = bc.genesisBlock 311 bc.currentBlock.Store(currentBlock) 312 } 313 } 314 // Rewind the fast block in a simpleton way to the target head 315 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && currentHeader.Number.Uint64() < currentFastBlock.NumberU64() { 316 currentFastBlock = bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()) 317 bc.currentFastBlock.Store(currentFastBlock) 318 } 319 // If either blocks reached nil, reset to the genesis state 320 if currentBlock == nil { 321 currentBlock = bc.genesisBlock 322 bc.currentBlock.Store(currentBlock) 323 } 324 if currentFastBlock == nil { 325 currentFastBlock = bc.genesisBlock 326 bc.currentFastBlock.Store(currentFastBlock) 327 } 328 rawdb.WriteHeadBlockHash(bc.db.GlobalTable(), currentBlock.Hash()) 329 rawdb.WriteHeadFastBlockHash(bc.db.GlobalTable(), currentFastBlock.Hash()) 330 return bc.loadLastState() 331 } 332 333 // FastSyncCommitHead sets the current head block to the one defined by the hash 334 // irrelevant what the chain contents were prior. 335 func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { 336 // Make sure that both the block as well at its state trie exists 337 block := bc.GetBlockByHash(hash) 338 if block == nil { 339 return fmt.Errorf("non existent block [%x…]", hash[:4]) 340 } 341 if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB(), 0); err != nil { 342 return err 343 } 344 // If all checks out, manually set the head block 345 bc.mu.Lock() 346 bc.currentBlock.Store(block) 347 bc.mu.Unlock() 348 349 log.Info("Committed new head block", "number", block.Number(), "hash", hash) 350 return nil 351 } 352 353 // GasLimit returns the gas limit of the current HEAD block. 354 func (bc *BlockChain) GasLimit() uint64 { 355 return bc.CurrentBlock().GasLimit() 356 } 357 358 // CurrentBlock retrieves the current head block of the canonical chain. The 359 // block is retrieved from the blockchain's internal cache. 360 func (bc *BlockChain) CurrentBlock() *types.Block { 361 return bc.currentBlock.Load().(*types.Block) 362 } 363 364 // CurrentFastBlock retrieves the current fast-sync head block of the canonical 365 // chain. The block is retrieved from the blockchain's internal cache. 366 func (bc *BlockChain) CurrentFastBlock() *types.Block { 367 return bc.currentFastBlock.Load().(*types.Block) 368 } 369 370 // SetProcessor sets the processor required for making state modifications. 371 func (bc *BlockChain) SetProcessor(processor Processor) { 372 bc.procmu.Lock() 373 defer bc.procmu.Unlock() 374 bc.processor = processor 375 } 376 377 // SetValidator sets the validator which is used to validate incoming blocks. 378 func (bc *BlockChain) SetValidator(validator Validator) { 379 bc.procmu.Lock() 380 defer bc.procmu.Unlock() 381 bc.validator = validator 382 } 383 384 // Validator returns the current validator. 385 func (bc *BlockChain) Validator() Validator { 386 bc.procmu.RLock() 387 defer bc.procmu.RUnlock() 388 return bc.validator 389 } 390 391 // Processor returns the current processor. 392 func (bc *BlockChain) Processor() Processor { 393 bc.procmu.RLock() 394 defer bc.procmu.RUnlock() 395 return bc.processor 396 } 397 398 // State returns a new mutable state based on the current HEAD block. 399 func (bc *BlockChain) State() (*state.StateDB, error) { 400 return bc.StateAt(bc.CurrentBlock().Root()) 401 } 402 403 // StateAt returns a new mutable state based on a particular point in time. 404 func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { 405 return state.New(root, bc.stateCache) 406 } 407 408 // Reset purges the entire blockchain, restoring it to its genesis state. 409 func (bc *BlockChain) Reset() error { 410 return bc.ResetWithGenesisBlock(bc.genesisBlock) 411 } 412 413 // ResetWithGenesisBlock purges the entire blockchain, restoring it to the 414 // specified genesis state. 415 func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { 416 // Dump the entire block chain and purge the caches 417 if err := bc.SetHead(0); err != nil { 418 return err 419 } 420 bc.mu.Lock() 421 defer bc.mu.Unlock() 422 423 // Prepare the genesis block and reinitialise the chain 424 bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()) 425 rawdb.WriteBlock(bc.db, genesis) 426 bc.genesisBlock = genesis 427 bc.insert(bc.genesisBlock) 428 bc.currentBlock.Store(bc.genesisBlock) 429 bc.hc.SetGenesis(bc.genesisBlock.Header()) 430 bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) 431 bc.currentFastBlock.Store(bc.genesisBlock) 432 433 return nil 434 } 435 436 // repair tries to repair the current blockchain by rolling back the current block 437 // until one with associated state is found. This is needed to fix incomplete db 438 // writes caused either by crashes/power outages, or simply non-committed tries. 439 // 440 // This method only rolls back the current block. The current header and current 441 // fast block are left intact. 442 func (bc *BlockChain) repair(head **types.Block) error { 443 for { 444 // Abort if we've rewound to a head block that does have associated state 445 if _, err := state.New((*head).Root(), bc.stateCache); err == nil { 446 log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash()) 447 return nil 448 } 449 // Otherwise rewind one block and recheck state availability there 450 (*head) = bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1) 451 } 452 } 453 454 // Export writes the active chain to the given writer. 455 func (bc *BlockChain) Export(w io.Writer) error { 456 return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64()) 457 } 458 459 // ExportN writes a subset of the active chain to the given writer. 460 func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { 461 bc.mu.RLock() 462 defer bc.mu.RUnlock() 463 464 if first > last { 465 return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) 466 } 467 log.Info("Exporting batch of blocks", "count", last-first+1) 468 469 start, reported := time.Now(), time.Now() 470 for nr := first; nr <= last; nr++ { 471 block := bc.GetBlockByNumber(nr) 472 if block == nil { 473 return fmt.Errorf("export failed on #%d: not found", nr) 474 } 475 if err := block.EncodeRLP(w); err != nil { 476 return err 477 } 478 if time.Since(reported) >= statsReportLimit { 479 log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start))) 480 reported = time.Now() 481 } 482 } 483 484 return nil 485 } 486 487 // insert injects a new head block into the current block chain. This method 488 // assumes that the block is indeed a true head. It will also reset the head 489 // header and the head fast sync block to this very same block if they are older 490 // or if they are on a different side chain. 491 // 492 // Note, this function assumes that the `mu` mutex is held! 493 func (bc *BlockChain) insert(block *types.Block) { 494 // If the block is on a side chain or an unknown one, force other heads onto it too 495 updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash() 496 497 // Add the block to the canonical chain number scheme and mark as the head 498 rawdb.WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64()) 499 rawdb.WriteHeadBlockHash(bc.db.GlobalTable(), block.Hash()) 500 bc.currentBlock.Store(block) 501 502 // If the block is better than our head or is on a different chain, force update heads 503 if updateHeads { 504 bc.hc.SetCurrentHeader(block.Header()) 505 506 rawdb.WriteHeadFastBlockHash(bc.db.GlobalTable(), block.Hash()) 507 bc.currentFastBlock.Store(block) 508 } 509 } 510 511 // Genesis retrieves the chain's genesis block. 512 func (bc *BlockChain) Genesis() *types.Block { 513 return bc.genesisBlock 514 } 515 516 // GetBody retrieves a block body (transactions and uncles) from the database by 517 // hash, caching it if found. 518 func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { 519 // Short circuit if the body's already in the cache, retrieve otherwise 520 if cached, ok := bc.bodyCache.Get(hash); ok { 521 body := cached.(*types.Body) 522 return body 523 } 524 number := bc.hc.GetBlockNumber(hash) 525 if number == nil { 526 return nil 527 } 528 body := rawdb.ReadBody(bc.db.BodyTable(), hash, *number) 529 if body == nil { 530 return nil 531 } 532 // Cache the found body for next time and return 533 bc.bodyCache.Add(hash, body) 534 return body 535 } 536 537 // GetBodyRLP retrieves a block body in RLP encoding from the database by hash, 538 // caching it if found. 539 func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { 540 // Short circuit if the body's already in the cache, retrieve otherwise 541 if cached, ok := bc.bodyRLPCache.Get(hash); ok { 542 return cached.(rlp.RawValue) 543 } 544 number := bc.hc.GetBlockNumber(hash) 545 if number == nil { 546 return nil 547 } 548 body := rawdb.ReadBodyRLP(bc.db.BodyTable(), hash, *number) 549 if len(body) == 0 { 550 return nil 551 } 552 // Cache the found body for next time and return 553 bc.bodyRLPCache.Add(hash, body) 554 return body 555 } 556 557 // HasBlock checks if a block is fully present in the database or not. 558 func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool { 559 if bc.blockCache.Contains(hash) { 560 return true 561 } 562 return rawdb.HasBody(bc.db.BodyTable(), hash, number) 563 } 564 565 // HasState checks if state trie is fully present in the database or not. 566 func (bc *BlockChain) HasState(hash common.Hash) bool { 567 _, err := bc.stateCache.OpenTrie(hash) 568 return err == nil 569 } 570 571 // HasBlockAndState checks if a block and associated state trie is fully present 572 // in the database or not, caching it if present. 573 func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool { 574 // Check first that the block itself is known 575 block := bc.GetBlock(hash, number) 576 if block == nil { 577 return false 578 } 579 return bc.HasState(block.Root()) 580 } 581 582 // GetBlock retrieves a block from the database by hash and number, 583 // caching it if found. 584 func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 585 // Short circuit if the block's already in the cache, retrieve otherwise 586 if block, ok := bc.blockCache.Get(hash); ok { 587 return block.(*types.Block) 588 } 589 block := rawdb.ReadBlock(bc.db, hash, number) 590 if block == nil { 591 return nil 592 } 593 // Cache the found block for next time and return 594 bc.blockCache.Add(block.Hash(), block) 595 return block 596 } 597 598 // GetBlockByHash retrieves a block from the database by hash, caching it if found. 599 func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { 600 number := bc.hc.GetBlockNumber(hash) 601 if number == nil { 602 return nil 603 } 604 return bc.GetBlock(hash, *number) 605 } 606 607 // GetBlockByNumber retrieves a block from the database by number, caching it 608 // (associated with its hash) if found. 609 func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { 610 hash := rawdb.ReadCanonicalHash(bc.db, number) 611 if hash == (common.Hash{}) { 612 return nil 613 } 614 return bc.GetBlock(hash, number) 615 } 616 617 // GetReceiptsByHash retrieves the receipts for all transactions in a given block. 618 func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { 619 if receipts, ok := bc.receiptsCache.Get(hash); ok { 620 return receipts.(types.Receipts) 621 } 622 623 number := rawdb.ReadHeaderNumber(bc.db.GlobalTable(), hash) 624 if number == nil { 625 return nil 626 } 627 628 receipts := rawdb.ReadReceipts(bc.db.ReceiptTable(), hash, *number) 629 bc.receiptsCache.Add(hash, receipts) 630 return receipts 631 } 632 633 // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. 634 // [deprecated by eth/62] 635 func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { 636 number := bc.hc.GetBlockNumber(hash) 637 if number == nil { 638 return nil 639 } 640 for i := 0; i < n; i++ { 641 block := bc.GetBlock(hash, *number) 642 if block == nil { 643 break 644 } 645 blocks = append(blocks, block) 646 hash = block.ParentHash() 647 *number-- 648 } 649 return 650 } 651 652 // GetUnclesInChain retrieves all the uncles from a given block backwards until 653 // a specific distance is reached. 654 func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { 655 uncles := []*types.Header{} 656 for i := 0; block != nil && i < length; i++ { 657 uncles = append(uncles, block.Uncles()...) 658 block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 659 } 660 return uncles 661 } 662 663 // TrieNode retrieves a blob of data associated with a trie node (or code hash) 664 // either from ephemeral in-memory cache, or from persistent storage. 665 func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) { 666 return bc.stateCache.TrieDB().Node(hash) 667 } 668 669 // Stop stops the blockchain service. If any imports are currently in progress 670 // it will abort them using the procInterrupt. 671 func (bc *BlockChain) Stop() { 672 if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { 673 return 674 } 675 // Unsubscribe all subscriptions registered from blockchain 676 bc.rmLogsFeed.Close() 677 bc.chainFeed.Close() 678 bc.chainSideFeed.Close() 679 bc.chainHeadFeed.Close() 680 bc.logsFeed.Close() 681 bc.closeQuit() 682 atomic.StoreInt32(&bc.procInterrupt, 1) 683 684 bc.wg.Wait() 685 686 // Ensure the state of a recent block is also stored to disk before exiting. 687 // We're writing three different states to catch different restart scenarios: 688 // - HEAD: So we don't need to reprocess any blocks in the general case 689 // - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle 690 // - HEAD-127: So we have a hard limit on the number of blocks reexecuted 691 if !bc.cacheConfig.Disabled { 692 triedb := bc.stateCache.TrieDB() 693 694 for _, offset := range []uint64{0, 1, triesInMemory - 1} { 695 if number := bc.CurrentBlock().NumberU64(); number > offset { 696 recent := bc.GetBlockByNumber(number - offset) 697 698 log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root()) 699 if err := triedb.Commit(recent.Root(), true); err != nil { 700 log.Error("Failed to commit recent state trie", "err", err) 701 } 702 } 703 } 704 for !bc.triegc.Empty() { 705 triedb.Dereference(bc.triegc.PopItem().(common.Hash)) 706 } 707 if size, _ := triedb.Size(); size != 0 { 708 log.Error("Dangling trie nodes after full cleanup") 709 } 710 } 711 log.Info("Blockchain manager stopped") 712 } 713 714 func (bc *BlockChain) procFutureBlocks(ctx context.Context) { 715 blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) 716 for _, hash := range bc.futureBlocks.Keys() { 717 if block, exist := bc.futureBlocks.Peek(hash); exist { 718 blocks = append(blocks, block.(*types.Block)) 719 } 720 } 721 if len(blocks) > 0 { 722 types.BlockBy(types.Number).Sort(blocks) 723 724 // Insert one by one as chain insertion needs contiguous ancestry between blocks 725 for i := range blocks { 726 if n, err := bc.InsertChain(ctx, blocks[i:i+1]); err != nil { 727 log.Error("Cannot insert future blocks into chain", "n", n, "err", err) 728 } 729 } 730 } 731 } 732 733 // WriteStatus status of write 734 type WriteStatus byte 735 736 const ( 737 NonStatTy WriteStatus = iota 738 CanonStatTy 739 SideStatTy 740 ) 741 742 func (ws WriteStatus) String() string { 743 switch ws { 744 case NonStatTy: 745 return "NonStatTy" 746 case CanonStatTy: 747 return "CanonStatTy" 748 case SideStatTy: 749 return "SideStatTy" 750 default: 751 return fmt.Sprintf("unknown WriteStatus: %d", ws) 752 } 753 } 754 755 // Rollback is designed to remove a chain of links from the database that aren't 756 // certain enough to be valid. 757 func (bc *BlockChain) Rollback(chain []common.Hash) { 758 bc.mu.Lock() 759 defer bc.mu.Unlock() 760 761 for i := len(chain) - 1; i >= 0; i-- { 762 hash := chain[i] 763 764 currentHeader := bc.hc.CurrentHeader() 765 if currentHeader.Hash() == hash { 766 bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) 767 } 768 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash { 769 newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1) 770 bc.currentFastBlock.Store(newFastBlock) 771 rawdb.WriteHeadFastBlockHash(bc.db.GlobalTable(), newFastBlock.Hash()) 772 } 773 if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash { 774 newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1) 775 bc.currentBlock.Store(newBlock) 776 rawdb.WriteHeadBlockHash(bc.db.GlobalTable(), newBlock.Hash()) 777 } 778 } 779 } 780 781 // SetReceiptsData computes all the non-consensus fields of the receipts 782 func SetReceiptsData(ctx context.Context, config *params.ChainConfig, block *types.Block, receipts types.Receipts) error { 783 signer := types.MakeSigner(config, block.Number()) 784 785 transactions, logIndex := block.Transactions(), uint(0) 786 if len(transactions) != len(receipts) { 787 return errors.New("transaction and receipt count mismatch") 788 } 789 790 for j := 0; j < len(receipts); j++ { 791 // The transaction hash can be retrieved from the transaction itself 792 receipts[j].TxHash = transactions[j].Hash() 793 794 // The contract address can be derived from the transaction itself 795 if transactions[j].To() == nil { 796 // Deriving the signer is expensive, only do if it's actually needed 797 from, _ := types.Sender(signer, transactions[j]) 798 receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce()) 799 } 800 // The used gas can be calculated based on previous receipts 801 if j == 0 { 802 receipts[j].GasUsed = receipts[j].CumulativeGasUsed 803 } else { 804 receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed 805 } 806 // The derived log fields can simply be set from the block and transaction 807 for k := 0; k < len(receipts[j].Logs); k++ { 808 receipts[j].Logs[k].BlockNumber = block.NumberU64() 809 receipts[j].Logs[k].BlockHash = block.Hash() 810 receipts[j].Logs[k].TxHash = receipts[j].TxHash 811 receipts[j].Logs[k].TxIndex = uint(j) 812 receipts[j].Logs[k].Index = logIndex 813 logIndex++ 814 } 815 } 816 return nil 817 } 818 819 // InsertReceiptChain attempts to complete an already existing header chain with 820 // transaction and receipt data. 821 func (bc *BlockChain) InsertReceiptChain(ctx context.Context, blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { 822 if !bc.wgAdd() { 823 return 0, ErrStopping 824 } 825 defer bc.wg.Done() 826 827 // Do a sanity check that the provided chain is actually ordered and linked 828 for i := 1; i < len(blockChain); i++ { 829 if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { 830 log.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(), 831 "prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash()) 832 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(), 833 blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4]) 834 } 835 } 836 837 var ( 838 stats = struct{ processed, ignored int32 }{} 839 start = time.Now() 840 bytes = 0 841 gbatch = bc.db.GlobalTable().NewBatch() 842 bbatch = bc.db.BodyTable().NewBatch() 843 rbatch = bc.db.ReceiptTable().NewBatch() 844 ) 845 for i, block := range blockChain { 846 receipts := receiptChain[i] 847 // Short circuit insertion if shutting down or processing failed 848 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 849 return 0, nil 850 } 851 // Short circuit if the owner header is unknown 852 if !bc.HasHeader(block.Hash(), block.NumberU64()) { 853 return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) 854 } 855 // Skip if the entire data is already known 856 if bc.HasBlock(block.Hash(), block.NumberU64()) { 857 stats.ignored++ 858 continue 859 } 860 // Compute all the non-consensus fields of the receipts 861 if err := SetReceiptsData(ctx, bc.chainConfig, block, receipts); err != nil { 862 return i, fmt.Errorf("failed to set receipts data: %v", err) 863 } 864 // Write all the data out into the database 865 rawdb.WriteBody(bbatch, block.Hash(), block.NumberU64(), block.Body()) 866 rawdb.WriteReceipts(rbatch, block.Hash(), block.NumberU64(), receipts) 867 rawdb.WriteTxLookupEntries(gbatch, block) 868 stats.processed++ 869 870 if bbatch.ValueSize() >= ethdb.IdealBatchSize || rbatch.ValueSize() >= ethdb.IdealBatchSize { 871 rawdb.Must("flush global batch", gbatch.Write) 872 rawdb.Must("flush body batch", bbatch.Write) 873 rawdb.Must("flush receipts batch", rbatch.Write) 874 bytes += gbatch.ValueSize() 875 bytes += bbatch.ValueSize() 876 bytes += rbatch.ValueSize() 877 gbatch.Reset() 878 bbatch.Reset() 879 rbatch.Reset() 880 } 881 } 882 if gbatch.ValueSize() > 0 { 883 bytes += gbatch.ValueSize() 884 rawdb.Must("write global batch", gbatch.Write) 885 } 886 if bbatch.ValueSize() > 0 { 887 bytes += bbatch.ValueSize() 888 rawdb.Must("write body batch", bbatch.Write) 889 } 890 if rbatch.ValueSize() > 0 { 891 bytes += rbatch.ValueSize() 892 rawdb.Must("write receipts batch", rbatch.Write) 893 } 894 895 // Update the head fast sync block if better 896 bc.mu.Lock() 897 head := blockChain[len(blockChain)-1] 898 if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case 899 currentFastBlock := bc.CurrentFastBlock() 900 if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 { 901 rawdb.WriteHeadFastBlockHash(bc.db.GlobalTable(), head.Hash()) 902 bc.currentFastBlock.Store(head) 903 } 904 } 905 bc.mu.Unlock() 906 907 log.Info("Imported new block receipts", 908 "count", stats.processed, 909 "elapsed", common.PrettyDuration(time.Since(start)), 910 "number", head.Number(), 911 "hash", head.Hash(), 912 "size", common.StorageSize(bytes), 913 "ignored", stats.ignored) 914 return 0, nil 915 } 916 917 var lastWrite uint64 918 919 // WriteBlockWithoutState writes only the block and its metadata to the database, 920 // but does not write any state. This is used to construct competing side forks 921 // up to the point where they exceed the canonical total difficulty. 922 func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (err error) { 923 if !bc.wgAdd() { 924 return ErrStopping 925 } 926 defer bc.wg.Done() 927 928 bc.hc.WriteTd(block.Hash(), block.NumberU64(), td) 929 rawdb.WriteBlock(bc.db, block) 930 return nil 931 } 932 933 // WriteBlockWithState writes the block and all associated state to the database. 934 func (bc *BlockChain) WriteBlockWithState(ctx context.Context, block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) { 935 ctx, span := trace.StartSpan(ctx, "BlockChain.WriteBlockWithState") 936 defer span.End() 937 938 if !bc.wgAdd() { 939 return 0, ErrStopping 940 } 941 defer bc.wg.Done() 942 943 // Calculate the total difficulty of the block 944 ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) 945 if ptd == nil { 946 return NonStatTy, consensus.ErrUnknownAncestor 947 } 948 // Make sure no inconsistent state is leaked during insertion 949 bc.mu.Lock() 950 defer bc.mu.Unlock() 951 952 currentBlock := bc.CurrentBlock() 953 currentHash := currentBlock.Hash() 954 localTd := bc.GetTd(currentHash, currentBlock.NumberU64()) 955 externTd := new(big.Int).Add(block.Difficulty(), ptd) 956 957 // Irrelevant of the canonical status, write the block itself to the database 958 hash := block.Hash() 959 bc.hc.WriteTd(hash, block.NumberU64(), externTd) 960 rawdb.WriteBlock(bc.db, block) 961 root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) 962 if err != nil { 963 return NonStatTy, err 964 } 965 triedb := bc.stateCache.TrieDB() 966 967 // If we're running an archive node, always flush 968 if bc.cacheConfig.Disabled { 969 if err := triedb.Commit(root, false); err != nil { 970 return NonStatTy, err 971 } 972 } else { 973 // Full but not archive node, do proper garbage collection 974 triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive 975 bc.triegc.Push(root, -int64(block.NumberU64())) 976 977 if current := block.NumberU64(); current > triesInMemory { 978 // If we exceeded our memory allowance, flush matured singleton nodes to disk 979 var ( 980 nodes, imgs = triedb.Size() 981 limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024 982 ) 983 if nodes > limit || imgs > 4*1024*1024 { 984 triedb.Cap(limit - ethdb.IdealBatchSize) 985 } 986 // Find the next state trie we need to commit 987 header := bc.GetHeaderByNumber(current - triesInMemory) 988 chosen := header.Number.Uint64() 989 990 // If we exceeded out time allowance, flush an entire trie to disk 991 if bc.gcproc > bc.cacheConfig.TrieTimeLimit { 992 // If we're exceeding limits but haven't reached a large enough memory gap, 993 // warn the user that the system is becoming unstable. 994 if chosen < lastWrite+triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { 995 log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory) 996 } 997 // Flush an entire trie and restart the counters 998 if err := triedb.Commit(header.Root, true); err != nil { 999 log.Error("Cannot commit trie db", "err", err) 1000 } 1001 lastWrite = chosen 1002 bc.gcproc = 0 1003 } 1004 // Garbage collect anything below our required write retention 1005 for !bc.triegc.Empty() { 1006 root, number := bc.triegc.Pop() 1007 if uint64(-number) > chosen { 1008 bc.triegc.Push(root, number) 1009 break 1010 } 1011 triedb.Dereference(root.(common.Hash)) 1012 } 1013 } 1014 } 1015 rawdb.WriteReceipts(bc.db.ReceiptTable(), block.Hash(), block.NumberU64(), receipts) 1016 local := chainHead{localTd, currentBlock.NumberU64(), currentBlock.GasUsed()} 1017 external := chainHead{externTd, block.NumberU64(), block.GasUsed()} 1018 if reorg(local, external) { 1019 // Reorganise the chain if the parent is not the head block 1020 if block.ParentHash() != currentBlock.Hash() { 1021 log.Info("Reorganizing block chain", "oldnum", currentBlock.NumberU64(), "newnum", block.NumberU64(), "oldtd", localTd, "newtd", externTd, "oldhash", currentHash, "newhash", hash) 1022 start := time.Now() 1023 if err := bc.reorg(ctx, currentBlock, block); err != nil { 1024 return NonStatTy, err 1025 } 1026 dur := time.Since(start) 1027 log.Info("Reorganized block chain", "dur", common.PrettyDuration(dur)) 1028 } 1029 rawdb.WriteTxLookupEntries(bc.db.GlobalTable(), block) 1030 rawdb.WritePreimages(bc.db.GlobalTable(), block.NumberU64(), state.Preimages()) 1031 status = CanonStatTy 1032 } else { 1033 status = SideStatTy 1034 } 1035 1036 // Set new head. 1037 if status == CanonStatTy { 1038 bc.insert(block) 1039 } 1040 bc.futureBlocks.Remove(block.Hash()) 1041 return status, nil 1042 } 1043 1044 type chainHead struct { 1045 totalDifficulty *big.Int 1046 number uint64 1047 gasUsed uint64 1048 } 1049 1050 // reorg returns true if the external chainHead should be used instead of local. 1051 // Cases include: 1052 // - higher total difficulty 1053 // - same total difficulty and lesser number 1054 // - same total difficulty and number, more gas used 1055 // - same total difficulty, number, and gas used, random 50/50 chance 1056 // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf 1057 func reorg(local, external chainHead) bool { 1058 cmp := external.totalDifficulty.Cmp(local.totalDifficulty) 1059 if cmp != 0 { 1060 return cmp > 0 1061 } 1062 log.Info("Reorg same difficulty", "diff", local.totalDifficulty, "oldnum", local.number, "newnum", external.number) 1063 // Split same-difficulty blocks by number, then most gas used, then randomly. 1064 if external.number < local.number { 1065 return true 1066 } 1067 if external.number == local.number { 1068 if external.gasUsed > local.gasUsed { 1069 return true 1070 } 1071 if external.gasUsed == local.gasUsed && rand.Float64() < 0.5 { 1072 return true 1073 } 1074 } 1075 return false 1076 } 1077 1078 // addFutureBlock checks if the block is within the max allowed window to get 1079 // accepted for future processing, and returns an error if the block is too far 1080 // ahead and was not added. 1081 func (bc *BlockChain) addFutureBlock(block *types.Block) error { 1082 max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks) 1083 if block.Time().Cmp(max) > 0 { 1084 return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max) 1085 } 1086 bc.futureBlocks.Add(block.Hash(), block) 1087 return nil 1088 } 1089 1090 // InsertChain attempts to insert the given batch of blocks in to the canonical 1091 // chain or, otherwise, create a fork. If an error is returned it will return 1092 // the index number of the failing block as well an error describing what went 1093 // wrong. 1094 // 1095 // After insertion is done, all accumulated events will be fired. 1096 func (bc *BlockChain) InsertChain(ctx context.Context, chain types.Blocks) (int, error) { 1097 ctx, span := trace.StartSpan(ctx, "BlockChain.InsertChain", trace.WithSampler(trace.AlwaysSample())) 1098 defer span.End() 1099 span.AddAttributes(trace.Int64Attribute("len", int64(len(chain)))) 1100 1101 // Sanity check that we have something meaningful to import 1102 if len(chain) == 0 { 1103 return 0, nil 1104 } 1105 // Do a sanity check that the provided chain is actually ordered and linked. 1106 for i := 1; i < len(chain); i++ { 1107 if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { 1108 // Chain broke ancestry, log a message (programming error) and skip insertion 1109 log.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(), 1110 "parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash()) 1111 1112 return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(), 1113 chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4]) 1114 } 1115 } 1116 // Pre-checks passed, start the full block imports 1117 if !bc.wgAdd() { 1118 return 0, ErrStopping 1119 } 1120 bc.chainmu.Lock() 1121 n, events, logs, err := bc.insertChain(ctx, chain, true) 1122 bc.chainmu.Unlock() 1123 bc.wg.Done() 1124 1125 bc.PostChainEvents(ctx, events, logs) 1126 return n, err 1127 } 1128 1129 // insertChain is the internal implementation of insertChain, which assumes that 1130 // 1) chains are contiguous, and 2) The chain mutex is held. 1131 // 1132 // This method is split out so that import batches that require re-injecting 1133 // historical blocks can do so without releasing the lock, which could lead to 1134 // racey behaviour. If a sidechain import is in progress, and the historic state 1135 // is imported, but then new canon-head is added before the actual sidechain 1136 // completes, then the historic state could be pruned again 1137 func (bc *BlockChain) insertChain(ctx context.Context, chain types.Blocks, verifySeals bool) (int, []interface{}, []*types.Log, error) { 1138 // If the chain is terminating, don't even bother starting u 1139 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1140 return 0, nil, nil, nil 1141 } 1142 // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) 1143 senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) 1144 1145 // A queued approach to delivering events. This is generally 1146 // faster than direct delivery and requires much less mutex 1147 // acquiring. 1148 var ( 1149 stats = insertStats{startTime: mclock.Now()} 1150 events = make([]interface{}, 0, len(chain)) 1151 lastCanon *types.Block 1152 coalescedLogs []*types.Log 1153 ) 1154 // Start the parallel header verifier 1155 headers := make([]*types.Header, len(chain)) 1156 for i, block := range chain { 1157 headers[i] = block.Header() 1158 } 1159 abortHeaders, results := bc.engine.VerifyHeaders(ctx, bc, headers) 1160 defer close(abortHeaders) 1161 1162 // Peek the error for the first block to decide the directing import logic 1163 it := newInsertIterator(chain, results, bc.Validator()) 1164 1165 block, err := it.next(ctx) 1166 switch { 1167 // First block is pruned, insert as sidechain and reorg only if TD grows enough 1168 case err == consensus.ErrPrunedAncestor: 1169 return bc.insertSidechain(ctx, it) 1170 1171 // First block is future, shove it (and all children) to the future queue (unknown ancestor) 1172 case err == consensus.ErrFutureBlock || (err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(it.first().ParentHash())): 1173 for block != nil && (it.index == 0 || err == consensus.ErrUnknownAncestor) { 1174 if err := bc.addFutureBlock(block); err != nil { 1175 return it.index, events, coalescedLogs, err 1176 } 1177 block, err = it.next(ctx) 1178 } 1179 stats.queued += it.processed() 1180 stats.ignored += it.remaining() 1181 1182 // If there are any still remaining, mark as ignored 1183 return it.index, events, coalescedLogs, err 1184 1185 // First block (and state) is known 1186 // 1. We did a roll-back, and should now do a re-import 1187 // 2. The block is stored as a sidechain, and is lying about it's stateroot, and passes a stateroot 1188 // from the canonical chain, which has not been verified. 1189 case err == ErrKnownBlock: 1190 // Skip all known blocks that behind us 1191 current := bc.CurrentBlock().NumberU64() 1192 1193 for block != nil && err == ErrKnownBlock && current >= block.NumberU64() { 1194 stats.ignored++ 1195 block, err = it.next(ctx) 1196 } 1197 // Falls through to the block import 1198 1199 // Some other error occurred, abort 1200 case err != nil: 1201 stats.ignored += len(it.chain) 1202 bc.reportBlock(block, nil, err) 1203 return it.index, events, coalescedLogs, err 1204 } 1205 // No validation errors for the first block (or chain prefix skipped) 1206 for ; block != nil && err == nil; block, err = it.next(ctx) { 1207 // If the chain is terminating, stop processing blocks 1208 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1209 log.Debug("Premature abort during blocks processing") 1210 break 1211 } 1212 // If the header is a banned one, straight out abort 1213 if BadHashes[block.Hash()] { 1214 bc.reportBlock(block, nil, ErrBlacklistedHash) 1215 return it.index, events, coalescedLogs, ErrBlacklistedHash 1216 } 1217 // Retrieve the parent block and it's state to execute on top 1218 start := time.Now() 1219 1220 parent := it.previous() 1221 if parent == nil { 1222 parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 1223 } 1224 state, err := state.New(parent.Root(), bc.stateCache) 1225 if err != nil { 1226 return it.index, events, coalescedLogs, err 1227 } 1228 // Process block using the parent state as reference point. 1229 t0 := time.Now() 1230 receipts, logs, usedGas, err := bc.processor.Process(ctx, block, state, bc.vmConfig) 1231 t1 := time.Now() 1232 if err != nil { 1233 bc.reportBlock(block, receipts, err) 1234 return it.index, events, coalescedLogs, err 1235 } 1236 // Validate the state using the default validator 1237 if err := bc.Validator().ValidateState(ctx, block, parent, state, receipts, usedGas); err != nil { 1238 bc.reportBlock(block, receipts, err) 1239 return it.index, events, coalescedLogs, err 1240 } 1241 t2 := time.Now() 1242 proctime := time.Since(start) 1243 1244 // Write the block to the chain and get the status. 1245 status, err := bc.WriteBlockWithState(ctx, block, receipts, state) 1246 t3 := time.Now() 1247 if err != nil { 1248 return it.index, events, coalescedLogs, err 1249 } 1250 blockInsertTimer.UpdateSince(start) 1251 blockExecutionTimer.Update(t1.Sub(t0)) 1252 blockValidationTimer.Update(t2.Sub(t1)) 1253 blockWriteTimer.Update(t3.Sub(t2)) 1254 switch status { 1255 case CanonStatTy: 1256 log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), "diff", block.Difficulty(), 1257 "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), 1258 "elapsed", common.PrettyDuration(time.Since(start)), 1259 "root", block.Root()) 1260 1261 coalescedLogs = append(coalescedLogs, logs...) 1262 events = append(events, ChainEvent{block, block.Hash(), logs}) 1263 lastCanon = block 1264 1265 // Only count canonical blocks for GC processing time 1266 bc.gcproc += proctime 1267 1268 case SideStatTy: 1269 log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), "diff", block.Difficulty(), 1270 "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), 1271 "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), 1272 "root", block.Root()) 1273 events = append(events, ChainSideEvent{block}) 1274 } 1275 blockInsertTimer.UpdateSince(start) 1276 stats.processed++ 1277 stats.usedGas += usedGas 1278 1279 cache, _ := bc.stateCache.TrieDB().Size() 1280 stats.report(chain, it.index, cache) 1281 } 1282 // Any blocks remaining here? The only ones we care about are the future ones 1283 if block != nil && err == consensus.ErrFutureBlock { 1284 if err := bc.addFutureBlock(block); err != nil { 1285 return it.index, events, coalescedLogs, err 1286 } 1287 block, err = it.next(ctx) 1288 1289 for ; block != nil && err == consensus.ErrUnknownAncestor; block, err = it.next(ctx) { 1290 if err := bc.addFutureBlock(block); err != nil { 1291 return it.index, events, coalescedLogs, err 1292 } 1293 stats.queued++ 1294 } 1295 } 1296 stats.ignored += it.remaining() 1297 1298 // Append a single chain head event if we've progressed the chain 1299 if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { 1300 events = append(events, ChainHeadEvent{lastCanon}) 1301 } 1302 return it.index, events, coalescedLogs, err 1303 } 1304 1305 // insertSidechain is called when an import batch hits upon a pruned ancestor 1306 // error, which happens when a sidechain with a sufficiently old fork-block is 1307 // found. 1308 // 1309 // The method writes all (header-and-body-valid) blocks to disk, then tries to 1310 // switch over to the new chain if the TD exceeded the current chain. 1311 func (bc *BlockChain) insertSidechain(ctx context.Context, it *insertIterator) (int, []interface{}, []*types.Log, error) { 1312 var ( 1313 externTd *big.Int 1314 current = bc.CurrentBlock().NumberU64() 1315 ) 1316 // The first sidechain block error is already verified to be ErrPrunedAncestor. 1317 // Since we don't import them here, we expect ErrUnknownAncestor for the remaining 1318 // ones. Any other errors means that the block is invalid, and should not be written 1319 // to disk. 1320 block, err := it.current(), consensus.ErrPrunedAncestor 1321 for ; block != nil && (err == consensus.ErrPrunedAncestor); block, err = it.next(ctx) { 1322 // Check the canonical state root for that number 1323 if number := block.NumberU64(); current >= number { 1324 if canonical := bc.GetBlockByNumber(number); canonical != nil && canonical.Root() == block.Root() { 1325 // This is most likely a shadow-state attack. When a fork is imported into the 1326 // database, and it eventually reaches a block height which is not pruned, we 1327 // just found that the state already exist! This means that the sidechain block 1328 // refers to a state which already exists in our canon chain. 1329 // 1330 // If left unchecked, we would now proceed importing the blocks, without actually 1331 // having verified the state of the previous blocks. 1332 log.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root()) 1333 1334 // If someone legitimately side-mines blocks, they would still be imported as usual. However, 1335 // we cannot risk writing unverified blocks to disk when they obviously target the pruning 1336 // mechanism. 1337 return it.index, nil, nil, errors.New("sidechain ghost-state attack") 1338 } 1339 } 1340 if externTd == nil { 1341 externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) 1342 } 1343 externTd = new(big.Int).Add(externTd, block.Difficulty()) 1344 1345 if !bc.HasBlock(block.Hash(), block.NumberU64()) { 1346 start := time.Now() 1347 if err := bc.WriteBlockWithoutState(block, externTd); err != nil { 1348 return it.index, nil, nil, err 1349 } 1350 log.Debug("Inserted sidechain block", "number", block.Number(), "hash", block.Hash(), 1351 "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), 1352 "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), 1353 "root", block.Root()) 1354 } 1355 } 1356 // At this point, we've written all sidechain blocks to database. Loop ended 1357 // either on some other error or all were processed. If there was some other 1358 // error, we can ignore the rest of those blocks. 1359 // 1360 // If the externTd was larger than our local TD, we now need to reimport the previous 1361 // blocks to regenerate the required state 1362 localTd := bc.GetTd(bc.CurrentBlock().Hash(), current) 1363 if localTd.Cmp(externTd) > 0 { 1364 log.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().NumberU64(), "sidetd", externTd, "localtd", localTd) 1365 return it.index, nil, nil, err 1366 } 1367 // Gather all the sidechain hashes (full blocks may be memory heavy) 1368 var ( 1369 hashes []common.Hash 1370 numbers []uint64 1371 ) 1372 parent := bc.GetHeader(it.previous().Hash(), it.previous().NumberU64()) 1373 for parent != nil && !bc.HasState(parent.Root) { 1374 hashes = append(hashes, parent.Hash()) 1375 numbers = append(numbers, parent.Number.Uint64()) 1376 1377 parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1) 1378 } 1379 if parent == nil { 1380 return it.index, nil, nil, errors.New("missing parent") 1381 } 1382 // Import all the pruned blocks to make the state available 1383 var ( 1384 blocks []*types.Block 1385 memory common.StorageSize 1386 ) 1387 for i := len(hashes) - 1; i >= 0; i-- { 1388 // Append the next block to our batch 1389 block := bc.GetBlock(hashes[i], numbers[i]) 1390 1391 blocks = append(blocks, block) 1392 memory += block.Size() 1393 1394 // If memory use grew too large, import and continue. Sadly we need to discard 1395 // all raised events and logs from notifications since we're too heavy on the 1396 // memory here. 1397 if len(blocks) >= 2048 || memory > 64*1024*1024 { 1398 log.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64()) 1399 if _, _, _, err := bc.insertChain(ctx, blocks, false); err != nil { 1400 return 0, nil, nil, err 1401 } 1402 blocks, memory = blocks[:0], 0 1403 1404 // If the chain is terminating, stop processing blocks 1405 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1406 log.Debug("Premature abort during blocks processing") 1407 return 0, nil, nil, nil 1408 } 1409 } 1410 } 1411 if len(blocks) > 0 { 1412 log.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64()) 1413 return bc.insertChain(ctx, blocks, false) 1414 } 1415 return 0, nil, nil, nil 1416 } 1417 1418 // reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them 1419 // to be part of the new canonical chain and accumulates potential missing transactions and post an 1420 // event about them 1421 func (bc *BlockChain) reorg(ctx context.Context, oldBlock, newBlock *types.Block) error { 1422 ctx, span := trace.StartSpan(ctx, "BlockChain.reorg") 1423 defer span.End() 1424 1425 var ( 1426 newChain types.Blocks 1427 oldChain types.Blocks 1428 commonBlock *types.Block 1429 deletedTxs types.Transactions 1430 deletedLogs []*types.Log 1431 // collectLogs collects the logs that were generated during the 1432 // processing of the block that corresponds with the given hash. 1433 // These logs are later announced as deleted. 1434 collectLogs = func(hash common.Hash) { 1435 // Coalesce logs and set 'Removed'. 1436 number := bc.hc.GetBlockNumber(hash) 1437 if number == nil { 1438 return 1439 } 1440 receipts := rawdb.ReadReceipts(bc.db.ReceiptTable(), hash, *number) 1441 for _, receipt := range receipts { 1442 for _, log := range receipt.Logs { 1443 del := *log 1444 del.Removed = true 1445 deletedLogs = append(deletedLogs, &del) 1446 } 1447 } 1448 } 1449 ) 1450 1451 // first reduce whoever is higher bound 1452 if oldBlock.NumberU64() > newBlock.NumberU64() { 1453 // reduce old chain 1454 for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { 1455 oldChain = append(oldChain, oldBlock) 1456 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1457 1458 collectLogs(oldBlock.Hash()) 1459 } 1460 } else { 1461 // reduce new chain and append new chain blocks for inserting later on 1462 for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { 1463 newChain = append(newChain, newBlock) 1464 } 1465 } 1466 if oldBlock == nil { 1467 return fmt.Errorf("Invalid old chain") 1468 } 1469 if newBlock == nil { 1470 return fmt.Errorf("Invalid new chain") 1471 } 1472 1473 for { 1474 if oldBlock.Hash() == newBlock.Hash() { 1475 commonBlock = oldBlock 1476 break 1477 } 1478 1479 oldChain = append(oldChain, oldBlock) 1480 newChain = append(newChain, newBlock) 1481 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1482 collectLogs(oldBlock.Hash()) 1483 1484 oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) 1485 if oldBlock == nil { 1486 return fmt.Errorf("Invalid old chain") 1487 } 1488 if newBlock == nil { 1489 return fmt.Errorf("Invalid new chain") 1490 } 1491 } 1492 // Ensure the user sees large reorgs 1493 if len(oldChain) > 0 && len(newChain) > 0 { 1494 logFn := log.Debug 1495 if len(oldChain) > 63 { 1496 logFn = log.Warn 1497 } 1498 logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(), 1499 "drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash()) 1500 } else { 1501 log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) 1502 } 1503 // Insert the new chain, taking care of the proper incremental order 1504 addedTxs := make(map[common.Hash]struct{}) 1505 batch := bc.db.GlobalTable().NewBatch() 1506 for i := len(newChain) - 1; i >= 0; i-- { 1507 // insert the block in the canonical way, re-writing history 1508 bc.insert(newChain[i]) 1509 // write lookup entries for hash based transaction/receipt searches 1510 rawdb.WriteTxLookupEntries(batch, newChain[i]) 1511 for _, tx := range newChain[i].Transactions() { 1512 addedTxs[tx.Hash()] = struct{}{} 1513 } 1514 } 1515 // calculate the difference between deleted and added transactions 1516 var diff types.Transactions 1517 for _, tx := range deletedTxs { 1518 if _, ok := addedTxs[tx.Hash()]; !ok { 1519 diff = append(diff, tx) 1520 } 1521 } 1522 // When transactions get deleted from the database that means the 1523 // receipts that were created in the fork must also be deleted 1524 for _, tx := range diff { 1525 rawdb.DeleteTxLookupEntry(batch, tx.Hash()) 1526 } 1527 rawdb.Must("batch delete tx lookup entries", batch.Write) 1528 if len(deletedLogs) > 0 { 1529 bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs}) 1530 } 1531 if len(oldChain) > 0 { 1532 for _, block := range oldChain { 1533 bc.chainSideFeed.Send(ChainSideEvent{Block: block}) 1534 } 1535 } 1536 1537 return nil 1538 } 1539 1540 // PostChainEvents iterates over the events generated by a chain insertion and 1541 // posts them into the event feed. 1542 // TODO: Should not expose PostChainEvents. The chain events should be posted in WriteBlock. 1543 func (bc *BlockChain) PostChainEvents(ctx context.Context, events []interface{}, logs []*types.Log) { 1544 ctx, span := trace.StartSpan(ctx, "BlockChain.PostChainEvents") 1545 defer span.End() 1546 1547 // post event logs for further processing 1548 if logs != nil { 1549 bc.logsFeed.Send(logs) 1550 } 1551 for _, event := range events { 1552 switch ev := event.(type) { 1553 case ChainEvent: 1554 bc.chainFeed.Send(ev) 1555 1556 case ChainHeadEvent: 1557 bc.chainHeadFeed.Send(ev) 1558 1559 case ChainSideEvent: 1560 bc.chainSideFeed.Send(ev) 1561 } 1562 } 1563 } 1564 1565 func (bc *BlockChain) update() { 1566 futureTimer := time.NewTicker(5 * time.Second) 1567 defer futureTimer.Stop() 1568 for { 1569 select { 1570 case <-futureTimer.C: 1571 ctx, span := trace.StartSpan(context.Background(), "BlockChain.update-futureTimer") 1572 bc.procFutureBlocks(ctx) 1573 span.End() 1574 case <-bc.quit: 1575 return 1576 } 1577 } 1578 } 1579 1580 // BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network 1581 func (bc *BlockChain) BadBlocks() []*types.Block { 1582 blocks := make([]*types.Block, 0, bc.badBlocks.Len()) 1583 for _, hash := range bc.badBlocks.Keys() { 1584 if blk, exist := bc.badBlocks.Peek(hash); exist { 1585 block := blk.(*types.Block) 1586 blocks = append(blocks, block) 1587 } 1588 } 1589 return blocks 1590 } 1591 1592 // addBadBlock adds a bad block to the bad-block LRU cache 1593 func (bc *BlockChain) addBadBlock(block *types.Block) { 1594 bc.badBlocks.Add(block.Header().Hash(), block.Header()) 1595 } 1596 1597 // reportBlock logs a bad block error. 1598 func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { 1599 bc.addBadBlock(block) 1600 1601 var receiptString string 1602 for _, receipt := range receipts { 1603 receiptString += fmt.Sprintf("\t%v\n", receipt) 1604 } 1605 log.Error(fmt.Sprintf(` 1606 ########## BAD BLOCK ######### 1607 Chain config: %v 1608 1609 Number: %v 1610 Hash: 0x%x 1611 %v 1612 1613 Error: %v 1614 ############################## 1615 `, bc.chainConfig, block.Number(), block.Hash(), receiptString, err)) 1616 } 1617 1618 // InsertHeaderChain attempts to insert the given header chain in to the local 1619 // chain, possibly creating a reorg. If an error is returned, it will return the 1620 // index number of the failing header as well an error describing what went wrong. 1621 // 1622 // The verify parameter can be used to fine tune whether nonce verification 1623 // should be done or not. The reason behind the optional check is because some 1624 // of the header retrieval mechanisms already need to verify nonces, as well as 1625 // because nonces can be verified sparsely, not needing to check each. 1626 func (bc *BlockChain) InsertHeaderChain(ctx context.Context, chain []*types.Header, checkFreq int) (int, error) { 1627 start := time.Now() 1628 if i, err := bc.hc.ValidateHeaderChain(ctx, chain, checkFreq); err != nil { 1629 return i, err 1630 } 1631 1632 // Make sure only one thread manipulates the chain at once 1633 bc.chainmu.Lock() 1634 defer bc.chainmu.Unlock() 1635 1636 if !bc.wgAdd() { 1637 return 0, ErrStopping 1638 } 1639 defer bc.wg.Done() 1640 1641 whFunc := func(header *types.Header) error { 1642 bc.mu.Lock() 1643 defer bc.mu.Unlock() 1644 1645 _, err := bc.hc.WriteHeader(header) 1646 return err 1647 } 1648 1649 return bc.hc.InsertHeaderChain(chain, whFunc, start) 1650 } 1651 1652 // writeHeader writes a header into the local chain, given that its parent is 1653 // already known. If the total difficulty of the newly inserted header becomes 1654 // greater than the current known TD, the canonical chain is re-routed. 1655 // 1656 // Note: This method is not concurrent-safe with inserting blocks simultaneously 1657 // into the chain, as side effects caused by reorganisations cannot be emulated 1658 // without the real blocks. Hence, writing headers directly should only be done 1659 // in two scenarios: pure-header mode of operation (light clients), or properly 1660 // separated header/block phases (non-archive clients). 1661 func (bc *BlockChain) writeHeader(header *types.Header) error { 1662 if !bc.wgAdd() { 1663 return ErrStopping 1664 } 1665 defer bc.wg.Done() 1666 1667 bc.mu.Lock() 1668 defer bc.mu.Unlock() 1669 1670 _, err := bc.hc.WriteHeader(header) 1671 return err 1672 } 1673 1674 // CurrentHeader retrieves the current head header of the canonical chain. The 1675 // header is retrieved from the HeaderChain's internal cache. 1676 func (bc *BlockChain) CurrentHeader() *types.Header { 1677 return bc.hc.CurrentHeader() 1678 } 1679 1680 // GetTd retrieves a block's total difficulty in the canonical chain from the 1681 // database by hash and number, caching it if found. 1682 func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { 1683 return bc.hc.GetTd(hash, number) 1684 } 1685 1686 // GetTdByHash retrieves a block's total difficulty in the canonical chain from the 1687 // database by hash, caching it if found. 1688 func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { 1689 return bc.hc.GetTdByHash(hash) 1690 } 1691 1692 // GetHeader retrieves a block header from the database by hash and number, 1693 // caching it if found. 1694 func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { 1695 return bc.hc.GetHeader(hash, number) 1696 } 1697 1698 // GetHeaderByHash retrieves a block header from the database by hash, caching it if 1699 // found. 1700 func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { 1701 return bc.hc.GetHeaderByHash(hash) 1702 } 1703 1704 // HasHeader checks if a block header is present in the database or not, caching 1705 // it if present. 1706 func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool { 1707 return bc.hc.HasHeader(hash, number) 1708 } 1709 1710 // GetBlockHashesFromHash retrieves a number of block hashes starting at a given 1711 // hash, fetching towards the genesis block. 1712 func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { 1713 return bc.hc.GetBlockHashesFromHash(hash, max) 1714 } 1715 1716 // GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or 1717 // a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the 1718 // number of blocks to be individually checked before we reach the canonical chain. 1719 // 1720 // Note: ancestor == 0 returns the same block, 1 returns its parent and so on. 1721 func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { 1722 bc.chainmu.Lock() 1723 defer bc.chainmu.Unlock() 1724 1725 return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical) 1726 } 1727 1728 // GetHeaderByNumber retrieves a block header from the database by number, 1729 // caching it (associated with its hash) if found. 1730 func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { 1731 return bc.hc.GetHeaderByNumber(number) 1732 } 1733 1734 // Config retrieves the blockchain's chain configuration. 1735 func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig } 1736 1737 // Engine retrieves the blockchain's consensus engine. 1738 func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } 1739 1740 // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent. 1741 func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent, name string) { 1742 bc.rmLogsFeed.Subscribe(ch, name) 1743 } 1744 1745 func (bc *BlockChain) UnsubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) { 1746 bc.rmLogsFeed.Unsubscribe(ch) 1747 } 1748 1749 // SubscribeChainEvent registers a subscription of ChainEvent. 1750 func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent, name string) { 1751 bc.chainFeed.Subscribe(ch, name) 1752 } 1753 1754 // SubscribeChainEvent registers a subscription of ChainEvent. 1755 func (bc *BlockChain) UnsubscribeChainEvent(ch chan<- ChainEvent) { 1756 bc.chainFeed.Unsubscribe(ch) 1757 } 1758 1759 // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. 1760 func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent, name string) { 1761 bc.chainHeadFeed.Subscribe(ch, name) 1762 } 1763 1764 // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. 1765 func (bc *BlockChain) UnsubscribeChainHeadEvent(ch chan<- ChainHeadEvent) { 1766 bc.chainHeadFeed.Unsubscribe(ch) 1767 } 1768 1769 // SubscribeChainSideEvent registers a subscription of ChainSideEvent. 1770 func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent, name string) { 1771 bc.chainSideFeed.Subscribe(ch, name) 1772 } 1773 1774 func (bc *BlockChain) UnsubscribeChainSideEvent(ch chan<- ChainSideEvent) { 1775 bc.chainSideFeed.Unsubscribe(ch) 1776 } 1777 1778 // SubscribeLogsEvent registers a subscription of []*types.Log. 1779 func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log, name string) { 1780 bc.logsFeed.Subscribe(ch, name) 1781 } 1782 1783 func (bc *BlockChain) UnsubscribeLogsEvent(ch chan<- []*types.Log) { 1784 bc.logsFeed.Unsubscribe(ch) 1785 } 1786 1787 // wgAdd adds 1 to wg while holding the read lock, unless the quit channel has been closed. 1788 // Returns true if added, or false if stopped. 1789 func (bc *BlockChain) wgAdd() bool { 1790 bc.wgQuitMu.RLock() 1791 defer bc.wgQuitMu.RUnlock() 1792 select { 1793 case <-bc.quit: 1794 return false 1795 default: 1796 } 1797 bc.wg.Add(1) 1798 return true 1799 } 1800 1801 // closeQuit closes the quit channel while holding the write lock. 1802 func (bc *BlockChain) closeQuit() { 1803 bc.wgQuitMu.Lock() 1804 defer bc.wgQuitMu.Unlock() 1805 close(bc.quit) 1806 }