trie, core/state: Add 'children' parameter to TrieIterator.next()

This commit is contained in:
Nick Johnson 2017-01-16 17:37:35 +00:00
parent 71a442ffbc
commit 4d7c0cae72
4 changed files with 16 additions and 10 deletions

View file

@ -80,7 +80,7 @@ func (it *NodeIterator) step() error {
}
// If we had data nodes previously, we surely have at least state nodes
if it.dataIt != nil {
if cont := it.dataIt.Next(); !cont {
if cont := it.dataIt.Next(true); !cont {
if it.dataIt.Error != nil {
return it.dataIt.Error
}
@ -94,7 +94,7 @@ func (it *NodeIterator) step() error {
return nil
}
// Step to the next state trie node, terminating if we're out of nodes
if cont := it.stateIt.Next(); !cont {
if cont := it.stateIt.Next(true); !cont {
if it.stateIt.Error != nil {
return it.stateIt.Error
}
@ -120,7 +120,7 @@ func (it *NodeIterator) step() error {
return err
}
it.dataIt = trie.NewNodeIterator(dataTrie)
if !it.dataIt.Next() {
if !it.dataIt.Next(true) {
it.dataIt = nil
}
if !bytes.Equal(account.CodeHash, emptyCodeHash) {

View file

@ -40,7 +40,7 @@ func NewIterator(trie *Trie) *Iterator {
// Next moves the iterator forward one key-value entry.
func (it *Iterator) Next() bool {
for it.nodeIt.Next() {
for it.nodeIt.Next(true) {
if it.nodeIt.Leaf {
it.Key = it.makeKey()
it.Value = it.nodeIt.LeafBlob
@ -104,14 +104,15 @@ func NewNodeIterator(trie *Trie) *NodeIterator {
// Next moves the iterator to the next node, returning whether there are any
// further nodes. In case of an internal error this method returns false and
// sets the Error field to the encountered failure.
func (it *NodeIterator) Next() bool {
// sets the Error field to the encountered failure. If `children` is false,
// skips iterating over any subnodes of the current node.
func (it *NodeIterator) Next(children bool) bool {
// If the iterator failed previously, don't do anything
if it.Error != nil {
return false
}
// Otherwise step forward with the iterator and report any errors
if err := it.step(); err != nil {
if err := it.step(children); err != nil {
it.Error = err
return false
}
@ -119,7 +120,7 @@ func (it *NodeIterator) Next() bool {
}
// step moves the iterator to the next node of the trie.
func (it *NodeIterator) step() error {
func (it *NodeIterator) step(children bool) error {
if it.trie == nil {
// Abort if we reached the end of the iteration
return nil
@ -135,6 +136,11 @@ func (it *NodeIterator) step() error {
return nil
}
if !children {
// If we're skipping children, pop the current node first
it.stack = it.stack[:len(it.stack)-1]
}
// Continue iteration to the next child
for {
if len(it.stack) == 0 {

View file

@ -101,7 +101,7 @@ func TestNodeIteratorCoverage(t *testing.T) {
// Gather all the node hashes found by the iterator
hashes := make(map[common.Hash]struct{})
for it := NewNodeIterator(trie); it.Next(); {
for it := NewNodeIterator(trie); it.Next(true); {
if it.Hash != (common.Hash{}) {
hashes[it.Hash] = struct{}{}
}

View file

@ -81,7 +81,7 @@ func checkTrieConsistency(db Database, root common.Hash) error {
return nil // // Consider a non existent state consistent
}
it := NewNodeIterator(trie)
for it.Next() {
for it.Next(true) {
}
return it.Error
}