erigon-pulse/aggregator/aggregator_test.go
ledgerwatch ea56078a4c
state aggregator - tests for contract storage (#165)
* First test for storage

* Debugging

* Fixes to delete account test

* Fix the lint

Co-authored-by: Alexey Sharp <alexeysharp@Alexeys-iMac.local>
Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro.local>
2021-11-16 00:11:40 +00:00

251 lines
5.9 KiB
Go

/*
Copyright 2021 Erigon contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package aggregator
import (
"bytes"
"context"
"encoding/binary"
"testing"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
)
func int160(i uint64) []byte {
b := make([]byte, 20)
binary.BigEndian.PutUint64(b[12:], i)
return b
}
func int256(i uint64) []byte {
b := make([]byte, 32)
binary.BigEndian.PutUint64(b[24:], i)
return b
}
func TestSimpleAggregator(t *testing.T) {
tmpDir := t.TempDir()
db := memdb.New()
defer db.Close()
a, err := NewAggregator(tmpDir, 16, 4)
if err != nil {
t.Fatal(err)
}
var rwTx kv.RwTx
if rwTx, err = db.BeginRw(context.Background()); err != nil {
t.Fatal(err)
}
defer rwTx.Rollback()
var w *Writer
if w, err = a.MakeStateWriter(rwTx, 0); err != nil {
t.Fatal(err)
}
var account1 = int256(1)
if err = w.UpdateAccountData(int160(1), account1); err != nil {
t.Fatal(err)
}
if err = w.Finish(); err != nil {
t.Fatal(err)
}
if err = rwTx.Commit(); err != nil {
t.Fatal(err)
}
var tx kv.Tx
if tx, err = db.BeginRo(context.Background()); err != nil {
t.Fatal(err)
}
defer tx.Rollback()
r := a.MakeStateReader(tx, 2)
var acc []byte
if acc, err = r.ReadAccountData(int160(1)); err != nil {
t.Fatal(err)
}
if !bytes.Equal(acc, account1) {
t.Errorf("read account %x, expected account %x", acc, account1)
}
a.Close()
}
func TestLoopAggregator(t *testing.T) {
tmpDir := t.TempDir()
db := memdb.New()
defer db.Close()
a, err := NewAggregator(tmpDir, 16, 4)
if err != nil {
t.Fatal(err)
}
defer a.Close()
var account1 = int256(1)
var rwTx kv.RwTx
defer func() {
rwTx.Rollback()
}()
var tx kv.Tx
defer func() {
tx.Rollback()
}()
for blockNum := uint64(0); blockNum < 1000; blockNum++ {
accountKey := int160(blockNum/10 + 1)
//fmt.Printf("blockNum = %d\n", blockNum)
if rwTx, err = db.BeginRw(context.Background()); err != nil {
t.Fatal(err)
}
var w *Writer
if w, err = a.MakeStateWriter(rwTx, blockNum); err != nil {
t.Fatal(err)
}
if err = w.UpdateAccountData(accountKey, account1); err != nil {
t.Fatal(err)
}
if err = w.Finish(); err != nil {
t.Fatal(err)
}
if err = rwTx.Commit(); err != nil {
t.Fatal(err)
}
if tx, err = db.BeginRo(context.Background()); err != nil {
t.Fatal(err)
}
r := a.MakeStateReader(tx, blockNum+1)
var acc []byte
if acc, err = r.ReadAccountData(accountKey); err != nil {
t.Fatal(err)
}
tx.Rollback()
if !bytes.Equal(acc, account1) {
t.Errorf("read account %x, expected account %x for block %d", acc, account1, blockNum)
}
account1 = int256(blockNum + 2)
}
if tx, err = db.BeginRo(context.Background()); err != nil {
t.Fatal(err)
}
blockNum := uint64(1000)
r := a.MakeStateReader(tx, blockNum)
for i := uint64(0); i < blockNum/10+1; i++ {
accountKey := int160(i)
var expected []byte
if i > 0 {
expected = int256(i * 10)
}
var acc []byte
if acc, err = r.ReadAccountData(accountKey); err != nil {
t.Fatal(err)
}
if !bytes.Equal(acc, expected) {
t.Errorf("read account %x, expected account %x for block %d", acc, expected, i)
}
}
tx.Rollback()
a.Close()
}
func TestRecreateAccountWithStorage(t *testing.T) {
tmpDir := t.TempDir()
db := memdb.New()
defer db.Close()
a, err := NewAggregator(tmpDir, 16, 4)
if err != nil {
t.Fatal(err)
}
defer a.Close()
accountKey := int160(1)
var account1 = int256(1)
var rwTx kv.RwTx
defer func() {
rwTx.Rollback()
}()
var tx kv.Tx
defer func() {
tx.Rollback()
}()
for blockNum := uint64(0); blockNum < 100; blockNum++ {
if rwTx, err = db.BeginRw(context.Background()); err != nil {
t.Fatal(err)
}
var w *Writer
if w, err = a.MakeStateWriter(rwTx, blockNum); err != nil {
t.Fatal(err)
}
switch blockNum {
case 1:
if err = w.UpdateAccountData(accountKey, account1); err != nil {
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 {
t.Fatal(err)
}
}
case 22:
if err = w.DeleteAccount(accountKey); err != nil {
t.Fatal(err)
}
}
if err = w.Finish(); err != nil {
t.Fatal(err)
}
if err = rwTx.Commit(); err != nil {
t.Fatal(err)
}
if tx, err = db.BeginRo(context.Background()); err != nil {
t.Fatal(err)
}
r := a.MakeStateReader(tx, blockNum+1)
switch blockNum {
case 1:
var acc []byte
if acc, err = r.ReadAccountData(accountKey); err != nil {
t.Fatal(err)
}
if !bytes.Equal(account1, acc) {
t.Errorf("wrong account after block %d, expected %x, got %x", blockNum, account1, acc)
}
for s := uint64(0); s < 100; s++ {
var v *uint256.Int
if v, err = r.ReadAccountStorage(accountKey, 1, 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)
}
}
case 22, 44:
var acc []byte
if acc, err = r.ReadAccountData(accountKey); err != nil {
t.Fatal(err)
}
if len(acc) > 0 {
t.Errorf("wrong account after block %d, expected nil, got %x", blockNum, acc)
}
for s := uint64(0); s < 100; s++ {
var v *uint256.Int
if v, err = r.ReadAccountStorage(accountKey, 1, int256(s)); err != nil {
t.Fatal(err)
}
if v != nil {
t.Errorf("wrong storage value after block %d, expected nil, got %s", blockNum, v)
}
}
}
tx.Rollback()
}
}