Skip to content

Commit 0a9b251

Browse files
rjl493456442cp-wjhan
authored andcommitted
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
1 parent 67a093e commit 0a9b251

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

trie/iterator.go

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

156156
func newNodeIterator(trie *Trie, start []byte) NodeIterator {
157-
if trie.Hash() == emptyState {
158-
return new(nodeIterator)
157+
if trie.Hash() == emptyRoot {
158+
return &nodeIterator{
159+
trie: trie,
160+
err: errIteratorEnd,
161+
}
159162
}
160163
it := &nodeIterator{trie: trie}
161164
it.err = it.seek(start)
@@ -425,7 +428,7 @@ func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node,
425428
func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) {
426429
switch node := parent.node.(type) {
427430
case *fullNode:
428-
//Full node, move to the first non-nil child.
431+
// Full node, move to the first non-nil child.
429432
if child, state, path, index := findChild(node, parent.index+1, it.path, ancestor); child != nil {
430433
parent.index = index - 1
431434
return state, path, true
@@ -503,8 +506,9 @@ func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []
503506
}
504507

505508
func (it *nodeIterator) pop() {
506-
parent := it.stack[len(it.stack)-1]
507-
it.path = it.path[:parent.pathlen]
509+
last := it.stack[len(it.stack)-1]
510+
it.path = it.path[:last.pathlen]
511+
it.stack[len(it.stack)-1] = nil
508512
it.stack = it.stack[:len(it.stack)-1]
509513
}
510514

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/ethereum/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 }{

0 commit comments

Comments
 (0)