From 827456711a55bbec7d18d8c44556e817d39282c1 Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Wed, 20 Sep 2023 20:58:09 +0800 Subject: [PATCH] trie: change comments --- trie/sync.go | 10 +++---- trie/sync_test.go | 73 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/trie/sync.go b/trie/sync.go index cf1ecee5e3..9da0706075 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -462,11 +462,9 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { if _, ok := node.Val.(hashNode); ok && s.scheme == rawdb.PathScheme { owner, inner := ResolvePath(req.path) for i := 1; i < len(key); i++ { - // Theoretically, it's necessary to check for the presence before - // blindly caching deletion commands. However, due to the fact that - // Pebble doesn't use a bloom filter to enhance read performance - // for non-existent items, this check would significantly slow down - // overall performance. FIX IT(rjl493456442) + // While checking for a non-existent item in Pebble can be less efficient + // without a bloom filter, the relatively low frequency of lookups makes + // the performance impact negligible. var exists bool if owner == (common.Hash{}) { exists = rawdb.ExistsAccountTrieNode(s.database, append(inner, key[:i]...)) @@ -476,7 +474,7 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { if exists { req.deletes = append(req.deletes, key[:i]) deletionGauge.Inc(1) - log.Info("Detected dangling node", "owner", owner, "path", append(inner, key[:i]...)) + log.Debug("Detected dangling node", "owner", owner, "path", append(inner, key[:i]...)) } } lookupGauge.Inc(int64(len(key) - 1)) diff --git a/trie/sync_test.go b/trie/sync_test.go index d298e74d00..840ffb8980 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -732,16 +732,73 @@ func syncWith(t *testing.T, root common.Hash, db ethdb.Database, srcDb *Database } } -// Tests that the syncing target is keeping moving which may overwrite the stale -// states synced in the last cycle. -func TestSyncMovingTarget(t *testing.T) { - testSyncMovingTarget(t, rawdb.HashScheme, true) - testSyncMovingTarget(t, rawdb.HashScheme, false) - testSyncMovingTarget(t, rawdb.PathScheme, true) - testSyncMovingTarget(t, rawdb.PathScheme, false) +func testSyncMovingTarget(t *testing.T, scheme string) { + // Create a random trie to copy + _, srcDb, srcTrie, srcData := makeTestTrie(scheme) + + // Create a destination trie and sync with the scheduler + diskdb := rawdb.NewMemoryDatabase() + syncWith(t, srcTrie.Hash(), diskdb, srcDb) + checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), srcData, false) + + // Push more modifications into the src trie, to see if dest trie can still + // sync with it(overwrite stale states) + var ( + preRoot = srcTrie.Hash() + diff = make(map[string][]byte) + ) + for i := byte(0); i < 10; i++ { + key, val := randBytes(32), randBytes(32) + srcTrie.MustUpdate(key, val) + diff[string(key)] = val + } + root, nodes, _ := srcTrie.Commit(false) + if err := srcDb.Update(root, preRoot, 0, trienode.NewWithNodeSet(nodes), nil); err != nil { + panic(err) + } + if err := srcDb.Commit(root, false); err != nil { + panic(err) + } + preRoot = root + srcTrie, _ = NewStateTrie(TrieID(root), srcDb) + + syncWith(t, srcTrie.Hash(), diskdb, srcDb) + checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), diff, false) + + // Revert added modifications from the src trie, to see if dest trie can still + // sync with it(overwrite reverted states) + var reverted = make(map[string][]byte) + for k := range diff { + srcTrie.MustDelete([]byte(k)) + reverted[k] = nil + } + for k := range srcData { + val := randBytes(32) + srcTrie.MustUpdate([]byte(k), val) + reverted[k] = val + } + root, nodes, _ = srcTrie.Commit(false) + if err := srcDb.Update(root, preRoot, 0, trienode.NewWithNodeSet(nodes), nil); err != nil { + panic(err) + } + if err := srcDb.Commit(root, false); err != nil { + panic(err) + } + srcTrie, _ = NewStateTrie(TrieID(root), srcDb) + + syncWith(t, srcTrie.Hash(), diskdb, srcDb) + checkTrieContents(t, diskdb, srcDb.Scheme(), srcTrie.Hash().Bytes(), reverted, false) } -func testSyncMovingTarget(t *testing.T, scheme string, tiny bool) { +// Tests if state syncer can correctly catch up the pivot move. +func TestPivotMove(t *testing.T) { + testPivotMove(t, rawdb.HashScheme, true) + testPivotMove(t, rawdb.HashScheme, false) + testPivotMove(t, rawdb.PathScheme, true) + testPivotMove(t, rawdb.PathScheme, false) +} + +func testPivotMove(t *testing.T, scheme string, tiny bool) { var ( srcDisk = rawdb.NewMemoryDatabase() srcTrieDB = newTestDatabase(srcDisk, scheme)