github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/chain/core/blockchain.go (about) 1 package core 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "math/big" 8 mrand "math/rand" 9 "sync" 10 "sync/atomic" 11 "time" 12 13 "github.com/neatio-net/neatio/chain/core/rawdb" 14 15 lru "github.com/hashicorp/golang-lru" 16 "github.com/neatio-net/neatio/chain/consensus" 17 "github.com/neatio-net/neatio/chain/core/state" 18 "github.com/neatio-net/neatio/chain/core/types" 19 "github.com/neatio-net/neatio/chain/core/vm" 20 "github.com/neatio-net/neatio/chain/log" 21 "github.com/neatio-net/neatio/chain/trie" 22 "github.com/neatio-net/neatio/neatdb" 23 "github.com/neatio-net/neatio/params" 24 "github.com/neatio-net/neatio/utilities/common" 25 "github.com/neatio-net/neatio/utilities/common/mclock" 26 "github.com/neatio-net/neatio/utilities/common/prque" 27 "github.com/neatio-net/neatio/utilities/crypto" 28 "github.com/neatio-net/neatio/utilities/event" 29 "github.com/neatio-net/neatio/utilities/metrics" 30 "github.com/neatio-net/neatio/utilities/rlp" 31 ) 32 33 var ( 34 blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) 35 36 ErrNoGenesis = errors.New("Genesis not found in chain") 37 ) 38 39 const ( 40 bodyCacheLimit = 256 41 blockCacheLimit = 256 42 receiptsCacheLimit = 32 43 maxFutureBlocks = 256 44 maxTimeFutureBlocks = 30 45 badBlockLimit = 10 46 triesInMemory = 128 47 48 BlockChainVersion = 3 49 50 TimeForBanned = 2 * time.Hour 51 BannedDuration = 24 * time.Hour 52 ) 53 54 type CacheConfig struct { 55 TrieCleanLimit int 56 57 TrieDirtyLimit int 58 TrieDirtyDisabled bool 59 TrieTimeLimit time.Duration 60 } 61 62 type BlockChain struct { 63 chainConfig *params.ChainConfig 64 cacheConfig *CacheConfig 65 66 db neatdb.Database 67 triegc *prque.Prque 68 gcproc time.Duration 69 70 hc *HeaderChain 71 rmLogsFeed event.Feed 72 chainFeed event.Feed 73 chainSideFeed event.Feed 74 chainHeadFeed event.Feed 75 logsFeed event.Feed 76 createSideChainFeed event.Feed 77 startMiningFeed event.Feed 78 stopMiningFeed event.Feed 79 80 scope event.SubscriptionScope 81 genesisBlock *types.Block 82 83 chainmu sync.RWMutex 84 85 currentBlock atomic.Value 86 currentFastBlock atomic.Value 87 88 stateCache state.Database 89 bodyCache *lru.Cache 90 bodyRLPCache *lru.Cache 91 receiptsCache *lru.Cache 92 blockCache *lru.Cache 93 futureBlocks *lru.Cache 94 95 quit chan struct{} 96 running int32 97 98 procInterrupt int32 99 wg sync.WaitGroup 100 101 engine consensus.Engine 102 validator Validator 103 processor Processor 104 vmConfig vm.Config 105 106 badBlocks *lru.Cache 107 108 cch CrossChainHelper 109 logger log.Logger 110 } 111 112 func NewBlockChain(db neatdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, cch CrossChainHelper) (*BlockChain, error) { 113 if cacheConfig == nil { 114 cacheConfig = &CacheConfig{ 115 TrieCleanLimit: 256, 116 TrieDirtyLimit: 256, 117 TrieTimeLimit: 5 * time.Minute, 118 } 119 } 120 bodyCache, _ := lru.New(bodyCacheLimit) 121 bodyRLPCache, _ := lru.New(bodyCacheLimit) 122 receiptsCache, _ := lru.New(receiptsCacheLimit) 123 blockCache, _ := lru.New(blockCacheLimit) 124 futureBlocks, _ := lru.New(maxFutureBlocks) 125 badBlocks, _ := lru.New(badBlockLimit) 126 127 bc := &BlockChain{ 128 chainConfig: chainConfig, 129 cacheConfig: cacheConfig, 130 db: db, 131 triegc: prque.New(nil), 132 stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit), 133 quit: make(chan struct{}), 134 bodyCache: bodyCache, 135 bodyRLPCache: bodyRLPCache, 136 receiptsCache: receiptsCache, 137 blockCache: blockCache, 138 futureBlocks: futureBlocks, 139 engine: engine, 140 vmConfig: vmConfig, 141 badBlocks: badBlocks, 142 cch: cch, 143 logger: chainConfig.ChainLogger, 144 } 145 bc.validator = NewBlockValidator(chainConfig, bc, engine) 146 bc.processor = NewStateProcessor(chainConfig, bc, engine, cch) 147 148 var err error 149 bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.getProcInterrupt) 150 if err != nil { 151 return nil, err 152 } 153 bc.genesisBlock = bc.GetBlockByNumber(0) 154 if bc.genesisBlock == nil { 155 return nil, ErrNoGenesis 156 } 157 if err := bc.loadLastState(); err != nil { 158 return nil, err 159 } 160 161 for hash := range BadHashes { 162 if header := bc.GetHeaderByHash(hash); header != nil { 163 164 headerByNumber := bc.GetHeaderByNumber(header.Number.Uint64()) 165 166 if headerByNumber != nil && headerByNumber.Hash() == header.Hash() { 167 bc.logger.Error("Found bad hash, rewinding chain", "number", header.Number, "hash", header.ParentHash) 168 bc.SetHead(header.Number.Uint64() - 1) 169 bc.logger.Error("Chain rewind was successful, resuming normal operation") 170 } 171 } 172 } 173 174 go bc.update() 175 return bc, nil 176 } 177 178 func (bc *BlockChain) getProcInterrupt() bool { 179 return atomic.LoadInt32(&bc.procInterrupt) == 1 180 } 181 182 func (bc *BlockChain) loadLastState() error { 183 184 head := rawdb.ReadHeadBlockHash(bc.db) 185 if head == (common.Hash{}) { 186 187 bc.logger.Warn("Empty database, resetting chain") 188 return bc.Reset() 189 } 190 191 currentBlock := bc.GetBlockByHash(head) 192 if currentBlock == nil { 193 194 bc.logger.Warn("Head block missing, resetting chain", "hash", head) 195 return bc.Reset() 196 } 197 198 if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil { 199 200 bc.logger.Warn("Head state missing, repairing chain", "number", currentBlock.Number(), "hash", currentBlock.Hash(), "err", err) 201 if err := bc.repair(¤tBlock); err != nil { 202 return err 203 } 204 } 205 206 bc.currentBlock.Store(currentBlock) 207 208 currentHeader := currentBlock.Header() 209 if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) { 210 if header := bc.GetHeaderByHash(head); header != nil { 211 currentHeader = header 212 } 213 } 214 bc.hc.SetCurrentHeader(currentHeader) 215 216 bc.currentFastBlock.Store(currentBlock) 217 if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) { 218 if block := bc.GetBlockByHash(head); block != nil { 219 bc.currentFastBlock.Store(block) 220 } 221 } 222 223 bc.logger.Info("Local chain block height is:", "Block", currentHeader.Number, "Hash", currentHeader.Hash()) 224 225 return nil 226 } 227 228 func (bc *BlockChain) SetHead(head uint64) error { 229 bc.logger.Warn("Rewinding blockchain", "target", head) 230 231 bc.chainmu.Lock() 232 defer bc.chainmu.Unlock() 233 234 delFn := func(db neatdb.Writer, hash common.Hash, num uint64) { 235 rawdb.DeleteBody(db, hash, num) 236 } 237 bc.hc.SetHead(head, delFn) 238 currentHeader := bc.hc.CurrentHeader() 239 240 bc.bodyCache.Purge() 241 bc.bodyRLPCache.Purge() 242 bc.receiptsCache.Purge() 243 bc.blockCache.Purge() 244 bc.futureBlocks.Purge() 245 246 if currentBlock := bc.CurrentBlock(); currentBlock != nil && currentHeader.Number.Uint64() < currentBlock.NumberU64() { 247 bc.currentBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64())) 248 } 249 if currentBlock := bc.CurrentBlock(); currentBlock != nil { 250 if _, err := state.New(currentBlock.Root(), bc.stateCache); err != nil { 251 252 bc.currentBlock.Store(bc.genesisBlock) 253 } 254 } 255 256 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && currentHeader.Number.Uint64() < currentFastBlock.NumberU64() { 257 bc.currentFastBlock.Store(bc.GetBlock(currentHeader.Hash(), currentHeader.Number.Uint64())) 258 } 259 260 if currentBlock := bc.CurrentBlock(); currentBlock == nil { 261 bc.currentBlock.Store(bc.genesisBlock) 262 } 263 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock == nil { 264 bc.currentFastBlock.Store(bc.genesisBlock) 265 } 266 currentBlock := bc.CurrentBlock() 267 currentFastBlock := bc.CurrentFastBlock() 268 269 rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash()) 270 rawdb.WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash()) 271 272 return bc.loadLastState() 273 } 274 275 func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { 276 277 block := bc.GetBlockByHash(hash) 278 if block == nil { 279 return fmt.Errorf("non existent block [%x…]", hash[:4]) 280 } 281 if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB()); err != nil { 282 return err 283 } 284 285 bc.chainmu.Lock() 286 bc.currentBlock.Store(block) 287 bc.chainmu.Unlock() 288 289 bc.logger.Info("Committed new head block", "number", block.Number(), "hash", hash) 290 return nil 291 } 292 293 func (bc *BlockChain) GasLimit() uint64 { 294 return bc.CurrentBlock().GasLimit() 295 } 296 297 func (bc *BlockChain) CurrentBlock() *types.Block { 298 return bc.currentBlock.Load().(*types.Block) 299 } 300 301 func (bc *BlockChain) CurrentFastBlock() *types.Block { 302 return bc.currentFastBlock.Load().(*types.Block) 303 } 304 305 func (bc *BlockChain) Validator() Validator { 306 return bc.validator 307 } 308 309 func (bc *BlockChain) Processor() Processor { 310 return bc.processor 311 } 312 313 func (bc *BlockChain) State() (*state.StateDB, error) { 314 return bc.StateAt(bc.CurrentBlock().Root()) 315 } 316 317 func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { 318 return state.New(root, bc.stateCache) 319 } 320 321 func (bc *BlockChain) StateCache() state.Database { 322 return bc.stateCache 323 } 324 325 func (bc *BlockChain) Reset() error { 326 return bc.ResetWithGenesisBlock(bc.genesisBlock) 327 } 328 329 func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { 330 331 if err := bc.SetHead(0); err != nil { 332 return err 333 } 334 bc.chainmu.Lock() 335 defer bc.chainmu.Unlock() 336 337 if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { 338 bc.logger.Crit("Failed to write genesis block TD", "err", err) 339 } 340 rawdb.WriteBlock(bc.db, genesis) 341 342 bc.genesisBlock = genesis 343 bc.insert(bc.genesisBlock) 344 bc.currentBlock.Store(bc.genesisBlock) 345 bc.hc.SetGenesis(bc.genesisBlock.Header()) 346 bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) 347 bc.currentFastBlock.Store(bc.genesisBlock) 348 349 return nil 350 } 351 352 func (bc *BlockChain) repair(head **types.Block) error { 353 for { 354 355 if _, err := state.New((*head).Root(), bc.stateCache); err == nil { 356 bc.logger.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash()) 357 return nil 358 } 359 360 block := bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1) 361 if block == nil { 362 return fmt.Errorf("missing block %d [%x]", (*head).NumberU64()-1, (*head).ParentHash()) 363 } 364 *head = block 365 } 366 } 367 368 func (bc *BlockChain) Export(w io.Writer) error { 369 return bc.ExportN(w, uint64(0), bc.CurrentBlock().NumberU64()) 370 } 371 372 func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { 373 bc.chainmu.RLock() 374 defer bc.chainmu.RUnlock() 375 376 if first > last { 377 return fmt.Errorf("export failed: first (%d) is greater than last (%d)", first, last) 378 } 379 bc.logger.Info("Exporting batch of blocks", "count", last-first+1) 380 381 for nr := first; nr <= last; nr++ { 382 block := bc.GetBlockByNumber(nr) 383 if block == nil { 384 return fmt.Errorf("export failed on #%d: not found", nr) 385 } 386 387 if err := block.EncodeRLP(w); err != nil { 388 return err 389 } 390 } 391 392 return nil 393 } 394 395 func (bc *BlockChain) insert(block *types.Block) { 396 397 updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash() 398 399 rawdb.WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64()) 400 rawdb.WriteHeadBlockHash(bc.db, block.Hash()) 401 402 bc.currentBlock.Store(block) 403 404 if updateHeads { 405 bc.hc.SetCurrentHeader(block.Header()) 406 rawdb.WriteHeadFastBlockHash(bc.db, block.Hash()) 407 408 bc.currentFastBlock.Store(block) 409 } 410 411 ibCbMap := GetInsertBlockCbMap() 412 for _, cb := range ibCbMap { 413 cb(bc, block) 414 } 415 } 416 417 func (bc *BlockChain) Genesis() *types.Block { 418 return bc.genesisBlock 419 } 420 421 func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { 422 423 if cached, ok := bc.bodyCache.Get(hash); ok { 424 body := cached.(*types.Body) 425 return body 426 } 427 number := bc.hc.GetBlockNumber(hash) 428 if number == nil { 429 return nil 430 } 431 body := rawdb.ReadBody(bc.db, hash, *number) 432 if body == nil { 433 return nil 434 } 435 436 bc.bodyCache.Add(hash, body) 437 return body 438 } 439 440 func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { 441 442 if cached, ok := bc.bodyRLPCache.Get(hash); ok { 443 return cached.(rlp.RawValue) 444 } 445 number := bc.hc.GetBlockNumber(hash) 446 if number == nil { 447 return nil 448 } 449 body := rawdb.ReadBodyRLP(bc.db, hash, *number) 450 if len(body) == 0 { 451 return nil 452 } 453 454 bc.bodyRLPCache.Add(hash, body) 455 return body 456 } 457 458 func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool { 459 if bc.blockCache.Contains(hash) { 460 return true 461 } 462 return rawdb.HasBody(bc.db, hash, number) 463 } 464 465 func (bc *BlockChain) HasState(hash common.Hash) bool { 466 _, err := bc.stateCache.OpenTrie(hash) 467 return err == nil 468 } 469 470 func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool { 471 472 block := bc.GetBlock(hash, number) 473 if block == nil { 474 return false 475 } 476 return bc.HasState(block.Root()) 477 } 478 479 func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 480 481 if block, ok := bc.blockCache.Get(hash); ok { 482 return block.(*types.Block) 483 } 484 block := rawdb.ReadBlock(bc.db, hash, number) 485 if block == nil { 486 return nil 487 } 488 489 bc.blockCache.Add(block.Hash(), block) 490 return block 491 } 492 493 func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { 494 number := bc.hc.GetBlockNumber(hash) 495 if number == nil { 496 return nil 497 } 498 return bc.GetBlock(hash, *number) 499 } 500 501 func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { 502 hash := rawdb.ReadCanonicalHash(bc.db, number) 503 if hash == (common.Hash{}) { 504 return nil 505 } 506 return bc.GetBlock(hash, number) 507 } 508 509 func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { 510 if receipts, ok := bc.receiptsCache.Get(hash); ok { 511 return receipts.(types.Receipts) 512 } 513 number := rawdb.ReadHeaderNumber(bc.db, hash) 514 if number == nil { 515 return nil 516 } 517 receipts := rawdb.ReadReceipts(bc.db, hash, *number) 518 if receipts == nil { 519 return nil 520 } 521 bc.receiptsCache.Add(hash, receipts) 522 return receipts 523 } 524 525 func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { 526 number := bc.hc.GetBlockNumber(hash) 527 if number == nil { 528 return nil 529 } 530 for i := 0; i < n; i++ { 531 block := bc.GetBlock(hash, *number) 532 if block == nil { 533 break 534 } 535 blocks = append(blocks, block) 536 hash = block.ParentHash() 537 *number-- 538 } 539 return 540 } 541 542 func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { 543 uncles := []*types.Header{} 544 for i := 0; block != nil && i < length; i++ { 545 uncles = append(uncles, block.Uncles()...) 546 block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 547 } 548 return uncles 549 } 550 551 func (bc *BlockChain) ValidateBlock(block *types.Block) (*state.StateDB, types.Receipts, *types.PendingOps, error) { 552 553 if BadHashes[block.Hash()] { 554 return nil, nil, nil, ErrBlacklistedHash 555 } 556 557 if err := bc.engine.(consensus.NeatCon).VerifyHeaderBeforeConsensus(bc, block.Header(), true); err != nil { 558 return nil, nil, nil, err 559 } 560 561 if err := bc.Validator().ValidateBody(block); err != nil { 562 log.Debugf("ValidateBlock-ValidateBody return with error: %v", err) 563 return nil, nil, nil, err 564 } 565 566 var parent *types.Block 567 parent = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) 568 state, err := state.New(parent.Root(), bc.stateCache) 569 if err != nil { 570 log.Debugf("ValidateBlock-state.New return with error: %v", err) 571 return nil, nil, nil, err 572 } 573 574 receipts, _, usedGas, ops, err := bc.processor.Process(block, state, bc.vmConfig) 575 if err != nil { 576 log.Debugf("ValidateBlock-Process return with error: %v", err) 577 return nil, nil, nil, err 578 } 579 580 err = bc.Validator().ValidateState(block, state, receipts, usedGas) 581 if err != nil { 582 log.Debugf("ValidateBlock-ValidateState return with error: %v", err) 583 return nil, nil, nil, err 584 } 585 586 return state, receipts, ops, nil 587 } 588 589 func (bc *BlockChain) TrieNode(hash common.Hash) ([]byte, error) { 590 return bc.stateCache.TrieDB().Node(hash) 591 } 592 593 func (bc *BlockChain) Stop() { 594 if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) { 595 return 596 } 597 598 bc.scope.Close() 599 close(bc.quit) 600 atomic.StoreInt32(&bc.procInterrupt, 1) 601 602 bc.wg.Wait() 603 604 if !bc.cacheConfig.TrieDirtyDisabled { 605 triedb := bc.stateCache.TrieDB() 606 607 for _, offset := range []uint64{0, 1, triesInMemory - 1} { 608 if number := bc.CurrentBlock().NumberU64(); number > offset { 609 recent := bc.GetBlockByNumber(number - offset) 610 611 bc.logger.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root()) 612 if err := triedb.Commit(recent.Root(), true); err != nil { 613 bc.logger.Error("Failed to commit recent state trie", "err", err) 614 } 615 } 616 } 617 for !bc.triegc.Empty() { 618 triedb.Dereference(bc.triegc.PopItem().(common.Hash)) 619 } 620 if size, _ := triedb.Size(); size != 0 { 621 bc.logger.Error("Dangling trie nodes after full cleanup") 622 } 623 } 624 bc.logger.Info("Blockchain manager stopped") 625 } 626 627 func (bc *BlockChain) procFutureBlocks() { 628 blocks := make([]*types.Block, 0, bc.futureBlocks.Len()) 629 for _, hash := range bc.futureBlocks.Keys() { 630 if block, exist := bc.futureBlocks.Peek(hash); exist { 631 blocks = append(blocks, block.(*types.Block)) 632 } 633 } 634 if len(blocks) > 0 { 635 types.BlockBy(types.Number).Sort(blocks) 636 637 for i := range blocks { 638 bc.InsertChain(blocks[i : i+1]) 639 } 640 } 641 } 642 643 type WriteStatus byte 644 645 const ( 646 NonStatTy WriteStatus = iota 647 CanonStatTy 648 SideStatTy 649 ) 650 651 func (bc *BlockChain) Rollback(chain []common.Hash) { 652 bc.chainmu.Lock() 653 defer bc.chainmu.Unlock() 654 655 for i := len(chain) - 1; i >= 0; i-- { 656 hash := chain[i] 657 658 currentHeader := bc.hc.CurrentHeader() 659 if currentHeader.Hash() == hash { 660 bc.hc.SetCurrentHeader(bc.GetHeader(currentHeader.ParentHash, currentHeader.Number.Uint64()-1)) 661 } 662 if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash { 663 newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1) 664 bc.currentFastBlock.Store(newFastBlock) 665 rawdb.WriteHeadFastBlockHash(bc.db, newFastBlock.Hash()) 666 } 667 if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash { 668 newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1) 669 bc.currentBlock.Store(newBlock) 670 rawdb.WriteHeadBlockHash(bc.db, newBlock.Hash()) 671 } 672 } 673 } 674 675 func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts types.Receipts) error { 676 signer := types.MakeSigner(config, block.Number()) 677 678 transactions, logIndex := block.Transactions(), uint(0) 679 if len(transactions) != len(receipts) { 680 return errors.New("transaction and receipt count mismatch") 681 } 682 683 for j := 0; j < len(receipts); j++ { 684 685 receipts[j].TxHash = transactions[j].Hash() 686 687 receipts[j].BlockHash = block.Hash() 688 receipts[j].BlockNumber = block.Number() 689 receipts[j].TransactionIndex = uint(j) 690 691 if transactions[j].To() == nil { 692 693 from, _ := types.Sender(signer, transactions[j]) 694 receipts[j].ContractAddress = crypto.CreateAddress(from, transactions[j].Nonce()) 695 } 696 697 if j == 0 { 698 receipts[j].GasUsed = receipts[j].CumulativeGasUsed 699 } else { 700 receipts[j].GasUsed = receipts[j].CumulativeGasUsed - receipts[j-1].CumulativeGasUsed 701 } 702 703 for k := 0; k < len(receipts[j].Logs); k++ { 704 receipts[j].Logs[k].BlockNumber = block.NumberU64() 705 receipts[j].Logs[k].BlockHash = block.Hash() 706 receipts[j].Logs[k].TxHash = receipts[j].TxHash 707 receipts[j].Logs[k].TxIndex = uint(j) 708 receipts[j].Logs[k].Index = logIndex 709 logIndex++ 710 } 711 } 712 return nil 713 } 714 715 func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts) (int, error) { 716 bc.wg.Add(1) 717 defer bc.wg.Done() 718 719 for i := 1; i < len(blockChain); i++ { 720 if blockChain[i].NumberU64() != blockChain[i-1].NumberU64()+1 || blockChain[i].ParentHash() != blockChain[i-1].Hash() { 721 bc.logger.Error("Non contiguous receipt insert", "number", blockChain[i].Number(), "hash", blockChain[i].Hash(), "parent", blockChain[i].ParentHash(), 722 "prevnumber", blockChain[i-1].Number(), "prevhash", blockChain[i-1].Hash()) 723 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(), 724 blockChain[i-1].Hash().Bytes()[:4], i, blockChain[i].NumberU64(), blockChain[i].Hash().Bytes()[:4], blockChain[i].ParentHash().Bytes()[:4]) 725 } 726 } 727 728 var ( 729 stats = struct{ processed, ignored int32 }{} 730 start = time.Now() 731 bytes = 0 732 batch = bc.db.NewBatch() 733 ) 734 for i, block := range blockChain { 735 receipts := receiptChain[i] 736 737 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 738 return 0, nil 739 } 740 741 if !bc.HasHeader(block.Hash(), block.NumberU64()) { 742 return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4]) 743 } 744 745 if bc.HasBlock(block.Hash(), block.NumberU64()) { 746 stats.ignored++ 747 continue 748 } 749 750 if err := SetReceiptsData(bc.chainConfig, block, receipts); err != nil { 751 return i, fmt.Errorf("failed to set receipts data: %v", err) 752 } 753 754 rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()) 755 rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts) 756 rawdb.WriteTxLookupEntries(batch, block) 757 758 stats.processed++ 759 760 if batch.ValueSize() >= neatdb.IdealBatchSize { 761 if err := batch.Write(); err != nil { 762 return 0, err 763 } 764 bytes += batch.ValueSize() 765 batch.Reset() 766 } 767 } 768 if batch.ValueSize() > 0 { 769 bytes += batch.ValueSize() 770 if err := batch.Write(); err != nil { 771 return 0, err 772 } 773 } 774 775 bc.chainmu.Lock() 776 head := blockChain[len(blockChain)-1] 777 if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { 778 currentFastBlock := bc.CurrentFastBlock() 779 if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 { 780 rawdb.WriteHeadFastBlockHash(bc.db, head.Hash()) 781 bc.currentFastBlock.Store(head) 782 } 783 } 784 bc.chainmu.Unlock() 785 786 bc.logger.Info("Imported new block receipts", 787 "count", stats.processed, 788 "elapsed", common.PrettyDuration(time.Since(start)), 789 "number", head.Number(), 790 "hash", head.Hash(), 791 "size", common.StorageSize(bytes), 792 "ignored", stats.ignored) 793 return 0, nil 794 } 795 796 var lastWrite uint64 797 798 func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (err error) { 799 bc.wg.Add(1) 800 defer bc.wg.Done() 801 802 if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), td); err != nil { 803 return err 804 } 805 rawdb.WriteBlock(bc.db, block) 806 807 return nil 808 } 809 810 func (bc *BlockChain) MuLock() { 811 bc.chainmu.Lock() 812 } 813 814 func (bc *BlockChain) MuUnLock() { 815 bc.chainmu.Unlock() 816 } 817 818 func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) { 819 820 return bc.writeBlockWithState(block, receipts, state) 821 } 822 823 func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) (status WriteStatus, err error) { 824 bc.wg.Add(1) 825 defer bc.wg.Done() 826 827 if bc.HasBlockAndState(block.Hash(), block.NumberU64()) { 828 bc.insert(block) 829 bc.futureBlocks.Remove(block.Hash()) 830 return CanonStatTy, nil 831 } 832 833 ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) 834 if ptd == nil { 835 return NonStatTy, consensus.ErrUnknownAncestor 836 } 837 838 currentBlock := bc.CurrentBlock() 839 localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) 840 externTd := new(big.Int).Add(block.Difficulty(), ptd) 841 842 if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), externTd); err != nil { 843 return NonStatTy, err 844 } 845 rawdb.WriteBlock(bc.db, block) 846 847 root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) 848 if err != nil { 849 return NonStatTy, err 850 } 851 triedb := bc.stateCache.TrieDB() 852 853 nc := bc.Engine().(consensus.NeatCon) 854 FORCEFULSHWINDOW := uint64(5) 855 curBlockNumber := block.NumberU64() 856 curEpoch := nc.GetEpoch().GetEpochByBlockNumber(curBlockNumber) 857 withinEpochSwitchWindow := curBlockNumber < curEpoch.StartBlock+FORCEFULSHWINDOW || curBlockNumber > curEpoch.EndBlock-FORCEFULSHWINDOW 858 859 FLUSHBLOCKSINTERVAL := uint64(5000) 860 meetFlushBlockInterval := curBlockNumber%FLUSHBLOCKSINTERVAL == 0 861 862 if withinEpochSwitchWindow || bc.cacheConfig.TrieDirtyDisabled || meetFlushBlockInterval { 863 if err := triedb.Commit(root, false); err != nil { 864 return NonStatTy, err 865 } 866 } else { 867 868 triedb.Reference(root, common.Hash{}) 869 bc.triegc.Push(root, -int64(block.NumberU64())) 870 871 if current := block.NumberU64(); current > triesInMemory { 872 873 var ( 874 nodes, imgs = triedb.Size() 875 limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024 876 ) 877 if nodes > limit || imgs > 4*1024*1024 { 878 triedb.Cap(limit - neatdb.IdealBatchSize) 879 } 880 881 chosen := current - triesInMemory 882 883 if bc.gcproc > bc.cacheConfig.TrieTimeLimit { 884 885 header := bc.GetHeaderByNumber(chosen) 886 if header == nil { 887 log.Warn("Reorg in progress, trie commit postponed", "number", chosen) 888 } else { 889 890 if chosen < lastWrite+triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { 891 log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory) 892 } 893 894 triedb.Commit(header.Root, true) 895 lastWrite = chosen 896 bc.gcproc = 0 897 } 898 } 899 900 for !bc.triegc.Empty() { 901 root, number := bc.triegc.Pop() 902 if uint64(-number) > chosen { 903 bc.triegc.Push(root, number) 904 break 905 } 906 triedb.Dereference(root.(common.Hash)) 907 } 908 } 909 } 910 911 batch := bc.db.NewBatch() 912 rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts) 913 914 var reorg bool 915 if _, ok := bc.engine.(consensus.NeatCon); ok { 916 917 reorg = true 918 } else { 919 920 reorg := externTd.Cmp(localTd) > 0 921 currentBlock = bc.CurrentBlock() 922 if !reorg && externTd.Cmp(localTd) == 0 { 923 924 reorg = block.NumberU64() < currentBlock.NumberU64() || (block.NumberU64() == currentBlock.NumberU64() && mrand.Float64() < 0.5) 925 } 926 } 927 if reorg { 928 929 if block.ParentHash() != currentBlock.Hash() { 930 if err := bc.reorg(currentBlock, block); err != nil { 931 return NonStatTy, err 932 } 933 } 934 935 rawdb.WriteTxLookupEntries(batch, block) 936 rawdb.WritePreimages(batch, state.Preimages()) 937 938 status = CanonStatTy 939 } else { 940 status = SideStatTy 941 } 942 if err := batch.Write(); err != nil { 943 return NonStatTy, err 944 } 945 946 if status == CanonStatTy { 947 bc.insert(block) 948 } 949 bc.futureBlocks.Remove(block.Hash()) 950 return status, nil 951 } 952 953 func (bc *BlockChain) addFutureBlock(block *types.Block) error { 954 max := uint64(time.Now().Unix() + maxTimeFutureBlocks) 955 if block.Time() > max { 956 return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max) 957 } 958 bc.futureBlocks.Add(block.Hash(), block) 959 return nil 960 } 961 962 func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { 963 964 if len(chain) == 0 { 965 return 0, nil 966 } 967 968 var ( 969 block, prev *types.Block 970 ) 971 972 for i := 1; i < len(chain); i++ { 973 block = chain[i] 974 prev = chain[i-1] 975 if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() { 976 977 log.Error("Non contiguous block insert", "number", block.Number(), "hash", block.Hash(), 978 "parent", block.ParentHash(), "prevnumber", prev.Number(), "prevhash", prev.Hash()) 979 980 return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, prev.NumberU64(), 981 prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4]) 982 } 983 } 984 985 bc.wg.Add(1) 986 bc.chainmu.Lock() 987 n, events, logs, err := bc.insertChain(chain, true) 988 bc.chainmu.Unlock() 989 bc.wg.Done() 990 991 bc.PostChainEvents(events, logs) 992 return n, err 993 } 994 995 func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []interface{}, []*types.Log, error) { 996 997 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 998 return 0, nil, nil, nil 999 } 1000 1001 var ( 1002 stats = insertStats{startTime: mclock.Now()} 1003 events = make([]interface{}, 0, len(chain)) 1004 lastCanon *types.Block 1005 coalescedLogs []*types.Log 1006 ) 1007 1008 headers := make([]*types.Header, len(chain)) 1009 seals := make([]bool, len(chain)) 1010 1011 for i, block := range chain { 1012 headers[i] = block.Header() 1013 seals[i] = verifySeals 1014 } 1015 1016 abort, results := bc.engine.VerifyHeaders(bc, headers, seals) 1017 defer close(abort) 1018 1019 it := newInsertIterator(chain, results, bc.validator) 1020 1021 block, err := it.next() 1022 1023 if err == ErrKnownBlock { 1024 1025 current := bc.CurrentBlock().NumberU64() 1026 for block != nil && err == ErrKnownBlock { 1027 if current >= block.NumberU64() { 1028 stats.ignored++ 1029 block, err = it.next() 1030 } else { 1031 log.Infof("this block has been written, but head not refreshed. hash %x, number %v\n", 1032 block.Hash(), block.NumberU64()) 1033 1034 err = nil 1035 break 1036 } 1037 } 1038 1039 } 1040 1041 switch { 1042 1043 case err == consensus.ErrPrunedAncestor: 1044 return bc.insertSidechain(block, it) 1045 1046 case err == consensus.ErrFutureBlock || (err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(it.first().ParentHash())): 1047 for block != nil && (it.index == 0 || err == consensus.ErrUnknownAncestor) { 1048 if err := bc.addFutureBlock(block); err != nil { 1049 return it.index, events, coalescedLogs, err 1050 } 1051 block, err = it.next() 1052 } 1053 stats.queued += it.processed() 1054 stats.ignored += it.remaining() 1055 1056 return it.index, events, coalescedLogs, err 1057 1058 case err != nil: 1059 stats.ignored += len(it.chain) 1060 bc.reportBlock(block, nil, err) 1061 return it.index, events, coalescedLogs, err 1062 } 1063 1064 for ; block != nil && err == nil; block, err = it.next() { 1065 1066 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1067 bc.logger.Debug("Premature abort during blocks processing") 1068 break 1069 } 1070 1071 if BadHashes[block.Hash()] { 1072 bc.reportBlock(block, nil, ErrBlacklistedHash) 1073 return it.index, events, coalescedLogs, ErrBlacklistedHash 1074 } 1075 1076 start := time.Now() 1077 1078 parent := it.previous() 1079 if parent == nil { 1080 parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) 1081 } 1082 statedb, err := state.New(parent.Root, bc.stateCache) 1083 if err != nil { 1084 return it.index, events, coalescedLogs, err 1085 } 1086 1087 receipts, logs, usedGas, ops, err := bc.processor.Process(block, statedb, bc.vmConfig) 1088 if err != nil { 1089 bc.reportBlock(block, receipts, err) 1090 return it.index, events, coalescedLogs, err 1091 } 1092 1093 err = bc.Validator().ValidateState(block, statedb, receipts, usedGas) 1094 if err != nil { 1095 bc.reportBlock(block, receipts, err) 1096 return it.index, events, coalescedLogs, err 1097 } 1098 proctime := time.Since(start) 1099 1100 status, err := bc.writeBlockWithState(block, receipts, statedb) 1101 if err != nil { 1102 return it.index, events, coalescedLogs, err 1103 } 1104 1105 for _, op := range ops.Ops() { 1106 if err := ApplyOp(op, bc, bc.cch); err != nil { 1107 bc.logger.Error("Failed executing op", op, "err", err) 1108 } 1109 } 1110 1111 blockInsertTimer.UpdateSince(start) 1112 1113 switch status { 1114 case CanonStatTy: 1115 bc.logger.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), 1116 "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), 1117 "elapsed", common.PrettyDuration(time.Since(start)), 1118 "root", block.Root()) 1119 1120 coalescedLogs = append(coalescedLogs, logs...) 1121 events = append(events, ChainEvent{block, block.Hash(), logs}) 1122 lastCanon = block 1123 1124 bc.gcproc += proctime 1125 1126 case SideStatTy: 1127 bc.logger.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), 1128 "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), 1129 "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), 1130 "root", block.Root()) 1131 events = append(events, ChainSideEvent{block}) 1132 } 1133 stats.processed++ 1134 stats.usedGas += usedGas 1135 1136 dirty, _ := bc.stateCache.TrieDB().Size() 1137 stats.report(chain, it.index, dirty) 1138 } 1139 1140 if block != nil && err == consensus.ErrFutureBlock { 1141 if err := bc.addFutureBlock(block); err != nil { 1142 return it.index, events, coalescedLogs, err 1143 } 1144 block, err = it.next() 1145 1146 for ; block != nil && err == consensus.ErrUnknownAncestor; block, err = it.next() { 1147 if err := bc.addFutureBlock(block); err != nil { 1148 return it.index, events, coalescedLogs, err 1149 } 1150 stats.queued++ 1151 } 1152 } 1153 stats.ignored += it.remaining() 1154 1155 if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { 1156 events = append(events, ChainHeadEvent{lastCanon}) 1157 } 1158 1159 return it.index, events, coalescedLogs, err 1160 } 1161 1162 func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (int, []interface{}, []*types.Log, error) { 1163 var ( 1164 externTd *big.Int 1165 current = bc.CurrentBlock() 1166 ) 1167 1168 err := consensus.ErrPrunedAncestor 1169 for ; block != nil && (err == consensus.ErrPrunedAncestor); block, err = it.next() { 1170 1171 if number := block.NumberU64(); current.NumberU64() >= number { 1172 canonical := bc.GetBlockByNumber(number) 1173 if canonical != nil && canonical.Hash() == block.Hash() { 1174 1175 continue 1176 } 1177 if canonical != nil && canonical.Root() == block.Root() { 1178 1179 bc.logger.Warn("Sidechain ghost-state attack detected", "number", block.NumberU64(), "sideroot", block.Root(), "canonroot", canonical.Root()) 1180 1181 return it.index, nil, nil, errors.New("sidechain ghost-state attack") 1182 } 1183 } 1184 if externTd == nil { 1185 externTd = bc.GetTd(block.ParentHash(), block.NumberU64()-1) 1186 } 1187 externTd = new(big.Int).Add(externTd, block.Difficulty()) 1188 1189 if !bc.HasBlock(block.Hash(), block.NumberU64()) { 1190 start := time.Now() 1191 if err := bc.WriteBlockWithoutState(block, externTd); err != nil { 1192 return it.index, nil, nil, err 1193 } 1194 bc.logger.Debug("Injected sidechain block", "number", block.Number(), "hash", block.Hash(), 1195 "diff", block.Difficulty(), "elapsed", common.PrettyDuration(time.Since(start)), 1196 "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()), 1197 "root", block.Root()) 1198 } 1199 } 1200 1201 localTd := bc.GetTd(current.Hash(), current.NumberU64()) 1202 if localTd.Cmp(externTd) > 0 { 1203 bc.logger.Info("Sidechain written to disk", "start", it.first().NumberU64(), "end", it.previous().Number, "sidetd", externTd, "localtd", localTd) 1204 return it.index, nil, nil, err 1205 } 1206 1207 var ( 1208 hashes []common.Hash 1209 numbers []uint64 1210 ) 1211 parent := it.previous() 1212 for parent != nil && !bc.HasState(parent.Root) { 1213 hashes = append(hashes, parent.Hash()) 1214 numbers = append(numbers, parent.Number.Uint64()) 1215 1216 parent = bc.GetHeader(parent.ParentHash, parent.Number.Uint64()-1) 1217 } 1218 if parent == nil { 1219 return it.index, nil, nil, errors.New("missing parent") 1220 } 1221 1222 var ( 1223 blocks []*types.Block 1224 memory common.StorageSize 1225 ) 1226 for i := len(hashes) - 1; i >= 0; i-- { 1227 1228 block := bc.GetBlock(hashes[i], numbers[i]) 1229 1230 blocks = append(blocks, block) 1231 memory += block.Size() 1232 1233 if len(blocks) >= 2048 || memory > 64*1024*1024 { 1234 bc.logger.Info("Importing heavy sidechain segment", "blocks", len(blocks), "start", blocks[0].NumberU64(), "end", block.NumberU64()) 1235 if _, _, _, err := bc.insertChain(blocks, false); err != nil { 1236 return 0, nil, nil, err 1237 } 1238 blocks, memory = blocks[:0], 0 1239 1240 if atomic.LoadInt32(&bc.procInterrupt) == 1 { 1241 bc.logger.Debug("Premature abort during blocks processing") 1242 return 0, nil, nil, nil 1243 } 1244 } 1245 } 1246 if len(blocks) > 0 { 1247 bc.logger.Info("Importing sidechain segment", "start", blocks[0].NumberU64(), "end", blocks[len(blocks)-1].NumberU64()) 1248 return bc.insertChain(blocks, false) 1249 } 1250 return 0, nil, nil, nil 1251 } 1252 1253 func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { 1254 var ( 1255 newChain types.Blocks 1256 oldChain types.Blocks 1257 commonBlock *types.Block 1258 1259 deletedTxs types.Transactions 1260 1261 deletedLogs []*types.Log 1262 1263 collectLogs = func(hash common.Hash) { 1264 number := bc.hc.GetBlockNumber(hash) 1265 if number == nil { 1266 return 1267 } 1268 1269 receipts := rawdb.ReadReceipts(bc.db, hash, *number) 1270 for _, receipt := range receipts { 1271 for _, log := range receipt.Logs { 1272 del := *log 1273 del.Removed = true 1274 deletedLogs = append(deletedLogs, &del) 1275 } 1276 } 1277 } 1278 ) 1279 1280 if oldBlock.NumberU64() > newBlock.NumberU64() { 1281 1282 for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { 1283 oldChain = append(oldChain, oldBlock) 1284 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1285 collectLogs(oldBlock.Hash()) 1286 } 1287 } else { 1288 1289 for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { 1290 newChain = append(newChain, newBlock) 1291 } 1292 } 1293 if oldBlock == nil { 1294 return fmt.Errorf("Invalid old chain") 1295 } 1296 if newBlock == nil { 1297 return fmt.Errorf("Invalid new chain") 1298 } 1299 1300 for { 1301 if oldBlock.Hash() == newBlock.Hash() { 1302 commonBlock = oldBlock 1303 break 1304 } 1305 1306 oldChain = append(oldChain, oldBlock) 1307 newChain = append(newChain, newBlock) 1308 deletedTxs = append(deletedTxs, oldBlock.Transactions()...) 1309 collectLogs(oldBlock.Hash()) 1310 1311 oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) 1312 if oldBlock == nil { 1313 return fmt.Errorf("Invalid old chain") 1314 } 1315 if newBlock == nil { 1316 return fmt.Errorf("Invalid new chain") 1317 } 1318 } 1319 1320 if len(oldChain) > 0 && len(newChain) > 0 { 1321 logFn := log.Debug 1322 if len(oldChain) > 63 { 1323 logFn = log.Warn 1324 } 1325 logFn("Chain split detected", "number", commonBlock.Number(), "hash", commonBlock.Hash(), 1326 "drop", len(oldChain), "dropfrom", oldChain[0].Hash(), "add", len(newChain), "addfrom", newChain[0].Hash()) 1327 } else { 1328 bc.logger.Error("Impossible reorg, please file an issue", "oldnum", oldBlock.Number(), "oldhash", oldBlock.Hash(), "newnum", newBlock.Number(), "newhash", newBlock.Hash()) 1329 } 1330 1331 var addedTxs types.Transactions 1332 for i := len(newChain) - 1; i >= 0; i-- { 1333 1334 bc.insert(newChain[i]) 1335 1336 rawdb.WriteTxLookupEntries(bc.db, newChain[i]) 1337 addedTxs = append(addedTxs, newChain[i].Transactions()...) 1338 } 1339 1340 batch := bc.db.NewBatch() 1341 for _, tx := range types.TxDifference(deletedTxs, addedTxs) { 1342 rawdb.DeleteTxLookupEntry(batch, tx.Hash()) 1343 } 1344 batch.Write() 1345 1346 if len(deletedLogs) > 0 { 1347 go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs}) 1348 } 1349 if len(oldChain) > 0 { 1350 go func() { 1351 for _, block := range oldChain { 1352 bc.chainSideFeed.Send(ChainSideEvent{Block: block}) 1353 } 1354 }() 1355 } 1356 1357 return nil 1358 } 1359 1360 func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) { 1361 1362 if logs != nil { 1363 bc.logsFeed.Send(logs) 1364 } 1365 for _, event := range events { 1366 switch ev := event.(type) { 1367 case ChainEvent: 1368 bc.chainFeed.Send(ev) 1369 1370 case ChainHeadEvent: 1371 bc.chainHeadFeed.Send(ev) 1372 1373 case ChainSideEvent: 1374 bc.chainSideFeed.Send(ev) 1375 1376 case CreateSideChainEvent: 1377 bc.createSideChainFeed.Send(ev) 1378 1379 case StartMiningEvent: 1380 bc.startMiningFeed.Send(ev) 1381 1382 case StopMiningEvent: 1383 bc.stopMiningFeed.Send(ev) 1384 } 1385 } 1386 } 1387 1388 func (bc *BlockChain) update() { 1389 futureTimer := time.NewTicker(5 * time.Second) 1390 defer futureTimer.Stop() 1391 for { 1392 select { 1393 case <-futureTimer.C: 1394 bc.procFutureBlocks() 1395 case <-bc.quit: 1396 return 1397 } 1398 } 1399 } 1400 1401 type BadBlockArgs struct { 1402 Hash common.Hash `json:"hash"` 1403 Header *types.Header `json:"header"` 1404 } 1405 1406 func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) { 1407 headers := make([]BadBlockArgs, 0, bc.badBlocks.Len()) 1408 for _, hash := range bc.badBlocks.Keys() { 1409 if hdr, exist := bc.badBlocks.Peek(hash); exist { 1410 header := hdr.(*types.Header) 1411 headers = append(headers, BadBlockArgs{header.Hash(), header}) 1412 } 1413 } 1414 return headers, nil 1415 } 1416 1417 func (bc *BlockChain) HasBadBlock(hash common.Hash) bool { 1418 return bc.badBlocks.Contains(hash) 1419 } 1420 1421 func (bc *BlockChain) addBadBlock(block *types.Block) { 1422 bc.badBlocks.Add(block.Header().Hash(), block.Header()) 1423 } 1424 1425 func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) { 1426 bc.addBadBlock(block) 1427 1428 var receiptString string 1429 for _, receipt := range receipts { 1430 receiptString += fmt.Sprintf("\t%v\n", receipt) 1431 } 1432 bc.logger.Error(fmt.Sprintf(` 1433 ########## BAD BLOCK ######### 1434 Chain config: %v 1435 1436 Number: %v 1437 Hash: 0x%x 1438 %v 1439 1440 Error: %v 1441 ############################## 1442 `, bc.chainConfig, block.Number(), block.Hash(), receiptString, err)) 1443 } 1444 1445 func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { 1446 start := time.Now() 1447 if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { 1448 return i, err 1449 } 1450 1451 bc.chainmu.Lock() 1452 defer bc.chainmu.Unlock() 1453 1454 bc.wg.Add(1) 1455 defer bc.wg.Done() 1456 1457 whFunc := func(header *types.Header) error { 1458 _, err := bc.hc.WriteHeader(header) 1459 return err 1460 } 1461 1462 return bc.hc.InsertHeaderChain(chain, whFunc, start) 1463 } 1464 1465 func (bc *BlockChain) CurrentHeader() *types.Header { 1466 return bc.hc.CurrentHeader() 1467 } 1468 1469 func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int { 1470 return bc.hc.GetTd(hash, number) 1471 } 1472 1473 func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { 1474 return bc.hc.GetTdByHash(hash) 1475 } 1476 1477 func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { 1478 return bc.hc.GetHeader(hash, number) 1479 } 1480 1481 func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { 1482 return bc.hc.GetHeaderByHash(hash) 1483 } 1484 1485 func (bc *BlockChain) HasHeader(hash common.Hash, number uint64) bool { 1486 return bc.hc.HasHeader(hash, number) 1487 } 1488 1489 func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []common.Hash { 1490 return bc.hc.GetBlockHashesFromHash(hash, max) 1491 } 1492 1493 func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { 1494 return bc.hc.GetHeaderByNumber(number) 1495 } 1496 1497 func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig } 1498 1499 func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } 1500 1501 func (bc *BlockChain) GetCrossChainHelper() CrossChainHelper { return bc.cch } 1502 1503 func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { 1504 return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch)) 1505 } 1506 1507 func (bc *BlockChain) SubscribeChainEvent(ch chan<- ChainEvent) event.Subscription { 1508 return bc.scope.Track(bc.chainFeed.Subscribe(ch)) 1509 } 1510 1511 func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { 1512 return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch)) 1513 } 1514 1515 func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription { 1516 return bc.scope.Track(bc.chainSideFeed.Subscribe(ch)) 1517 } 1518 1519 func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { 1520 return bc.scope.Track(bc.logsFeed.Subscribe(ch)) 1521 } 1522 1523 func (bc *BlockChain) SubscribeCreateSideChainEvent(ch chan<- CreateSideChainEvent) event.Subscription { 1524 return bc.scope.Track(bc.createSideChainFeed.Subscribe(ch)) 1525 } 1526 1527 func (bc *BlockChain) SubscribeStartMiningEvent(ch chan<- StartMiningEvent) event.Subscription { 1528 return bc.scope.Track(bc.startMiningFeed.Subscribe(ch)) 1529 } 1530 1531 func (bc *BlockChain) SubscribeStopMiningEvent(ch chan<- StopMiningEvent) event.Subscription { 1532 return bc.scope.Track(bc.stopMiningFeed.Subscribe(ch)) 1533 }