diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go index 878aef9948..025a83adc5 100644 --- a/eth/protocols/snap/sync.go +++ b/eth/protocols/snap/sync.go @@ -756,6 +756,9 @@ func (s *Syncer) loadSyncStatus() { rawdb.WriteTrieNode(task.genBatch, common.Hash{}, path, hash, blob, s.scheme) }) if s.scheme == rawdb.PathScheme { + // Configure the dangling node cleaner and also filter out boundary nodes + // only in the context of the path scheme. Deletion is forbidden in the + // hash scheme, as it can disrupt state completeness. options = options.WithCleaner(func(path []byte) { s.cleanPath(task.genBatch, common.Hash{}, path) }) @@ -780,6 +783,9 @@ func (s *Syncer) loadSyncStatus() { rawdb.WriteTrieNode(subtask.genBatch, owner, path, hash, blob, s.scheme) }) if s.scheme == rawdb.PathScheme { + // Configure the dangling node cleaner and also filter out boundary nodes + // only in the context of the path scheme. Deletion is forbidden in the + // hash scheme, as it can disrupt state completeness. options = options.WithCleaner(func(path []byte) { s.cleanPath(subtask.genBatch, owner, path) }) @@ -844,6 +850,9 @@ func (s *Syncer) loadSyncStatus() { rawdb.WriteTrieNode(batch, common.Hash{}, path, hash, blob, s.scheme) }) if s.scheme == rawdb.PathScheme { + // Configure the dangling node cleaner and also filter out boundary nodes + // only in the context of the path scheme. Deletion is forbidden in the + // hash scheme, as it can disrupt state completeness. options = options.WithCleaner(func(path []byte) { s.cleanPath(batch, common.Hash{}, path) }) @@ -2080,6 +2089,9 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { rawdb.WriteTrieNode(batch, owner, path, hash, blob, s.scheme) }) if s.scheme == rawdb.PathScheme { + // Configure the dangling node cleaner and also filter out boundary nodes + // only in the context of the path scheme. Deletion is forbidden in the + // hash scheme, as it can disrupt state completeness. options = options.WithCleaner(func(path []byte) { s.cleanPath(batch, owner, path) }) @@ -2143,6 +2155,12 @@ func (s *Syncer) processStorageResponse(res *storageResponse) { rawdb.WriteTrieNode(batch, account, path, hash, blob, s.scheme) }) if s.scheme == rawdb.PathScheme { + // Configure the dangling node cleaner only in the context of the + // path scheme. Deletion is forbidden in the hash scheme, as it can + // disrupt state completeness. + // + // Notably, boundary nodes can be also kept because the whole storage + // trie is complete. options = options.WithCleaner(func(path []byte) { s.cleanPath(batch, account, path) }) diff --git a/trie/stacktrie.go b/trie/stacktrie.go index 0504f04792..0a02441d1a 100644 --- a/trie/stacktrie.go +++ b/trie/stacktrie.go @@ -49,7 +49,7 @@ func (o *StackTrieOptions) WithWriter(writer func(path []byte, hash common.Hash, return o } -// WithCleaner configures path cleaner within the options. +// WithCleaner configures the cleaner in the option for removing dangling nodes. func (o *StackTrieOptions) WithCleaner(cleaner func(path []byte)) *StackTrieOptions { o.Cleaner = cleaner return o @@ -74,7 +74,7 @@ type StackTrie struct { h *hasher first []byte // The key of first inserted entry, tracked as left boundary. - last []byte // The key of last inserted entry, tracked as left boundary. + last []byte // The key of last inserted entry, tracked as right boundary. } // NewStackTrie allocates and initializes an empty trie. @@ -102,9 +102,9 @@ func (t *StackTrie) Update(key, value []byte) error { t.first = append([]byte{}, k...) } if t.last == nil { - t.last = append([]byte{}, k...) + t.last = append([]byte{}, k...) // allocate key slice } else { - t.last = append(t.last[:0], k...) + t.last = append(t.last[:0], k...) // reuse key slice } t.insert(t.root, k, value, nil) return nil