reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them to be part of the new canonical chain and accumulates potential missing transactions and post an event about them
(oldBlock, newBlock *types.Block)
| 1626 | // to be part of the new canonical chain and accumulates potential missing transactions and post an |
| 1627 | // event about them |
| 1628 | func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { |
| 1629 | var ( |
| 1630 | newChain types.Blocks |
| 1631 | oldChain types.Blocks |
| 1632 | commonBlock *types.Block |
| 1633 | deletedTxs types.Transactions |
| 1634 | deletedLogs []*types.Log |
| 1635 | // collectLogs collects the logs that were generated during the |
| 1636 | // processing of the block that corresponds with the given hash. |
| 1637 | // These logs are later announced as deleted. |
| 1638 | collectLogs = func(hash common.Hash) { |
| 1639 | // Coalesce logs and set 'Removed'. |
| 1640 | number := bc.hc.GetBlockNumber(hash) |
| 1641 | if number == nil { |
| 1642 | return |
| 1643 | } |
| 1644 | receipts := rawdb.ReadReceipts(bc.db, hash, *number) |
| 1645 | for _, receipt := range receipts { |
| 1646 | for _, log := range receipt.Logs { |
| 1647 | del := *log |
| 1648 | del.Removed = true |
| 1649 | deletedLogs = append(deletedLogs, &del) |
| 1650 | } |
| 1651 | } |
| 1652 | } |
| 1653 | ) |
| 1654 | |
| 1655 | // first reduce whoever is higher bound |
| 1656 | if oldBlock.NumberU64() > newBlock.NumberU64() { |
| 1657 | // reduce old chain |
| 1658 | for ; oldBlock != nil && oldBlock.NumberU64() != newBlock.NumberU64(); oldBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1) { |
| 1659 | oldChain = append(oldChain, oldBlock) |
| 1660 | deletedTxs = append(deletedTxs, oldBlock.Transactions()...) |
| 1661 | |
| 1662 | collectLogs(oldBlock.Hash()) |
| 1663 | } |
| 1664 | } else { |
| 1665 | // reduce new chain and append new chain blocks for inserting later on |
| 1666 | for ; newBlock != nil && newBlock.NumberU64() != oldBlock.NumberU64(); newBlock = bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) { |
| 1667 | newChain = append(newChain, newBlock) |
| 1668 | } |
| 1669 | } |
| 1670 | if oldBlock == nil { |
| 1671 | return fmt.Errorf("Invalid old chain") |
| 1672 | } |
| 1673 | if newBlock == nil { |
| 1674 | return fmt.Errorf("Invalid new chain") |
| 1675 | } |
| 1676 | |
| 1677 | for { |
| 1678 | if oldBlock.Hash() == newBlock.Hash() { |
| 1679 | commonBlock = oldBlock |
| 1680 | break |
| 1681 | } |
| 1682 | |
| 1683 | oldChain = append(oldChain, oldBlock) |
| 1684 | newChain = append(newChain, newBlock) |
| 1685 | deletedTxs = append(deletedTxs, oldBlock.Transactions()...) |
no test coverage detected