From 95cacba326057dacd074de3e80819ffd15f78769 Mon Sep 17 00:00:00 2001 From: Francesco4203 Date: Fri, 11 Oct 2024 17:33:48 +0700 Subject: [PATCH] trie: remove nodes method and add diskdb method for consistency with pathdb --- core/state/iterator_test.go | 67 ++++++++++++++++++++++++++-------- trie/database.go | 23 +++++------- trie/triedb/hashdb/database.go | 14 ------- trie/triedb/pathdb/database.go | 5 +++ 4 files changed, 66 insertions(+), 43 deletions(-) diff --git a/core/state/iterator_test.go b/core/state/iterator_test.go index b093083db2..24b192c26c 100644 --- a/core/state/iterator_test.go +++ b/core/state/iterator_test.go @@ -17,10 +17,11 @@ package state import ( - "bytes" "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" ) // Tests that the node iterator indeed walks over the entire database contents. @@ -40,29 +41,63 @@ func TestNodeIteratorCoverage(t *testing.T) { hashes[it.Hash] = struct{}{} } } + // Check in-disk nodes + var ( + seenNodes = make(map[common.Hash]struct{}) + seenCodes = make(map[common.Hash]struct{}) + ) + it := db.NewIterator(nil, nil) + for it.Next() { + ok, hash := isTrieNode(sdb.TrieDB().Scheme(), it.Key(), it.Value()) + if !ok { + continue + } + seenNodes[hash] = struct{}{} + } + it.Release() + + // Check in-disk codes + it = db.NewIterator(nil, nil) + for it.Next() { + ok, hash := rawdb.IsCodeKey(it.Key()) + if !ok { + continue + } + if _, ok := hashes[common.BytesToHash(hash)]; !ok { + t.Errorf("state entry not reported %x", it.Key()) + } + seenCodes[common.BytesToHash(hash)] = struct{}{} + } + it.Release() + // Cross check the iterated hashes and the database/nodepool content for hash := range hashes { - if _, err = sdb.TrieDB().Node(hash); err != nil { - _, err = sdb.ContractCode(common.Hash{}, hash) + _, ok := seenNodes[hash] + if !ok { + _, ok = seenCodes[hash] } - if err != nil { + if !ok { t.Errorf("failed to retrieve reported node %x", hash) } } - for _, hash := range sdb.TrieDB().Nodes() { - if _, ok := hashes[hash]; !ok { - t.Errorf("state entry not reported %x", hash) +} + +// isTrieNode is a helper function which reports if the provided +// database entry belongs to a trie node or not. +func isTrieNode(scheme string, key, val []byte) (bool, common.Hash) { + if scheme == rawdb.HashScheme { + if rawdb.IsLegacyTrieNode(key, val) { + return true, common.BytesToHash(key) } - } - it := db.NewIterator(nil, nil) - for it.Next() { - key := it.Key() - if bytes.HasPrefix(key, []byte("secure-key-")) { - continue + } else { + ok, _ := rawdb.IsAccountTrieNode(key) + if ok { + return true, crypto.Keccak256Hash(val) } - if _, ok := hashes[common.BytesToHash(key)]; !ok { - t.Errorf("state entry not reported %x", key) + ok, _, _ = rawdb.IsStorageTrieNode(key) + if ok { + return true, crypto.Keccak256Hash(val) } } - it.Release() + return false, common.Hash{} } diff --git a/trie/database.go b/trie/database.go index 8988859a50..92791a92d8 100644 --- a/trie/database.go +++ b/trie/database.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/trie/triedb/hashdb" + "github.com/ethereum/go-ethereum/trie/triedb/pathdb" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/triestate" ) @@ -57,11 +58,6 @@ type backend interface { // everything. Therefore, these maps must not be changed afterwards. Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *triestate.Set) error - // Nodes retrieves the hashes of all the nodes cached within the memory database. - // This method is extremely expensive and should only be used to validate internal - // states in test code. - Nodes() []common.Hash - // DiskDB retrieves the persistent storage backing the trie database. DiskDB() ethdb.KeyValueStore @@ -120,7 +116,15 @@ func NewDatabaseWithConfig(diskdb ethdb.Database, config *Config) *Database { // Reader returns a reader for accessing all trie nodes with provided state root. // Nil is returned in case the state is not available. func (db *Database) Reader(blockRoot common.Hash) Reader { - return db.backend.(*hashdb.Database).Reader(blockRoot) + switch b := db.backend.(type) { + case *hashdb.Database: + return b.Reader(blockRoot) + case *pathdb.Database: + reader, _ := b.Reader(blockRoot) + return reader + } + return nil + } // Update performs a state transition by committing dirty nodes contained in the @@ -177,13 +181,6 @@ func (db *Database) DiskDB() ethdb.KeyValueStore { return db.backend.DiskDB() } -// Nodes retrieves the hashes of all the nodes cached within the memory database. -// This method is extremely expensive and should only be used to validate internal -// states in test code. -func (db *Database) Nodes() []common.Hash { - return db.backend.Nodes() -} - // Close flushes the dangling preimages to disk and closes the trie database. // It is meant to be called when closing the blockchain object, so that all // resources held can be released correctly. diff --git a/trie/triedb/hashdb/database.go b/trie/triedb/hashdb/database.go index 56cd38699a..8d8701a60b 100644 --- a/trie/triedb/hashdb/database.go +++ b/trie/triedb/hashdb/database.go @@ -221,20 +221,6 @@ func (db *Database) Node(hash common.Hash) ([]byte, error) { return nil, errors.New("not found") } -// Nodes retrieves the hashes of all the nodes cached within the memory database. -// This method is extremely expensive and should only be used to validate internal -// states in test code. -func (db *Database) Nodes() []common.Hash { - db.lock.RLock() - defer db.lock.RUnlock() - - var hashes = make([]common.Hash, 0, len(db.dirties)) - for hash := range db.dirties { - hashes = append(hashes, hash) - } - return hashes -} - // Reference adds a new reference from a parent node to a child node. // This function is used to add reference between internal trie node // and external node(e.g. storage trie root), all internal trie nodes diff --git a/trie/triedb/pathdb/database.go b/trie/triedb/pathdb/database.go index 48b4744b40..588e477eb0 100644 --- a/trie/triedb/pathdb/database.go +++ b/trie/triedb/pathdb/database.go @@ -383,6 +383,11 @@ func (db *Database) SetBufferSize(size int) error { return db.tree.bottom().setBufferSize(db.bufferSize) } +// DiskDB retrieves the persistent storage backing the trie database. +func (db *Database) DiskDB() ethdb.KeyValueStore { + return db.diskdb +} + // Scheme returns the node scheme used in the database. func (db *Database) Scheme() string { return rawdb.PathScheme