all: simplify and fix database iteration with prefix/start (#20808)
* core/state/snapshot: start fixing disk iterator seek * ethdb, rawdb, leveldb, memorydb: implement iterators with prefix and start * les, core/state/snapshot: iterator fixes * all: remove two iterator methods * all: rename Iteratee.NewIteratorWith -> NewIterator * ethdb: fix review concerns
This commit is contained in:
committed by
GitHub
parent
00064ddcfb
commit
6402c42b67
@ -18,11 +18,15 @@ package snapshot
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/VictoriaMetrics/fastcache"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/ethdb/leveldb"
|
||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
||||
)
|
||||
|
||||
@ -432,4 +436,76 @@ func TestDiskPartialMerge(t *testing.T) {
|
||||
// This test case is a tiny specialized case of TestDiskPartialMerge, which tests
|
||||
// some very specific cornercases that random tests won't ever trigger.
|
||||
func TestDiskMidAccountPartialMerge(t *testing.T) {
|
||||
// TODO(@karalabe) ?
|
||||
}
|
||||
|
||||
// TestDiskSeek tests that seek-operations work on the disk layer
|
||||
func TestDiskSeek(t *testing.T) {
|
||||
// Create some accounts in the disk layer
|
||||
var db ethdb.Database
|
||||
|
||||
if dir, err := ioutil.TempDir("", "disklayer-test"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
defer os.RemoveAll(dir)
|
||||
diskdb, err := leveldb.New(dir, 256, 0, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
db = rawdb.NewDatabase(diskdb)
|
||||
}
|
||||
// Fill even keys [0,2,4...]
|
||||
for i := 0; i < 0xff; i += 2 {
|
||||
acc := common.Hash{byte(i)}
|
||||
rawdb.WriteAccountSnapshot(db, acc, acc[:])
|
||||
}
|
||||
// Add an 'higher' key, with incorrect (higher) prefix
|
||||
highKey := []byte{rawdb.SnapshotAccountPrefix[0] + 1}
|
||||
db.Put(highKey, []byte{0xff, 0xff})
|
||||
|
||||
baseRoot := randomHash()
|
||||
rawdb.WriteSnapshotRoot(db, baseRoot)
|
||||
|
||||
snaps := &Tree{
|
||||
layers: map[common.Hash]snapshot{
|
||||
baseRoot: &diskLayer{
|
||||
diskdb: db,
|
||||
cache: fastcache.New(500 * 1024),
|
||||
root: baseRoot,
|
||||
},
|
||||
},
|
||||
}
|
||||
// Test some different seek positions
|
||||
type testcase struct {
|
||||
pos byte
|
||||
expkey byte
|
||||
}
|
||||
var cases = []testcase{
|
||||
{0xff, 0x55}, // this should exit immediately without checking key
|
||||
{0x01, 0x02},
|
||||
{0xfe, 0xfe},
|
||||
{0xfd, 0xfe},
|
||||
{0x00, 0x00},
|
||||
}
|
||||
for i, tc := range cases {
|
||||
it, err := snaps.AccountIterator(baseRoot, common.Hash{tc.pos})
|
||||
if err != nil {
|
||||
t.Fatalf("case %d, error: %v", i, err)
|
||||
}
|
||||
count := 0
|
||||
for it.Next() {
|
||||
k, v, err := it.Hash()[0], it.Account()[0], it.Error()
|
||||
if err != nil {
|
||||
t.Fatalf("test %d, item %d, error: %v", i, count, err)
|
||||
}
|
||||
// First item in iterator should have the expected key
|
||||
if count == 0 && k != tc.expkey {
|
||||
t.Fatalf("test %d, item %d, got %v exp %v", i, count, k, tc.expkey)
|
||||
}
|
||||
count++
|
||||
if v != k {
|
||||
t.Fatalf("test %d, item %d, value wrong, got %v exp %v", i, count, v, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user