From a536c5d33cdb7142170112088b48cf22d4c76714 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Tue, 23 Jul 2019 14:06:41 +0800 Subject: [PATCH] core: skip tx indices writing during fast sync --- core/blockchain.go | 24 ++++++++++++++++++------ core/rawdb/accessors_chain_test.go | 30 +++++++++++++++++------------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index dbd472ea07..aa04593ff2 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1090,7 +1090,11 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ } // Flush data into ancient database. size += rawdb.WriteAncientBlock(bc.db, block, receiptChain[i], bc.GetTd(block.Hash(), block.NumberU64())) - rawdb.WriteTxLookupEntries(batch, block) + + // We don't write tx lookup indices here because Geth can offer a CLI flag `txlookuplimt` + // with which user can choose to drop historical indices data and only keep latest indices. + // After the fast sync, we will reconstruct all missing indices even user requires to keep + // all historical indices. stats.processed++ } @@ -1165,7 +1169,11 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // Write all the data out into the database rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()) rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i]) - rawdb.WriteTxLookupEntries(batch, block) + + // We don't write tx lookup indices here because Geth can offer a CLI flag `txlookuplimt` + // with which user can choose to drop historical indices data and only keep latest indices. + // After the fast sync, we will reconstruct all missing indices even user requires to keep + // all historical indices. stats.processed++ if batch.ValueSize() >= ethdb.IdealBatchSize { @@ -2080,10 +2088,14 @@ func (bc *BlockChain) updateTxIndices() { rawdb.IndexTxLookup(bc.db, from, to) // No block has been indexed. } else { rawdb.IndexTxLookup(bc.db, from, *oldest) - } - // Delete useless tx indices if user requires. - if from > 0 { - rawdb.RemoveTxsLookup(bc.db, 0, from) + + // Drop all useless tx indices below the HEAD-limit. + if from > 0 { + oldest := rawdb.FindOldestIndexedBlock(bc.db, 0, from) + if oldest != nil { + rawdb.RemoveTxsLookup(bc.db, *oldest, from) + } + } } log.Debug("Initialised transaction indices", "elapsed", common.PrettyDuration(time.Since(start))) } diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index aacbe32216..810a948dac 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -361,20 +361,24 @@ func checkReceiptsRLP(have, want types.Receipts) error { func TestFindOldestIndexedBlock(t *testing.T) { var cases = []struct { - empty bool oldest uint64 height uint64 nilBlocks map[uint64]bool + start uint64 + end uint64 expect uint64 + expectNil bool }{ - {true, 0, 10, nil, 0}, // No block has been indexed - {false, 0, 10, nil, 1}, // Genesis block doesn't have indices - {false, 1, 10, nil, 1}, - {false, 4, 10, nil, 4}, - {false, 5, 10, nil, 5}, - {false, 6, 10, nil, 6}, - {false, 10, 10, nil, 10}, - {false, 3, 10, map[uint64]bool{4: true, 6: true, 8: true}, 5}, + {11, 10, nil, 0, 10, 0, true}, // No block has been indexed + {0, 10, nil, 0, 10, 1, false}, // Genesis block doesn't have indices + {1, 10, nil, 0, 10, 1, false}, + {5, 10, nil, 0, 10, 5, false}, + {5, 10, nil, 0, 5, 5, false}, + {5, 10, nil, 0, 4, 0, true}, + {5, 10, nil, 5, 5, 5, false}, + {5, 10, nil, 10, 10, 10, false}, + {10, 10, nil, 0, 10, 10, false}, + {3, 10, map[uint64]bool{4: true, 6: true, 8: true}, 0, 10, 5, false}, } for cid, c := range cases { var ( @@ -394,15 +398,15 @@ func TestFindOldestIndexedBlock(t *testing.T) { } WriteBlock(db, block) WriteCanonicalHash(db, block.Hash(), block.NumberU64()) - if !c.empty && block.NumberU64() >= c.oldest { + if block.NumberU64() >= c.oldest { WriteTxLookupEntries(db, block) } } - res := FindOldestIndexedBlock(db, 0, c.height) - if c.empty && res != nil { + res := FindOldestIndexedBlock(db, c.start, c.end) + if c.expectNil && res != nil { t.Fatalf("Case %d failed, oldest block mismatch, want nil, have %d", cid, *res) } - if !c.empty && *res != c.expect { + if !c.expectNil && *res != c.expect { t.Fatalf("Case %d failed, oldest block mismatch, want %d, have %d", cid, c.expect, *res) } }