From 24192a95c05edb8f75fa5ff7f1d59de845c5baa9 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Thu, 25 Jul 2019 18:59:33 +0800 Subject: [PATCH] cmd/utils, core/rawdb: address some comments --- cmd/utils/flags.go | 5 +++- core/blockchain.go | 40 +++++++++++++++--------------- core/blockchain_test.go | 2 +- core/rawdb/accessors_chain.go | 18 +++++++------- core/rawdb/accessors_chain_test.go | 2 +- core/rawdb/chain_iterator.go | 6 ++--- core/rawdb/schema.go | 4 +-- 7 files changed, 40 insertions(+), 37 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2c5f548a94..fd8c2cbb30 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1424,7 +1424,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { CheckExclusive(ctx, LightLegacyServFlag, LightServeFlag, SyncModeFlag, "light") CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer CheckExclusive(ctx, GCModeFlag, "archive", TxLookupLimitFlag) - + // todo(rjl493456442) make it available for les server + // Ancient tx indices pruning is not available for les server now + // since light client relies on the server for transaction status query. + CheckExclusive(ctx, SyncModeFlag, "light", TxLookupLimitFlag) var ks *keystore.KeyStore if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 { ks = keystores[0].(*keystore.KeyStore) diff --git a/core/blockchain.go b/core/blockchain.go index aa04593ff2..3a9e4ab98f 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -290,7 +290,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par } // Take ownership of this particular state go bc.update() - go bc.updateTxIndices() + go bc.maintainTxIndex() return bc, nil } @@ -2046,7 +2046,7 @@ func (bc *BlockChain) update() { } } -// updateTxIndices is responsible for the construction and deletion of the +// maintainTxIndex is responsible for the construction and deletion of the // transaction index. // // User can use flag `txlookuplimit` to specify a "recentness" block, below @@ -2055,22 +2055,12 @@ func (bc *BlockChain) update() { // // The user can adjust the txlookuplimit value for each launch, Geth will // automatically construct the missing indices and delete the extra indices. -func (bc *BlockChain) updateTxIndices() { - var ( - done chan struct{} // Non-nil if background unindexing or reindexing routine is active. - headCh = make(chan ChainHeadEvent) - ) - sub := bc.SubscribeChainHeadEvent(headCh) - defer func() { - if sub != nil { - sub.Unsubscribe() - } - }() +func (bc *BlockChain) maintainTxIndex() { // initialiseIndices inits txlookup indices into the database. // If there already exists some indices, this function will find // the oldest block which has been indexed and start indexing from // this point. - initialiseIndices := func(head uint64) { + initialiseIndices := func(head uint64, done chan struct{}) { defer func() { done <- struct{}{} }() from, to := uint64(0), head @@ -2080,7 +2070,7 @@ func (bc *BlockChain) updateTxIndices() { // Find oldest indexed block via binary search when we don't // have this flag in database. start := time.Now() - oldest := rawdb.FindOldestIndexedBlock(bc.db, from, to) + oldest := rawdb.FindTxIndexTail(bc.db, from, to) log.Debug("Find oldest indexed block", "oldest", oldest, "elapsed", common.PrettyDuration(time.Since(start))) // Re-construct missing tx indices. @@ -2091,7 +2081,7 @@ func (bc *BlockChain) updateTxIndices() { // Drop all useless tx indices below the HEAD-limit. if from > 0 { - oldest := rawdb.FindOldestIndexedBlock(bc.db, 0, from) + oldest := rawdb.FindTxIndexTail(bc.db, 0, from) if oldest != nil { rawdb.RemoveTxsLookup(bc.db, *oldest, from) } @@ -2101,7 +2091,7 @@ func (bc *BlockChain) updateTxIndices() { } // indexBlocks reindex or unindex transaction indices depends // on user's requirement. - indexBlocks := func(oldest uint64, head uint64) { + indexBlocks := func(oldest uint64, head uint64, done chan struct{}) { defer func() { done <- struct{}{} }() // All indices should be reserved. @@ -2125,16 +2115,26 @@ func (bc *BlockChain) updateTxIndices() { rawdb.RemoveTxsLookup(bc.db, oldest, head-bc.txLookupLimit) } } + var ( + done chan struct{} // Non-nil if background unindexing or reindexing routine is active. + headCh = make(chan ChainHeadEvent) + ) + sub := bc.SubscribeChainHeadEvent(headCh) + defer func() { + if sub != nil { + sub.Unsubscribe() + } + }() for { select { case head := <-headCh: if done == nil { done = make(chan struct{}) - if number := rawdb.ReadOldestIndexedBlock(bc.db); number == nil { - go initialiseIndices(head.Block.NumberU64()) + if number := rawdb.ReadTxIndexTail(bc.db); number == nil { + go initialiseIndices(head.Block.NumberU64(), done) } else { - go indexBlocks(*number, head.Block.NumberU64()) + go indexBlocks(*number, head.Block.NumberU64(), done) } } case <-done: diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 161b3a015c..c1943118a9 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -2155,7 +2155,7 @@ func TestTransactionIndices(t *testing.T) { blocks2, _ := GenerateChain(gspec.Config, blocks[len(blocks)-1], ethash.NewFaker(), gendb, 10, nil) check := func(oldest *uint64, chain *BlockChain) { - indexed := rawdb.ReadOldestIndexedBlock(chain.db) + indexed := rawdb.ReadTxIndexTail(chain.db) if oldest == nil && indexed != nil { t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *indexed) } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index e546af5bba..927f049880 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -171,11 +171,11 @@ func WriteFastTrieProgress(db ethdb.KeyValueWriter, count uint64) { } } -// ReadOldestIndexedBlock retrieves the number of oldest indexed block +// ReadTxIndexTail retrieves the number of oldest indexed block // whose transaction indices has been indexed. If the corresponding entry // is non-existent in database it means the indexing has been finished. -func ReadOldestIndexedBlock(db ethdb.KeyValueReader) *uint64 { - data, _ := db.Get(oldestIndexedBlockKey) +func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 { + data, _ := db.Get(txIndexTailKey) if len(data) != 8 { return nil } @@ -183,10 +183,10 @@ func ReadOldestIndexedBlock(db ethdb.KeyValueReader) *uint64 { return &number } -// WriteOldestIndexedBlock stores the number of oldest indexed block +// WriteTxIndexTail stores the number of oldest indexed block // into database. -func WriteOldestIndexedBlock(db ethdb.KeyValueWriter, number uint64) { - if err := db.Put(oldestIndexedBlockKey, encodeBlockNumber(number)); err != nil { +func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) { + if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil { log.Crit("Failed to store the number of oldest indexed block", "err", err) } } @@ -579,14 +579,14 @@ func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { return a } -// FindOldestIndexedBlock binary searches the oldest block which has been indexed. +// FindTxIndexTail binary searches the oldest block which has been indexed. // We will always ensures that if Bi is indexed, then Bi+1 must has been indexed. // // If no block has been indexed, then the returned value is to+1. // // The block doesn't contain any transaction will be regarded as unindexed. It can -// cause the blocks before this block can be reindexed. -func FindOldestIndexedBlock(db ethdb.Reader, from uint64, to uint64) *uint64 { +// cause the blocks before this block will be reindexed. +func FindTxIndexTail(db ethdb.Reader, from uint64, to uint64) *uint64 { low, high := from, to+1 check := func(number uint64) bool { diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 810a948dac..094296c440 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -402,7 +402,7 @@ func TestFindOldestIndexedBlock(t *testing.T) { WriteTxLookupEntries(db, block) } } - res := FindOldestIndexedBlock(db, c.start, c.end) + res := FindTxIndexTail(db, c.start, c.end) if c.expectNil && res != nil { t.Fatalf("Case %d failed, oldest block mismatch, want nil, have %d", cid, *res) } diff --git a/core/rawdb/chain_iterator.go b/core/rawdb/chain_iterator.go index e54217c15d..6755a37899 100644 --- a/core/rawdb/chain_iterator.go +++ b/core/rawdb/chain_iterator.go @@ -200,13 +200,13 @@ func IndexTxLookup(db ethdb.Database, from uint64, to uint64) { writeIndices := func(batch ethdb.Batch, block *types.Block) { WriteTxLookupEntries(batch, block) if block.NumberU64()%1000000 == 0 { - WriteOldestIndexedBlock(batch, block.NumberU64()) + WriteTxIndexTail(batch, block.NumberU64()) } } if err := iterateCanonicalChain(db, from, to, "txlookup", hashTxs, writeIndices, true, true); err != nil { log.Crit("Failed to iterate canonical chain", "err", err) } - WriteOldestIndexedBlock(db, from) + WriteTxIndexTail(db, from) log.Info("Constructed transaction indices", "from", from, "to", to, "count", to-from) } @@ -214,7 +214,7 @@ func IndexTxLookup(db ethdb.Database, from uint64, to uint64) { func RemoveTxsLookup(db ethdb.Database, from uint64, to uint64) { // Write flag first and then unindex the transaction indices. Some indices // will be left in the database if crash happens but it's fine. - WriteOldestIndexedBlock(db, to) + WriteTxIndexTail(db, to) if from+1 == to { hash := ReadCanonicalHash(db, from) diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 097b04fcac..372b6d2312 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -41,8 +41,8 @@ var ( // fastTrieProgressKey tracks the number of trie entries imported during fast sync. fastTrieProgressKey = []byte("TrieSync") - // oldestIndexedBlockKey tracks the oldest block whose transaction indices(txlookup) has been indexed. - oldestIndexedBlockKey = []byte("OldestIndexedBlock") + // txIndexTailKey tracks the oldest block whose transaction indices(txlookup) has been indexed. + txIndexTailKey = []byte("TxIndexTail") // Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes). headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header