github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/core/blockchain.go (about) 1 // Copyright 2014 The Spectrum Authors 2 // This file is part of the Spectrum library. 3 // 4 // The Spectrum 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 Spectrum 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 Spectrum 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 "sync" 27 "sync/atomic" 28 "time" 29 30 "crypto/ecdsa" 31 32 "github.com/SmartMeshFoundation/Spectrum/common" 33 "github.com/SmartMeshFoundation/Spectrum/common/mclock" 34 "github.com/SmartMeshFoundation/Spectrum/consensus" 35 "github.com/SmartMeshFoundation/Spectrum/core/state" 36 "github.com/SmartMeshFoundation/Spectrum/core/types" 37 "github.com/SmartMeshFoundation/Spectrum/core/vm" 38 "github.com/SmartMeshFoundation/Spectrum/crypto" 39 "github.com/SmartMeshFoundation/Spectrum/ethdb" 40 "github.com/SmartMeshFoundation/Spectrum/event" 41 "github.com/SmartMeshFoundation/Spectrum/log" 42 "github.com/SmartMeshFoundation/Spectrum/metrics" 43 "github.com/SmartMeshFoundation/Spectrum/params" 44 "github.com/SmartMeshFoundation/Spectrum/rlp" 45 "github.com/SmartMeshFoundation/Spectrum/trie" 46 lru "github.com/hashicorp/golang-lru" 47 ) 48 49 var ( 50 blockInsertTimer = metrics.NewTimer("chain/inserts") 51 52 ErrNoGenesis = errors.New("Genesis not found in chain") 53 ) 54 55 const ( 56 bodyCacheLimit = 256 57 blockCacheLimit = 256 58 maxFutureBlocks = 256 59 maxTimeFutureBlocks = 30 60 badBlockLimit = 10 61 62 // BlockChainVersion ensures that an incompatible database forces a resync from scratch. 63 BlockChainVersion = 3 64 ) 65 66 // BlockChain represents the canonical chain given a database with a genesis 67 // block. The Blockchain manages chain imports, reverts, chain reorganisations. 68 // 69 // Importing blocks in to the block chain happens according to the set of rules 70 // defined by the two stage Validator. Processing of blocks is done using the 71 // Processor which processes the included transaction. The validation of the state 72 // is done in the second part of the Validator. Failing results in aborting of 73 // the import. 74 // 75 // The BlockChain also helps in returning blocks from **any** chain included 76 // in the database as well as blocks that represents the canonical chain. It's 77 // important to note that GetBlock can return any block and does not need to be 78 // included in the canonical one where as GetBlockByNumber always represents the 79 // canonical chain. 80 type BlockChain struct { 81 config *params.ChainConfig // chain & network configuration 82 83 hc *HeaderChain 84 chainDb ethdb.Database 85 rmLogsFeed event.Feed 86 chainFeed event.Feed 87 chainSideFeed event.Feed 88 chainHeadFeed event.Feed 89 logsFeed event.Feed 90 scope event.SubscriptionScope 91 genesisBlock *types.Block 92 93 mu sync.RWMutex // global mutex for locking chain operations 94 chainmu sync.RWMutex // blockchain insertion lock 95 procmu sync.RWMutex // block processor lock 96 97 checkpoint int // checkpoint counts towards the new checkpoint 98 currentBlock *types.Block // Current head of the block chain 99 currentFastBlock *types.Block // Current head of the fast-sync chain (may be above the block chain!) 100 101 stateCache state.Database // State database to reuse between imports (contains state cache) 102 bodyCache *lru.Cache // Cache for the most recent block bodies 103 bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format 104 blockCache *lru.Cache // Cache for the most recent entire blocks 105 futureBlocks *lru.Cache // future blocks are blocks added for later processing 106 107 quit chan struct{} // blockchain quit channel 108 running int32 // running must be called atomically 109 // procInterrupt must be atomically called 110 procInterrupt int32 // interrupt signaler for block processing 111 wg sync.WaitGroup // chain processing wait group for shutting down 112 113 engine consensus.Engine 114 processor Processor // block processor interface 115 validator Validator // block and state validator interface 116 vmConfig vm.Config 117 118 badBlocks *lru.Cache // Bad block cache 119 120 nodeKey *ecdsa.PrivateKey 121 } 122 123 // NewBlockChain returns a fully initialised block chain using information 124 // available in the database. It initialises the default Ethereum Validator and 125 // Processor. 126 func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) { 127 bodyCache, _ := lru.New(bodyCacheLimit) 128 bodyRLPCache, _ := lru.New(bodyCacheLimit) 129 blockCache, _ := lru.New(blockCacheLimit) 130 futureBlocks, _ := lru.New(maxFutureBlocks) 131 badBlocks, _ := lru.New(badBlockLimit) 132 133 bc := &BlockChain{ 134 config: config, 135 chainDb: chainDb, 136 stateCache: state.NewDatabase(chainDb), 137 quit: make(chan struct{}), 138 bodyCache: bodyCache, 139 bodyRLPCache: bodyRLPCache, 140 blockCache: blockCache, 141 futureBlocks: futureBlocks, 142 engine: engine, 143 vmConfig: vmConfig, 144 badBlocks: badBlocks, 145 } 146 bc.SetValidator(NewBlockValidator(config, bc, engine)) 147 bc.SetProcessor(NewStateProcessor(config, bc, engine)) 148 149 var err error 150 bc.hc, err = NewHeaderChain(chainDb, config, engine, bc.getProcInterrupt) 151 if err != nil { 152 return nil, err 153 } 154 bc.genesisBlock = bc.GetBlockByNumber(0) 155 if bc.genesisBlock == nil { 156 return nil, ErrNoGenesis 157 } 158 if err := bc.loadLastState(); err != nil { 159 return nil, err 160 } 161 // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain 162 for hash := range BadHashes { 163 if header := bc.GetHeaderByHash(hash); header != nil { 164 // get the canonical block corresponding to the offending header's number 165 headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64()) 166 // make sure the headerByNumber (if present) is in our current canonical chain 167 if headerByNumber != nil && headerByNumber.Hash() == header.Hash() { 168 log.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) 169 bc.SetHead(header.Number.Uint64() - 1) 170 log.Error("Chain rewind was successful, resuming normal operation") 171 } 172 } 173 } 174 // Take ownership of this particular state 175 go bc.update() 176 // add by liangc : set nodekey 177 go func() { 178 <-params.InitTribeStatus 179 rtn := params.SendToMsgBox("GetNodeKey") 180 success := <-rtn 181 bc.nodeKey = success.Entity.(*ecdsa.PrivateKey) 182 }() 183 return bc, nil 184 } 185 186 func (bc *BlockChain) getProcInterrupt() bool { 187 return atomic.LoadInt32(&bc.procInterrupt) == 1 188 } 189 190 // loadLastState loads the last known chain state from the database. This method 191 // assumes that the chain manager mutex is held. 192 func (bc *BlockChain) loadLastState() error { 193 // Restore the last known head block 194 head := GetHeadBlockHash(bc.chainDb) 195 if head == (common.Hash{}) { 196 // Corrupt or empty database, init from scratch 197 log.Warn("Empty database, resetting chain") 198 return bc.Reset() 199 } 200 // Make sure the entire head block is available 201 currentBlock := bc.GetBlockByHash(head) 202 if currentBlock == nil { 203 // Corrupt or empty database, init from scratch 204 log.Warn("Head block missing, resetting chain", "hash", head) 205 return bc.Reset() 206 } 207 // Make sure the state associated with the block is available 208 if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil { 209 // Dangling block without a state associated, init from scratch 210 log.Warn("Head state missing, resetting chain", "number", currentBlock.Number(), "hash", currentBlock.Hash()) 211 return bc.Reset() 212 } 213 // Everything seems to be fine, set as the head block 214 bc.currentBlock = currentBlock 215 216 // Restore the last known head header 217 currentHeader := bc.currentBlock.Header() 218 if head := GetHeadHeaderHash(bc.chainDb); head != (common.Hash{}) { 219 if header := bc.GetHeaderByHash(head); header != nil { 220 currentHeader = header 221 } 222 } 223 bc.hc.SetCurrentHeader(currentHeader) 224 225 // Restore the last known head fast block 226 bc.currentFastBlock = bc.currentBlock 227 if head := GetHeadFastBlockHash(bc.chainDb); head != (common.Hash{}) { 228 if block := bc.GetBlockByHash(head); block != nil { 229 bc.currentFastBlock = block 230 } 231 } 232 233 // Issue a status log for the user 234 headerTd := bc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()) 235 blockTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()) 236 fastTd := bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()) 237 238 log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd) 239 log.Info("Loaded most recent local full block", "number", bc.currentBlock.Number(), "hash", bc.currentBlock.Hash(), "td", blockTd) 240 log.Info("Loaded most recent local fast block", "number", bc.currentFastBlock.Number(), "hash", bc.currentFastBlock.Hash(), "td", fastTd) 241 242 return nil 243 } 244 245 // SetHead rewinds the local chain to a new head. In the case of headers, everything 246 // above the new head will be deleted and the new one set. In the case of blocks 247 // though, the head may be further rewound if block bodies are missing (non-archive 248 // nodes after a fast sync). 249 func (bc *BlockChain) SetHead(head uint64) error { 250 log.Warn("Rewinding blockchain", "target", head) 251 252 bc.mu.Lock() 253 defer bc.mu.Unlock() 254 255 // Rewind the header chain, deleting all block bodies until then 256 delFn := func(hash common.Hash, num uint64) { 257 DeleteBody(bc.chainDb, hash, num) 258 } 259 bc.hc.SetHead(head, delFn) 260 currentHeader := bc.hc.CurrentHeader() 261 262 // Clear out any stale content from the caches 263 bc.bodyCache.Purge() 264 bc.bodyRLPCache.Purge() 265 bc.blockCache.Purge() 266 bc.futureBlocks.Purge() 267 268 // Rewind the block chain, ensuring we don't end up with a stateless head block 269 if bc.currentBlock != nil && currentHeader.Number.Uint64() < bc.currentBlock.NumberU64() { 270 bc.currentBlock = bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()) 271 } 272 if bc.currentBlock != nil { 273 if _, err := state.New(bc.currentBlock.Root(), bc.stateCache); err != nil { 274 // Rewound state missing, rolled back to before pivot, reset to genesis 275 bc.currentBlock = nil 276 } 277 } 278 // Rewind the fast block in a simpleton way to the target head 279 if bc.currentFastBlock != nil && currentHeader.Number.Uint64() < bc.currentFastBlock.NumberU64() { 280 bc.currentFastBlock = bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64()) 281 } 282 // If either blocks reached nil, reset to the genesis state 283 if bc.currentBlock == nil { 284 bc.currentBlock = bc.genesisBlock 285 } 286 if bc.currentFastBlock == nil { 287 bc.currentFastBlock = bc.genesisBlock 288 } 289 if err := WriteHeadBlockHash(bc.chainDb, bc.currentBlock.Hash()); err != nil { 290 log.Crit("Failed to reset head full block", "err", err) 291 } 292 if err := WriteHeadFastBlockHash(bc.chainDb, bc.currentFastBlock.Hash()); err != nil { 293 log.Crit("Failed to reset head fast block", "err", err) 294 } 295 return bc.loadLastState() 296 } 297 298 // FastSyncCommitHead sets the current head block to the one defined by the hash 299 // irrelevant what the chain contents were prior. 300 func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { 301 // Make sure that both the block as well at its state trie exists 302 block := bc.GetBlockByHash(hash) 303 if block == nil { 304 return fmt.Errorf("non existent block [%x…]", hash[:4]) 305 } 306 if _, err := trie.NewSecure(block.Root(), bc.chainDb, 0); err != nil { 307 return err 308 } 309 // If all checks out, manually set the head block 310 bc.mu.Lock() 311 bc.currentBlock = block 312 bc.mu.Unlock() 313 314 log.Info("Committed new head block", "number", block.Number(), "hash", hash) 315 return nil 316 } 317 318 // GasLimit returns the gas limit of the current HEAD block. 319 func (bc *BlockChain) GasLimit() *big.Int { 320 bc.mu.RLock() 321 defer bc.mu.RUnlock() 322 323 return bc.currentBlock.GasLimit() 324 } 325 326 // LastBlockHash return the hash of the HEAD block. 327 func (bc *BlockChain) LastBlockHash() common.Hash { 328 bc.mu.RLock() 329 defer bc.mu.RUnlock() 330 331 return bc.currentBlock.Hash() 332 } 333 334 // CurrentBlock retrieves the current head block of the canonical chain. The 335 // block is retrieved from the blockchain's internal cache. 336 func (bc *BlockChain) CurrentBlock() *types.Block { 337 bc.mu.RLock() 338 defer bc.mu.RUnlock() 339 340 return bc.currentBlock 341 } 342 343 // CurrentFastBlock retrieves the current fast-sync head block of the canonical 344 // chain. The block is retrieved from the blockchain's internal cache. 345 func (bc *BlockChain) CurrentFastBlock() *types.Block { 346 bc.mu.RLock() 347 defer bc.mu.RUnlock() 348 349 return bc.currentFastBlock 350 } 351 352 // Status returns status information about the current chain such as the HEAD Td, 353 // the HEAD hash and the hash of the genesis block. 354 func (bc *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) { 355 bc.mu.RLock() 356 defer bc.mu.RUnlock() 357 358 return bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()), bc.currentBlock.Hash(), bc.genesisBlock.Hash() 359 } 360 361 // SetProcessor sets the processor required for making state modifications. 362 func (bc *BlockChain) SetProcessor(processor Processor) { 363 bc.procmu.Lock() 364 defer bc.procmu.Unlock() 365 bc.processor = processor 366 } 367 368 // SetValidator sets the validator which is used to validate incoming blocks. 369 func (bc *BlockChain) SetValidator(validator Validator) { 370 bc.procmu.Lock() 371 defer bc.procmu.Unlock() 372 bc.validator = validator 373 } 374 375 // Validator returns the current validator. 376 func (bc *BlockChain) Validator() Validator { 377 bc.procmu.RLock() 378 defer bc.procmu.RUnlock() 379 return bc.validator 380 } 381 382 // Processor returns the current processor. 383 func (bc *BlockChain) Processor() Processor { 384 bc.procmu.RLock() 385 defer bc.procmu.RUnlock() 386 return bc.processor 387 } 388 389 // State returns a new mutable state based on the current HEAD block. 390 func (bc *BlockChain) State() (*state.StateDB, error) { 391 return bc.StateAt(bc.CurrentBlock().Root()) 392 } 393 394 // StateAt returns a new mutable state based on a particular point in time. 395 func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { 396 return state.New(root, bc.stateCache) 397 } 398 399 // Reset purges the entire blockchain, restoring it to its genesis state. 400 func (bc *BlockChain) Reset() error { 401 return bc.ResetWithGenesisBlock(bc.genesisBlock) 402 } 403 404 // ResetWithGenesisBlock purges the entire blockchain, restoring it to the 405 // specified genesis state. 406 func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { 407 // Dump the entire block chain and purge the caches 408 if err := bc.SetHead(0); err != nil { 409 return err 410 } 411 bc.mu.Lock() 412 defer bc.mu.Unlock() 413 414 // Prepare the genesis block and reinitialise the chain 415 if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { 416 log.Crit("Failed to write genesis block TD", "err", err) 417 } 418 if err := WriteBlock(bc.chainDb, genesis); err != nil { 419 log.Crit("Failed to write genesis block", "err", err) 420 } 421 bc.genesisBlock = genesis 422 bc.insert(bc.genesisBlock) 423 bc.currentBlock = bc.genesisBlock 424 bc.hc.SetGenesis(bc.genesisBlock.Header()) 425 bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) 426 bc.currentFastBlock = bc.genesisBlock 427 428 return nil 429 } 430 431 // Export writes the active chain to the given writer. 432 func (bc *BlockChain) Export(w io.Writer) error { 433 return bc.ExportN(w, uint64(0), bc.currentBlock.NumberU64()) 434 } 435 436 // ExportN writes a subset of the active chain to the given writer. 437 func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { 438 bc.mu.RLock() 439 defer bc.mu.RUnlock() 440 441 if first > last { 442 return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) 443 } 444 log.Info("Exporting batch of blocks", "count", last-first+1) 445 446 for nr := first; nr <= last; nr++ { 447 block := bc.GetBlockByNumber(nr) 448 if block == nil { 449 return fmt.Errorf("export failed on #%d: not found", nr) 450 } 451 452 if err := block.EncodeRLP(w); err != nil { 453 return err 454 } 455 } 456 457 return nil 458 } 459 460 // insert injects a new head block into the current block chain. This method 461 // assumes that the block is indeed a true head. It will also reset the head 462 // header and the head fast sync block to this very same block if they are older 463 // or if they are on a different side chain. 464 // 465 // Note, this function assumes that the `mu` mutex is held! 466 func (bc *BlockChain) insert(block *types.Block) { 467 // If the block is on a side chain or an unknown one, force other heads onto it too 468 updateHeads := GetCanonicalHash(bc.chainDb, block.NumberU64()) != block.Hash() 469 470 // Add the block to the canonical chain number scheme and mark as the head 471 if err := WriteCanonicalHash(bc.chainDb, block.Hash(), block.NumberU64()); err != nil { 472 log.Crit("Failed to insert block number", "err", err) 473 } 474 if err := WriteHeadBlockHash(bc.chainDb, block.Hash()); err != nil { 475 log.Crit("Failed to insert head block hash", "err", err) 476 } 477 bc.currentBlock = block 478 479 // If the block is better than out head or is on a different chain, force update heads 480 if updateHeads { 481 bc.hc.SetCurrentHeader(block.Header()) 482 483 if err := WriteHeadFastBlockHash(bc.chainDb, block.Hash()); err != nil { 484 log.Crit("Failed to insert head fast block hash", "err", err) 485 } 486 bc.currentFastBlock = block 487 } 488 } 489 490 // Genesis retrieves the chain's genesis block. 491 func (bc *BlockChain) Genesis() *types.Block { 492 return bc.genesisBlock 493 } 494 495 // GetBody retrieves a block body (transactions and uncles) from the database by 496 // hash, caching it if found. 497 func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { 498 // Short circuit if the body's already in the cache, retrieve otherwise 499 if cached, ok := bc.bodyCache.Get(hash); ok { 500 body := cached.(*types.Body) 501 return body 502 } 503 body := GetBody(bc.chainDb, hash, bc.hc.GetBlockNumber(hash)) 504 if body == nil { 505 return nil 506 } 507 // Cache the found body for next time and return 508 bc.bodyCache.Add(hash, body) 509 return body 510 } 511 512 // GetBodyRLP retrieves a block body in RLP encoding from the database by hash, 513 // caching it if found. 514 func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { 515 // Short circuit if the body's already in the cache, retrieve otherwise 516 if cached, ok := bc.bodyRLPCache.Get(hash); ok { 517 return cached.(rlp.RawValue) 518 } 519 body := GetBodyRLP(bc.chainDb, hash, bc.hc.GetBlockNumber(hash)) 520 if len(body) == 0 { 521 return nil 522 } 523 // Cache the found body for next time and return 524 bc.bodyRLPCache.Add(hash, body) 525 return body 526 } 527 528 // HasBlock checks if a block is fully present in the database or not. 529 func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool { 530 if bc.blockCache.Contains(hash) { 531 return true 532 } 533 ok, _ := bc.chainDb.Has(blockBodyKey(hash, number)) 534 return ok 535 } 536 537 // HasBlockAndState checks if a block and associated state trie is fully present 538 // in the database or not, caching it if present. 539 func (bc *BlockChain) HasBlockAndState(hash common.Hash) bool { 540 // Check first that the block itself is known 541 block := bc.GetBlockByHash(hash) 542 if block == nil { 543 return false 544 } 545 // Ensure the associated state is also present 546 _, err := bc.stateCache.OpenTrie(block.Root()) 547 return err == nil 548 } 549 550 // GetBlock retrieves a block from the database by hash and number, 551 // caching it if found. 552 func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 553 // Short circuit if the block's already in the cache, retrieve otherwise 554 if block, ok := bc.blockCache.Get(hash); ok { 555 return block.(*types.Block) 556 } 557 block := GetBlock(bc.chainDb, hash, number) 558 if block == nil { 559 return nil 560 } 561 // Cache the found block for next time and return 562 bc.blockCache.Add(block.Hash(), block) 563 return block 564 } 565 566 // GetBlockByHash retrieves a block from the database by hash, caching it if found. 567 func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { 568 return bc.GetBlock(hash, bc.hc.GetBlockNumber(hash)) 569 } 570 571 // GetBlockByNumber retrieves a block from the database by number, caching it 572 // (associated with its hash) if found. 573 func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { 574 hash := GetCanonicalHash(bc.chainDb, number) 575 if hash == (common.Hash{}) { 576 return nil 577 } 578 return bc.GetBlock(hash, number) 579 } 580 581 // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. 582 // [deprecated by eth/62] 583 func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { 584 number := bc.hc.GetBlockNumber(hash) 585 for i := 0; i < n; i++ { 586 block := bc.GetBlock(hash, number) 587 if block == nil { 588 break 589 } 590 blocks = append(blocks, block) 591 hash = block.ParentHash() 592 number-- 593 } 594 return 595 } 596 597 // GetUnclesInChain retrieves all the uncles from a given block backwards until 598 // a specific distance is reached. 599 func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { 600 uncles := []*types.Header{} 601 for i := 0; block != nil && i < length; i++ { 602 uncles = append(uncles, block.Uncles()...) 603 block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 604 } 605 return uncles 606 } 607 608 // Stop stops the blockchain service. If any imports are currently in progress 609 // it will abort them using the procInterrupt. 610 func (bc *BlockChain) Stop() { 611 if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { 612 return 613 } 614 // Unsubscribe all subscriptions registered from blockchain 615 bc.scope.Close() 616 close(bc.quit) 617 atomic.StoreInt32(&bc.procInterrupt, 1) 618 619 bc.wg.Wait() 620 log.Info("Blockchain manager stopped") 621 } 622 623 func (bc *BlockChain) procFutureBlocks() { 624 blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) 625 for _, hash := range bc.futureBlocks.Keys() { 626 if block, exist := bc.futureBlocks.Peek(hash); exist { 627 blocks = append(blocks, block.(*types.Block)) 628 } 629 } 630 if len(blocks) > 0 { 631 types.BlockBy(types.Number).Sort(blocks) 632 633 // Insert one by one as chain insertion needs contiguous ancestry between blocks 634 for i := range blocks { 635 bc.InsertChain(blocks[i : i+1]) 636 } 637 } 638 } 639 640 // WriteStatus status of write 641 type WriteStatus byte 642 643 const ( 644 NonStatTy WriteStatus = iota 645 CanonStatTy 646 SideStatTy 647 ) 648 649 // Rollback is designed to remove a chain of links from the database that aren't 650 // certain enough to be valid. 651 func (bc *BlockChain) Rollback(chain []common.Hash) { 652 bc.mu.Lock() 653 defer bc.mu.Unlock() 654 655 for i := len(chain) - 1; i >= 0; i-- { 656 hash := chain[i] 657 658 currentHeader := bc.hc.CurrentHeader() 659 if currentHeader.Hash() == hash { 660 bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) 661 } 662 if bc.currentFastBlock.Hash() == hash { 663 bc.currentFastBlock = bc.GetBlock(bc.currentFastBlock.ParentHash(), bc.currentFastBlock.NumberU64()-1) 664 WriteHeadFastBlockHash(bc.chainDb, bc.currentFastBlock.Hash()) 665 } 666 if bc.currentBlock.Hash() == hash { 667 bc.currentBlock = bc.GetBlock(bc.currentBlock.ParentHash(), bc.currentBlock.NumberU64()-1) 668 WriteHeadBlockHash(bc.chainDb, bc.currentBlock.Hash()) 669 } 670 } 671 } 672 673 // SetReceiptsData computes all the non-consensus fields of the receipts 674 func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) { 675 signer := types.MakeSigner(config, block.Number()) 676 677 transactions, logIndex := block.Transactions(), uint(0) 678 679 for j := 0; j < len(receipts); j++ { 680 // The transaction hash can be retrieved from the transaction itself 681 receipts[j].TxHash = transactions[j].Hash() 682 683 // The contract address can be derived from the transaction itself 684 if transactions[j].To() == nil { 685 // Deriving the signer is expensive, only do if it's actually needed 686 from, _ := types.Sender(signer, transactions[j]) 687 receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce()) 688 } 689 // The used gas can be calculated based on previous receipts 690 if j == 0 { 691 receipts[j].GasUsed = new(big.Int).Set(receipts[j].CumulativeGasUsed) 692 } else { 693 receipts[j].GasUsed = new(big.Int).Sub(receipts[j].CumulativeGasUsed, receipts[j-1].CumulativeGasUsed) 694 } 695 // The derived log fields can simply be set from the block and transaction 696 for k := 0; k < len(receipts[j].Logs); k++ { 697 receipts[j].Logs[k].BlockNumber = block.NumberU64() 698 receipts[j].Logs[k].BlockHash = block.Hash() 699 receipts[j].Logs[k].TxHash = receipts[j].TxHash 700 receipts[j].Logs[k].TxIndex = uint(j) 701 receipts[j].Logs[k].Index = logIndex 702 logIndex++ 703 } 704 } 705 } 706 707 // InsertReceiptChain attempts to complete an already existing header chain with 708 // transaction and receipt data. 709 func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { 710 bc.wg.Add(1) 711 defer bc.wg.Done() 712 713 // Do a sanity check that the provided chain is actually ordered and linked 714 for i := 1; i < len(blockChain); i++ { 715 if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { 716 log.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(), 717 "prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash()) 718 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(), 719 blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4]) 720 } 721 } 722 723 var ( 724 stats = struct{ processed, ignored int32 }{} 725 start = time.Now() 726 bytes = 0 727 batch = bc.chainDb.NewBatch() 728 ) 729 for i, block := range blockChain { 730 receipts := receiptChain[i] 731 // Short circuit insertion if shutting down or processing failed 732 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 733 return 0, nil 734 } 735 // Short circuit if the owner header is unknown 736 if !bc.HasHeader(block.Hash(), block.NumberU64()) { 737 return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) 738 } 739 // Skip if the entire data is already known 740 if bc.HasBlock(block.Hash(), block.NumberU64()) { 741 stats.ignored++ 742 continue 743 } 744 // Compute all the non-consensus fields of the receipts 745 SetReceiptsData(bc.config, block, receipts) 746 // Write all the data out into the database 747 if err := WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()); err != nil { 748 return i, fmt.Errorf("failed to write block body: %v", err) 749 } 750 if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil { 751 return i, fmt.Errorf("failed to write block receipts: %v", err) 752 } 753 if err := WriteTxLookupEntries(batch, block); err != nil { 754 return i, fmt.Errorf("failed to write lookup metadata: %v", err) 755 } 756 stats.processed++ 757 758 if batch.ValueSize() >= ethdb.IdealBatchSize { 759 if err := batch.Write(); err != nil { 760 return 0, err 761 } 762 bytes += batch.ValueSize() 763 batch = bc.chainDb.NewBatch() 764 } 765 } 766 if batch.ValueSize() > 0 { 767 bytes += batch.ValueSize() 768 if err := batch.Write(); err != nil { 769 return 0, err 770 } 771 } 772 773 // Update the head fast sync block if better 774 bc.mu.Lock() 775 head := blockChain[len(blockChain)-1] 776 if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case 777 if bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()).Cmp(td) < 0 { 778 if err := WriteHeadFastBlockHash(bc.chainDb, head.Hash()); err != nil { 779 log.Crit("Failed to update head fast block hash", "err", err) 780 } 781 bc.currentFastBlock = head 782 } 783 } 784 bc.mu.Unlock() 785 786 log.Debug("Imported new block receipts", 787 "count", stats.processed, 788 "elapsed", common.PrettyDuration(time.Since(start)), 789 "bytes", bytes, 790 "number", head.Number(), 791 "hash", head.Hash(), 792 "ignored", stats.ignored) 793 return 0, nil 794 } 795 796 // WriteBlock writes the block to the chain. 797 func (bc *BlockChain) WriteBlockAndState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) { 798 bc.wg.Add(1) 799 defer bc.wg.Done() 800 801 // Calculate the total difficulty of the block 802 ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) 803 if ptd == nil { 804 return NonStatTy, consensus.ErrUnknownAncestor 805 } 806 // Make sure no inconsistent state is leaked during insertion 807 bc.mu.Lock() 808 defer func() { 809 bc.mu.Unlock() 810 }() 811 812 localTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()) 813 externTd := new(big.Int).Add(block.Difficulty(), ptd) 814 815 // Irrelevant of the canonical status, write the block itself to the database 816 if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil { 817 return NonStatTy, err 818 } 819 // Write other block data using a batch. 820 batch := bc.chainDb.NewBatch() 821 if err := WriteBlock(batch, block); err != nil { 822 return NonStatTy, err 823 } 824 if _, err := state.CommitTo(batch, bc.config.IsEIP158(block.Number())); err != nil { 825 return NonStatTy, err 826 } 827 if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil { 828 return NonStatTy, err 829 } 830 831 // If the total difficulty is higher than our known, add it to the canonical chain 832 // Second clause in the if statement reduces the vulnerability to selfish mining. 833 // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf 834 reorg := externTd.Cmp(localTd) > 0 835 if !reorg && externTd.Cmp(localTd) == 0 { 836 // Split same-difficulty blocks by number, then at random 837 reorg = block.NumberU64() < bc.currentBlock.NumberU64() || (block.NumberU64() == bc.currentBlock.NumberU64() && mrand.Float64() < 0.5) 838 } 839 if reorg { 840 // Reorganise the chain if the parent is not the head block 841 if block.ParentHash() != bc.currentBlock.Hash() { 842 if err := bc.reorg(bc.currentBlock, block); err != nil { 843 return NonStatTy, err 844 } 845 } 846 // Write the positional metadata for transaction and receipt lookups 847 if err := WriteTxLookupEntries(batch, block); err != nil { 848 return NonStatTy, err 849 } 850 // Write hash preimages 851 if err := WritePreimages(bc.chainDb, block.NumberU64(), state.Preimages()); err != nil { 852 return NonStatTy, err 853 } 854 status = CanonStatTy 855 } else { 856 status = SideStatTy 857 } 858 if err := batch.Write(); err != nil { 859 return NonStatTy, err 860 } 861 862 // Set new head. 863 if status == CanonStatTy { 864 bc.insert(block) 865 } 866 bc.futureBlocks.Remove(block.Hash()) 867 return status, nil 868 } 869 870 // InsertChain attempts to insert the given batch of blocks in to the canonical 871 // chain or, otherwise, create a fork. If an error is returned it will return 872 // the index number of the failing block as well an error describing what went 873 // wrong. 874 // 875 // After insertion is done, all accumulated events will be fired. 876 func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { 877 n, events, logs, err := bc.insertChain(chain) 878 bc.PostChainEvents(events, logs) 879 log.Debug("Inserted block end", "number", chain[0].Number()) 880 return n, err 881 } 882 883 // insertChain will execute the actual chain insertion and event aggregation. The 884 // only reason this method exists as a separate one is to make locking cleaner 885 // with deferred statements. 886 func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*types.Log, error) { 887 // Do a sanity check that the provided chain is actually ordered and linked 888 for i := 1; i < len(chain); i++ { 889 if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { 890 // Chain broke ancestry, log a messge (programming error) and skip insertion 891 log.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(), 892 "parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash()) 893 894 return 0, nil, nil, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(), 895 chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4]) 896 } 897 } 898 // Pre-checks passed, start the full block imports 899 bc.wg.Add(1) 900 defer bc.wg.Done() 901 902 bc.chainmu.Lock() 903 defer func() { 904 bc.chainmu.Unlock() 905 }() 906 907 // A queued approach to delivering events. This is generally 908 // faster than direct delivery and requires much less mutex 909 // acquiring. 910 var ( 911 stats = insertStats{startTime: mclock.Now()} 912 events = make([]interface{}, 0, len(chain)) 913 lastCanon *types.Block 914 coalescedLogs []*types.Log 915 ) 916 // Start the parallel header verifier 917 headers := make([]*types.Header, len(chain)) 918 seals := make([]bool, len(chain)) 919 920 for i, block := range chain { 921 headers[i] = block.Header() 922 seals[i] = true 923 } 924 abort, results := bc.engine.VerifyHeaders(bc, headers, seals) 925 defer close(abort) 926 927 // Iterate over the blocks and insert when the verifier permits 928 for i, block := range chain { 929 // If the chain is terminating, stop processing blocks 930 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 931 log.Debug("Premature abort during blocks processing") 932 break 933 } 934 // If the header is a banned one, straight out abort 935 if BadHashes[block.Hash()] { 936 bc.reportBlock(block, nil, ErrBlacklistedHash) 937 return i, events, coalescedLogs, ErrBlacklistedHash 938 } 939 // Wait for the block's verification to complete 940 bstart := time.Now() 941 942 err := <-results 943 if err == nil { 944 err = bc.Validator().ValidateBody(bc.GetBlockByHash(block.ParentHash()), block) 945 } 946 if err != nil { 947 if err == ErrKnownBlock { 948 stats.ignored++ 949 continue 950 } 951 952 if err == consensus.ErrFutureBlock { 953 // Allow up to MaxFuture second in the future blocks. If this limit 954 // is exceeded the chain is discarded and processed at a later time 955 // if given. 956 max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks) 957 if block.Time().Cmp(max) > 0 { 958 return i, events, coalescedLogs, fmt.Errorf("future block: %v > %v", block.Time(), max) 959 } 960 bc.futureBlocks.Add(block.Hash(), block) 961 stats.queued++ 962 continue 963 } 964 965 if err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(block.ParentHash()) { 966 bc.futureBlocks.Add(block.Hash(), block) 967 stats.queued++ 968 continue 969 } 970 /* 971 this block is a bad block 972 if this block is in the futureblocks then remove it. 973 if this block is not in the future blocks, do nothing. 974 */ 975 bc.futureBlocks.Remove(block.Hash()) 976 977 bc.reportBlock(block, nil, err) 978 return i, events, coalescedLogs, err 979 } 980 981 // Create a new statedb using the parent block and report an 982 // error if it fails. 983 var parent *types.Block 984 if i == 0 { 985 parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 986 } else { 987 parent = chain[i-1] 988 } 989 state, err := state.New(parent.Root(), bc.stateCache) 990 if err != nil { 991 return i, events, coalescedLogs, err 992 } 993 // Process block using the parent state as reference point. 994 receipts, logs, usedGas, err := bc.processor.Process(block, state, bc.vmConfig) 995 if err != nil { 996 bc.reportBlock(block, receipts, err) 997 return i, events, coalescedLogs, err 998 } 999 if params.IsSIP100Block(block.Number()) { 1000 if len(receipts) <= 0 || receipts[0].Status != types.ReceiptStatusSuccessful { 1001 err = errors.New("there must be one chief update tx,and it must be successful") 1002 return i, events, coalescedLogs, err 1003 } 1004 } 1005 // Validate the state using the default validator 1006 err = bc.Validator().ValidateState(block, parent, state, receipts, usedGas) 1007 if err != nil { 1008 bc.reportBlock(block, receipts, err) 1009 return i, events, coalescedLogs, err 1010 } 1011 // Write the block to the chain and get the status. 1012 status, err := bc.WriteBlockAndState(block, receipts, state) 1013 if err != nil { 1014 return i, events, coalescedLogs, err 1015 } 1016 switch status { 1017 case CanonStatTy: 1018 log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), "uncles", len(block.Uncles()), 1019 "txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart))) 1020 1021 coalescedLogs = append(coalescedLogs, logs...) 1022 blockInsertTimer.UpdateSince(bstart) 1023 events = append(events, ChainEvent{block, block.Hash(), logs}) 1024 lastCanon = block 1025 1026 case SideStatTy: 1027 log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), "diff", block.Difficulty(), "elapsed", 1028 common.PrettyDuration(time.Since(bstart)), "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles())) 1029 1030 blockInsertTimer.UpdateSince(bstart) 1031 events = append(events, ChainSideEvent{block}) 1032 } 1033 stats.processed++ 1034 stats.usedGas += usedGas.Uint64() 1035 stats.report(chain, i) 1036 } 1037 // Append a single chain head event if we've progressed the chain 1038 if lastCanon != nil && bc.LastBlockHash() == lastCanon.Hash() { 1039 events = append(events, ChainHeadEvent{lastCanon}) 1040 } 1041 return 0, events, coalescedLogs, nil 1042 } 1043 1044 // insertStats tracks and reports on block insertion. 1045 type insertStats struct { 1046 queued, processed, ignored int 1047 usedGas uint64 1048 lastIndex int 1049 startTime mclock.AbsTime 1050 } 1051 1052 // statsReportLimit is the time limit during import after which we always print 1053 // out progress. This avoids the user wondering what's going on. 1054 const statsReportLimit = 8 * time.Second 1055 1056 // report prints statistics if some number of blocks have been processed 1057 // or more than a few seconds have passed since the last message. 1058 func (st *insertStats) report(chain []*types.Block, index int) { 1059 // Fetch the timings for the batch 1060 var ( 1061 now = mclock.Now() 1062 elapsed = time.Duration(now) - time.Duration(st.startTime) 1063 ) 1064 // If we're at the last block of the batch or report period reached, log 1065 if index == len(chain)-1 || elapsed >= statsReportLimit { 1066 var ( 1067 end = chain[index] 1068 txs = countTransactions(chain[st.lastIndex : index+1]) 1069 ) 1070 context := []interface{}{ 1071 "blocks", st.processed, 1072 "txs", txs, 1073 /* 1074 "mgas", float64(st.usedGas) / 1000000, 1075 "elapsed", common.PrettyDuration(elapsed), 1076 "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), 1077 */ 1078 "number", end.Number(), 1079 "miner", end.Coinbase().Hex(), 1080 "hash", end.Hash().Hex(), 1081 } 1082 if st.queued > 0 { 1083 context = append(context, []interface{}{"queued", st.queued}...) 1084 } 1085 if st.ignored > 0 { 1086 context = append(context, []interface{}{"ignored", st.ignored}...) 1087 } 1088 //log.Info(fmt.Sprintf("[report] new_block : num=%d , diff=%d , hash=%s , miner=%s", end.Number(), end.Difficulty(), end.Hash().Hex(), end.Coinbase().Hex())) 1089 log.Info(fmt.Sprintf("[report] new_block : num=%d , diff=%d , coinbase=%s", end.Number(), end.Difficulty(), end.Coinbase().Hex())) 1090 1091 *st = insertStats{startTime: now, lastIndex: index + 1} 1092 } 1093 } 1094 1095 func countTransactions(chain []*types.Block) (c int) { 1096 for _, b := range chain { 1097 c += len(b.Transactions()) 1098 } 1099 return c 1100 } 1101 1102 // reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them 1103 // to be part of the new canonical chain and accumulates potential missing transactions and post an 1104 // event about them 1105 func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { 1106 var ( 1107 newChain types.Blocks 1108 oldChain types.Blocks 1109 commonBlock *types.Block 1110 deletedTxs types.Transactions 1111 deletedLogs []*types.Log 1112 // collectLogs collects the logs that were generated during the 1113 // processing of the block that corresponds with the given hash. 1114 // These logs are later announced as deleted. 1115 collectLogs = func(h common.Hash) { 1116 // Coalesce logs and set 'Removed'. 1117 receipts := GetBlockReceipts(bc.chainDb, h, bc.hc.GetBlockNumber(h)) 1118 for _, receipt := range receipts { 1119 for _, log := range receipt.Logs { 1120 del := *log 1121 del.Removed = true 1122 deletedLogs = append(deletedLogs, &del) 1123 } 1124 } 1125 } 1126 ) 1127 1128 // first reduce whoever is higher bound 1129 if oldBlock.NumberU64() > newBlock.NumberU64() { 1130 // reduce old chain 1131 for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { 1132 oldChain = append(oldChain, oldBlock) 1133 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1134 1135 collectLogs(oldBlock.Hash()) 1136 } 1137 } else { 1138 // reduce new chain and append new chain blocks for inserting later on 1139 for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { 1140 newChain = append(newChain, newBlock) 1141 } 1142 } 1143 if oldBlock == nil { 1144 return fmt.Errorf("Invalid old chain") 1145 } 1146 if newBlock == nil { 1147 return fmt.Errorf("Invalid new chain") 1148 } 1149 1150 for { 1151 if oldBlock.Hash() == newBlock.Hash() { 1152 commonBlock = oldBlock 1153 break 1154 } 1155 1156 oldChain = append(oldChain, oldBlock) 1157 newChain = append(newChain, newBlock) 1158 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1159 collectLogs(oldBlock.Hash()) 1160 1161 oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) 1162 if oldBlock == nil { 1163 return fmt.Errorf("Invalid old chain") 1164 } 1165 if newBlock == nil { 1166 return fmt.Errorf("Invalid new chain") 1167 } 1168 } 1169 // Ensure the user sees large reorgs 1170 if len(oldChain) > 0 && len(newChain) > 0 { 1171 logFn := log.Debug 1172 if len(oldChain) > 63 { 1173 logFn = log.Warn 1174 } 1175 logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(), 1176 "drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash()) 1177 } else { 1178 log.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) 1179 } 1180 var addedTxs types.Transactions 1181 // insert blocks. Order does not matter. Last block will be written in ImportChain itself which creates the new head properly 1182 for _, block := range newChain { 1183 // insert the block in the canonical way, re-writing history 1184 bc.insert(block) 1185 // write lookup entries for hash based transaction/receipt searches 1186 if err := WriteTxLookupEntries(bc.chainDb, block); err != nil { 1187 return err 1188 } 1189 addedTxs = append(addedTxs, block.Transactions()...) 1190 } 1191 1192 // calculate the difference between deleted and added transactions 1193 diff := types.TxDifference(deletedTxs, addedTxs) 1194 // When transactions get deleted from the database that means the 1195 // receipts that were created in the fork must also be deleted 1196 for _, tx := range diff { 1197 DeleteTxLookupEntry(bc.chainDb, tx.Hash()) 1198 } 1199 if len(deletedLogs) > 0 { 1200 go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs}) 1201 } 1202 if len(oldChain) > 0 { 1203 go func() { 1204 for _, block := range oldChain { 1205 bc.chainSideFeed.Send(ChainSideEvent{Block: block}) 1206 } 1207 }() 1208 } 1209 1210 return nil 1211 } 1212 1213 // PostChainEvents iterates over the events generated by a chain insertion and 1214 // posts them into the event feed. 1215 // TODO: Should not expose PostChainEvents. The chain events should be posted in WriteBlock. 1216 func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) { 1217 // post event logs for further processing 1218 if logs != nil { 1219 bc.logsFeed.Send(logs) 1220 } 1221 for _, event := range events { 1222 switch ev := event.(type) { 1223 case ChainEvent: 1224 bc.chainFeed.Send(ev) 1225 1226 case ChainHeadEvent: 1227 bc.chainHeadFeed.Send(ev) 1228 1229 case ChainSideEvent: 1230 bc.chainSideFeed.Send(ev) 1231 } 1232 } 1233 } 1234 1235 func (bc *BlockChain) update() { 1236 futureTimer := time.Tick(5 * time.Second) 1237 for { 1238 select { 1239 case <-futureTimer: 1240 bc.procFutureBlocks() 1241 case <-bc.quit: 1242 return 1243 } 1244 } 1245 } 1246 1247 // BadBlockArgs represents the entries in the list returned when bad blocks are queried. 1248 type BadBlockArgs struct { 1249 Hash common.Hash `json:"hash"` 1250 Header *types.Header `json:"header"` 1251 } 1252 1253 // BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network 1254 func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) { 1255 headers := make([]BadBlockArgs, 0, bc.badBlocks.Len()) 1256 for _, hash := range bc.badBlocks.Keys() { 1257 if hdr, exist := bc.badBlocks.Peek(hash); exist { 1258 header := hdr.(*types.Header) 1259 headers = append(headers, BadBlockArgs{header.Hash(), header}) 1260 } 1261 } 1262 return headers, nil 1263 } 1264 1265 // addBadBlock adds a bad block to the bad-block LRU cache 1266 func (bc *BlockChain) addBadBlock(block *types.Block) { 1267 bc.badBlocks.Add(block.Header().Hash(), block.Header()) 1268 } 1269 1270 // reportBlock logs a bad block error. 1271 func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { 1272 bc.addBadBlock(block) 1273 1274 var receiptString string 1275 for _, receipt := range receipts { 1276 receiptString += fmt.Sprintf("\t%v\n", receipt) 1277 } 1278 log.Error(fmt.Sprintf(` 1279 ########## BAD BLOCK ######### 1280 Chain config: %v 1281 1282 Number: %v 1283 Hash: 0x%x 1284 %v 1285 1286 Error: %v 1287 ############################## 1288 `, bc.config, block.Number(), block.Hash(), receiptString, err)) 1289 } 1290 1291 // InsertHeaderChain attempts to insert the given header chain in to the local 1292 // chain, possibly creating a reorg. If an error is returned, it will return the 1293 // index number of the failing header as well an error describing what went wrong. 1294 // 1295 // The verify parameter can be used to fine tune whether nonce verification 1296 // should be done or not. The reason behind the optional check is because some 1297 // of the header retrieval mechanisms already need to verify nonces, as well as 1298 // because nonces can be verified sparsely, not needing to check each. 1299 func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { 1300 start := time.Now() 1301 if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { 1302 return i, err 1303 } 1304 1305 // Make sure only one thread manipulates the chain at once 1306 bc.chainmu.Lock() 1307 defer bc.chainmu.Unlock() 1308 1309 bc.wg.Add(1) 1310 defer bc.wg.Done() 1311 1312 whFunc := func(header *types.Header) error { 1313 bc.mu.Lock() 1314 defer bc.mu.Unlock() 1315 1316 _, err := bc.hc.WriteHeader(header) 1317 return err 1318 } 1319 1320 i, e := bc.hc.InsertHeaderChain(chain, whFunc, start) 1321 return i, e 1322 } 1323 1324 // writeHeader writes a header into the local chain, given that its parent is 1325 // already known. If the total difficulty of the newly inserted header becomes 1326 // greater than the current known TD, the canonical chain is re-routed. 1327 // 1328 // Note: This method is not concurrent-safe with inserting blocks simultaneously 1329 // into the chain, as side effects caused by reorganisations cannot be emulated 1330 // without the real blocks. Hence, writing headers directly should only be done 1331 // in two scenarios: pure-header mode of operation (light clients), or properly 1332 // separated header/block phases (non-archive clients). 1333 func (bc *BlockChain) writeHeader(header *types.Header) error { 1334 bc.wg.Add(1) 1335 defer bc.wg.Done() 1336 1337 bc.mu.Lock() 1338 defer bc.mu.Unlock() 1339 1340 _, err := bc.hc.WriteHeader(header) 1341 return err 1342 } 1343 1344 // CurrentHeader retrieves the current head header of the canonical chain. The 1345 // header is retrieved from the HeaderChain's internal cache. 1346 func (bc *BlockChain) CurrentHeader() *types.Header { 1347 bc.mu.RLock() 1348 defer bc.mu.RUnlock() 1349 1350 return bc.hc.CurrentHeader() 1351 } 1352 1353 // GetTd retrieves a block's total difficulty in the canonical chain from the 1354 // database by hash and number, caching it if found. 1355 func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { 1356 return bc.hc.GetTd(hash, number) 1357 } 1358 1359 // GetTdByHash retrieves a block's total difficulty in the canonical chain from the 1360 // database by hash, caching it if found. 1361 func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { 1362 return bc.hc.GetTdByHash(hash) 1363 } 1364 1365 // GetHeader retrieves a block header from the database by hash and number, 1366 // caching it if found. 1367 func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { 1368 return bc.hc.GetHeader(hash, number) 1369 } 1370 1371 // GetHeaderByHash retrieves a block header from the database by hash, caching it if 1372 // found. 1373 func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { 1374 return bc.hc.GetHeaderByHash(hash) 1375 } 1376 1377 // HasHeader checks if a block header is present in the database or not, caching 1378 // it if present. 1379 func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool { 1380 return bc.hc.HasHeader(hash, number) 1381 } 1382 1383 // GetBlockHashesFromHash retrieves a number of block hashes starting at a given 1384 // hash, fetching towards the genesis block. 1385 func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { 1386 return bc.hc.GetBlockHashesFromHash(hash, max) 1387 } 1388 1389 // GetHeaderByNumber retrieves a block header from the database by number, 1390 // caching it (associated with its hash) if found. 1391 func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { 1392 return bc.hc.GetHeaderByNumber(number) 1393 } 1394 1395 // Config retrieves the blockchain's chain configuration. 1396 func (bc *BlockChain) Config() *params.ChainConfig { return bc.config } 1397 1398 // Engine retrieves the blockchain's consensus engine. 1399 func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } 1400 1401 // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent. 1402 func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { 1403 return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch)) 1404 } 1405 1406 // SubscribeChainEvent registers a subscription of ChainEvent. 1407 func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription { 1408 return bc.scope.Track(bc.chainFeed.Subscribe(ch)) 1409 } 1410 1411 // SubscribeChainHeadEvent registers a subscription of ChainHeadEvent. 1412 func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 1413 return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch)) 1414 } 1415 1416 // SubscribeChainSideEvent registers a subscription of ChainSideEvent. 1417 func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription { 1418 return bc.scope.Track(bc.chainSideFeed.Subscribe(ch)) 1419 } 1420 1421 // SubscribeLogsEvent registers a subscription of []*types.Log. 1422 func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { 1423 return bc.scope.Track(bc.logsFeed.Subscribe(ch)) 1424 }