mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
core/state/snapshot: fix binary iterator
This commit is contained in:
parent
e9fc202fa1
commit
5fcf093668
2 changed files with 38 additions and 27 deletions
|
|
@ -117,33 +117,47 @@ func (dl *diffLayer) initBinaryStorageIterator(account, seek common.Hash) Iterat
|
||||||
// or an error if iteration failed for some reason (e.g. root being iterated
|
// or an error if iteration failed for some reason (e.g. root being iterated
|
||||||
// becomes stale and garbage collected).
|
// becomes stale and garbage collected).
|
||||||
func (it *binaryIterator) Next() bool {
|
func (it *binaryIterator) Next() bool {
|
||||||
|
for {
|
||||||
|
ok := it.next()
|
||||||
|
if !ok {
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
if len(it.Account()) == 0 && len(it.Slot()) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *binaryIterator) next() bool {
|
||||||
if it.aDone && it.bDone {
|
if it.aDone && it.bDone {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
first:
|
for {
|
||||||
if it.aDone {
|
if it.aDone {
|
||||||
it.k = it.b.Hash()
|
it.k = it.b.Hash()
|
||||||
|
it.bDone = !it.b.Next()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if it.bDone {
|
||||||
|
it.k = it.a.Hash()
|
||||||
|
it.aDone = !it.a.Next()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
nextA, nextB := it.a.Hash(), it.b.Hash()
|
||||||
|
if diff := bytes.Compare(nextA[:], nextB[:]); diff < 0 {
|
||||||
|
it.aDone = !it.a.Next()
|
||||||
|
it.k = nextA
|
||||||
|
return true
|
||||||
|
} else if diff == 0 {
|
||||||
|
// Now we need to advance one of them
|
||||||
|
it.aDone = !it.a.Next()
|
||||||
|
continue
|
||||||
|
}
|
||||||
it.bDone = !it.b.Next()
|
it.bDone = !it.b.Next()
|
||||||
|
it.k = nextB
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if it.bDone {
|
|
||||||
it.k = it.a.Hash()
|
|
||||||
it.aDone = !it.a.Next()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
nextA, nextB := it.a.Hash(), it.b.Hash()
|
|
||||||
if diff := bytes.Compare(nextA[:], nextB[:]); diff < 0 {
|
|
||||||
it.aDone = !it.a.Next()
|
|
||||||
it.k = nextA
|
|
||||||
return true
|
|
||||||
} else if diff == 0 {
|
|
||||||
// Now we need to advance one of them
|
|
||||||
it.aDone = !it.a.Next()
|
|
||||||
goto first
|
|
||||||
}
|
|
||||||
it.bDone = !it.b.Next()
|
|
||||||
it.k = nextB
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error returns any failure that occurred during iteration, which might have
|
// Error returns any failure that occurred during iteration, which might have
|
||||||
|
|
|
||||||
|
|
@ -99,9 +99,6 @@ func TestStorageIteratorBasics(t *testing.T) {
|
||||||
for account := range accounts {
|
for account := range accounts {
|
||||||
it, _ := diffLayer.StorageIterator(account, common.Hash{})
|
it, _ := diffLayer.StorageIterator(account, common.Hash{})
|
||||||
verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
|
verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
|
||||||
|
|
||||||
it = diffLayer.newBinaryStorageIterator(account, common.Hash{})
|
|
||||||
verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
|
|
||||||
}
|
}
|
||||||
|
|
||||||
diskLayer := diffToDisk(diffLayer)
|
diskLayer := diffToDisk(diffLayer)
|
||||||
|
|
@ -569,7 +566,7 @@ func TestAccountIteratorFlattening(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("binary", func(t *testing.T) {
|
t.Run("binary", func(t *testing.T) {
|
||||||
testAccountIteratorFlattening(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
testAccountIteratorFlattening(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||||
return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -771,7 +768,7 @@ func TestAccountIteratorDeletions(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("binary", func(t *testing.T) {
|
t.Run("binary", func(t *testing.T) {
|
||||||
testAccountIteratorDeletions(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
testAccountIteratorDeletions(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
|
||||||
return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(common.Hash{})
|
return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -833,7 +830,7 @@ func TestStorageIteratorDeletions(t *testing.T) {
|
||||||
})
|
})
|
||||||
t.Run("binary", func(t *testing.T) {
|
t.Run("binary", func(t *testing.T) {
|
||||||
testStorageIteratorDeletions(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
|
testStorageIteratorDeletions(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
|
||||||
return snaps.layers[root].(*diffLayer).newBinaryStorageIterator(account, common.Hash{})
|
return snaps.layers[root].(*diffLayer).newBinaryStorageIterator(account, seek)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue