Add WriteStateSnapshot #15

Merged
roysc merged 23 commits from with-iterator-tracker into main 2023-09-28 03:35:47 +00:00
Showing only changes of commit e6d312f98b - Show all commits

View File

@ -45,37 +45,33 @@ func TestSymmetricDifferenceIterator(t *testing.T) {
t.Run("with no difference", func(t *testing.T) { t.Run("with no difference", func(t *testing.T) {
db := trie.NewDatabase(rawdb.NewMemoryDatabase()) db := trie.NewDatabase(rawdb.NewMemoryDatabase())
triea := trie.NewEmpty(db) triea := trie.NewEmpty(db)
di, count := utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), triea.NodeIterator(nil)) di, aux := utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), triea.NodeIterator(nil))
for di.Next(true) { for di.Next(true) {
t.Errorf("iterator should not yield any elements") t.Errorf("iterator should not yield any elements")
} }
assert.Equal(t, 0, *count) assert.Equal(t, 0, aux.Count())
triea.MustUpdate([]byte("foo"), []byte("bar")) triea.MustUpdate([]byte("foo"), []byte("bar"))
di, count = utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), triea.NodeIterator(nil)) di, aux = utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), triea.NodeIterator(nil))
for di.Next(true) { for di.Next(true) {
t.Errorf("iterator should not yield any elements") t.Errorf("iterator should not yield any elements")
} }
assert.Equal(t, 2, *count) // two nodes visited: the leaf (value) and its parent
assert.Equal(t, 2, aux.Count())
// TODO will fail until fixed https://github.com/ethereum/go-ethereum/pull/27838
trieb := trie.NewEmpty(db) trieb := trie.NewEmpty(db)
di, count = utils.NewSymmetricDifferenceIterator( di, aux = utils.NewSymmetricDifferenceIterator(triea.NodeIterator([]byte("jars")), trieb.NodeIterator(nil))
triea.NodeIterator([]byte("jars")),
trieb.NodeIterator(nil))
for di.Next(true) { for di.Next(true) {
t.Errorf("iterator should not yield any elements, but got key %s", di.Path()) t.Errorf("iterator should not yield any elements")
} }
assert.Equal(t, 0, *count) assert.Equal(t, 0, aux.Count())
// // TODO will fail until merged: https://github.com/ethereum/go-ethereum/pull/27838 // TODO will fail until merged: https://github.com/ethereum/go-ethereum/pull/27838
// di, count = utils.NewSymmetricDifferenceIterator( // di, aux = utils.NewSymmetricDifferenceIterator(triea.NodeIterator([]byte("food")), trieb.NodeIterator(nil))
// triea.NodeIterator([]byte("food")),
// trieb.NodeIterator(nil))
// for di.Next(true) { // for di.Next(true) {
// t.Errorf("iterator should not yield any elements, but got key %s", di.Path()) // t.Errorf("iterator should not yield any elements")
// } // }
// assert.Equal(t, 0, *count) // assert.Equal(t, 0, aux.Count())
}) })
t.Run("small difference", func(t *testing.T) { t.Run("small difference", func(t *testing.T) {
@ -86,32 +82,32 @@ func TestSymmetricDifferenceIterator(t *testing.T) {
trieb := trie.NewEmpty(dbb) trieb := trie.NewEmpty(dbb)
trieb.MustUpdate([]byte("foo"), []byte("bar")) trieb.MustUpdate([]byte("foo"), []byte("bar"))
di, count := utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), trieb.NodeIterator(nil)) di, aux := utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), trieb.NodeIterator(nil))
leaves := 0 leaves := 0
for di.Next(true) { for di.Next(true) {
if di.Leaf() { if di.Leaf() {
assert.False(t, di.CommonPath()) assert.False(t, aux.CommonPath())
assert.Equal(t, "foo", string(di.LeafKey())) assert.Equal(t, "foo", string(di.LeafKey()))
assert.Equal(t, "bar", string(di.LeafBlob())) assert.Equal(t, "bar", string(di.LeafBlob()))
leaves++ leaves++
} }
} }
assert.Equal(t, 1, leaves) assert.Equal(t, 1, leaves)
assert.Equal(t, 2, *count) assert.Equal(t, 2, aux.Count())
trieb.MustUpdate([]byte("quux"), []byte("bars")) trieb.MustUpdate([]byte("quux"), []byte("bars"))
di, count = utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), trieb.NodeIterator([]byte("quux"))) di, aux = utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), trieb.NodeIterator([]byte("quux")))
leaves = 0 leaves = 0
for di.Next(true) { for di.Next(true) {
if di.Leaf() { if di.Leaf() {
assert.False(t, di.CommonPath()) assert.False(t, aux.CommonPath())
assert.Equal(t, "quux", string(di.LeafKey())) assert.Equal(t, "quux", string(di.LeafKey()))
assert.Equal(t, "bars", string(di.LeafBlob())) assert.Equal(t, "bars", string(di.LeafBlob()))
leaves++ leaves++
} }
} }
assert.Equal(t, 1, leaves) assert.Equal(t, 1, leaves)
assert.Equal(t, 1, *count) assert.Equal(t, 1, aux.Count())
}) })
dba := trie.NewDatabase(rawdb.NewMemoryDatabase()) dba := trie.NewDatabase(rawdb.NewMemoryDatabase())
@ -128,20 +124,20 @@ func TestSymmetricDifferenceIterator(t *testing.T) {
onlyA := make(map[string]string) onlyA := make(map[string]string)
onlyB := make(map[string]string) onlyB := make(map[string]string)
var deletions, creations []string var deletions, creations []string
it, _ := utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), trieb.NodeIterator(nil)) it, aux := utils.NewSymmetricDifferenceIterator(triea.NodeIterator(nil), trieb.NodeIterator(nil))
for it.Next(true) { for it.Next(true) {
if !it.Leaf() { if !it.Leaf() {
continue continue
} }
key, value := string(it.LeafKey()), string(it.LeafBlob()) key, value := string(it.LeafKey()), string(it.LeafBlob())
if it.FromA() { if aux.FromA() {
onlyA[key] = value onlyA[key] = value
if !it.CommonPath() { if !aux.CommonPath() {
deletions = append(deletions, key) deletions = append(deletions, key)
} }
} else { } else {
onlyB[key] = value onlyB[key] = value
if !it.CommonPath() { if !aux.CommonPath() {
creations = append(creations, key) creations = append(creations, key)
} }
} }
@ -209,10 +205,10 @@ func TestCompareDifferenceIterators(t *testing.T) {
pathsA = append(pathsA, itAonly.Path()) pathsA = append(pathsA, itAonly.Path())
} }
itSym, _ := utils.NewSymmetricDifferenceIterator(treeA.NodeIterator(nil), treeB.NodeIterator(nil)) itSym, aux := utils.NewSymmetricDifferenceIterator(treeA.NodeIterator(nil), treeB.NodeIterator(nil))
var idxA, idxB int var idxA, idxB int
for itSym.Next(true) { for itSym.Next(true) {
if itSym.FromA() { if aux.FromA() {
require.Equal(t, pathsA[idxA], itSym.Path()) require.Equal(t, pathsA[idxA], itSym.Path())
idxA++ idxA++
} else { } else {