e3: state reader constructor in tests (#7338)

This commit is contained in:
Alex Sharov 2023-04-19 10:10:33 +07:00 committed by GitHub
parent 283bd9bbef
commit 21d66d6c01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 119 additions and 68 deletions

View File

@ -193,10 +193,8 @@ func (b *SimulatedBackend) emptyPendingBlock() {
// stateByBlockNumber retrieves a state by a given blocknumber.
func (b *SimulatedBackend) stateByBlockNumber(db kv.Tx, blockNumber *big.Int) *state.IntraBlockState {
if blockNumber == nil || blockNumber.Cmp(b.pendingBlock.Number()) == 0 {
//return state.New(state.NewPlainState(db, b.pendingBlock.NumberU64()+1, nil))
return state.New(b.m.NewHistoryStateReader(b.pendingBlock.NumberU64()+1, db))
}
//return state.New(state.NewPlainState(db, blockNumber.Uint64()+1, nil))
return state.New(b.m.NewHistoryStateReader(blockNumber.Uint64()+1, db))
}

View File

@ -147,7 +147,6 @@ func TestNewSimulatedBackend(t *testing.T) {
}
statedb := sim.stateByBlockNumber(tx, big.NewInt(int64(num+1)))
//statedb := state.New(state.NewPlainState(tx, num+1, nil))
bal := statedb.GetBalance(testAddr)
if !bal.Eq(expectedBal) {
t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)

View File

@ -1223,8 +1223,12 @@ func TestWrongIncarnation2(t *testing.T) {
func TestChangeAccountCodeBetweenBlocks(t *testing.T) {
contract := libcommon.HexToAddress("0x71dd1027069078091B3ca48093B00E4735B20624")
_, tx := memdb.NewTestTx(t)
r, tsw := state.NewPlainStateReader(tx), state.NewPlainStateWriter(tx, nil, 0)
m := stages.Mock(t)
tx, err := m.DB.BeginRw(m.Ctx)
require.NoError(t, err)
defer tx.Rollback()
r, tsw := m.NewStateReader(tx), m.NewStateWriter(tx, 0)
intraBlockState := state.New(r)
// Start the 1st transaction
intraBlockState.CreateAccount(contract, true)
@ -1236,8 +1240,7 @@ func TestChangeAccountCodeBetweenBlocks(t *testing.T) {
if err := intraBlockState.FinalizeTx(&chain.Rules{}, tsw); err != nil {
t.Errorf("error finalising 1st tx: %v", err)
}
_, err := trie.CalcRoot("test", tx)
require.NoError(t, err)
_ = m.CalcStateRoot(tx)
oldCodeHash := libcommon.BytesToHash(crypto.Keccak256(oldCode))
trieCode, tcErr := r.ReadAccountCode(contract, 1, oldCodeHash)
assert.NoError(t, tcErr, "you can receive the new code")

View File

@ -6,6 +6,7 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/common/dbutils"
"github.com/ledgerwatch/erigon/core/types/accounts"
@ -21,6 +22,9 @@ type PlainStateReader struct {
}
func NewPlainStateReader(db kv.Getter) *PlainStateReader {
if ethconfig.EnableHistoryV4InTest {
panic("historyV4 require use StateReaderV4 instead of PlainStateReader")
}
return &PlainStateReader{
db: db,
}

View File

@ -27,6 +27,8 @@ import (
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/kvcfg"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon/turbo/stages"
"github.com/stretchr/testify/require"
checker "gopkg.in/check.v1"
"github.com/ledgerwatch/erigon/core/types/accounts"
@ -324,9 +326,12 @@ func compareStateObjects(so0, so1 *stateObject, t *testing.T) {
}
func TestDump(t *testing.T) {
_, tx := memdb.NewTestTx(t)
w := NewPlainStateWriter(tx, tx, 0)
state := New(NewPlainStateReader(tx))
m := stages.Mock(t)
tx, err := m.DB.BeginRw(m.Ctx)
require.NoError(t, err)
defer tx.Rollback()
w := m.NewStateWriter(tx, 0)
state := New(m.NewStateReader(tx))
// generate a few entries
obj1 := state.GetOrNewStateObject(toAddr([]byte{0x01}))
@ -338,7 +343,7 @@ func TestDump(t *testing.T) {
obj3.SetBalance(uint256.NewInt(44))
// write some of them to the trie
err := w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account))
err = w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account))
if err != nil {
t.Fatal(err)
}
@ -352,18 +357,22 @@ func TestDump(t *testing.T) {
t.Fatal(err)
}
blockWriter := NewPlainStateWriter(tx, tx, 1)
blockWriter := m.NewStateWriter(tx, 1)
err = state.CommitBlock(&chain.Rules{}, blockWriter)
if err != nil {
t.Fatal(err)
}
err = blockWriter.WriteChangeSets()
if err != nil {
t.Fatal(err)
}
err = blockWriter.WriteHistory()
if err != nil {
t.Fatal(err)
if casted, ok := blockWriter.(WriterWithChangeSets); ok {
err = casted.WriteChangeSets()
if err != nil {
t.Fatal(err)
}
err = casted.WriteHistory()
if err != nil {
t.Fatal(err)
}
} else {
panic("implement me")
}
// check that dump contains the state objects that are in trie

View File

@ -24,7 +24,8 @@ import (
"github.com/holiman/uint256"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon/turbo/stages"
"github.com/stretchr/testify/require"
"github.com/ledgerwatch/erigon/common/hexutil"
"github.com/ledgerwatch/erigon/core/state"
@ -89,14 +90,17 @@ func TestEIP2200(t *testing.T) {
t.Run(strconv.Itoa(i), func(t *testing.T) {
address := libcommon.BytesToAddress([]byte("contract"))
_, tx := memdb.NewTestTx(t)
m := stages.Mock(t)
tx, err := m.DB.BeginRw(m.Ctx)
require.NoError(t, err)
defer tx.Rollback()
s := state.New(state.NewPlainStateReader(tx))
s := state.New(m.NewStateReader(tx))
s.CreateAccount(address, true)
s.SetCode(address, hexutil.MustDecode(tt.input))
s.SetState(address, &libcommon.Hash{}, *uint256.NewInt(uint64(tt.original)))
_ = s.CommitBlock(params.AllProtocolChanges.Rules(0, 0), state.NewPlainStateWriter(tx, tx, 0))
_ = s.CommitBlock(params.AllProtocolChanges.Rules(0, 0), m.NewStateWriter(tx, 0))
vmctx := evmtypes.BlockContext{
CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) bool { return true },
Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) {},
@ -135,12 +139,15 @@ var createGasTests = []struct {
func TestCreateGas(t *testing.T) {
for i, tt := range createGasTests {
address := libcommon.BytesToAddress([]byte("contract"))
_, tx := memdb.NewTestTx(t)
m := stages.Mock(t)
tx, err := m.DB.BeginRw(m.Ctx)
require.NoError(t, err)
defer tx.Rollback()
s := state.New(state.NewPlainStateReader(tx))
s := state.New(m.NewStateReader(tx))
s.CreateAccount(address, true)
s.SetCode(address, hexutil.MustDecode(tt.code))
_ = s.CommitBlock(params.TestChainConfig.Rules(0, 0), state.NewPlainStateWriter(tx, tx, 0))
_ = s.CommitBlock(params.TestChainConfig.Rules(0, 0), m.NewStateWriter(tx, 0))
vmctx := evmtypes.BlockContext{
CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) bool { return true },

View File

@ -26,7 +26,6 @@ import (
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon/accounts/abi"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/consensus"
@ -36,6 +35,7 @@ import (
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/eth/tracers/logger"
"github.com/ledgerwatch/erigon/turbo/stages"
)
func TestDefaults(t *testing.T) {
@ -106,8 +106,14 @@ func TestExecute(t *testing.T) {
}
func TestCall(t *testing.T) {
_, tx := memdb.NewTestTx(t)
state := state.New(state.NewDbStateReader(tx))
m := stages.Mock(t)
db := m.DB
tx, err := db.BeginRw(context.Background())
if err != nil {
panic(err)
}
defer tx.Rollback()
state := state.New(m.NewStateReader(tx))
address := libcommon.HexToAddress("0x0a")
state.SetCode(address, []byte{
byte(vm.PUSH1), 10,
@ -152,15 +158,15 @@ func BenchmarkCall(b *testing.B) {
b.Fatal(err)
}
cfg := &Config{}
db := memdb.New("")
defer db.Close()
m := stages.Mock(b)
db := m.DB
tx, err := db.BeginRw(context.Background())
if err != nil {
panic(err)
}
defer tx.Rollback()
cfg.r = state.NewPlainStateReader(tx)
cfg.w = state.NewPlainStateWriter(tx, tx, 0)
cfg.r = m.NewStateReader(tx)
cfg.w = m.NewStateWriter(tx, 0)
cfg.State = state.New(cfg.r)
cfg.Debug = true
@ -174,9 +180,16 @@ func BenchmarkCall(b *testing.B) {
}
}
func benchmarkEVM_Create(b *testing.B, code string) {
_, tx := memdb.NewTestTx(b)
m := stages.Mock(b)
db := m.DB
tx, err := db.BeginRw(context.Background())
if err != nil {
panic(err)
}
defer tx.Rollback()
var (
statedb = state.New(state.NewPlainState(tx, 1, nil))
statedb = state.New(m.NewHistoryStateReader(1, tx))
sender = libcommon.BytesToAddress([]byte("sender"))
receiver = libcommon.BytesToAddress([]byte("receiver"))
)
@ -341,8 +354,14 @@ func TestBlockhash(t *testing.T) {
func benchmarkNonModifyingCode(b *testing.B, gas uint64, code []byte, name string) { //nolint:unparam
cfg := new(Config)
setDefaults(cfg)
_, tx := memdb.NewTestTx(b)
cfg.State = state.New(state.NewPlainState(tx, 1, nil))
m := stages.Mock(b)
db := m.DB
tx, err := db.BeginRw(context.Background())
if err != nil {
panic(err)
}
defer tx.Rollback()
cfg.State = state.New(m.NewHistoryStateReader(1, tx))
cfg.GasLimit = gas
var (
destination = libcommon.BytesToAddress([]byte("contract"))

View File

@ -104,7 +104,7 @@ func TestSelfDestructReceive(t *testing.T) {
}
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(address) {
t.Error("expected account to exist")
}
@ -130,7 +130,7 @@ func TestSelfDestructReceive(t *testing.T) {
panic(err)
}
defer tx.Rollback()
st = state.New(state.NewPlainStateReader(tx))
st = state.New(m.NewStateReader(tx))
if !st.Exist(address) {
t.Error("expected account to exist")
}

View File

@ -77,7 +77,7 @@ func TestInsertIncorrectStateRootDifferentAccounts(t *testing.T) {
require.NoError(t, err)
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(to) {
t.Error("expected account to exist")
}
@ -145,7 +145,7 @@ func TestInsertIncorrectStateRootSameAccount(t *testing.T) {
require.NoError(t, err)
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(to) {
t.Error("expected account to exist")
}
@ -207,7 +207,7 @@ func TestInsertIncorrectStateRootSameAccountSameAmount(t *testing.T) {
require.NoError(t, err)
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(to) {
t.Error("expected account to exist")
}
@ -269,7 +269,7 @@ func TestInsertIncorrectStateRootAllFundsRoot(t *testing.T) {
require.NoError(t, err)
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(to) {
t.Error("expected account to exist")
}
@ -331,7 +331,7 @@ func TestInsertIncorrectStateRootAllFunds(t *testing.T) {
require.NoError(t, err)
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(to) {
t.Error("expected account to exist")
}
@ -372,7 +372,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) {
t.Fatal(err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -395,7 +395,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -413,7 +413,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -459,7 +459,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -477,7 +477,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) {
t.Fatal(err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -543,7 +543,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -562,7 +562,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -632,7 +632,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}
@ -650,7 +650,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) {
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if !st.Exist(from) {
t.Error("expected account to exist")
}

View File

@ -928,7 +928,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
t.Fatal(err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
if st := state.New(state.NewPlainStateReader(tx)); !st.Exist(theAddr) {
if st := state.New(m.NewStateReader(tx)); !st.Exist(theAddr) {
t.Error("expected account to exist")
}
return nil
@ -939,8 +939,8 @@ func TestEIP161AccountRemoval(t *testing.T) {
if err = m.InsertChain(chain.Slice(1, 2)); err != nil {
t.Fatal(err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
if st := state.New(state.NewPlainStateReader(tx)); st.Exist(theAddr) {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) {
t.Error("account should not exist")
}
return nil
@ -951,8 +951,8 @@ func TestEIP161AccountRemoval(t *testing.T) {
if err = m.InsertChain(chain.Slice(2, 3)); err != nil {
t.Fatal(err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
if st := state.New(state.NewPlainStateReader(tx)); st.Exist(theAddr) {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) {
t.Error("account should not exist")
}
return nil
@ -1017,7 +1017,7 @@ func TestDoubleAccountRemoval(t *testing.T) {
})
assert.NoError(t, err)
tx, err := m.DB.BeginRo(context.Background())
tx, err := m.DB.BeginRo(m.Ctx)
if err != nil {
t.Fatalf("read only db tx to read state: %v", err)
}
@ -1074,7 +1074,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
t.Fatalf("block %d: failed to insert into chain: %v", i, err)
}
if err := m2.DB.View(context.Background(), func(tx kv.Tx) error {
if err := m2.DB.View(m2.Ctx, func(tx kv.Tx) error {
b, h := rawdb.ReadCurrentBlock(tx), rawdb.ReadCurrentHeader(tx)
if b.Hash() != h.Hash() {
t.Errorf("block %d: current block/header mismatch: block #%d [%x…], header #%d [%x…]", i, b.Number(), b.Hash().Bytes()[:4], h.Number, h.Hash().Bytes()[:4])
@ -1385,7 +1385,7 @@ func TestDeleteRecreateSlots(t *testing.T) {
if err := m.InsertChain(chain); err != nil {
t.Fatalf("failed to insert into chain: %v", err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
statedb := state.New(m.NewHistoryStateReader(2, tx))
// If all is correct, then slot 1 and 2 are zero
@ -1503,7 +1503,7 @@ func TestCVE2020_26265(t *testing.T) {
if err := m.InsertChain(chain); err != nil {
t.Fatalf("failed to insert into chain: %v", err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
reader := m.NewHistoryStateReader(2, tx)
statedb := state.New(reader)
@ -1570,7 +1570,7 @@ func TestDeleteRecreateAccount(t *testing.T) {
if err := m.InsertChain(chain); err != nil {
t.Fatalf("failed to insert into chain: %v", err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
statedb := state.New(m.NewHistoryStateReader(2, tx))
// If all is correct, then both slots are zero
@ -1880,7 +1880,7 @@ func TestInitThenFailCreateContract(t *testing.T) {
t.Fatalf("generate blocks: %v", err)
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
// Import the canonical chain
statedb := state.New(m.NewHistoryStateReader(2, tx))
@ -1978,7 +1978,7 @@ func TestEIP2718Transition(t *testing.T) {
t.Fatalf("failed to insert into chain: %v", err)
}
tx, err := m.DB.BeginRo(context.Background())
tx, err := m.DB.BeginRo(m.Ctx)
if err != nil {
t.Fatal(err)
}
@ -2088,7 +2088,7 @@ func TestEIP1559Transition(t *testing.T) {
t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
}
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
statedb := state.New(m.NewHistoryStateReader(1, tx))
// 3: Ensure that miner received only the tx's tip.
@ -2129,7 +2129,7 @@ func TestEIP1559Transition(t *testing.T) {
}
block = chain.Blocks[0]
err = m.DB.View(context.Background(), func(tx kv.Tx) error {
err = m.DB.View(m.Ctx, func(tx kv.Tx) error {
statedb := state.New(m.NewHistoryStateReader(1, tx))
effectiveTip := block.Transactions()[0].GetPrice().Uint64() - block.BaseFee().Uint64()

View File

@ -105,7 +105,7 @@ func TestGenerateChain(t *testing.T) {
}
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
st := state.New(m.NewStateReader(tx))
if big.NewInt(5).Cmp(current(m.DB).Number()) != 0 {
t.Errorf("wrong block number: %d", current(m.DB).Number())
}

View File

@ -29,6 +29,7 @@ import (
"github.com/ledgerwatch/erigon-lib/txpool"
"github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg"
types2 "github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/erigon/turbo/trie"
"github.com/ledgerwatch/log/v3"
"google.golang.org/protobuf/types/known/emptypb"
@ -768,6 +769,17 @@ func (ms *MockSentry) NewStateReader(tx kv.Tx) state.StateReader {
return state.NewPlainStateReader(tx)
}
func (ms *MockSentry) NewStateWriter(tx kv.RwTx, blockNum uint64) state.StateWriter {
return state.NewPlainStateWriter(tx, tx, blockNum)
}
func (ms *MockSentry) CalcStateRoot(tx kv.Tx) libcommon.Hash {
h, err := trie.CalcRoot("test", tx)
if err != nil {
panic(err)
}
return h
}
func (ms *MockSentry) HistoryV3Components() *libstate.AggregatorV3 {
return ms.agg
}