github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/core/blockchain.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package core implements the Ethereum consensus protocol. 18 package core 19 20 import ( 21 "errors" 22 "fmt" 23 "io" 24 "log" 25 "math/big" 26 mrand "math/rand" 27 "runtime" 28 "sync" 29 "sync/atomic" 30 "time" 31 32 "reflect" 33 "strconv" 34 35 "encoding/binary" 36 37 "github.com/ethereumproject/go-ethereum/common" 38 "github.com/ethereumproject/go-ethereum/core/state" 39 "github.com/ethereumproject/go-ethereum/core/types" 40 "github.com/ethereumproject/go-ethereum/core/vm" 41 "github.com/ethereumproject/go-ethereum/crypto" 42 "github.com/ethereumproject/go-ethereum/ethdb" 43 "github.com/ethereumproject/go-ethereum/event" 44 "github.com/ethereumproject/go-ethereum/logger" 45 "github.com/ethereumproject/go-ethereum/logger/glog" 46 "github.com/ethereumproject/go-ethereum/pow" 47 "github.com/ethereumproject/go-ethereum/rlp" 48 "github.com/ethereumproject/go-ethereum/trie" 49 "github.com/hashicorp/golang-lru" 50 ) 51 52 var ( 53 ErrNoGenesis = errors.New("Genesis not found in chain") 54 errNilBlock = errors.New("nil block") 55 errNilHeader = errors.New("nil header") 56 ) 57 58 const ( 59 headerCacheLimit = 512 60 bodyCacheLimit = 256 61 tdCacheLimit = 1024 62 blockCacheLimit = 256 63 maxFutureBlocks = 256 64 maxTimeFutureBlocks = 30 65 // must be bumped when consensus algorithm is changed, this forces the upgradedb 66 // command to be run (forces the blocks to be imported again using the new algorithm) 67 BlockChainVersion = 3 68 ) 69 70 // BlockChain represents the canonical chain given a database with a genesis 71 // block. The Blockchain manages chain imports, reverts, chain reorganisations. 72 // 73 // Importing blocks in to the block chain happens according to the set of rules 74 // defined by the two stage Validator. Processing of blocks is done using the 75 // Processor which processes the included transaction. The validation of the state 76 // is done in the second part of the Validator. Failing results in aborting of 77 // the import. 78 // 79 // The BlockChain also helps in returning blocks from **any** chain included 80 // in the database as well as blocks that represents the canonical chain. It's 81 // important to note that GetBlock can return any block and does not need to be 82 // included in the canonical one where as GetBlockByNumber always represents the 83 // canonical chain. 84 type BlockChain struct { 85 config *ChainConfig // chain & network configuration 86 87 hc *HeaderChain 88 chainDb ethdb.Database 89 eventMux *event.TypeMux 90 genesisBlock *types.Block 91 92 mu sync.RWMutex // global mutex for locking chain operations 93 chainmu sync.RWMutex // blockchain insertion lock 94 procmu sync.RWMutex // block processor lock 95 96 currentBlock *types.Block // Current head of the block chain 97 currentFastBlock *types.Block // Current head of the fast-sync chain (may be above the block chain!) 98 99 stateCache *state.StateDB // State database to reuse between imports (contains state cache) 100 bodyCache *lru.Cache // Cache for the most recent block bodies 101 bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format 102 blockCache *lru.Cache // Cache for the most recent entire blocks 103 futureBlocks *lru.Cache // future blocks are blocks added for later processing 104 105 quit chan struct{} // blockchain quit channel 106 running int32 // running must be called atomically 107 // procInterrupt must be atomically called 108 procInterrupt int32 // interrupt signaler for block processing 109 wg sync.WaitGroup // chain processing wait group for shutting down 110 111 pow pow.PoW 112 processor Processor // block processor interface 113 validator Validator // block and state validator interface 114 115 atxi *AtxiT 116 } 117 118 type ChainInsertResult struct { 119 ChainInsertEvent 120 Index int 121 Error error 122 } 123 124 type ReceiptChainInsertResult struct { 125 ReceiptChainInsertEvent 126 Index int 127 Error error 128 } 129 130 type HeaderChainInsertResult struct { 131 HeaderChainInsertEvent 132 Index int 133 Error error 134 } 135 136 func (bc *BlockChain) GetHeaderByHash(h common.Hash) *types.Header { 137 return bc.hc.GetHeader(h) 138 } 139 140 func (bc *BlockChain) GetBlockByHash(h common.Hash) *types.Block { 141 return bc.GetBlock(h) 142 } 143 144 // NewBlockChain returns a fully initialised block chain using information 145 // available in the database. It initialises the default Ethereum Validator and 146 // Processor. 147 func NewBlockChain(chainDb ethdb.Database, config *ChainConfig, pow pow.PoW, mux *event.TypeMux) (*BlockChain, error) { 148 bodyCache, _ := lru.New(bodyCacheLimit) 149 bodyRLPCache, _ := lru.New(bodyCacheLimit) 150 blockCache, _ := lru.New(blockCacheLimit) 151 futureBlocks, _ := lru.New(maxFutureBlocks) 152 153 bc := &BlockChain{ 154 config: config, 155 chainDb: chainDb, 156 eventMux: mux, 157 quit: make(chan struct{}), 158 bodyCache: bodyCache, 159 bodyRLPCache: bodyRLPCache, 160 blockCache: blockCache, 161 futureBlocks: futureBlocks, 162 pow: pow, 163 } 164 bc.SetValidator(NewBlockValidator(config, bc, pow)) 165 bc.SetProcessor(NewStateProcessor(config, bc)) 166 167 gv := func() HeaderValidator { return bc.Validator() } 168 var err error 169 bc.hc, err = NewHeaderChain(chainDb, config, mux, gv, bc.getProcInterrupt) 170 if err != nil { 171 return nil, err 172 } 173 174 bc.genesisBlock = bc.GetBlockByNumber(0) 175 if bc.genesisBlock == nil { 176 return nil, ErrNoGenesis 177 } 178 179 if err := bc.LoadLastState(false); err != nil { 180 return nil, err 181 } 182 // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain 183 for i := range config.BadHashes { 184 if header := bc.GetHeader(config.BadHashes[i].Hash); header != nil && header.Number.Cmp(config.BadHashes[i].Block) == 0 { 185 glog.V(logger.Error).Infof("Found bad hash, rewinding chain to block #%d [%s]", header.Number, header.ParentHash.Hex()) 186 bc.SetHead(header.Number.Uint64() - 1) 187 glog.V(logger.Error).Infoln("Chain rewind was successful, resuming normal operation") 188 } 189 } 190 // Take ownership of this particular state 191 go bc.update() 192 return bc, nil 193 } 194 195 func NewBlockChainDryrun(chainDb ethdb.Database, config *ChainConfig, pow pow.PoW, mux *event.TypeMux) (*BlockChain, error) { 196 bodyCache, _ := lru.New(bodyCacheLimit) 197 bodyRLPCache, _ := lru.New(bodyCacheLimit) 198 blockCache, _ := lru.New(blockCacheLimit) 199 futureBlocks, _ := lru.New(maxFutureBlocks) 200 201 bc := &BlockChain{ 202 config: config, 203 chainDb: chainDb, 204 eventMux: mux, 205 quit: make(chan struct{}), 206 bodyCache: bodyCache, 207 bodyRLPCache: bodyRLPCache, 208 blockCache: blockCache, 209 futureBlocks: futureBlocks, 210 pow: pow, 211 } 212 bc.SetValidator(NewBlockValidator(config, bc, pow)) 213 bc.SetProcessor(NewStateProcessor(config, bc)) 214 215 gv := func() HeaderValidator { return bc.Validator() } 216 var err error 217 bc.hc, err = NewHeaderChain(chainDb, config, mux, gv, bc.getProcInterrupt) 218 if err != nil { 219 return nil, err 220 } 221 222 bc.genesisBlock = bc.GetBlockByNumber(0) 223 if bc.genesisBlock == nil { 224 return nil, ErrNoGenesis 225 } 226 227 //if err := bc.loadLastState(); err != nil { 228 // return nil, err 229 //} 230 // Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain 231 for i := range config.BadHashes { 232 if header := bc.GetHeader(config.BadHashes[i].Hash); header != nil && header.Number.Cmp(config.BadHashes[i].Block) == 0 { 233 glog.V(logger.Error).Infof("Found bad hash, rewinding chain to block #%d [%s]", header.Number, header.ParentHash.Hex()) 234 bc.SetHead(header.Number.Uint64() - 1) 235 glog.V(logger.Error).Infoln("Chain rewind was successful, resuming normal operation") 236 } 237 } 238 // // Take ownership of this particular state 239 //go bc.update() 240 return bc, nil 241 } 242 243 // GetEventMux returns the blockchain's event mux 244 func (bc *BlockChain) GetEventMux() *event.TypeMux { 245 return bc.eventMux 246 } 247 248 // SetAtxi sets the db and in-use var for atx indexing. 249 func (bc *BlockChain) SetAtxi(a *AtxiT) { 250 bc.atxi = a 251 } 252 253 // GetAtxi return indexes db and if atx index in use. 254 func (bc *BlockChain) GetAtxi() *AtxiT { 255 return bc.atxi 256 } 257 258 func (bc *BlockChain) getProcInterrupt() bool { 259 return atomic.LoadInt32(&bc.procInterrupt) == 1 260 } 261 262 func (bc *BlockChain) blockIsGenesis(b *types.Block) bool { 263 if bc.Genesis() != nil { 264 return reflect.DeepEqual(b, bc.Genesis()) 265 } 266 ht, _ := DefaultConfigMorden.Genesis.Header() 267 hm, _ := DefaultConfigMainnet.Genesis.Header() 268 return b.Hash() == ht.Hash() || b.Hash() == hm.Hash() 269 270 } 271 272 // blockIsInvalid sanity checks for a block's health. 273 func (bc *BlockChain) blockIsInvalid(b *types.Block) error { 274 275 type testCases struct { 276 explanation string 277 test func(b *types.Block) error 278 } 279 280 blockAgnosticCases := []testCases{ 281 { 282 "block is nil", 283 func(b *types.Block) error { 284 if b == nil { 285 return errNilBlock 286 } 287 return nil 288 }, 289 }, 290 { 291 "block has nil header", 292 func(b *types.Block) error { 293 if b.Header() == nil { 294 return errNilHeader 295 } 296 return nil 297 }, 298 }, 299 { 300 "block has nil body", 301 func(b *types.Block) error { 302 if b.Body() == nil { 303 return errors.New("nil body") 304 } 305 return nil 306 }, 307 }, 308 { 309 "block has invalid hash", 310 func(b *types.Block) error { 311 if b.Hash() == (common.Hash{}) { 312 return errors.New("block hash empty") 313 } 314 // Note that we're confirming that blockchain "has" this block; 315 // later we'll use "has-with-state" to differentiate fast/full blocks, and want to be sure 316 // that not only is the hash valid, but also that only the state is missing if HasBlock returns false. 317 if !bc.HasBlock(b.Hash()) { 318 return fmt.Errorf("blockchain cannot find block with hash=%x", b.Hash()) 319 } 320 return nil 321 }, 322 }, 323 { 324 "block has invalid td", 325 func(b *types.Block) error { 326 if td := b.Difficulty(); td == nil { 327 return fmt.Errorf("invalid TD=%v for block #%d", td, b.NumberU64()) 328 } 329 pTd := bc.GetTd(b.ParentHash()) 330 externTd := new(big.Int).Add(pTd, b.Difficulty()) 331 if gotTd := bc.GetTd(b.Hash()); gotTd != nil && externTd.Cmp(gotTd) != 0 { 332 return fmt.Errorf("invalid TD=%v (want=%v) for block #%d", b.Difficulty(), gotTd, b.NumberU64()) 333 } 334 return nil 335 }, 336 }, 337 } 338 339 for _, c := range blockAgnosticCases { 340 if e := c.test(b); e != nil { 341 return e 342 } 343 } 344 345 // Assume genesis block is healthy from chain configuration. 346 if bc.blockIsGenesis(b) { 347 return nil 348 } 349 350 // If header number is 0 and hash is not genesis hash, 351 // something is wrong; possibly missing/malformed header. 352 if b.NumberU64() == 0 { 353 return fmt.Errorf("block number: 0, but is not genesis block: block: %v, \ngenesis: %v", b, bc.genesisBlock) 354 } 355 356 // sharedBlockCheck does everything that bc.Validator().ValidateBlock does, except that it 357 // 1. won't return an early error if the block is already known (eg. ErrKnownBlock) 358 // 2. won't check state 359 sharedBlockCheck := func(b *types.Block) error { 360 // Fast and full blocks should always have headers. 361 pHash := b.ParentHash() 362 if pHash == (common.Hash{}) { 363 return ParentError(pHash) 364 } 365 pHeader := bc.hc.GetHeader(pHash) 366 if pHeader == nil { 367 return fmt.Errorf("nil parent header for hash: %x", pHash) 368 } 369 // Use parent header hash to get block (instead of b.ParentHash) 370 parent := bc.GetBlock(pHeader.Hash()) 371 if parent == nil { 372 return ParentError(b.ParentHash()) 373 } 374 375 if err := bc.Validator().ValidateHeader(b.Header(), parent.Header(), true); err != nil { 376 return err 377 } 378 379 // verify the uncles are correctly rewarded 380 if err := bc.Validator().VerifyUncles(b, parent); err != nil { 381 return err 382 } 383 384 // Verify UncleHash before running other uncle validations 385 unclesSha := types.CalcUncleHash(b.Uncles()) 386 if unclesSha != b.Header().UncleHash { 387 return fmt.Errorf("invalid uncles root hash. received=%x calculated=%x", b.Header().UncleHash, unclesSha) 388 } 389 390 // The transactions Trie's root (R = (Tr [[i, RLP(T1)], [i, RLP(T2)], ... [n, RLP(Tn)]])) 391 // can be used by light clients to make sure they've received the correct Txs 392 txSha := types.DeriveSha(b.Transactions()) 393 if txSha != b.Header().TxHash { 394 return fmt.Errorf("invalid transaction root hash. received=%x calculated=%x", b.Header().TxHash, txSha) 395 } 396 return nil 397 } 398 399 // fullBlockCheck ensures state exists for parent and current blocks. 400 fullBlockCheck := func(b *types.Block) error { 401 parent := bc.GetBlock(b.ParentHash()) 402 if parent == nil { 403 return ParentError(b.ParentHash()) 404 } 405 // Parent does not have state; this is only a corruption if it's the not the point where fast 406 // sync was disabled and full states started to be synced. 407 if !bc.HasBlockAndState(parent.Hash()) { 408 grandparent := bc.GetBlock(parent.ParentHash()) 409 // If grandparent DOES have state, then so should parent. 410 // If grandparent doesn't have state, then assume that it was the first full block synced. 411 if bc.HasBlockAndState(grandparent.Hash()) { 412 return ParentError(b.ParentHash()) 413 } 414 } 415 return nil 416 } 417 418 // Since we're using absent state to decide that a full block check isn't required, 419 // we need to be sure that an absent state isn't actually a db corruption/inconsistency. 420 // Check parent block and confirm that there is NOT any state available for that block, either. 421 fastBlockCheck := func(b *types.Block) error { 422 pi := b.NumberU64() - 1 423 cb := bc.GetBlockByNumber(pi) 424 if cb == nil { 425 return fmt.Errorf("preceding nil block=#%d, while checking block=#%d health", pi, b.NumberU64()) 426 } 427 if cb.Header() == nil { 428 return fmt.Errorf("preceding nil header block=#%d, while checking block=#%d health", pi, b.NumberU64()) 429 } 430 // Genesis will have state. 431 if pi > 1 { 432 if bc.HasBlockAndState(cb.Hash()) { 433 return fmt.Errorf("checking block=%d without state, found nonabsent state for block #%d", b.NumberU64(), pi) 434 } 435 } 436 return nil 437 } 438 439 // Use shared block check. The only thing this doesn't check is state. 440 if e := sharedBlockCheck(b); e != nil { 441 return e 442 } 443 444 // Separate checks for fast/full blocks. 445 // 446 // Assume state is not missing. 447 // Fast block. 448 if !bc.HasBlockAndState(b.Hash()) { 449 glog.V(logger.Debug).Infof("Validating recovery FAST block #%d", b.Number()) 450 return fastBlockCheck(b) 451 } 452 453 // Full block. 454 glog.V(logger.Debug).Infof("Validating recovery FULL block #%d", b.Number()) 455 return fullBlockCheck(b) 456 } 457 458 // Recovery progressively validates the health of stored blockchain data. 459 // Soft resets should only be called in case of probable corrupted or invalid stored data, 460 // and which are invalid for known or expected reasons. 461 // It requires that the blockchain state be loaded so that cached head values are available, eg CurrentBlock(), etc. 462 func (bc *BlockChain) Recovery(from int, increment int) (checkpoint uint64) { 463 464 // Function for random dynamic incremental stepping through recoverable blocks. 465 // This avoids a set pattern for checking block validity, which might present 466 // a vulnerability. 467 // Random increments are only implemented with using an interval > 1. 468 randomizeIncrement := func(i int) int { 469 halfIncrement := i / 2 470 ri := mrand.Int63n(int64(halfIncrement)) 471 if ri%2 == 0 { 472 return i + int(ri) 473 } 474 return i - int(ri) 475 } 476 477 if from > 1 { 478 checkpoint = uint64(from) 479 } 480 481 // Hold setting if should randomize incrementing. 482 shouldRandomizeIncrement := increment > 1 483 // Always base randomization off of original increment, 484 // otherwise we'll eventually skew (narrow) the random set. 485 dynamicalIncrement := increment 486 487 // Establish initial increment value. 488 if shouldRandomizeIncrement { 489 dynamicalIncrement = randomizeIncrement(increment) 490 } 491 492 // Set up logging for block recovery progress. 493 ticker := time.NewTicker(time.Second * 3) 494 defer ticker.Stop() 495 go func() { 496 for range ticker.C { 497 glog.V(logger.Info).Warnf("Recovered checkpoints through block #%d", checkpoint) 498 glog.D(logger.Warn).Warnf("Recovered checkpoints through block #%d", checkpoint) 499 } 500 }() 501 502 // Step next block. 503 // Genesis is used only as a shorthand memory placeholder at a *types.Block; it will be replaced 504 // or never returned. 505 var checkpointBlockNext = bc.Genesis() 506 507 // In order for this number to be available at the time this function is called, the number (eg. `from`) 508 // may need to be persisted locally from the last connection. 509 for i := from; i > 0 && checkpointBlockNext != nil; i += dynamicalIncrement { 510 511 checkpointBlockNext = bc.GetBlockByNumber(uint64(i)) 512 513 // If block does not exist in db. 514 if checkpointBlockNext == nil { 515 // Traverse in small steps (increment =1) from last known big step (increment >1) checkpoint. 516 if increment > 1 && i-increment > 1 { 517 glog.V(logger.Debug).Warnf("Reached nil block #%d, retrying recovery beginning from #%d, incrementing +%d", i, i-increment, 1) 518 return bc.Recovery(i-increment, 1) // hone in 519 } 520 glog.V(logger.Debug).Warnf("No block data available for block #%d", uint64(i)) 521 break 522 } 523 524 // blockIsInvalid runs various block sanity checks, over and above Validator efforts to ensure 525 // no known block strangenesses. 526 ee := bc.blockIsInvalid(checkpointBlockNext) 527 if ee == nil { 528 // Everything seems to be fine, set as the head block 529 glog.V(logger.Debug).Infof("Found OK later block #%d", checkpointBlockNext.NumberU64()) 530 531 checkpoint = checkpointBlockNext.NumberU64() 532 533 bc.hc.SetCurrentHeader(checkpointBlockNext.Header()) 534 bc.currentFastBlock = checkpointBlockNext 535 536 // If state information is available for block, it is a full block. 537 // State validity has been confirmed by `blockIsInvalid == nil` 538 if bc.HasBlockAndState(checkpointBlockNext.Hash()) { 539 bc.currentBlock = checkpointBlockNext 540 } 541 542 if shouldRandomizeIncrement { 543 dynamicalIncrement = randomizeIncrement(increment) 544 } 545 continue 546 } 547 glog.V(logger.Error).Errorf("Found unhealthy block #%d (%v): \n\n%v", i, ee, checkpointBlockNext) 548 if increment == 1 { 549 break 550 } 551 return bc.Recovery(i-increment, 1) 552 } 553 if checkpoint > 0 { 554 glog.V(logger.Warn).Warnf("Found recoverable blockchain data through block #%d", checkpoint) 555 } 556 return checkpoint 557 } 558 559 // loadLastState loads the last known chain state from the database. This method 560 // assumes that the chain manager mutex is held. 561 func (bc *BlockChain) LoadLastState(dryrun bool) error { 562 563 bc.mu.Lock() 564 defer bc.mu.Unlock() 565 566 // recoverOrReset checks for recoverable block data. 567 // If no recoverable block data is found, plain Reset() is called. 568 // If safe blockchain data exists (so head block was wrong/invalid), blockchain db head 569 // is set to last available safe checkpoint. 570 recoverOrReset := func() error { 571 glog.V(logger.Warn).Infoln("Checking database for recoverable block data...") 572 573 recoveredHeight := bc.Recovery(1, 100) 574 575 bc.mu.Unlock() 576 defer bc.mu.Lock() 577 578 if recoveredHeight == 0 { 579 glog.V(logger.Error).Errorln("No recoverable data found, resetting to genesis.") 580 return bc.Reset() 581 } 582 // Remove all block header and canonical data above recoveredHeight 583 bc.PurgeAbove(recoveredHeight + 1) 584 return bc.SetHead(recoveredHeight) 585 } 586 587 // Restore the last known head block 588 head := GetHeadBlockHash(bc.chainDb) 589 if head == (common.Hash{}) { 590 // Corrupt or empty database, init from scratch 591 if !dryrun { 592 glog.V(logger.Warn).Errorln("Empty database, attempting chain reset with recovery.") 593 return recoverOrReset() 594 } 595 return errors.New("empty HeadBlockHash") 596 } 597 598 // Get head block by hash 599 currentBlock := bc.GetBlock(head) 600 601 // Make sure head block is available. 602 if currentBlock == nil { 603 // Corrupt or empty database, init from scratch 604 if !dryrun { 605 glog.V(logger.Warn).Errorf("Head block missing, hash: %x\nAttempting chain reset with recovery.", head) 606 return recoverOrReset() 607 } 608 return errors.New("nil currentBlock") 609 } 610 611 // If currentBlock (fullblock) is not genesis, check that it is valid 612 // and that it has a state associated with it. 613 if currentBlock.Number().Cmp(new(big.Int)) > 0 { 614 glog.V(logger.Info).Infof("Validating currentBlock: %v", currentBlock.Number()) 615 if e := bc.blockIsInvalid(currentBlock); e != nil { 616 if !dryrun { 617 glog.V(logger.Warn).Errorf("Found unhealthy head full block #%d (%x): %v \nAttempting chain reset with recovery.", currentBlock.Number(), currentBlock.Hash(), e) 618 return recoverOrReset() 619 } 620 return fmt.Errorf("invalid currentBlock: %v", e) 621 } 622 } 623 624 // Everything seems to be fine, set as the head block 625 bc.currentBlock = currentBlock 626 627 // Restore the last known head header 628 currentHeader := bc.currentBlock.Header() 629 630 // Get head header by hash. 631 if head := GetHeadHeaderHash(bc.chainDb); head != (common.Hash{}) { 632 if header := bc.GetHeader(head); header != nil { 633 currentHeader = header 634 } 635 } 636 // Ensure total difficulty exists and is valid for current header. 637 if td := currentHeader.Difficulty; td == nil || td.Sign() < 1 { 638 if !dryrun { 639 glog.V(logger.Warn).Errorf("Found current header #%d with invalid TD=%v\nAttempting chain reset with recovery...", currentHeader.Number, td) 640 return recoverOrReset() 641 } 642 return fmt.Errorf("invalid TD=%v for currentHeader=#%d", td, currentHeader.Number) 643 } 644 645 bc.hc.SetCurrentHeader(currentHeader) 646 647 // Restore the last known head fast block from placeholder 648 bc.currentFastBlock = bc.currentBlock 649 if head := GetHeadFastBlockHash(bc.chainDb); head != (common.Hash{}) { 650 if block := bc.GetBlock(head); block != nil { 651 bc.currentFastBlock = block 652 } 653 } 654 655 // If currentBlock (fullblock) is not genesis, check that it is valid 656 // and that it has a state associated with it. 657 if bc.currentFastBlock.Number().Cmp(new(big.Int)) > 0 { 658 glog.V(logger.Info).Infof("Validating currentFastBlock: %v", bc.currentFastBlock.Number()) 659 if e := bc.blockIsInvalid(bc.currentFastBlock); e != nil { 660 if !dryrun { 661 glog.V(logger.Warn).Errorf("Found unhealthy head fast block #%d (%x): %v \nAttempting chain reset with recovery.", bc.currentFastBlock.Number(), bc.currentFastBlock.Hash(), e) 662 return recoverOrReset() 663 } 664 return fmt.Errorf("invalid currentFastBlock: %v", e) 665 } 666 } 667 668 // Case: Head full block and fastblock, where there actually exist blocks beyond that 669 // in the chain, but last-h/b/fb key-vals (placeholders) are corrupted/wrong, causing it to appear 670 // as if the latest block is below the actual blockchain db head block. 671 // Update: initial reported case had genesis as constant apparent head. 672 // New logs also can show `1` as apparent head. 673 // -- Solve: instead of checking via hardcode if apparent genesis block and block `1` is nonnil, check if 674 // any block data exists ahead of whatever apparent head is. 675 // 676 // Look to "rewind" FORWARDS in case of missing/malformed header/placeholder at or near 677 // actual stored block head, caused by improper/unfulfilled `WriteHead*` functions, 678 // possibly caused by ungraceful stopping on SIGKILL. 679 // WriteHead* failing to write in this scenario would cause the head header to be 680 // misidentified an artificial non-purged re-sync to begin. 681 // I think. 682 683 // If dryrun, don't use additional safety checks or logging and just return state as-is. 684 if dryrun { 685 return nil 686 } 687 688 // Use highest known header number to check for "invisible" block data beyond. 689 highestApparentHead := bc.hc.CurrentHeader().Number.Uint64() 690 aboveHighestApparentHead := highestApparentHead + 2048 691 692 if b := bc.GetBlockByNumber(aboveHighestApparentHead); b != nil { 693 glog.V(logger.Warn).Errorf("Found block data beyond apparent head (head=%d, found=%d)", highestApparentHead, aboveHighestApparentHead) 694 return recoverOrReset() 695 } 696 697 // Check head block number congruent to hash. 698 if b := bc.GetBlockByNumber(bc.currentBlock.NumberU64()); b != nil && b.Header() != nil && b.Header().Hash() != bc.currentBlock.Hash() { 699 glog.V(logger.Error).Errorf("Found head block number and hash mismatch: number=%d, hash=%x", bc.currentBlock.NumberU64(), bc.currentBlock.Hash()) 700 return recoverOrReset() 701 } 702 703 // Check head header number congruent to hash. 704 if h := bc.hc.GetHeaderByNumber(bc.hc.CurrentHeader().Number.Uint64()); h != nil && bc.hc.GetHeader(h.Hash()) != h { 705 glog.V(logger.Error).Errorf("Found head header number and hash mismatch: number=%d, hash=%x", bc.hc.CurrentHeader().Number.Uint64(), bc.hc.CurrentHeader().Hash()) 706 return recoverOrReset() 707 } 708 709 // Case: current header below fast or full block. 710 // 711 highestCurrentBlockFastOrFull := bc.currentBlock.Number() 712 if bc.currentFastBlock.Number().Cmp(highestCurrentBlockFastOrFull) > 0 { 713 highestCurrentBlockFastOrFull = bc.currentFastBlock.Number() 714 } 715 // If the current header is behind head full block OR fast block, we should reset to the height of last OK header. 716 if bc.hc.CurrentHeader().Number.Cmp(highestCurrentBlockFastOrFull) < 0 { 717 glog.V(logger.Error).Errorf("Found header height below block height, attempting reset with recovery...") 718 return recoverOrReset() 719 } 720 721 // If header is beyond genesis, but both current and current fast blocks are 0, maybe something has gone wrong, 722 // like a write error on previous shutdown. 723 if bc.hc.CurrentHeader().Number.Cmp(big.NewInt(0)) > 0 && highestCurrentBlockFastOrFull.Cmp(big.NewInt(0)) == 0 { 724 glog.V(logger.Error).Errorf("Found unaccompanied headerchain (headers > 0 && current|fast ==0), attempting reset with recovery...") 725 } 726 727 // Initialize a statedb cache to ensure singleton account bloom filter generation 728 statedb, err := state.New(bc.currentBlock.Root(), state.NewDatabase(bc.chainDb)) 729 if err != nil { 730 return err 731 } 732 bc.stateCache = statedb 733 bc.stateCache.GetAccount(common.Address{}) 734 735 // Issue a status log and return 736 headerTd := bc.GetTd(bc.hc.CurrentHeader().Hash()) 737 blockTd := bc.GetTd(bc.currentBlock.Hash()) 738 fastTd := bc.GetTd(bc.currentFastBlock.Hash()) 739 glog.V(logger.Warn).Infof("Last header: #%d [%x…] TD=%v", bc.hc.CurrentHeader().Number, bc.hc.CurrentHeader().Hash().Bytes()[:4], headerTd) 740 glog.V(logger.Warn).Infof("Last block: #%d [%x…] TD=%v", bc.currentBlock.Number(), bc.currentBlock.Hash().Bytes()[:4], blockTd) 741 glog.V(logger.Warn).Infof("Fast block: #%d [%x…] TD=%v", bc.currentFastBlock.Number(), bc.currentFastBlock.Hash().Bytes()[:4], fastTd) 742 glog.D(logger.Warn).Infof("Local head header: #%s [%s…] TD=%s", 743 logger.ColorGreen(strconv.FormatUint(bc.hc.CurrentHeader().Number.Uint64(), 10)), 744 logger.ColorGreen(bc.hc.CurrentHeader().Hash().Hex()[:8]), 745 logger.ColorGreen(fmt.Sprintf("%v", headerTd))) 746 glog.D(logger.Warn).Infof("Local head full block: #%s [%s…] TD=%s", 747 logger.ColorGreen(strconv.FormatUint(bc.currentBlock.Number().Uint64(), 10)), 748 logger.ColorGreen(bc.currentBlock.Hash().Hex()[:8]), 749 logger.ColorGreen(fmt.Sprintf("%v", blockTd))) 750 glog.D(logger.Warn).Infof("Local head fast block: #%s [%s…] TD=%s", 751 logger.ColorGreen(strconv.FormatUint(bc.currentFastBlock.Number().Uint64(), 10)), 752 logger.ColorGreen(bc.currentFastBlock.Hash().Hex()[:8]), 753 logger.ColorGreen(fmt.Sprintf("%v", fastTd))) 754 755 return nil 756 } 757 758 // PurgeAbove works like SetHead, but instead of rm'ing head <-> bc.currentBlock, 759 // it removes all stored blockchain data n -> *anyexistingblockdata* 760 // TODO: possibly replace with kv database iterator 761 func (bc *BlockChain) PurgeAbove(n uint64) { 762 bc.mu.Lock() 763 764 delFn := func(hash common.Hash) { 765 DeleteBody(bc.chainDb, hash) 766 } 767 bc.hc.PurgeAbove(n, delFn) 768 bc.mu.Unlock() 769 } 770 771 // SetHead rewinds the local chain to a new head. In the case of headers, everything 772 // above the new head will be deleted and the new one set. In the case of blocks 773 // though, the head may be further rewound if block bodies are missing (non-archive 774 // nodes after a fast sync). 775 func (bc *BlockChain) SetHead(head uint64) error { 776 glog.V(logger.Warn).Infof("Setting blockchain head, target: %v", head) 777 778 bc.mu.Lock() 779 780 delFn := func(hash common.Hash) { 781 DeleteBody(bc.chainDb, hash) 782 } 783 bc.hc.SetHead(head, delFn) 784 currentHeader := bc.hc.CurrentHeader() 785 786 // Clear out any stale content from the caches 787 bc.bodyCache.Purge() 788 bc.bodyRLPCache.Purge() 789 bc.blockCache.Purge() 790 bc.futureBlocks.Purge() 791 792 // Rewind the block chain, ensuring we don't end up with a stateless head block 793 if bc.currentBlock != nil && currentHeader.Number.Uint64() < bc.currentBlock.NumberU64() { 794 bc.currentBlock = bc.GetBlock(currentHeader.Hash()) 795 } 796 if bc.currentBlock != nil { 797 if _, err := state.New(bc.currentBlock.Root(), state.NewDatabase(bc.chainDb)); err != nil { 798 // Rewound state missing, rolled back to before pivot, reset to genesis 799 bc.currentBlock = nil 800 } 801 } 802 // Rewind the fast block in a simpleton way to the target head 803 if bc.currentFastBlock != nil && currentHeader.Number.Uint64() < bc.currentFastBlock.NumberU64() { 804 bc.currentFastBlock = bc.GetBlock(currentHeader.Hash()) 805 } 806 // If either blocks reached nil, reset to the genesis state 807 if bc.currentBlock == nil { 808 bc.currentBlock = bc.genesisBlock 809 } 810 if bc.currentFastBlock == nil { 811 bc.currentFastBlock = bc.genesisBlock 812 } 813 814 if err := WriteHeadBlockHash(bc.chainDb, bc.currentBlock.Hash()); err != nil { 815 glog.Fatalf("failed to reset head block hash: %v", err) 816 } 817 if err := WriteHeadFastBlockHash(bc.chainDb, bc.currentFastBlock.Hash()); err != nil { 818 glog.Fatalf("failed to reset head fast block hash: %v", err) 819 } 820 821 if bc.atxi != nil && bc.atxi.AutoMode { 822 ldb, ok := bc.atxi.Db.(*ethdb.LDBDatabase) 823 if !ok { 824 glog.Fatal("could not cast indexes db to level db") 825 } 826 827 var removals [][]byte 828 deleteRemovalsFn := func(rs [][]byte) { 829 for _, r := range rs { 830 if e := ldb.Delete(r); e != nil { 831 glog.Fatal(e) 832 } 833 } 834 } 835 836 pre := ethdb.NewBytesPrefix(txAddressIndexPrefix) 837 it := ldb.NewIteratorRange(pre) 838 839 for it.Next() { 840 key := it.Key() 841 _, bn, _, _, _ := resolveAddrTxBytes(key) 842 n := binary.LittleEndian.Uint64(bn) 843 if n > head { 844 removals = append(removals, key) 845 // Prevent removals from getting too massive in case it's a big rollback 846 // 100000 is a guess at a big but not-too-big memory allowance 847 if len(removals) > 100000 { 848 deleteRemovalsFn(removals) 849 removals = [][]byte{} 850 } 851 } 852 } 853 it.Release() 854 if e := it.Error(); e != nil { 855 return e 856 } 857 deleteRemovalsFn(removals) 858 859 // update atxi bookmark to lower head in the case that its progress was higher than the new head 860 if bc.atxi != nil && bc.atxi.AutoMode { 861 if i := bc.atxi.GetATXIBookmark(); i > head { 862 if err := bc.atxi.SetATXIBookmark(head); err != nil { 863 return err 864 } 865 } 866 } 867 } 868 869 bc.mu.Unlock() 870 return bc.LoadLastState(false) 871 } 872 873 // FastSyncCommitHead sets the current head block to the one defined by the hash 874 // irrelevant what the chain contents were prior. 875 func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { 876 // Make sure that both the block as well at its state trie exists 877 block := bc.GetBlock(hash) 878 if block == nil { 879 return fmt.Errorf("non existent block [%x…]", hash[:4]) 880 } 881 if _, err := trie.NewSecure(block.Root(), bc.chainDb, 0); err != nil { 882 return err 883 } 884 // If all checks out, manually set the head block 885 bc.mu.Lock() 886 bc.currentBlock = block 887 bc.mu.Unlock() 888 889 glog.V(logger.Info).Infof("committed block #%d [%x…] as new head", block.Number(), hash[:4]) 890 return nil 891 } 892 893 // GasLimit returns the gas limit of the current HEAD block. 894 func (bc *BlockChain) GasLimit() *big.Int { 895 bc.mu.RLock() 896 defer bc.mu.RUnlock() 897 898 return bc.currentBlock.GasLimit() 899 } 900 901 // LastBlockHash return the hash of the HEAD block. 902 func (bc *BlockChain) LastBlockHash() common.Hash { 903 bc.mu.RLock() 904 defer bc.mu.RUnlock() 905 906 return bc.currentBlock.Hash() 907 } 908 909 // CurrentBlock retrieves the current head block of the canonical chain. The 910 // block is retrieved from the blockchain's internal cache. 911 func (bc *BlockChain) CurrentBlock() *types.Block { 912 bc.mu.RLock() 913 defer bc.mu.RUnlock() 914 915 return bc.currentBlock 916 } 917 918 // CurrentFastBlock retrieves the current fast-sync head block of the canonical 919 // chain. The block is retrieved from the blockchain's internal cache. 920 func (bc *BlockChain) CurrentFastBlock() *types.Block { 921 bc.mu.RLock() 922 defer bc.mu.RUnlock() 923 924 return bc.currentFastBlock 925 } 926 927 // Status returns status information about the current chain such as the HEAD Td, 928 // the HEAD hash and the hash of the genesis block. 929 func (bc *BlockChain) Status() (td *big.Int, currentBlock common.Hash, genesisBlock common.Hash) { 930 bc.mu.RLock() 931 defer bc.mu.RUnlock() 932 return bc.GetTd(bc.currentBlock.Hash()), bc.currentBlock.Hash(), bc.genesisBlock.Hash() 933 } 934 935 // SetProcessor sets the processor required for making state modifications. 936 func (bc *BlockChain) SetProcessor(processor Processor) { 937 bc.procmu.Lock() 938 defer bc.procmu.Unlock() 939 bc.processor = processor 940 } 941 942 // SetValidator sets the validator which is used to validate incoming blocks. 943 func (bc *BlockChain) SetValidator(validator Validator) { 944 bc.procmu.Lock() 945 defer bc.procmu.Unlock() 946 bc.validator = validator 947 } 948 949 // Validator returns the current validator. 950 func (bc *BlockChain) Validator() Validator { 951 bc.procmu.RLock() 952 defer bc.procmu.RUnlock() 953 return bc.validator 954 } 955 956 // Processor returns the current processor. 957 func (bc *BlockChain) Processor() Processor { 958 bc.procmu.RLock() 959 defer bc.procmu.RUnlock() 960 return bc.processor 961 } 962 963 // AuxValidator returns the auxiliary validator (Proof of work atm) 964 func (bc *BlockChain) AuxValidator() pow.PoW { return bc.pow } 965 966 // State returns a new mutable state based on the current HEAD block. 967 func (bc *BlockChain) State() (*state.StateDB, error) { 968 return bc.StateAt(bc.CurrentBlock().Root()) 969 } 970 971 // StateAt returns a new mutable state based on a particular point in time. 972 func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { 973 return state.New(root, state.NewDatabase(bc.chainDb)) 974 } 975 976 // Reset purges the entire blockchain, restoring it to its genesis state. 977 func (bc *BlockChain) Reset() error { 978 return bc.ResetWithGenesisBlock(bc.genesisBlock) 979 } 980 981 // ResetWithGenesisBlock purges the entire blockchain, restoring it to the 982 // specified genesis state. 983 func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { 984 // Dump the entire block chain and purge the caches 985 if err := bc.SetHead(0); err != nil { 986 return err 987 } 988 bc.mu.Lock() 989 defer bc.mu.Unlock() 990 991 // Prepare the genesis block and reinitialise the chain 992 if err := bc.hc.WriteTd(genesis.Hash(), genesis.Difficulty()); err != nil { 993 glog.Fatalf("failed to write genesis block TD: %v", err) 994 } 995 if err := WriteBlock(bc.chainDb, genesis); err != nil { 996 glog.Fatalf("failed to write genesis block: %v", err) 997 } 998 bc.genesisBlock = genesis 999 bc.insert(bc.genesisBlock) 1000 bc.currentBlock = bc.genesisBlock 1001 bc.hc.SetGenesis(bc.genesisBlock.Header()) 1002 bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) 1003 bc.currentFastBlock = bc.genesisBlock 1004 1005 return nil 1006 } 1007 1008 // Export writes the active chain to the given writer. 1009 func (bc *BlockChain) Export(w io.Writer) error { 1010 if err := bc.ExportN(w, uint64(0), bc.currentBlock.NumberU64()); err != nil { 1011 return err 1012 } 1013 return nil 1014 } 1015 1016 // ExportN writes a subset of the active chain to the given writer. 1017 func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { 1018 bc.mu.RLock() 1019 defer bc.mu.RUnlock() 1020 1021 if first > last { 1022 return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) 1023 } 1024 1025 glog.V(logger.Info).Infof("exporting %d blocks...\n", last-first+1) 1026 1027 for nr := first; nr <= last; nr++ { 1028 block := bc.GetBlockByNumber(nr) 1029 if block == nil { 1030 return fmt.Errorf("export failed on #%d: not found", nr) 1031 } 1032 1033 if err := block.EncodeRLP(w); err != nil { 1034 return err 1035 } 1036 } 1037 1038 return nil 1039 } 1040 1041 // insert injects a new head block into the current block chain. This method 1042 // assumes that the block is indeed a true head. It will also reset the head 1043 // header and the head fast sync block to this very same block if they are older 1044 // or if they are on a different side chain. 1045 // 1046 // Note, this function assumes that the `mu` mutex is held! 1047 func (bc *BlockChain) insert(block *types.Block) { 1048 // If the block is on a side chain or an unknown one, force other heads onto it too 1049 updateHeads := GetCanonicalHash(bc.chainDb, block.NumberU64()) != block.Hash() 1050 1051 // Add the block to the canonical chain number scheme and mark as the head 1052 if err := WriteCanonicalHash(bc.chainDb, block.Hash(), block.NumberU64()); err != nil { 1053 glog.Fatalf("failed to insert block number: %v", err) 1054 } 1055 if err := WriteHeadBlockHash(bc.chainDb, block.Hash()); err != nil { 1056 glog.Fatalf("failed to insert head block hash: %v", err) 1057 } 1058 bc.currentBlock = block 1059 1060 // If the block is better than our head or is on a different chain, force update heads 1061 if updateHeads { 1062 bc.hc.SetCurrentHeader(block.Header()) 1063 1064 if err := WriteHeadFastBlockHash(bc.chainDb, block.Hash()); err != nil { 1065 glog.Fatalf("failed to insert head fast block hash: %v", err) 1066 } 1067 bc.currentFastBlock = block 1068 } 1069 } 1070 1071 // Accessors 1072 func (bc *BlockChain) Genesis() *types.Block { 1073 return bc.genesisBlock 1074 } 1075 1076 // GetBody retrieves a block body (transactions and uncles) from the database by 1077 // hash, caching it if found. 1078 func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { 1079 // Short circuit if the body's already in the cache, retrieve otherwise 1080 if cached, ok := bc.bodyCache.Get(hash); ok { 1081 body := cached.(*types.Body) 1082 return body 1083 } 1084 body := GetBody(bc.chainDb, hash) 1085 if body == nil { 1086 return nil 1087 } 1088 // Cache the found body for next time and return 1089 bc.bodyCache.Add(hash, body) 1090 return body 1091 } 1092 1093 // GetBodyRLP retrieves a block body in RLP encoding from the database by hash, 1094 // caching it if found. 1095 func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { 1096 // Short circuit if the body's already in the cache, retrieve otherwise 1097 if cached, ok := bc.bodyRLPCache.Get(hash); ok { 1098 return cached.(rlp.RawValue) 1099 } 1100 body := GetBodyRLP(bc.chainDb, hash) 1101 if len(body) == 0 { 1102 return nil 1103 } 1104 // Cache the found body for next time and return 1105 bc.bodyRLPCache.Add(hash, body) 1106 return body 1107 } 1108 1109 // HasBlock checks if a block is fully present in the database or not, caching 1110 // it if present. 1111 func (bc *BlockChain) HasBlock(hash common.Hash) bool { 1112 return bc.GetBlock(hash) != nil 1113 } 1114 1115 // HasBlockAndState checks if a block and associated state trie is fully present 1116 // in the database or not, caching it if present. 1117 func (bc *BlockChain) HasBlockAndState(hash common.Hash) bool { 1118 // Check first that the block itbc is known 1119 block := bc.GetBlock(hash) 1120 if block == nil { 1121 return false 1122 } 1123 // Ensure the associated state is also present 1124 _, err := state.New(block.Root(), state.NewDatabase(bc.chainDb)) 1125 return err == nil 1126 } 1127 1128 // GetBlock retrieves a block from the database by hash, caching it if found. 1129 func (bc *BlockChain) GetBlock(hash common.Hash) *types.Block { 1130 // Short circuit if the block's already in the cache, retrieve otherwise 1131 if block, ok := bc.blockCache.Get(hash); ok { 1132 return block.(*types.Block) 1133 } 1134 block := GetBlock(bc.chainDb, hash) 1135 if block == nil { 1136 return nil 1137 } 1138 // Cache the found block for next time and return 1139 bc.blockCache.Add(block.Hash(), block) 1140 return block 1141 } 1142 1143 // GetBlockByNumber retrieves a block from the database by number, caching it 1144 // (associated with its hash) if found. 1145 func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { 1146 hash := GetCanonicalHash(bc.chainDb, number) 1147 if hash == (common.Hash{}) { 1148 return nil 1149 } 1150 return bc.GetBlock(hash) 1151 } 1152 1153 // [deprecated by eth/62] 1154 // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. 1155 func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { 1156 for i := 0; i < n; i++ { 1157 block := bc.GetBlock(hash) 1158 if block == nil { 1159 break 1160 } 1161 blocks = append(blocks, block) 1162 hash = block.ParentHash() 1163 } 1164 return 1165 } 1166 1167 // GetUnclesInChain retrieves all the uncles from a given block backwards until 1168 // a specific distance is reached. 1169 func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { 1170 uncles := []*types.Header{} 1171 for i := 0; block != nil && i < length; i++ { 1172 uncles = append(uncles, block.Uncles()...) 1173 block = bc.GetBlock(block.ParentHash()) 1174 } 1175 return uncles 1176 } 1177 1178 // Stop stops the blockchain service. If any imports are currently in progress 1179 // it will abort them using the procInterrupt. 1180 func (bc *BlockChain) Stop() { 1181 if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { 1182 return 1183 } 1184 close(bc.quit) 1185 atomic.StoreInt32(&bc.procInterrupt, 1) 1186 1187 bc.wg.Wait() 1188 1189 glog.V(logger.Info).Infoln("Chain manager stopped") 1190 } 1191 1192 type WriteStatus byte 1193 1194 const ( 1195 NonStatTy WriteStatus = iota 1196 CanonStatTy 1197 SideStatTy 1198 ) 1199 1200 // Rollback is designed to remove a chain of links from the database that aren't 1201 // certain enough to be valid. 1202 func (bc *BlockChain) Rollback(chain []common.Hash) { 1203 bc.mu.Lock() 1204 defer bc.mu.Unlock() 1205 1206 for i := len(chain) - 1; i >= 0; i-- { 1207 hash := chain[i] 1208 1209 if bc.hc.CurrentHeader().Hash() == hash { 1210 bc.hc.SetCurrentHeader(bc.GetHeader(bc.hc.CurrentHeader().ParentHash)) 1211 } 1212 if bc.currentFastBlock.Hash() == hash { 1213 bc.currentFastBlock = bc.GetBlock(bc.currentFastBlock.ParentHash()) 1214 if err := WriteHeadFastBlockHash(bc.chainDb, bc.currentFastBlock.Hash()); err != nil { 1215 glog.Fatalf("failed to write fast head block hash: %v", err) 1216 } 1217 } 1218 if bc.currentBlock.Hash() == hash { 1219 bc.currentBlock = bc.GetBlock(bc.currentBlock.ParentHash()) 1220 if err := WriteHeadBlockHash(bc.chainDb, bc.currentBlock.Hash()); err != nil { 1221 glog.Fatalf("failed to write head block hash: %v", err) 1222 } 1223 } 1224 } 1225 } 1226 1227 // InsertReceiptChain attempts to complete an already existing header chain with 1228 // transaction and receipt data. 1229 func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (res *ReceiptChainInsertResult) { 1230 res = &ReceiptChainInsertResult{} 1231 1232 bc.wg.Add(1) 1233 defer bc.wg.Done() 1234 1235 // Collect some import statistics to report on 1236 stats := struct{ processed, ignored int32 }{} 1237 start := time.Now() 1238 1239 // Create the block importing task queue and worker functions 1240 tasks := make(chan int, len(blockChain)) 1241 for i := 0; i < len(blockChain) && i < len(receiptChain); i++ { 1242 tasks <- i 1243 } 1244 close(tasks) 1245 1246 errs, failed := make([]error, len(tasks)), int32(0) 1247 process := func(worker int) { 1248 for index := range tasks { 1249 block, receipts := blockChain[index], receiptChain[index] 1250 1251 // Short circuit insertion if shutting down or processing failed 1252 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1253 return 1254 } 1255 if atomic.LoadInt32(&failed) > 0 { 1256 return 1257 } 1258 // Short circuit if the owner header is unknown 1259 if !bc.HasHeader(block.Hash()) { 1260 errs[index] = fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) 1261 atomic.AddInt32(&failed, 1) 1262 return 1263 } 1264 // Skip if the entire data is already known 1265 if bc.HasBlock(block.Hash()) { 1266 atomic.AddInt32(&stats.ignored, 1) 1267 continue 1268 } 1269 signer := bc.config.GetSigner(block.Number()) 1270 // Compute all the non-consensus fields of the receipts 1271 transactions, logIndex := block.Transactions(), uint(0) 1272 for j := 0; j < len(receipts); j++ { 1273 // The transaction hash can be retrieved from the transaction itbc 1274 receipts[j].TxHash = transactions[j].Hash() 1275 tx := transactions[j] 1276 from, _ := types.Sender(signer, tx) 1277 1278 // The contract address can be derived from the transaction itbc 1279 if MessageCreatesContract(transactions[j]) { 1280 receipts[j].ContractAddress = crypto.CreateAddress(from, tx.Nonce()) 1281 } 1282 // The used gas can be calculated based on previous receipts 1283 if j == 0 { 1284 receipts[j].GasUsed = new(big.Int).Set(receipts[j].CumulativeGasUsed) 1285 } else { 1286 receipts[j].GasUsed = new(big.Int).Sub(receipts[j].CumulativeGasUsed, receipts[j-1].CumulativeGasUsed) 1287 } 1288 // The derived log fields can simply be set from the block and transaction 1289 for k := 0; k < len(receipts[j].Logs); k++ { 1290 receipts[j].Logs[k].BlockNumber = block.NumberU64() 1291 receipts[j].Logs[k].BlockHash = block.Hash() 1292 receipts[j].Logs[k].TxHash = receipts[j].TxHash 1293 receipts[j].Logs[k].TxIndex = uint(j) 1294 receipts[j].Logs[k].Index = logIndex 1295 logIndex++ 1296 } 1297 } 1298 // Write all the data out into the database 1299 if err := WriteBody(bc.chainDb, block.Hash(), block.Body()); err != nil { 1300 errs[index] = fmt.Errorf("failed to write block body: %v", err) 1301 atomic.AddInt32(&failed, 1) 1302 glog.Fatal(errs[index]) 1303 return 1304 } 1305 if err := WriteBlockReceipts(bc.chainDb, block.Hash(), receipts); err != nil { 1306 errs[index] = fmt.Errorf("failed to write block receipts: %v", err) 1307 atomic.AddInt32(&failed, 1) 1308 glog.Fatal(errs[index]) 1309 return 1310 } 1311 if err := WriteMipmapBloom(bc.chainDb, block.NumberU64(), receipts); err != nil { 1312 errs[index] = fmt.Errorf("failed to write log blooms: %v", err) 1313 atomic.AddInt32(&failed, 1) 1314 glog.Fatal(errs[index]) 1315 return 1316 } 1317 if err := WriteTransactions(bc.chainDb, block); err != nil { 1318 errs[index] = fmt.Errorf("failed to write individual transactions: %v", err) 1319 atomic.AddInt32(&failed, 1) 1320 glog.Fatal(errs[index]) 1321 return 1322 } 1323 if err := WriteReceipts(bc.chainDb, receipts); err != nil { 1324 errs[index] = fmt.Errorf("failed to write individual receipts: %v", err) 1325 atomic.AddInt32(&failed, 1) 1326 glog.Fatal(errs[index]) 1327 return 1328 } 1329 // Store the addr-tx indexes if enabled 1330 if bc.atxi != nil { 1331 if err := WriteBlockAddTxIndexes(bc.atxi.Db, block); err != nil { 1332 glog.Fatalf("failed to write block add-tx indexes, err: %v", err) 1333 } 1334 // if buildATXI has been in use (via RPC) and is NOT finished, current < stop 1335 // if buildATXI has been in use (via RPC) and IS finished, current == stop 1336 // else if builtATXI has not been in use (via RPC), then current == stop == 0 1337 if bc.atxi.AutoMode && bc.atxi.Progress.Current == bc.atxi.Progress.Stop { 1338 if err := bc.atxi.SetATXIBookmark(block.NumberU64()); err != nil { 1339 glog.Fatalln(err) 1340 } 1341 } 1342 } 1343 atomic.AddInt32(&stats.processed, 1) 1344 } 1345 } 1346 // Start as many worker threads as goroutines allowed 1347 pending := new(sync.WaitGroup) 1348 for i := 0; i < runtime.GOMAXPROCS(0); i++ { 1349 pending.Add(1) 1350 go func(id int) { 1351 defer pending.Done() 1352 process(id) 1353 }(i) 1354 } 1355 pending.Wait() 1356 1357 // If anything failed, report 1358 if failed > 0 { 1359 for i, err := range errs { 1360 if err != nil { 1361 res.Index = i 1362 res.Error = err 1363 return 1364 } 1365 } 1366 } 1367 1368 // if aborted, db could be closed and the td may not be cached so don't attempt to write bookmark 1369 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1370 glog.V(logger.Debug).Infoln("premature abort during receipt chain processing") 1371 return 1372 } 1373 1374 // Update the head fast sync block if better 1375 bc.mu.Lock() 1376 head := blockChain[len(errs)-1] 1377 if bc.GetTd(bc.currentFastBlock.Hash()).Cmp(bc.GetTd(head.Hash())) < 0 { 1378 if err := WriteHeadFastBlockHash(bc.chainDb, head.Hash()); err != nil { 1379 glog.Fatalf("failed to update head fast block hash: %v", err) 1380 } 1381 bc.currentFastBlock = head 1382 } 1383 bc.mu.Unlock() 1384 1385 // Report some public statistics so the user has a clue what's going on 1386 first, last := blockChain[0], blockChain[len(blockChain)-1] 1387 1388 re := ReceiptChainInsertEvent{ 1389 Processed: int(stats.processed), 1390 Ignored: int(stats.ignored), 1391 Elasped: time.Since(start), 1392 FirstHash: first.Hash(), 1393 FirstNumber: first.NumberU64(), 1394 LastHash: last.Hash(), 1395 LastNumber: last.NumberU64(), 1396 LatestReceiptTime: time.Unix(last.Time().Int64(), 0), 1397 } 1398 res.ReceiptChainInsertEvent = re 1399 1400 glog.V(logger.Info).Infof("imported %d receipt(s) (%d ignored) in %v. #%d [%x… / %x…]", res.Processed, res.Ignored, 1401 res.Elasped, res.LastNumber, res.FirstHash.Bytes()[:4], res.LastHash.Bytes()[:4]) 1402 go bc.eventMux.Post(re) 1403 return res 1404 } 1405 1406 // WriteBlockAddrTxIndexesBatch builds indexes for a given range of blocks N. It writes batches at increment 'step'. 1407 // If any error occurs during db writing it will be returned immediately. 1408 // It's sole implementation is the command 'atxi-build', since we must use individual block atxi indexing during 1409 // sync and import in order to ensure we're on the canonical chain for each block. 1410 func (bc *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN, stepN uint64) (txsCount int, err error) { 1411 block := bc.GetBlockByNumber(startBlockN) 1412 batch := indexDb.NewBatch() 1413 1414 blockProcessedCount := uint64(0) 1415 blockProcessedHead := func() uint64 { 1416 return startBlockN + blockProcessedCount 1417 } 1418 1419 for block != nil && blockProcessedHead() <= stopBlockN { 1420 txP, err := putBlockAddrTxsToBatch(batch, block) 1421 if err != nil { 1422 return txsCount, err 1423 } 1424 txsCount += txP 1425 blockProcessedCount++ 1426 1427 // Write on stepN mod 1428 if blockProcessedCount%stepN == 0 { 1429 if err := batch.Write(); err != nil { 1430 return txsCount, err 1431 } else { 1432 batch = indexDb.NewBatch() 1433 } 1434 } 1435 block = bc.GetBlockByNumber(blockProcessedHead()) 1436 } 1437 1438 // This will put the last batch 1439 return txsCount, batch.Write() 1440 } 1441 1442 // WriteBlock writes the block to the chain. 1443 func (bc *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) { 1444 1445 if logger.MlogEnabled() { 1446 defer func() { 1447 mlogWriteStatus := "UNKNOWN" 1448 switch status { 1449 case NonStatTy: 1450 mlogWriteStatus = "NONE" 1451 case CanonStatTy: 1452 mlogWriteStatus = "CANON" 1453 case SideStatTy: 1454 mlogWriteStatus = "SIDE" 1455 } 1456 parent := bc.GetBlock(block.ParentHash()) 1457 parentTimeDiff := new(big.Int) 1458 if parent != nil { 1459 parentTimeDiff = new(big.Int).Sub(block.Time(), parent.Time()) 1460 } 1461 mlogBlockchainWriteBlock.AssignDetails( 1462 mlogWriteStatus, 1463 err, 1464 block.Number(), 1465 block.Hash().Hex(), 1466 block.Size().Int64(), 1467 block.Transactions().Len(), 1468 block.GasUsed(), 1469 block.Coinbase().Hex(), 1470 block.Time(), 1471 block.Difficulty(), 1472 len(block.Uncles()), 1473 block.ReceivedAt, 1474 parentTimeDiff, 1475 ).Send(mlogBlockchain) 1476 }() 1477 } 1478 1479 bc.wg.Add(1) 1480 defer bc.wg.Done() 1481 1482 // Calculate the total difficulty of the block 1483 ptd := bc.GetTd(block.ParentHash()) 1484 if ptd == nil { 1485 return NonStatTy, ParentError(block.ParentHash()) 1486 } 1487 // Make sure no inconsistent state is leaked during insertion 1488 bc.mu.Lock() 1489 defer bc.mu.Unlock() 1490 1491 localTd := bc.GetTd(bc.currentBlock.Hash()) 1492 externTd := new(big.Int).Add(block.Difficulty(), ptd) 1493 1494 // If the total difficulty is higher than our known, add it to the canonical chain 1495 // Compare local vs external difficulties 1496 tdCompare := externTd.Cmp(localTd) 1497 1498 // Initialize reorg if incoming TD is greater than local. 1499 reorg := tdCompare > 0 1500 1501 // If TDs are the same, randomize. 1502 if tdCompare == 0 { 1503 // Reduces the vulnerability to bcish mining. 1504 // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf 1505 // Split same-difficulty blocks by number, then at random 1506 reorg = block.NumberU64() < bc.currentBlock.NumberU64() || (block.NumberU64() == bc.currentBlock.NumberU64() && mrand.Float64() < 0.5) 1507 } 1508 1509 if reorg { 1510 // Reorganise the chain if the parent is not the head block 1511 if block.ParentHash() != bc.currentBlock.Hash() { 1512 if err := bc.reorg(bc.currentBlock, block); err != nil { 1513 return NonStatTy, err 1514 } 1515 } 1516 bc.insert(block) // Insert the block as the new head of the chain 1517 status = CanonStatTy 1518 } else { 1519 status = SideStatTy 1520 } 1521 // Irrelevant of the canonical status, write the block itbc to the database 1522 if err := bc.hc.WriteTd(block.Hash(), externTd); err != nil { 1523 glog.Fatalf("failed to write block total difficulty: %v", err) 1524 } 1525 if err := WriteBlock(bc.chainDb, block); err != nil { 1526 glog.Fatalf("failed to write block contents: %v", err) 1527 } 1528 1529 bc.futureBlocks.Remove(block.Hash()) 1530 1531 return 1532 } 1533 1534 // InsertChain inserts the given chain into the canonical chain or, otherwise, create a fork. 1535 // If the err return is not nil then chainIndex points to the cause in chain. 1536 func (bc *BlockChain) InsertChain(chain types.Blocks) (res *ChainInsertResult) { 1537 res = &ChainInsertResult{} // initialize 1538 // Do a sanity check that the provided chain is actually ordered and linked 1539 for i := 1; i < len(chain); i++ { 1540 if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { 1541 // Chain broke ancestry, log a messge (programming error) and skip insertion 1542 glog.V(logger.Error).Infoln("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(), 1543 "parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash()) 1544 1545 res.Error = fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(), 1546 chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4]) 1547 return 1548 } 1549 } 1550 1551 bc.wg.Add(1) 1552 defer bc.wg.Done() 1553 1554 bc.chainmu.Lock() 1555 defer bc.chainmu.Unlock() 1556 1557 // A queued approach to delivering events. This is generally 1558 // faster than direct delivery and requires much less mutex 1559 // acquiring. 1560 var ( 1561 stats struct{ queued, processed, ignored int } 1562 events = make([]interface{}, 0, len(chain)) 1563 coalescedLogs vm.Logs 1564 tstart = time.Now() 1565 1566 nonceChecked = make([]bool, len(chain)) 1567 ) 1568 1569 // Start the parallel nonce verifier. 1570 nonceAbort, nonceResults := verifyNoncesFromBlocks(bc.pow, chain) 1571 defer close(nonceAbort) 1572 1573 txcount := 0 1574 for i, block := range chain { 1575 res.Index = i 1576 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1577 glog.V(logger.Debug).Infoln("Premature abort during block chain processing") 1578 break 1579 } 1580 1581 bstart := time.Now() 1582 // Wait for block i's nonce to be verified before processing 1583 // its state transition. 1584 for !nonceChecked[i] { 1585 r := <-nonceResults 1586 nonceChecked[r.index] = true 1587 if !r.valid { 1588 block := chain[r.index] 1589 res.Index = r.index 1590 res.Error = &BlockNonceErr{Hash: block.Hash(), Number: block.Number(), Nonce: block.Nonce()} 1591 return 1592 } 1593 } 1594 1595 if err := bc.config.HeaderCheck(block.Header()); err != nil { 1596 res.Error = err 1597 return 1598 } 1599 1600 // Stage 1 validation of the block using the chain's validator 1601 // interface. 1602 err := bc.Validator().ValidateBlock(block) 1603 if err != nil { 1604 if IsKnownBlockErr(err) { 1605 stats.ignored++ 1606 continue 1607 } 1608 1609 if err == BlockFutureErr { 1610 // Allow up to MaxFuture second in the future blocks. If this limit 1611 // is exceeded the chain is discarded and processed at a later time 1612 // if given. 1613 max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks) 1614 if block.Time().Cmp(max) == 1 { 1615 res.Error = fmt.Errorf("%v: BlockFutureErr, %v > %v", BlockFutureErr, block.Time(), max) 1616 return 1617 } 1618 bc.futureBlocks.Add(block.Hash(), block) 1619 stats.queued++ 1620 continue 1621 } 1622 1623 if IsParentErr(err) && bc.futureBlocks.Contains(block.ParentHash()) { 1624 bc.futureBlocks.Add(block.Hash(), block) 1625 stats.queued++ 1626 continue 1627 } 1628 1629 res.Error = err 1630 return 1631 } 1632 1633 // Create a new statedb using the parent block and report an 1634 // error if it fails. 1635 switch { 1636 case i == 0: 1637 err = bc.stateCache.Reset(bc.GetBlock(block.ParentHash()).Root()) 1638 default: 1639 err = bc.stateCache.Reset(chain[i-1].Root()) 1640 } 1641 res.Error = err 1642 if err != nil { 1643 return 1644 } 1645 // Process block using the parent state as reference point. 1646 receipts, logs, usedGas, err := bc.processor.Process(block, bc.stateCache) 1647 if err != nil { 1648 res.Error = err 1649 return 1650 } 1651 // Validate the state using the default validator 1652 err = bc.Validator().ValidateState(block, bc.GetBlock(block.ParentHash()), bc.stateCache, receipts, usedGas) 1653 if err != nil { 1654 res.Error = err 1655 return 1656 } 1657 // Write state changes to database 1658 _, err = bc.stateCache.CommitTo(bc.chainDb, false) 1659 if err != nil { 1660 res.Error = err 1661 return 1662 } 1663 1664 // coalesce logs for later processing 1665 coalescedLogs = append(coalescedLogs, logs...) 1666 1667 if err := WriteBlockReceipts(bc.chainDb, block.Hash(), receipts); err != nil { 1668 res.Error = err 1669 return 1670 } 1671 1672 txcount += len(block.Transactions()) 1673 // write the block to the chain and get the status 1674 status, err := bc.WriteBlock(block) 1675 if err != nil { 1676 res.Error = err 1677 return 1678 } 1679 1680 switch status { 1681 case CanonStatTy: 1682 if glog.V(logger.Debug) { 1683 glog.Infof("[%v] inserted block #%d (%d TXs %v G %d UNCs) [%s]. Took %v\n", time.Now().UnixNano(), block.Number(), len(block.Transactions()), block.GasUsed(), len(block.Uncles()), block.Hash().Hex(), time.Since(bstart)) 1684 } 1685 events = append(events, ChainEvent{block, block.Hash(), logs}) 1686 1687 // This puts transactions in a extra db for rpc 1688 if err := WriteTransactions(bc.chainDb, block); err != nil { 1689 res.Error = err 1690 return 1691 } 1692 // store the receipts 1693 if err := WriteReceipts(bc.chainDb, receipts); err != nil { 1694 res.Error = err 1695 return 1696 } 1697 // Write map map bloom filters 1698 if err := WriteMipmapBloom(bc.chainDb, block.NumberU64(), receipts); err != nil { 1699 res.Error = err 1700 return 1701 } 1702 // Store the addr-tx indexes if enabled 1703 if bc.atxi != nil { 1704 if err := WriteBlockAddTxIndexes(bc.atxi.Db, block); err != nil { 1705 res.Error = fmt.Errorf("failed to write block add-tx indexes: %v", err) 1706 return 1707 } 1708 // if buildATXI has been in use (via RPC) and is NOT finished, current < stop 1709 // if buildATXI has been in use (via RPC) and IS finished, current == stop 1710 // else if builtATXI has not been in use (via RPC), then current == stop == 0 1711 if bc.atxi.AutoMode && bc.atxi.Progress.Current == bc.atxi.Progress.Stop { 1712 if err := bc.atxi.SetATXIBookmark(block.NumberU64()); err != nil { 1713 res.Error = err 1714 return 1715 } 1716 } 1717 } 1718 case SideStatTy: 1719 if glog.V(logger.Detail) { 1720 glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) [%s]. Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Hex(), time.Since(bstart)) 1721 } 1722 events = append(events, ChainSideEvent{block, logs}) 1723 } 1724 stats.processed++ 1725 } 1726 1727 ev := ChainInsertEvent{ 1728 Processed: stats.processed, 1729 Queued: stats.queued, 1730 Ignored: stats.ignored, 1731 TxCount: txcount, 1732 } 1733 r := &ChainInsertResult{ChainInsertEvent: ev} 1734 r.Index = 0 // NOTE/FIXME?(whilei): it's kind of strange that it returns 0 when no error... why not len(blocks)-1? 1735 if stats.queued > 0 || stats.processed > 0 || stats.ignored > 0 { 1736 elapsed := time.Since(tstart) 1737 start, end := chain[0], chain[len(chain)-1] 1738 // fn result 1739 r.LastNumber = end.NumberU64() 1740 r.LastHash = end.Hash() 1741 r.Elasped = elapsed 1742 r.LatestBlockTime = time.Unix(end.Time().Int64(), 0) 1743 // add event 1744 events = append(events, r.ChainInsertEvent) 1745 // mlog 1746 if logger.MlogEnabled() { 1747 mlogBlockchainInsertBlocks.AssignDetails( 1748 stats.processed, 1749 stats.queued, 1750 stats.ignored, 1751 txcount, 1752 end.Number(), 1753 start.Hash().Hex(), 1754 end.Hash().Hex(), 1755 elapsed, 1756 ).Send(mlogBlockchain) 1757 } 1758 // glog 1759 glog.V(logger.Info).Infof("imported %d block(s) (%d queued %d ignored) including %d txs in %v. #%v [%s / %s]\n", 1760 stats.processed, 1761 stats.queued, 1762 stats.ignored, 1763 txcount, 1764 elapsed, 1765 end.Number(), 1766 start.Hash().Hex(), 1767 end.Hash().Hex()) 1768 } 1769 go bc.postChainEvents(events, coalescedLogs) 1770 1771 return r 1772 } 1773 1774 // reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them 1775 // to be part of the new canonical chain and accumulates potential missing transactions and post an 1776 // event about them 1777 func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { 1778 var ( 1779 newChain types.Blocks 1780 oldChain types.Blocks 1781 commonBlock *types.Block 1782 oldStart = oldBlock 1783 newStart = newBlock 1784 deletedTxs types.Transactions 1785 deletedLogs vm.Logs 1786 deletedLogsByHash = make(map[common.Hash]vm.Logs) 1787 // collectLogs collects the logs that were generated during the 1788 // processing of the block that corresponds with the given hash. 1789 // These logs are later announced as deleted. 1790 collectLogs = func(h common.Hash) { 1791 // Coalesce logs 1792 receipts := GetBlockReceipts(bc.chainDb, h) 1793 for _, receipt := range receipts { 1794 deletedLogs = append(deletedLogs, receipt.Logs...) 1795 1796 deletedLogsByHash[h] = receipt.Logs 1797 } 1798 } 1799 ) 1800 1801 // first reduce whoever is higher bound 1802 if oldBlock.NumberU64() > newBlock.NumberU64() { 1803 // reduce old chain 1804 for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash()) { 1805 oldChain = append(oldChain, oldBlock) 1806 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1807 1808 collectLogs(oldBlock.Hash()) 1809 } 1810 } else { 1811 // reduce new chain and append new chain blocks for inserting later on 1812 for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash()) { 1813 newChain = append(newChain, newBlock) 1814 } 1815 } 1816 if oldBlock == nil { 1817 return fmt.Errorf("Invalid old chain") 1818 } 1819 if newBlock == nil { 1820 return fmt.Errorf("Invalid new chain") 1821 } 1822 1823 numSplit := newBlock.Number() 1824 for { 1825 if oldBlock.Hash() == newBlock.Hash() { 1826 commonBlock = oldBlock 1827 break 1828 } 1829 1830 oldChain = append(oldChain, oldBlock) 1831 newChain = append(newChain, newBlock) 1832 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1833 collectLogs(oldBlock.Hash()) 1834 1835 oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash()), bc.GetBlock(newBlock.ParentHash()) 1836 if oldBlock == nil { 1837 return fmt.Errorf("Invalid old chain") 1838 } 1839 if newBlock == nil { 1840 return fmt.Errorf("Invalid new chain") 1841 } 1842 } 1843 1844 commonHash := commonBlock.Hash() 1845 if glog.V(logger.Debug) { 1846 glog.Infof("Chain split detected @ [%s]. Reorganising chain from #%v %s to %s", commonHash.Hex(), numSplit, oldStart.Hash().Hex(), newStart.Hash().Hex()) 1847 } 1848 if logger.MlogEnabled() { 1849 mlogBlockchainReorgBlocks.AssignDetails( 1850 commonHash.Hex(), 1851 numSplit, 1852 oldStart.Hash().Hex(), 1853 newStart.Hash().Hex(), 1854 ).Send(mlogBlockchain) 1855 } 1856 1857 // Remove all atxis from old chain; indexes should only reflect canonical 1858 // Doesn't matter whether automode or not, they should be removed. 1859 if bc.atxi != nil { 1860 for _, block := range oldChain { 1861 for _, tx := range block.Transactions() { 1862 if err := RmAddrTx(bc.atxi.Db, tx); err != nil { 1863 return err 1864 } 1865 } 1866 } 1867 } 1868 1869 var addedTxs types.Transactions 1870 // insert blocks. Order does not matter. Last block will be written in ImportChain itbc which creates the new head properly 1871 for _, block := range newChain { 1872 // insert the block in the canonical way, re-writing history 1873 bc.insert(block) 1874 // write canonical receipts and transactions 1875 if err := WriteTransactions(bc.chainDb, block); err != nil { 1876 return err 1877 } 1878 // Store the addr-tx indexes if enabled 1879 if bc.atxi != nil { 1880 if err := WriteBlockAddTxIndexes(bc.atxi.Db, block); err != nil { 1881 return err 1882 } 1883 // if buildATXI has been in use (via RPC) and is NOT finished, current < stop 1884 // if buildATXI has been in use (via RPC) and IS finished, current == stop 1885 // else if builtATXI has not been in use (via RPC), then current == stop == 0 1886 if bc.atxi.AutoMode && bc.atxi.Progress.Current == bc.atxi.Progress.Stop { 1887 if err := bc.atxi.SetATXIBookmark(block.NumberU64()); err != nil { 1888 return err 1889 } 1890 } 1891 } 1892 receipts := GetBlockReceipts(bc.chainDb, block.Hash()) 1893 // write receipts 1894 if err := WriteReceipts(bc.chainDb, receipts); err != nil { 1895 return err 1896 } 1897 // Write map map bloom filters 1898 if err := WriteMipmapBloom(bc.chainDb, block.NumberU64(), receipts); err != nil { 1899 return err 1900 } 1901 addedTxs = append(addedTxs, block.Transactions()...) 1902 } 1903 1904 // calculate the difference between deleted and added transactions 1905 diff := types.TxDifference(deletedTxs, addedTxs) 1906 // When transactions get deleted from the database that means the 1907 // receipts that were created in the fork must also be deleted 1908 for _, tx := range diff { 1909 DeleteReceipt(bc.chainDb, tx.Hash()) 1910 DeleteTransaction(bc.chainDb, tx.Hash()) 1911 } 1912 // Must be posted in a goroutine because of the transaction pool trying 1913 // to acquire the chain manager lock 1914 if len(diff) > 0 { 1915 go bc.eventMux.Post(RemovedTransactionEvent{diff}) 1916 } 1917 if len(deletedLogs) > 0 { 1918 go bc.eventMux.Post(RemovedLogsEvent{deletedLogs}) 1919 } 1920 1921 if len(oldChain) > 0 { 1922 go func() { 1923 for _, block := range oldChain { 1924 bc.eventMux.Post(ChainSideEvent{Block: block, Logs: deletedLogsByHash[block.Hash()]}) 1925 } 1926 }() 1927 } 1928 1929 return nil 1930 } 1931 1932 // postChainEvents iterates over the events generated by a chain insertion and 1933 // posts them into the event mux. 1934 func (bc *BlockChain) postChainEvents(events []interface{}, logs vm.Logs) { 1935 // post event logs for further processing 1936 bc.eventMux.Post(logs) 1937 for _, event := range events { 1938 if event, ok := event.(ChainEvent); ok { 1939 // We need some control over the mining operation. Acquiring locks and waiting for the miner to create new block takes too long 1940 // and in most cases isn't even necessary. 1941 if bc.LastBlockHash() == event.Hash { 1942 bc.eventMux.Post(ChainHeadEvent{event.Block}) 1943 } 1944 } 1945 // Fire the insertion events individually too 1946 bc.eventMux.Post(event) 1947 } 1948 } 1949 1950 func (bc *BlockChain) update() { 1951 ticker := time.NewTicker(5 * time.Second) 1952 defer ticker.Stop() 1953 1954 for range ticker.C { 1955 select { 1956 case <-bc.quit: 1957 return 1958 default: 1959 } 1960 1961 blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) 1962 for _, hash := range bc.futureBlocks.Keys() { 1963 if block, exist := bc.futureBlocks.Get(hash); exist { 1964 blocks = append(blocks, block.(*types.Block)) 1965 } 1966 } 1967 1968 if len(blocks) > 0 { 1969 types.BlockBy(types.Number).Sort(blocks) 1970 if res := bc.InsertChain(blocks); res.Error != nil { 1971 log.Printf("periodic future chain update on block #%d [%s]: %s", blocks[res.Index].Number(), blocks[res.Index].Hash().Hex(), res.Error) 1972 } 1973 } 1974 } 1975 } 1976 1977 // InsertHeaderChain attempts to insert the given header chain in to the local 1978 // chain, possibly creating a reorg. If an error is returned, it will return the 1979 // index number of the failing header as well an error describing what went wrong. 1980 // 1981 // The verify parameter can be used to fine tune whether nonce verification 1982 // should be done or not. The reason behind the optional check is because some 1983 // of the header retrieval mechanisms already need to verify nonces, as well as 1984 // because nonces can be verified sparsely, not needing to check each. 1985 func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) *HeaderChainInsertResult { 1986 // Make sure only one thread manipulates the chain at once 1987 bc.chainmu.Lock() 1988 defer bc.chainmu.Unlock() 1989 1990 bc.wg.Add(1) 1991 defer bc.wg.Done() 1992 1993 whFunc := func(header *types.Header) error { 1994 bc.mu.Lock() 1995 defer bc.mu.Unlock() 1996 1997 _, err := bc.hc.WriteHeader(header) 1998 return err 1999 } 2000 2001 return bc.hc.InsertHeaderChain(chain, checkFreq, whFunc) 2002 } 2003 2004 // CurrentHeader retrieves the current head header of the canonical chain. The 2005 // header is retrieved from the HeaderChain's internal cache. 2006 func (bc *BlockChain) CurrentHeader() *types.Header { 2007 bc.mu.RLock() 2008 defer bc.mu.RUnlock() 2009 2010 return bc.hc.CurrentHeader() 2011 } 2012 2013 // GetTd retrieves a block's total difficulty in the canonical chain from the 2014 // database by hash, caching it if found. 2015 func (bc *BlockChain) GetTd(hash common.Hash) *big.Int { 2016 return bc.hc.GetTd(hash) 2017 } 2018 2019 // GetHeader retrieves a block header from the database by hash, caching it if 2020 // found. 2021 func (bc *BlockChain) GetHeader(hash common.Hash) *types.Header { 2022 return bc.hc.GetHeader(hash) 2023 } 2024 2025 // HasHeader checks if a block header is present in the database or not, caching 2026 // it if present. 2027 func (bc *BlockChain) HasHeader(hash common.Hash) bool { 2028 return bc.hc.HasHeader(hash) 2029 } 2030 2031 // GetBlockHashesFromHash retrieves a number of block hashes starting at a given 2032 // hash, fetching towards the genesis block. 2033 func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { 2034 return bc.hc.GetBlockHashesFromHash(hash, max) 2035 } 2036 2037 // GetHeaderByNumber retrieves a block header from the database by number, 2038 // caching it (associated with its hash) if found. 2039 func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { 2040 return bc.hc.GetHeaderByNumber(number) 2041 } 2042 2043 // Config retrieves the blockchain's chain configuration. 2044 func (bc *BlockChain) Config() *ChainConfig { return bc.config }