forked from cerc-io/plugeth
core, eth, les, tests, trie: abstract node scheme (#25532)
This PR introduces a node scheme abstraction. The interface is only implemented by `hashScheme` at the moment, but will be extended by `pathScheme` very soon. Apart from that, a few changes are also included which is worth mentioning: - port the changes in the stacktrie, tracking the path prefix of nodes during commit - use ethdb.Database for constructing trie.Database. This is not necessary right now, but it is required for path-based used to open reverse diff freezer
This commit is contained in:
@@ -107,10 +107,7 @@ func (t *BlockTest) Run(snapshotter bool) error {
|
||||
// import pre accounts & construct test genesis block & state root
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
gspec := t.genesis(config)
|
||||
gblock, err := gspec.Commit(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gblock := gspec.MustCommit(db)
|
||||
if gblock.Hash() != t.json.Genesis.Hash {
|
||||
return fmt.Errorf("genesis block hash doesn't match test: computed=%x, test=%x", gblock.Hash().Bytes()[:6], t.json.Genesis.Hash[:6])
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ import (
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"golang.org/x/crypto/sha3"
|
||||
@@ -143,11 +146,14 @@ func Debug(data []byte) int {
|
||||
func (f *fuzzer) fuzz() int {
|
||||
// This spongeDb is used to check the sequence of disk-db-writes
|
||||
var (
|
||||
spongeA = &spongeDb{sponge: sha3.NewLegacyKeccak256()}
|
||||
dbA = trie.NewDatabase(spongeA)
|
||||
trieA = trie.NewEmpty(dbA)
|
||||
spongeB = &spongeDb{sponge: sha3.NewLegacyKeccak256()}
|
||||
trieB = trie.NewStackTrie(spongeB)
|
||||
spongeA = &spongeDb{sponge: sha3.NewLegacyKeccak256()}
|
||||
dbA = trie.NewDatabase(rawdb.NewDatabase(spongeA))
|
||||
trieA = trie.NewEmpty(dbA)
|
||||
spongeB = &spongeDb{sponge: sha3.NewLegacyKeccak256()}
|
||||
dbB = trie.NewDatabase(rawdb.NewDatabase(spongeB))
|
||||
trieB = trie.NewStackTrie(func(owner common.Hash, path []byte, hash common.Hash, blob []byte) {
|
||||
dbB.Scheme().WriteTrieNode(spongeB, owner, path, hash, blob)
|
||||
})
|
||||
vals kvs
|
||||
useful bool
|
||||
maxElements = 10000
|
||||
@@ -206,5 +212,48 @@ func (f *fuzzer) fuzz() int {
|
||||
if !bytes.Equal(sumA, sumB) {
|
||||
panic(fmt.Sprintf("sequence differ: (trie) %x != %x (stacktrie)", sumA, sumB))
|
||||
}
|
||||
|
||||
// Ensure all the nodes are persisted correctly
|
||||
var (
|
||||
nodeset = make(map[string][]byte) // path -> blob
|
||||
trieC = trie.NewStackTrie(func(owner common.Hash, path []byte, hash common.Hash, blob []byte) {
|
||||
if crypto.Keccak256Hash(blob) != hash {
|
||||
panic("invalid node blob")
|
||||
}
|
||||
if owner != (common.Hash{}) {
|
||||
panic("invalid node owner")
|
||||
}
|
||||
nodeset[string(path)] = common.CopyBytes(blob)
|
||||
})
|
||||
checked int
|
||||
)
|
||||
for _, kv := range vals {
|
||||
trieC.Update(kv.k, kv.v)
|
||||
}
|
||||
rootC, _ := trieC.Commit()
|
||||
if rootA != rootC {
|
||||
panic(fmt.Sprintf("roots differ: (trie) %x != %x (stacktrie)", rootA, rootC))
|
||||
}
|
||||
trieA, _ = trie.New(trie.TrieID(rootA), dbA)
|
||||
iterA := trieA.NodeIterator(nil)
|
||||
for iterA.Next(true) {
|
||||
if iterA.Hash() == (common.Hash{}) {
|
||||
if _, present := nodeset[string(iterA.Path())]; present {
|
||||
panic("unexpected tiny node")
|
||||
}
|
||||
continue
|
||||
}
|
||||
nodeBlob, present := nodeset[string(iterA.Path())]
|
||||
if !present {
|
||||
panic("missing node")
|
||||
}
|
||||
if !bytes.Equal(nodeBlob, iterA.NodeBlob()) {
|
||||
panic("node blob is not matched")
|
||||
}
|
||||
checked += 1
|
||||
}
|
||||
if checked != len(nodeset) {
|
||||
panic("node number is not matched")
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
)
|
||||
|
||||
@@ -139,7 +139,7 @@ func Fuzz(input []byte) int {
|
||||
}
|
||||
|
||||
func runRandTest(rt randTest) error {
|
||||
triedb := trie.NewDatabase(memorydb.New())
|
||||
triedb := trie.NewDatabase(rawdb.NewMemoryDatabase())
|
||||
|
||||
tr := trie.NewEmpty(triedb)
|
||||
values := make(map[string]string) // tracks content of the trie
|
||||
|
||||
Reference in New Issue
Block a user