core: delete stale future canon number mappings during reorg to shorter+heavier chain

This commit is contained in:
Martin Holst Swende 2019-05-01 22:12:49 +02:00
parent f23767027c
commit 3dbfb1aa48
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 9 additions and 5 deletions

View file

@ -1577,8 +1577,16 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
for _, tx := range types.TxDifference(deletedTxs, addedTxs) { for _, tx := range types.TxDifference(deletedTxs, addedTxs) {
rawdb.DeleteTxLookupEntry(batch, tx.Hash()) rawdb.DeleteTxLookupEntry(batch, tx.Hash())
} }
// Delete any canonical number assignments above the new head
number := bc.CurrentBlock().NumberU64()
for i := number + 1; ; i++ {
hash := rawdb.ReadCanonicalHash(bc.db, i)
if hash == (common.Hash{}) {
break
}
rawdb.DeleteCanonicalHash(batch, i)
}
batch.Write() batch.Write()
// If any logs need to be fired, do it now. In theory we could avoid creating // If any logs need to be fired, do it now. In theory we could avoid creating
// this goroutine if there are no events to fire, but realistcally that only // this goroutine if there are no events to fire, but realistcally that only
// ever happens if we're reorging empty blocks, which will only happen on idle // ever happens if we're reorging empty blocks, which will only happen on idle

View file

@ -1870,7 +1870,6 @@ func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error
// 2. Reorg to shorter but heavier chain [0 ... N ... Y] // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
// 3. Then there should be no canon mapping for the block at height X // 3. Then there should be no canon mapping for the block at height X
func TestReorgToShorterRemovesCanonMapping(t *testing.T) { func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
chain, canonblocks, sideblocks, err := getLongAndShortChains() chain, canonblocks, sideblocks, err := getLongAndShortChains()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -1894,14 +1893,12 @@ func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil { if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64()) t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
} }
} }
// TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
// as TestReorgToShorterRemovesCanonMapping, but applied on headerchain // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
// imports -- that is, for fast sync // imports -- that is, for fast sync
func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) { func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
chain, canonblocks, sideblocks, err := getLongAndShortChains() chain, canonblocks, sideblocks, err := getLongAndShortChains()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -1933,5 +1930,4 @@ func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil { if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64()) t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
} }
} }