From 3dbfb1aa48fc70b260191c5ef1f0b36efae23ebe Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 1 May 2019 22:12:49 +0200 Subject: [PATCH] core: delete stale future canon number mappings during reorg to shorter+heavier chain --- core/blockchain.go | 10 +++++++++- core/blockchain_test.go | 4 ---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 4a347ec81d..8ff37a3fe5 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1577,8 +1577,16 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { for _, tx := range types.TxDifference(deletedTxs, addedTxs) { 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() - // 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 // ever happens if we're reorging empty blocks, which will only happen on idle diff --git a/core/blockchain_test.go b/core/blockchain_test.go index a04c290998..fbd64da560 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -1870,7 +1870,6 @@ func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error // 2. Reorg to shorter but heavier chain [0 ... N ... Y] // 3. Then there should be no canon mapping for the block at height X func TestReorgToShorterRemovesCanonMapping(t *testing.T) { - chain, canonblocks, sideblocks, err := getLongAndShortChains() if err != nil { t.Fatal(err) @@ -1894,14 +1893,12 @@ func TestReorgToShorterRemovesCanonMapping(t *testing.T) { if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil { t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64()) } - } // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain // imports -- that is, for fast sync func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) { - chain, canonblocks, sideblocks, err := getLongAndShortChains() if err != nil { t.Fatal(err) @@ -1933,5 +1930,4 @@ func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) { if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil { t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64()) } - }