mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/state/snapshot: start fixing disk iterator seek
This commit is contained in:
parent
613af7ceea
commit
02ba3dd9b3
4 changed files with 88 additions and 2 deletions
|
|
@ -145,3 +145,14 @@ func TrimLeftZeroes(s []byte) []byte {
|
||||||
}
|
}
|
||||||
return s[idx:]
|
return s[idx:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TrimRightZeroes returns a subslice of s without trailing zeroes
|
||||||
|
func TrimRightZeroes(s []byte) []byte {
|
||||||
|
idx := len(s)
|
||||||
|
for ; idx > 0; idx-- {
|
||||||
|
if s[idx-1] != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[:idx]
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,3 +105,22 @@ func TestNoPrefixShortHexOddLength(t *testing.T) {
|
||||||
t.Errorf("Expected %x got %x", expected, result)
|
t.Errorf("Expected %x got %x", expected, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTrimRightZeroes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
arr []byte
|
||||||
|
exp []byte
|
||||||
|
}{
|
||||||
|
{FromHex("0x00ffff00ff0000"), FromHex("0x00ffff00ff")},
|
||||||
|
{FromHex("0x00000000000000"), []byte{}},
|
||||||
|
{FromHex("0xff"), FromHex("0xff")},
|
||||||
|
{[]byte{}, []byte{}},
|
||||||
|
{FromHex("0x00ffffffffffff"), FromHex("0x00ffffffffffff")},
|
||||||
|
}
|
||||||
|
for i, test := range tests {
|
||||||
|
got := TrimRightZeroes(test.arr)
|
||||||
|
if !bytes.Equal(got, test.exp) {
|
||||||
|
t.Errorf("test %d, got %x exp %x", i, got, test.exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -432,4 +432,60 @@ func TestDiskPartialMerge(t *testing.T) {
|
||||||
// This test case is a tiny specialized case of TestDiskPartialMerge, which tests
|
// This test case is a tiny specialized case of TestDiskPartialMerge, which tests
|
||||||
// some very specific cornercases that random tests won't ever trigger.
|
// some very specific cornercases that random tests won't ever trigger.
|
||||||
func TestDiskMidAccountPartialMerge(t *testing.T) {
|
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
|
||||||
|
db := memorydb.New()
|
||||||
|
// Fill even keys [0,2,4...]
|
||||||
|
for i := 0; i < 0xff; i += 2 {
|
||||||
|
acc := common.Hash{byte(i)}
|
||||||
|
rawdb.WriteAccountSnapshot(db, acc, acc[:])
|
||||||
|
}
|
||||||
|
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() {
|
||||||
|
count++
|
||||||
|
k, v, err := it.Hash()[0], it.Account()[0], it.Error()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("test %d, error: %v", i, err)
|
||||||
|
}
|
||||||
|
if k != tc.expkey {
|
||||||
|
t.Fatalf("test %d, got %v exp %v", i, k, tc.expkey)
|
||||||
|
}
|
||||||
|
if v != k {
|
||||||
|
t.Fatalf("test %d, value wrong, got %v exp %v", i, v, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,10 +148,10 @@ type diskAccountIterator struct {
|
||||||
|
|
||||||
// AccountIterator creates an account iterator over a disk layer.
|
// AccountIterator creates an account iterator over a disk layer.
|
||||||
func (dl *diskLayer) AccountIterator(seek common.Hash) AccountIterator {
|
func (dl *diskLayer) AccountIterator(seek common.Hash) AccountIterator {
|
||||||
// TODO: Fix seek position, or remove seek parameter
|
pos := append(rawdb.SnapshotAccountPrefix, common.TrimRightZeroes(seek[:])...)
|
||||||
return &diskAccountIterator{
|
return &diskAccountIterator{
|
||||||
layer: dl,
|
layer: dl,
|
||||||
it: dl.diskdb.NewIteratorWithPrefix(rawdb.SnapshotAccountPrefix),
|
it: dl.diskdb.NewIteratorWithPrefix(pos),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue