reset retrieves the current state of the blockchain and ensures the content of the transaction pool is valid with regard to the chain state.
(oldHead, newHead *types.Header)
| 456 | // reset retrieves the current state of the blockchain and ensures the content |
| 457 | // of the transaction pool is valid with regard to the chain state. |
| 458 | func (pool *TxPool) reset(oldHead, newHead *types.Header) { |
| 459 | // If we're reorging an old state, reinject all dropped transactions |
| 460 | var reinject types.Transactions |
| 461 | |
| 462 | if oldHead != nil && oldHead.Hash() != newHead.ParentHash { |
| 463 | // If the reorg is too deep, avoid doing it (will happen during fast sync) |
| 464 | oldNum := oldHead.Number.Uint64() |
| 465 | newNum := newHead.Number.Uint64() |
| 466 | |
| 467 | if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 { |
| 468 | log.Debug("Skipping deep transaction reorg", "depth", depth) |
| 469 | } else { |
| 470 | // Reorg seems shallow enough to pull in all transactions into memory |
| 471 | var discarded, included types.Transactions |
| 472 | |
| 473 | var ( |
| 474 | rem = pool.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64()) |
| 475 | add = pool.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64()) |
| 476 | ) |
| 477 | for rem.NumberU64() > add.NumberU64() { |
| 478 | discarded = append(discarded, rem.Transactions()...) |
| 479 | if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { |
| 480 | log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash().Hex()) |
| 481 | return |
| 482 | } |
| 483 | } |
| 484 | for add.NumberU64() > rem.NumberU64() { |
| 485 | included = append(included, add.Transactions()...) |
| 486 | if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { |
| 487 | log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash().Hex()) |
| 488 | return |
| 489 | } |
| 490 | } |
| 491 | for rem.Hash() != add.Hash() { |
| 492 | discarded = append(discarded, rem.Transactions()...) |
| 493 | if rem = pool.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil { |
| 494 | log.Error("Unrooted old chain seen by tx pool", "block", oldHead.Number, "hash", oldHead.Hash().Hex()) |
| 495 | return |
| 496 | } |
| 497 | included = append(included, add.Transactions()...) |
| 498 | if add = pool.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil { |
| 499 | log.Error("Unrooted new chain seen by tx pool", "block", newHead.Number, "hash", newHead.Hash()) |
| 500 | return |
| 501 | } |
| 502 | } |
| 503 | reinject = types.TxDifference(discarded, included) |
| 504 | } |
| 505 | } |
| 506 | // Initialize the internal state to the current head |
| 507 | if newHead == nil { |
| 508 | newHead = pool.chain.CurrentBlock().Header() // Special case during testing |
| 509 | } |
| 510 | statedb, err := pool.chain.StateAt(newHead.StateRoot) |
| 511 | if err != nil { |
| 512 | log.Error("Failed to reset txpool state", "err", err) |
| 513 | return |
| 514 | } |
| 515 | pool.currentState = statedb |
no test coverage detected