forked from cerc-io/plugeth
all: remove database commit callback, rework noderesolver (#26637)
This change ports some changes from the main PBSS PR: - get rid of callback function in `trie.Database.Commit` which is not required anymore - rework the `nodeResolver` in `trie.Iterator` to make it compatible with multiple state scheme - some other shallow changes in tests and typo-fixes
This commit is contained in:
+44
-19
@@ -17,17 +17,17 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
)
|
||||
|
||||
// Tests that the node iterator indeed walks over the entire database contents.
|
||||
func TestNodeIteratorCoverage(t *testing.T) {
|
||||
// Create some arbitrary test state to iterate
|
||||
db, sdb, root, _ := makeTestState()
|
||||
sdb.TrieDB().Commit(root, false, nil)
|
||||
sdb.TrieDB().Commit(root, false)
|
||||
|
||||
state, err := New(root, sdb, nil)
|
||||
if err != nil {
|
||||
@@ -40,29 +40,54 @@ 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 len(key) == common.HashLength {
|
||||
return true, common.BytesToHash(key)
|
||||
}
|
||||
}
|
||||
it := db.NewIterator(nil, nil)
|
||||
for it.Next() {
|
||||
key := it.Key()
|
||||
if bytes.HasPrefix(key, []byte("secure-key-")) {
|
||||
continue
|
||||
}
|
||||
if _, ok := hashes[common.BytesToHash(key)]; !ok {
|
||||
t.Errorf("state entry not reported %x", key)
|
||||
}
|
||||
}
|
||||
it.Release()
|
||||
return false, common.Hash{}
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ func RecoverPruning(datadir string, db ethdb.Database, trieCachePath string) err
|
||||
}
|
||||
headBlock := rawdb.ReadHeadBlock(db)
|
||||
if headBlock == nil {
|
||||
return errors.New("Failed to load head block")
|
||||
return errors.New("failed to load head block")
|
||||
}
|
||||
// Initialize the snapshot tree in recovery mode to handle this special case:
|
||||
// - Users run the `prune-state` command multiple times
|
||||
|
||||
@@ -359,19 +359,22 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, trieId *trie.ID, prefi
|
||||
}
|
||||
// We use the snap data to build up a cache which can be used by the
|
||||
// main account trie as a primary lookup when resolving hashes
|
||||
var snapNodeCache ethdb.Database
|
||||
var resolver trie.NodeResolver
|
||||
if len(result.keys) > 0 {
|
||||
snapNodeCache = rawdb.NewMemoryDatabase()
|
||||
snapTrieDb := trie.NewDatabase(snapNodeCache)
|
||||
snapTrie := trie.NewEmpty(snapTrieDb)
|
||||
mdb := rawdb.NewMemoryDatabase()
|
||||
tdb := trie.NewDatabase(mdb)
|
||||
snapTrie := trie.NewEmpty(tdb)
|
||||
for i, key := range result.keys {
|
||||
snapTrie.Update(key, result.vals[i])
|
||||
}
|
||||
root, nodes, _ := snapTrie.Commit(false)
|
||||
if nodes != nil {
|
||||
snapTrieDb.Update(trie.NewWithNodeSet(nodes))
|
||||
root, nodes, err := snapTrie.Commit(false)
|
||||
if err == nil && nodes != nil {
|
||||
tdb.Update(trie.NewWithNodeSet(nodes))
|
||||
tdb.Commit(root, false)
|
||||
}
|
||||
resolver = func(owner common.Hash, path []byte, hash common.Hash) []byte {
|
||||
return rawdb.ReadTrieNode(mdb, owner, path, hash, tdb.Scheme())
|
||||
}
|
||||
snapTrieDb.Commit(root, false, nil)
|
||||
}
|
||||
// Construct the trie for state iteration, reuse the trie
|
||||
// if it's already opened with some nodes resolved.
|
||||
@@ -400,7 +403,7 @@ func (dl *diskLayer) generateRange(ctx *generatorContext, trieId *trie.ID, prefi
|
||||
start = time.Now()
|
||||
internal time.Duration
|
||||
)
|
||||
nodeIt.AddResolver(snapNodeCache)
|
||||
nodeIt.AddResolver(resolver)
|
||||
|
||||
for iter.Next() {
|
||||
if last != nil && bytes.Compare(iter.Key, last) > 0 {
|
||||
|
||||
@@ -203,7 +203,7 @@ func (t *testHelper) Commit() common.Hash {
|
||||
t.nodes.Merge(nodes)
|
||||
}
|
||||
t.triedb.Update(t.nodes)
|
||||
t.triedb.Commit(root, false, nil)
|
||||
t.triedb.Commit(root, false)
|
||||
return root
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ func TestGenerateCorruptAccountTrie(t *testing.T) {
|
||||
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
||||
|
||||
// Delete an account trie leaf and ensure the generator chokes
|
||||
helper.triedb.Commit(root, false, nil)
|
||||
helper.triedb.Commit(root, false)
|
||||
helper.diskdb.Delete(common.HexToHash("0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7").Bytes())
|
||||
|
||||
snap := generateSnapshot(helper.diskdb, helper.triedb, 16, root)
|
||||
|
||||
@@ -55,7 +55,7 @@ func TestUpdateLeaks(t *testing.T) {
|
||||
}
|
||||
|
||||
root := state.IntermediateRoot(false)
|
||||
if err := state.Database().TrieDB().Commit(root, false, nil); err != nil {
|
||||
if err := state.Database().TrieDB().Commit(root, false); err != nil {
|
||||
t.Errorf("can not commit trie %v to persistent database", root.Hex())
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit transition state: %v", err)
|
||||
}
|
||||
if err = transState.Database().TrieDB().Commit(transRoot, false, nil); err != nil {
|
||||
if err = transState.Database().TrieDB().Commit(transRoot, false); err != nil {
|
||||
t.Errorf("can not commit trie %v to persistent database", transRoot.Hex())
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit final state: %v", err)
|
||||
}
|
||||
if err = finalState.Database().TrieDB().Commit(finalRoot, false, nil); err != nil {
|
||||
if err = finalState.Database().TrieDB().Commit(finalRoot, false); err != nil {
|
||||
t.Errorf("can not commit trie %v to persistent database", finalRoot.Hex())
|
||||
}
|
||||
|
||||
@@ -948,7 +948,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
|
||||
if err := statedb.TrieDB().Cap(1024); err != nil {
|
||||
t.Fatalf("failed to cap trie dirty cache: %v", err)
|
||||
}
|
||||
if err := statedb.TrieDB().Commit(root, false, nil); err != nil {
|
||||
if err := statedb.TrieDB().Commit(root, false); err != nil {
|
||||
t.Fatalf("failed to commit state trie: %v", err)
|
||||
}
|
||||
// Reopen the state trie from flushed disk and verify it
|
||||
|
||||
@@ -174,7 +174,7 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool) {
|
||||
// Create a random state to copy
|
||||
_, srcDb, srcRoot, srcAccounts := makeTestState()
|
||||
if commit {
|
||||
srcDb.TrieDB().Commit(srcRoot, false, nil)
|
||||
srcDb.TrieDB().Commit(srcRoot, false)
|
||||
}
|
||||
srcTrie, _ := trie.New(trie.StateTrieID(srcRoot), srcDb.TrieDB())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user