diff --git a/trie/verkle_iterator.go b/trie/verkle_iterator.go index 9c57e5da1956..72e309622445 100644 --- a/trie/verkle_iterator.go +++ b/trie/verkle_iterator.go @@ -142,7 +142,18 @@ func (it *verkleNodeIterator) Parent() common.Hash { // Callers must not retain references to the return value after calling Next. // For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. func (it *verkleNodeIterator) Path() []byte { - panic("not completely implemented") + if it.Leaf() { + return it.LeafKey() + } + var path []byte + for i, state := range it.stack { + // skip the last byte + if i <= len(it.stack)-1 { + break + } + path = append(path, byte(state.Index)) + } + return path } func (it *verkleNodeIterator) NodeBlob() []byte { @@ -204,5 +215,5 @@ func (it *verkleNodeIterator) LeafProof() [][]byte { // making trie.Database an interface and wrapping at that level. It's a huge // refactor, but it could be worth it if another occurrence arises. func (it *verkleNodeIterator) AddResolver(ethdb.KeyValueReader) { - panic("not completely implemented") + // Not implemented, but should not panic } diff --git a/trie/verkle_iterator_test.go b/trie/verkle_iterator_test.go new file mode 100644 index 000000000000..45180a7b4d7f --- /dev/null +++ b/trie/verkle_iterator_test.go @@ -0,0 +1,65 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/trie/utils" + "github.com/gballet/go-verkle" +) + +func TestVerkleIterator(t *testing.T) { + trie := NewVerkleTrie(verkle.New(), NewDatabase(rawdb.NewMemoryDatabase()), utils.NewPointCache()) + account0 := &types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(2), + Root: emptyRoot, + CodeHash: nil, + } + // NOTE: the code size isn't written to the trie via TryUpdateAccount + // so it will be missing from the test nodes. + trie.TryUpdateAccount(zero[:], account0) + account1 := &types.StateAccount{ + Nonce: 1337, + Balance: big.NewInt(2000), + Root: emptyRoot, + CodeHash: nil, + } + // This address is meant to hash to a value that has the same first byte as 0xbf + var clash = common.Hex2Bytes("69fd8034cdb20934dedffa7dccb4fb3b8062a8be") + trie.TryUpdateAccount(clash, account1) + + // Manually go over every node to check that we get all + // the correct nodes. + it := trie.NodeIterator(nil) + var leafcount int + for it.Next(true) { + t.Logf("Node: %x", it.Path()) + if it.Leaf() { + leafcount++ + t.Logf("\tLeaf: %x", it.LeafKey()) + } + } + if leafcount != 6 { + t.Fatalf("invalid leaf count: %d != 6", leafcount) + } +}