trie, les, tests, core: implement trie tracer (#24403)
Trie tracer is an auxiliary tool to capture all deleted nodes which can't be captured by trie.Committer. The deleted nodes can be removed from the disk later.
This commit is contained in:
@ -32,6 +32,7 @@ import (
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
@ -53,7 +54,7 @@ func newEmpty() *Trie {
|
||||
}
|
||||
|
||||
func TestEmptyTrie(t *testing.T) {
|
||||
var trie Trie
|
||||
trie, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
|
||||
res := trie.Hash()
|
||||
exp := emptyRoot
|
||||
if res != exp {
|
||||
@ -62,7 +63,7 @@ func TestEmptyTrie(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNull(t *testing.T) {
|
||||
var trie Trie
|
||||
trie, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
|
||||
key := make([]byte, 32)
|
||||
value := []byte("test")
|
||||
trie.Update(key, value)
|
||||
@ -374,6 +375,7 @@ const (
|
||||
opHash
|
||||
opReset
|
||||
opItercheckhash
|
||||
opNodeDiff
|
||||
opMax // boundary value, not an actual op
|
||||
)
|
||||
|
||||
@ -408,10 +410,13 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value {
|
||||
}
|
||||
|
||||
func runRandTest(rt randTest) bool {
|
||||
triedb := NewDatabase(memorydb.New())
|
||||
|
||||
tr, _ := New(common.Hash{}, triedb)
|
||||
values := make(map[string]string) // tracks content of the trie
|
||||
var (
|
||||
triedb = NewDatabase(memorydb.New())
|
||||
tr, _ = New(common.Hash{}, triedb)
|
||||
values = make(map[string]string) // tracks content of the trie
|
||||
origTrie, _ = New(common.Hash{}, triedb)
|
||||
)
|
||||
tr.tracer = newTracer()
|
||||
|
||||
for i, step := range rt {
|
||||
// fmt.Printf("{op: %d, key: common.Hex2Bytes(\"%x\"), value: common.Hex2Bytes(\"%x\")}, // step %d\n",
|
||||
@ -432,6 +437,7 @@ func runRandTest(rt randTest) bool {
|
||||
}
|
||||
case opCommit:
|
||||
_, _, rt[i].err = tr.Commit(nil)
|
||||
origTrie = tr.Copy()
|
||||
case opHash:
|
||||
tr.Hash()
|
||||
case opReset:
|
||||
@ -446,6 +452,9 @@ func runRandTest(rt randTest) bool {
|
||||
return false
|
||||
}
|
||||
tr = newtr
|
||||
tr.tracer = newTracer()
|
||||
|
||||
origTrie = tr.Copy()
|
||||
case opItercheckhash:
|
||||
checktr, _ := New(common.Hash{}, triedb)
|
||||
it := NewIterator(tr.NodeIterator(nil))
|
||||
@ -455,6 +464,59 @@ func runRandTest(rt randTest) bool {
|
||||
if tr.Hash() != checktr.Hash() {
|
||||
rt[i].err = fmt.Errorf("hash mismatch in opItercheckhash")
|
||||
}
|
||||
case opNodeDiff:
|
||||
var (
|
||||
inserted = tr.tracer.insertList()
|
||||
deleted = tr.tracer.deleteList()
|
||||
origIter = origTrie.NodeIterator(nil)
|
||||
curIter = tr.NodeIterator(nil)
|
||||
origSeen = make(map[string]struct{})
|
||||
curSeen = make(map[string]struct{})
|
||||
)
|
||||
for origIter.Next(true) {
|
||||
if origIter.Leaf() {
|
||||
continue
|
||||
}
|
||||
origSeen[string(origIter.Path())] = struct{}{}
|
||||
}
|
||||
for curIter.Next(true) {
|
||||
if curIter.Leaf() {
|
||||
continue
|
||||
}
|
||||
curSeen[string(curIter.Path())] = struct{}{}
|
||||
}
|
||||
var (
|
||||
insertExp = make(map[string]struct{})
|
||||
deleteExp = make(map[string]struct{})
|
||||
)
|
||||
for path := range curSeen {
|
||||
_, present := origSeen[path]
|
||||
if !present {
|
||||
insertExp[path] = struct{}{}
|
||||
}
|
||||
}
|
||||
for path := range origSeen {
|
||||
_, present := curSeen[path]
|
||||
if !present {
|
||||
deleteExp[path] = struct{}{}
|
||||
}
|
||||
}
|
||||
if len(insertExp) != len(inserted) {
|
||||
rt[i].err = fmt.Errorf("insert set mismatch")
|
||||
}
|
||||
if len(deleteExp) != len(deleted) {
|
||||
rt[i].err = fmt.Errorf("delete set mismatch")
|
||||
}
|
||||
for _, insert := range inserted {
|
||||
if _, present := insertExp[string(insert)]; !present {
|
||||
rt[i].err = fmt.Errorf("missing inserted node")
|
||||
}
|
||||
}
|
||||
for _, del := range deleted {
|
||||
if _, present := deleteExp[string(del)]; !present {
|
||||
rt[i].err = fmt.Errorf("missing deleted node")
|
||||
}
|
||||
}
|
||||
}
|
||||
// Abort the test on error.
|
||||
if rt[i].err != nil {
|
||||
@ -481,7 +543,7 @@ func BenchmarkUpdateLE(b *testing.B) { benchUpdate(b, binary.LittleEndian) }
|
||||
const benchElemCount = 20000
|
||||
|
||||
func benchGet(b *testing.B, commit bool) {
|
||||
trie := new(Trie)
|
||||
trie, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
|
||||
if commit {
|
||||
_, tmpdb := tempDB()
|
||||
trie, _ = New(common.Hash{}, tmpdb)
|
||||
|
Reference in New Issue
Block a user