erigon-pulse/turbo/trie/witnessdb_sub_trie_loader_test.go
Igor Mandrigin adf52465e3
move ./trie to ./turbo/trie (#1114)
Useful for minimizing merge conflicts when rebasing new geth
2020-09-14 11:33:39 +01:00

124 lines
2.6 KiB
Go

package trie
import (
"bytes"
"fmt"
"testing"
)
type testWitnessStorage []byte
func (s *testWitnessStorage) GetWitnessesForBlock(_ uint64, _ uint32) ([]byte, error) {
return []byte(*s), nil
}
func generateKey(i int) []byte {
return []byte(fmt.Sprintf("key-number-%05d", i))
}
func generateValue(i int) []byte {
return []byte(fmt.Sprintf("value-number-%05d", i))
}
func buildTestTrie(numberOfNodes int) *Trie {
trie := New(EmptyRoot)
for i := 0; i < numberOfNodes; i++ {
trie.Update(generateKey(i), generateValue(i))
}
return trie
}
func TestRebuildTrie(t *testing.T) {
trie1 := buildTestTrie(0)
trie2 := buildTestTrie(10)
trie3 := buildTestTrie(100)
w1, err := extractWitnessFromRootNode(trie1.root, false, nil)
if err != nil {
t.Error(err)
}
w2, err := extractWitnessFromRootNode(trie2.root, false, nil)
if err != nil {
t.Error(err)
}
w3, err := extractWitnessFromRootNode(trie3.root, false, nil)
if err != nil {
t.Error(err)
}
var buff bytes.Buffer
_, err = w1.WriteTo(&buff)
if err != nil {
t.Error(err)
}
err = buff.WriteByte(byte(OpNewTrie))
if err != nil {
t.Error(err)
}
_, err = w2.WriteTo(&buff)
if err != nil {
t.Error(err)
}
err = buff.WriteByte(byte(OpNewTrie))
if err != nil {
t.Error(err)
}
_, err = w3.WriteTo(&buff)
if err != nil {
t.Error(err)
}
storage := testWitnessStorage(buff.Bytes())
loadedTries := make([]*Trie, 3)
// it should ignore duplicate loaded requests
loader := NewWitnessDbSubTrieLoader()
subTries, pos, err := loader.LoadSubTries(&storage, 1, 1, 0, 2)
if err != nil {
t.Error(err)
}
currentTrie := 0
for i, root := range subTries.roots {
tr := New(subTries.Hashes[i])
tr.root = root
loadedTries[currentTrie] = tr
currentTrie++
}
// we also support partial resolution with continuation (for storage tries)
// so basically we first load accounts, then storages separately
// but we still want to keep one entry in a DB per block, so we store the last read position
// and then use it as a start
loader = NewWitnessDbSubTrieLoader()
subTries, _, err = loader.LoadSubTries(&storage, 1, 1, pos, 1)
if err != nil {
t.Error(err)
}
for i, root := range subTries.roots {
tr := New(subTries.Hashes[i])
tr.root = root
loadedTries[currentTrie] = tr
currentTrie++
}
if !bytes.Equal(loadedTries[0].Hash().Bytes(), trie1.Hash().Bytes()) {
t.Errorf("tries are different")
}
if !bytes.Equal(loadedTries[1].Hash().Bytes(), trie2.Hash().Bytes()) {
t.Errorf("tries are different")
}
if !bytes.Equal(loadedTries[2].Hash().Bytes(), trie3.Hash().Bytes()) {
t.Errorf("tries are different")
}
}