Skip to content

Commit 760f234

Browse files
0xmountaintoprjl493456442HAOYUatHZ
authored
trie: fix two issues in trie iterator (ethereum#24539) (#778)
* trie: fix two issues in trie iterator (ethereum#24539) * trie: fix memory leak in trie iterator In the trie iterator, live nodes are tracked in a stack while iterating. Popped node states should be explictly set to nil in order to get garbage-collected. * trie: fix empty trie iterator * fix lint * chore: auto version bump [bot] --------- Co-authored-by: rjl493456442 <[email protected]> Co-authored-by: HAOYUatHZ <[email protected]>
1 parent bfe8030 commit 760f234

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

trie/iterator.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,11 @@ func (e seekError) Error() string {
151151
}
152152

153153
func newNodeIterator(trie *Trie, start []byte) NodeIterator {
154-
if trie.Hash() == emptyState {
155-
return new(nodeIterator)
154+
if trie.Hash() == emptyRoot {
155+
return &nodeIterator{
156+
trie: trie,
157+
err: errIteratorEnd,
158+
}
156159
}
157160
it := &nodeIterator{trie: trie}
158161
it.err = it.seek(start)
@@ -402,7 +405,7 @@ func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node,
402405
func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) {
403406
switch node := parent.node.(type) {
404407
case *fullNode:
405-
//Full node, move to the first non-nil child.
408+
// Full node, move to the first non-nil child.
406409
if child, state, path, index := findChild(node, parent.index+1, it.path, ancestor); child != nil {
407410
parent.index = index - 1
408411
return state, path, true
@@ -480,8 +483,9 @@ func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []
480483
}
481484

482485
func (it *nodeIterator) pop() {
483-
parent := it.stack[len(it.stack)-1]
484-
it.path = it.path[:parent.pathlen]
486+
last := it.stack[len(it.stack)-1]
487+
it.path = it.path[:last.pathlen]
488+
it.stack[len(it.stack)-1] = nil
485489
it.stack = it.stack[:len(it.stack)-1]
486490
}
487491

trie/iterator_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ import (
2929
"github.com/scroll-tech/go-ethereum/ethdb/memorydb"
3030
)
3131

32+
func TestEmptyIterator(t *testing.T) {
33+
trie := newEmpty()
34+
iter := trie.NodeIterator(nil)
35+
36+
seen := make(map[string]struct{})
37+
for iter.Next(true) {
38+
seen[string(iter.Path())] = struct{}{}
39+
}
40+
if len(seen) != 0 {
41+
t.Fatal("Unexpected trie node iterated")
42+
}
43+
}
44+
3245
func TestIterator(t *testing.T) {
3346
trie := newEmpty()
3447
vals := []struct{ k, v string }{

trie/trie.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,13 @@ import (
2525

2626
"github.com/scroll-tech/go-ethereum/common"
2727
"github.com/scroll-tech/go-ethereum/core/types"
28-
"github.com/scroll-tech/go-ethereum/crypto"
2928
"github.com/scroll-tech/go-ethereum/log"
3029
"github.com/scroll-tech/go-ethereum/rlp"
3130
)
3231

3332
var (
3433
// emptyRoot is the known root hash of an empty trie.
3534
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
36-
37-
// emptyState is the known hash of an empty state trie entry.
38-
emptyState = crypto.Keccak256Hash(nil)
3935
)
4036

4137
// LeafCallback is a callback type invoked when a trie operation reaches a leaf

0 commit comments

Comments
 (0)