diff --git a/go.mod b/go.mod index 4b667ca..e05b0e3 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/cerc-io/plugeth-statediff go 1.19 require ( + github.com/cerc-io/eth-test-data v0.1.0 github.com/ethereum/go-ethereum v1.11.6 github.com/georgysavva/scany v0.2.9 github.com/golang/mock v1.6.0 @@ -122,6 +123,7 @@ require ( ) replace ( + github.com/cerc-io/eth-test-data => git.vdb.to/cerc-io/eth-test-data v0.1.1 github.com/ethereum/go-ethereum => git.vdb.to/cerc-io/plugeth v0.0.0-20230808125822-691dc334fab1 github.com/openrelayxyz/plugeth-utils => git.vdb.to/cerc-io/plugeth-utils v0.0.0-20230706160122-cd41de354c46 ) diff --git a/go.sum b/go.sum index 2ebf04f..149fe54 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +git.vdb.to/cerc-io/eth-test-data v0.1.1 h1:J0dO1ozKdimMgvxO1rubTgLrOp7vljRm1g0OfTaUp7k= +git.vdb.to/cerc-io/eth-test-data v0.1.1/go.mod h1:8BypMWF/Xz4CGSn3ad4yXz0deCFFk1DxujOCU8+ydGE= git.vdb.to/cerc-io/plugeth v0.0.0-20230808125822-691dc334fab1 h1:KLjxHwp9Zp7xhECccmJS00RiL+VwTuUGLU7qeIctg8g= git.vdb.to/cerc-io/plugeth v0.0.0-20230808125822-691dc334fab1/go.mod h1:cYXZu70+6xmDgIgrTD81GPasv16piiAFJnKyAbwVPMU= git.vdb.to/cerc-io/plugeth-utils v0.0.0-20230706160122-cd41de354c46 h1:KYcbbne/RXd7AuxbUd/3hgk1jPN+33k2CKiNsUsMCC0= diff --git a/test_helpers/util.go b/test_helpers/util.go index 30c7530..95ccfdf 100644 --- a/test_helpers/util.go +++ b/test_helpers/util.go @@ -6,7 +6,8 @@ import ( "github.com/cerc-io/plugeth-statediff/utils/log" ) -// The geth sync logs are noisy, it can be useful to silence them +// SilenceLogs silences the geth logs and sets the plugin test log level to "warning" +// The geth sync logs are noisy, so it can be nice to silence them. func SilenceLogs() { geth_log.Root().SetHandler(geth_log.DiscardHandler()) log.TestLogger.SetLevel(2) diff --git a/utils/iterator_test.go b/utils/iterator_test.go index 92c461e..3a97939 100644 --- a/utils/iterator_test.go +++ b/utils/iterator_test.go @@ -3,11 +3,17 @@ package utils_test import ( "testing" - "github.com/cerc-io/plugeth-statediff/utils" + "github.com/cerc-io/eth-test-data/fixture/mainnet" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/trie" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cerc-io/plugeth-statediff/test_helpers" + "github.com/cerc-io/plugeth-statediff/utils" ) type kvs struct{ k, v string } @@ -169,3 +175,52 @@ func TestSymmetricDifferenceIterator(t *testing.T) { assert.Equal(t, expectedDeletions, deletions) assert.Equal(t, expectedCreations, creations) } + +// compare the paths traversed by the geth difference iterator and symmetric difference iterator +// within a sample of mainnet data. +func TestCompareDifferenceIterators(t *testing.T) { + test_helpers.SilenceLogs() + + db := rawdb.NewMemoryDatabase() + core.DefaultGenesisBlock().MustCommit(db) + blocks := mainnet.LoadBlocks(2) + chain, _ := core.NewBlockChain(db, nil, nil, nil, ethash.NewFaker(), vm.Config{}, nil, nil) + _, err := chain.InsertChain(blocks[1:]) + if err != nil { + t.Fatal(err) + } + treeA, err := chain.StateCache().OpenTrie(blocks[1].Root()) + if err != nil { + t.Fatal(err) + } + treeB, err := chain.StateCache().OpenTrie(blocks[2].Root()) + if err != nil { + t.Fatal(err) + } + + // collect the paths of nodes exclusive to A and B separately, then make sure the symmetric + // iterator produces the same sets + var pathsA, pathsB [][]byte + itBonly, _ := trie.NewDifferenceIterator(treeA.NodeIterator(nil), treeB.NodeIterator(nil)) + for itBonly.Next(true) { + pathsB = append(pathsB, itBonly.Path()) + } + itAonly, _ := trie.NewDifferenceIterator(treeB.NodeIterator(nil), treeA.NodeIterator(nil)) + for itAonly.Next(true) { + pathsA = append(pathsA, itAonly.Path()) + } + + itSym, _ := utils.NewSymmetricDifferenceIterator(treeA.NodeIterator(nil), treeB.NodeIterator(nil)) + var idxA, idxB int + for itSym.Next(true) { + if itSym.FromA() { + require.Equal(t, pathsA[idxA], itSym.Path()) + idxA++ + } else { + require.Equal(t, pathsB[idxB], itSym.Path()) + idxB++ + } + } + require.Equal(t, len(pathsA), idxA) + require.Equal(t, len(pathsB), idxB) +}