erigon-pulse/ethdb/boltdb_test.go
b00ris bcee4845dc
Thin history (#272)
* save state

* remove repair

* save state

* remove emptydb check

* save state

* add walkAsOf test

* add WalkAsOf and MultiWalkAsOf tests

* deployed contracts counter

* reference counter for contract code

* drop storage root&contract hash for changesets

* start incarnation is 1(save state)

* fix ReorgOverSelfDestruct test

* hack fix TestReorgOverSelfDestruct

* test benchmark

* cleanup

* remove useless debug

* remove print trie

* return remove subtrie call  to updateTrieRoot

* save state

* add mutation test

* remove useless test

* fix

* added mutation commit test

* rename experiment to thin history

* thin history mutation commit test

* fix ethdb tests

* getAsOf test

* add test&fix history index

* fix test

* make test for index search

* compute trie root incarnation fix

* tests fixes

* done job in case of panic

* fix lint

* fix&test for bad incarnation

* fix initial incarnation for genesis

* fix lint

* fix changeset test

* fix storage ranges test

* fix lint

* move set incarnation to create contract

* add comment

Co-authored-by: ledgerwatch <akhounov@gmail.com>
Co-authored-by: Evgeny Danilenko <6655321@bk.ru>
2019-12-20 15:25:40 +03:00

333 lines
7.6 KiB
Go

package ethdb
import (
"fmt"
"github.com/davecgh/go-spew/spew"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/common/dbutils"
"reflect"
"strconv"
"testing"
)
func TestBoltDB_WalkAsOf1(t *testing.T) {
db := NewMemDatabase()
block2Expected := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block4Expected := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block6Expected := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
//create state and history
for i := uint8(1); i < 5; i++ {
key := dbutils.GenerateCompositeStorageKey(common.Hash{i}, uint64(1), common.Hash{i})
val := []byte("state " + strconv.Itoa(int(i)))
err := db.Put(dbutils.StorageBucket, key, val)
if err != nil {
t.Fatal(err)
}
err = block6Expected.Add(key, val)
if err != nil {
t.Fatal(err)
}
if i <= 2 {
err = block4Expected.Add(key, val)
if err != nil {
t.Fatal(err)
}
}
}
for i := uint8(1); i <= 7; i++ {
key := dbutils.GenerateCompositeStorageKey(common.Hash{i}, 1, common.Hash{i})
val := []byte("block 3 " + strconv.Itoa(int(i)))
err := db.PutS(
dbutils.StorageHistoryBucket,
key,
val,
3,
false,
)
if err != nil {
t.Fatal(err)
}
err = block2Expected.Add(key, val)
if err != nil {
t.Fatal(err)
}
}
for i := uint8(3); i <= 7; i++ {
key := dbutils.GenerateCompositeStorageKey(common.Hash{i}, 1, common.Hash{i})
val := []byte("block 5 " + strconv.Itoa(int(i)))
err := db.PutS(
dbutils.StorageHistoryBucket,
key,
val,
5,
false,
)
if err != nil {
t.Fatal(err)
}
err = block4Expected.Add(key, val)
if err != nil {
t.Fatal(err)
}
}
block2 := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block4 := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block6 := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
//walk and collect walkAsOf result
var err error
var startKey [72]byte
err = db.WalkAsOf(dbutils.StorageBucket, dbutils.StorageHistoryBucket, startKey[:], 0, 2, func(k []byte, v []byte) (b bool, e error) {
err = block2.Add(k, v)
if err != nil {
t.Fatal(err)
}
//fmt.Printf("%v - %v \n", common.BytesToHash(k).String(), string(v))
return true, nil
})
if err != nil {
t.Fatal(err)
}
err = db.WalkAsOf(dbutils.StorageBucket, dbutils.StorageHistoryBucket, startKey[:], 0, 4, func(k []byte, v []byte) (b bool, e error) {
err = block4.Add(k, v)
if err != nil {
t.Fatal(err)
}
//fmt.Printf("%v - %v \n", common.BytesToHash(k).String(), string(v))
return true, nil
})
if err != nil {
t.Fatal(err)
}
err = db.WalkAsOf(dbutils.StorageBucket, dbutils.StorageHistoryBucket, startKey[:], 0, 6, func(k []byte, v []byte) (b bool, e error) {
err = block6.Add(k, v)
if err != nil {
t.Fatal(err)
}
//fmt.Printf("%v - %v \n", common.BytesToHash(k).String(), string(v))
return true, nil
})
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(block2, block2Expected) {
spew.Dump("expected", block2Expected)
spew.Dump("current", block2)
t.Fatal("block 2 result is incorrect")
}
if !reflect.DeepEqual(block4, block4Expected) {
spew.Dump(block6)
t.Fatal("block 4 result is incorrect")
}
if !reflect.DeepEqual(block6, block6Expected) {
spew.Dump(block6)
t.Fatal("block 6 result is incorrect")
}
}
func TestBoltDB_MultiWalkAsOf(t *testing.T) {
db := NewMemDatabase()
block2Expected := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block4Expected := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block6Expected := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
//create state and history
for i := uint8(1); i < 5; i++ {
key := dbutils.GenerateCompositeStorageKey(common.Hash{i}, uint64(1), common.Hash{i})
val := []byte("state " + strconv.Itoa(int(i)))
err := db.Put(dbutils.StorageBucket, key, val)
if err != nil {
t.Fatal(err)
}
}
for i := uint8(1); i <= 7; i++ {
key := dbutils.GenerateCompositeStorageKey(common.Hash{i}, 1, common.Hash{i})
val := []byte("block 3 " + strconv.Itoa(int(i)))
err := db.PutS(
dbutils.StorageHistoryBucket,
key,
val,
3,
false,
)
if err != nil {
t.Fatal(err)
}
}
for i := uint8(3); i <= 7; i++ {
key := dbutils.GenerateCompositeStorageKey(common.Hash{i}, 1, common.Hash{i})
val := []byte("block 5 " + strconv.Itoa(int(i)))
err := db.PutS(
dbutils.StorageHistoryBucket,
key,
val,
5,
false,
)
if err != nil {
t.Fatal(err)
}
}
//walk and collect walkAsOf result
var err error
startKeys := [][]byte{
dbutils.GenerateCompositeStorageKey(common.Hash{1}, 1, common.Hash{1}),
dbutils.GenerateCompositeStorageKey(common.Hash{3}, 1, common.Hash{3}),
dbutils.GenerateCompositeStorageKey(common.Hash{7}, 1, common.Hash{7}),
}
fixedBits := []uint{
60,
60,
60,
}
err = block2Expected.MultiAdd([]dbutils.Change{
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{1}, 1, common.Hash{1}),
Value: []byte("block 3 " + strconv.Itoa(1)),
},
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{3}, 1, common.Hash{3}),
Value: []byte("block 3 " + strconv.Itoa(3)),
},
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{7}, 1, common.Hash{7}),
Value: []byte("block 3 " + strconv.Itoa(7)),
},
})
if err != nil {
t.Fatal(err)
}
err = block4Expected.MultiAdd([]dbutils.Change{
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{1}, 1, common.Hash{1}),
Value: []byte("state " + strconv.Itoa(1)),
},
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{3}, 1, common.Hash{3}),
Value: []byte("block 5 " + strconv.Itoa(3)),
},
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{7}, 1, common.Hash{7}),
Value: []byte("block 5 " + strconv.Itoa(7)),
},
})
if err != nil {
t.Fatal(err)
}
err = block6Expected.MultiAdd([]dbutils.Change{
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{1}, 1, common.Hash{1}),
Value: []byte("state " + strconv.Itoa(1)),
},
{
Key: dbutils.GenerateCompositeStorageKey(common.Hash{3}, 1, common.Hash{3}),
Value: []byte("state " + strconv.Itoa(3)),
},
})
if err != nil {
t.Fatal(err)
}
block2 := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block4 := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
block6 := &dbutils.ChangeSet{
Changes: make([]dbutils.Change, 0),
}
err = db.MultiWalkAsOf(dbutils.StorageBucket, dbutils.StorageHistoryBucket, startKeys, fixedBits, 2, func(idx int, k []byte, v []byte) error {
fmt.Printf("%v - %s - %s\n", idx, string(k), string(v))
err = block2.Add(k, v)
if err != nil {
t.Fatal(err)
}
return nil
})
if err != nil {
t.Fatal(err)
}
err = db.MultiWalkAsOf(dbutils.StorageBucket, dbutils.StorageHistoryBucket, startKeys, fixedBits, 4, func(idx int, k []byte, v []byte) error {
fmt.Printf("%v - %s - %s\n", idx, string(k), string(v))
err = block4.Add(k, v)
if err != nil {
t.Fatal(err)
}
return nil
})
if err != nil {
t.Fatal(err)
}
err = db.MultiWalkAsOf(dbutils.StorageBucket, dbutils.StorageHistoryBucket, startKeys, fixedBits, 6, func(idx int, k []byte, v []byte) error {
fmt.Printf("%v - %s - %s\n", idx, string(k), string(v))
err = block6.Add(k, v)
if err != nil {
t.Fatal(err)
}
return nil
})
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(block2Expected, block2) {
spew.Dump(block2)
t.Fatal("block2")
}
if !reflect.DeepEqual(block4Expected, block4) {
spew.Dump(block4)
t.Fatal("block4")
}
if !reflect.DeepEqual(block6Expected, block6) {
spew.Dump(block6)
t.Fatal("block6")
}
}