Skip to content

Commit

Permalink
trie: remove nodes method and add diskdb method for consistency with …
Browse files Browse the repository at this point in the history
…pathdb
  • Loading branch information
Francesco4203 authored and huyngopt1994 committed Oct 25, 2024
1 parent f5ad220 commit 95cacba
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 43 deletions.
67 changes: 51 additions & 16 deletions core/state/iterator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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{}
}
23 changes: 10 additions & 13 deletions trie/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
14 changes: 0 additions & 14 deletions trie/triedb/hashdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions trie/triedb/pathdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 95cacba

Please sign in to comment.