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