[state aggregator] contract recreation storage test (#169)

* Remove incarnation, add recreation

* Fix recreation test

Co-authored-by: Alexey Sharp <alexeysharp@Alexeys-iMac.local>
Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro.local>
This commit is contained in:
ledgerwatch 2021-11-16 21:59:26 +00:00 committed by GitHub
parent 1b6c2266f5
commit 14b6423388
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 18 deletions

View File

@ -849,7 +849,7 @@ func (a *Aggregator) readCode(blockNum uint64, addr []byte) []byte {
a.byEndBlock.DescendLessOrEqual(&byEndBlockItem{endBlock: blockNum}, func(i btree.Item) bool {
item := i.(*byEndBlockItem)
if item.codeIdx.Empty() {
return false
return true
}
offset := item.codeIdx.Lookup(addr)
g := item.codeD.MakeGetter() // TODO Cache in the reader
@ -874,7 +874,7 @@ func (a *Aggregator) readStorage(blockNum uint64, filekey []byte) []byte {
a.byEndBlock.DescendLessOrEqual(&byEndBlockItem{endBlock: blockNum}, func(i btree.Item) bool {
item := i.(*byEndBlockItem)
if item.storageIdx.Empty() {
return false
return true
}
offset := item.storageIdx.Lookup(filekey)
g := item.storageD.MakeGetter() // TODO Cache in the reader
@ -924,7 +924,7 @@ func (r *Reader) ReadAccountData(addr []byte) ([]byte, error) {
return val, nil
}
func (r *Reader) ReadAccountStorage(addr []byte, incarnation uint64, loc []byte) (*uint256.Int, error) {
func (r *Reader) ReadAccountStorage(addr []byte, loc []byte) (*uint256.Int, error) {
// Look in the summary table first
dbkey := make([]byte, len(addr)+len(loc))
copy(dbkey[0:], addr)
@ -1107,7 +1107,7 @@ type CursorItem struct {
c kv.Cursor
}
type CursorHeap []CursorItem
type CursorHeap []*CursorItem
func (ch CursorHeap) Len() int {
return len(ch)
@ -1127,7 +1127,7 @@ func (ch *CursorHeap) Swap(i, j int) {
}
func (ch *CursorHeap) Push(x interface{}) {
*ch = append(*ch, x.(CursorItem))
*ch = append(*ch, x.(*CursorItem))
}
func (ch *CursorHeap) Pop() interface{} {
@ -1175,7 +1175,7 @@ func (w *Writer) DeleteAccount(addr []byte) error {
return err
}
if k != nil && bytes.HasPrefix(k, addr) {
heap.Push(&cp, CursorItem{file: false, key: common.Copy(k), val: common.Copy(v), c: c, endBlock: w.blockNum})
heap.Push(&cp, &CursorItem{file: false, key: common.Copy(k), val: common.Copy(v), c: c, endBlock: w.blockNum})
}
w.a.byEndBlock.Ascend(func(i btree.Item) bool {
item := i.(*byEndBlockItem)
@ -1193,7 +1193,7 @@ func (w *Writer) DeleteAccount(addr []byte) error {
key, _ := g.Next(nil)
if bytes.HasPrefix(key, addr) {
val, _ := g.Next(nil)
heap.Push(&cp, CursorItem{file: true, key: key, val: val, dg: g, endBlock: item.endBlock})
heap.Push(&cp, &CursorItem{file: true, key: key, val: val, dg: g, endBlock: item.endBlock})
}
}
return true
@ -1203,7 +1203,7 @@ func (w *Writer) DeleteAccount(addr []byte) error {
lastVal := common.Copy(cp[0].val)
// Advance all the items that have this key (including the top)
for cp.Len() > 0 && bytes.Equal(cp[0].key, lastKey) {
ci1 := &cp[0]
ci1 := cp[0]
if ci1.file {
if ci1.dg.HasNext() {
ci1.key, _ = ci1.dg.Next(ci1.key[:0])
@ -1250,7 +1250,7 @@ func (w *Writer) DeleteAccount(addr []byte) error {
return nil
}
func (w *Writer) WriteAccountStorage(addr []byte, incarnation uint64, loc []byte, _, value *uint256.Int) error {
func (w *Writer) WriteAccountStorage(addr []byte, loc []byte, value *uint256.Int) error {
dbkey := make([]byte, len(addr)+len(loc))
copy(dbkey[0:], addr)
copy(dbkey[len(addr):], loc)
@ -1376,7 +1376,7 @@ func (w *Writer) aggregateUpto(blockFrom, blockTo uint64) error {
if g.HasNext() {
key, _ := g.Next(nil)
val, _ := g.Next(nil)
heap.Push(&cp, CursorItem{file: true, dg: g, key: key, val: val, endBlock: ag.endBlock})
heap.Push(&cp, &CursorItem{file: true, dg: g, key: key, val: val, endBlock: ag.endBlock})
}
}
if item2.accountsD, item2.accountsIdx, err = mergeIntoStateFile(&cp, 0, "accounts", lastStart, blockTo, w.a.diffDir); err != nil {
@ -1389,7 +1389,7 @@ func (w *Writer) aggregateUpto(blockFrom, blockTo uint64) error {
if g.HasNext() {
key, _ := g.Next(nil)
val, _ := g.Next(nil)
heap.Push(&cp, CursorItem{file: true, dg: g, key: key, val: val, endBlock: ag.endBlock})
heap.Push(&cp, &CursorItem{file: true, dg: g, key: key, val: val, endBlock: ag.endBlock})
}
}
if item2.codeD, item2.codeIdx, err = mergeIntoStateFile(&cp, 0, "code", lastStart, blockTo, w.a.diffDir); err != nil {
@ -1398,11 +1398,13 @@ func (w *Writer) aggregateUpto(blockFrom, blockTo uint64) error {
cp = cp[:0]
heap.Init(&cp)
for _, ag := range toAggregate {
//fmt.Printf("merging [%d-%d] into [%d-%d]\n", ag.startBlock, ag.endBlock, lastStart, blockTo)
g := ag.storageD.MakeGetter()
if g.HasNext() {
key, _ := g.Next(nil)
val, _ := g.Next(nil)
heap.Push(&cp, CursorItem{file: true, dg: g, key: key, val: val, endBlock: ag.endBlock})
heap.Push(&cp, &CursorItem{file: true, dg: g, key: key, val: val, endBlock: ag.endBlock})
//fmt.Printf("starting with %x => %x\n", key, val)
}
}
if item2.storageD, item2.storageIdx, err = mergeIntoStateFile(&cp, 20, "storage", lastStart, blockTo, w.a.diffDir); err != nil {
@ -1474,6 +1476,7 @@ func mergeIntoStateFile(cp *CursorHeap, prefixLen int, basename string, startBlo
var keyBuf, valBuf []byte
for cp.Len() > 0 {
lastKey := common.Copy((*cp)[0].key)
//fmt.Printf("looking at key %x to merge into [%d-%d]\n", lastKey, startBlock, endBlock)
lastVal := common.Copy((*cp)[0].val)
var first, firstDelete, firstInsert bool
// Advance all the items that have this key (including the top)
@ -1516,7 +1519,7 @@ func mergeIntoStateFile(cp *CursorHeap, prefixLen int, basename string, startBlo
if err = comp.AddWord(keyBuf); err != nil {
return nil, nil, err
}
//fmt.Printf("merge key %x into %s\n", keyBuf, datPath)
//fmt.Printf("merge key %x into [%d-%d]\n", keyBuf, startBlock, endBlock)
count++ // Only counting keys, not values
if err = comp.AddWord(valBuf); err != nil {
return nil, nil, err
@ -1524,13 +1527,15 @@ func mergeIntoStateFile(cp *CursorHeap, prefixLen int, basename string, startBlo
}
keyBuf = append(keyBuf[:0], lastKey...)
valBuf = append(valBuf[:0], lastVal...)
//} else {
// fmt.Printf("skipped key %x for [%d-%d]\n", keyBuf, startBlock, endBlock)
}
}
if keyBuf != nil {
if err = comp.AddWord(keyBuf); err != nil {
return nil, nil, err
}
//fmt.Printf("merge key %x into %s\n", keyBuf, datPath)
//fmt.Printf("merge key %x into [%d-%d]\n", keyBuf, startBlock, endBlock)
count++ // Only counting keys, not values
if err = comp.AddWord(valBuf); err != nil {
return nil, nil, err

View File

@ -168,6 +168,7 @@ func TestRecreateAccountWithStorage(t *testing.T) {
defer a.Close()
accountKey := int160(1)
var account1 = int256(1)
var account2 = int256(2)
var rwTx kv.RwTx
defer func() {
rwTx.Rollback()
@ -190,7 +191,7 @@ func TestRecreateAccountWithStorage(t *testing.T) {
t.Fatal(err)
}
for s := uint64(0); s < 100; s++ {
if err = w.WriteAccountStorage(accountKey, 1, int256(s), nil, uint256.NewInt(s+1)); err != nil {
if err = w.WriteAccountStorage(accountKey, int256(s), uint256.NewInt(s+1)); err != nil {
t.Fatal(err)
}
}
@ -198,6 +199,15 @@ func TestRecreateAccountWithStorage(t *testing.T) {
if err = w.DeleteAccount(accountKey); err != nil {
t.Fatal(err)
}
case 45:
if err = w.UpdateAccountData(accountKey, account2); err != nil {
t.Fatal(err)
}
for s := uint64(50); s < 150; s++ {
if err = w.WriteAccountStorage(accountKey, int256(s), uint256.NewInt(2*s+1)); err != nil {
t.Fatal(err)
}
}
}
if err = w.Finish(); err != nil {
t.Fatal(err)
@ -220,11 +230,11 @@ func TestRecreateAccountWithStorage(t *testing.T) {
}
for s := uint64(0); s < 100; s++ {
var v *uint256.Int
if v, err = r.ReadAccountStorage(accountKey, 1, int256(s)); err != nil {
if v, err = r.ReadAccountStorage(accountKey, int256(s)); err != nil {
t.Fatal(err)
}
if !uint256.NewInt(s + 1).Eq(v) {
t.Errorf("wrong storage value after block %d, expected %d, got %s", blockNum, s, v)
t.Errorf("wrong storage value after block %d, expected %d, got %s", blockNum, s+1, v)
}
}
case 22, 44:
@ -237,13 +247,34 @@ func TestRecreateAccountWithStorage(t *testing.T) {
}
for s := uint64(0); s < 100; s++ {
var v *uint256.Int
if v, err = r.ReadAccountStorage(accountKey, 1, int256(s)); err != nil {
if v, err = r.ReadAccountStorage(accountKey, int256(s)); err != nil {
t.Fatal(err)
}
if v != nil {
t.Errorf("wrong storage value after block %d, expected nil, got %s", blockNum, v)
}
}
case 66:
var acc []byte
if acc, err = r.ReadAccountData(accountKey); err != nil {
t.Fatal(err)
}
if !bytes.Equal(account2, acc) {
t.Errorf("wrong account after block %d, expected %x, got %x", blockNum, account1, acc)
}
for s := uint64(0); s < 150; s++ {
var v *uint256.Int
if v, err = r.ReadAccountStorage(accountKey, int256(s)); err != nil {
t.Fatal(err)
}
if s < 50 {
if v != nil {
t.Errorf("wrong storage value after block %d, expected nil, got %s", blockNum, v)
}
} else if v == nil || !uint256.NewInt(2*s+1).Eq(v) {
t.Errorf("wrong storage value after block %d, expected %d, got %s", blockNum, 2*s+1, v)
}
}
}
tx.Rollback()
}