From 172fba927e8544696ce5fc7f892dab851be0f4a1 Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Tue, 3 Dec 2024 13:24:29 +0100 Subject: [PATCH] Restore execution-spec-tests submodule and revert PR #12925 (#12976) Submodule `execution-spec-tests` was inadvertently deleted by PR #10915 and then PR #12925 broke the tests, which went unnoticed because of the submodule deletion. --- accounts/abi/bind/backends/simulated.go | 25 +- accounts/abi/bind/backends/simulated_test.go | 5 +- cl/beacon/handler/subscription.go | 1 - cl/phase1/forkchoice/on_attestation.go | 1 + cl/phase1/forkchoice/on_attester_slashing.go | 1 + cl/phase1/network/services/block_service.go | 1 + cmd/state/exec3/state.go | 1 - consensus/consensus.go | 9 +- consensus/misc/dao.go | 15 +- consensus/misc/eip2935.go | 18 +- core/chain_makers.go | 12 +- core/evm.go | 8 +- core/genesis_test.go | 6 +- core/state/database_test.go | 201 +++--------- core/state/intra_block_state.go | 304 ++++++------------ core/state/intra_block_state_logger_test.go | 6 +- core/state/intra_block_state_test.go | 82 +---- core/state/journal.go | 85 ++--- core/state/state_test.go | 45 +-- core/state/txtask.go | 5 +- core/state_transition.go | 97 ++---- core/vm/eips.go | 5 +- core/vm/errors.go | 4 - core/vm/evm.go | 52 +-- core/vm/evmtypes/evmtypes.go | 50 +-- core/vm/gas_table.go | 42 +-- core/vm/gas_table_test.go | 12 +- core/vm/instructions.go | 47 +-- core/vm/operations_acl.go | 35 +- core/vm/runtime/runtime.go | 5 +- eth/stagedsync/exec3.go | 290 ++++++++--------- eth/stagedsync/exec3_parallel.go | 190 +++++------ eth/stagedsync/exec3_serial.go | 49 ++- eth/tracers/js/goja.go | 28 +- eth/tracers/js/tracer_test.go | 6 +- eth/tracers/logger/access_list_tracer.go | 3 +- eth/tracers/native/prestate.go | 22 +- polygon/bor/bor.go | 40 +-- tests/block_test_util.go | 15 +- tests/execution-spec-tests | 1 + tests/statedb_chain_test.go | 30 +- .../statedb_insert_chain_transaction_test.go | 205 ++---------- turbo/jsonrpc/eth_call.go | 5 +- turbo/jsonrpc/eth_call_test.go | 8 +- turbo/jsonrpc/overlay_api.go | 16 +- turbo/jsonrpc/overlay_create_tracer.go | 6 +- turbo/jsonrpc/trace_adhoc.go | 81 +---- turbo/stages/blockchain_test.go | 85 +---- turbo/stages/chain_makers_test.go | 24 +- 49 files changed, 680 insertions(+), 1604 deletions(-) create mode 160000 tests/execution-spec-tests diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 3645d0cc824..667309affa4 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -207,7 +207,7 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract libcommon.Addres } defer tx.Rollback() stateDB := b.stateByBlockNumber(tx, blockNumber) - return stateDB.GetCode(contract) + return stateDB.GetCode(contract), nil } // BalanceAt returns the wei balance of a certain account in the blockchain. @@ -220,7 +220,7 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract libcommon.Add } defer tx.Rollback() stateDB := b.stateByBlockNumber(tx, blockNumber) - return stateDB.GetBalance(contract) + return stateDB.GetBalance(contract), nil } // NonceAt returns the nonce of a certain account in the blockchain. @@ -234,7 +234,7 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract libcommon.Addre defer tx.Rollback() stateDB := b.stateByBlockNumber(tx, blockNumber) - return stateDB.GetNonce(contract) + return stateDB.GetNonce(contract), nil } // StorageAt returns the value of key in the storage of an account in the blockchain. @@ -518,7 +518,7 @@ func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract libcommon b.mu.Lock() defer b.mu.Unlock() - return b.pendingState.GetCode(contract) + return b.pendingState.GetCode(contract), nil } func newRevertError(result *evmtypes.ExecutionResult) *revertError { @@ -600,7 +600,7 @@ func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account libcommon b.mu.Lock() defer b.mu.Unlock() - return b.pendingState.GetNonce(account) + return b.pendingState.GetNonce(account), nil } // SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated @@ -628,10 +628,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs } // Recap the highest gas allowance with account's balance. if call.GasPrice != nil && !call.GasPrice.IsZero() { - balance, err := b.pendingState.GetBalance(call.From) // from can't be nil - if err != nil { - return 0, err - } + balance := b.pendingState.GetBalance(call.From) // from can't be nil available := balance.ToBig() if call.Value != nil { if call.Value.ToBig().Cmp(available) >= 0 { @@ -727,10 +724,7 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg call.Value = new(uint256.Int) } // Set infinite balance to the fake caller account. - from, err := statedb.GetOrNewStateObject(call.From) - if err != nil { - return nil, err - } + from := statedb.GetOrNewStateObject(call.From) from.SetBalance(uint256.NewInt(0).SetAllOne(), tracing.BalanceChangeUnspecified) // Execute the call. msg := callMsg{call} @@ -758,10 +752,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, txn types.Transa if senderErr != nil { return fmt.Errorf("invalid transaction: %w", senderErr) } - nonce, err := b.pendingState.GetNonce(sender) - if err != nil { - return err - } + nonce := b.pendingState.GetNonce(sender) if txn.GetNonce() != nonce { return fmt.Errorf("invalid transaction nonce: got %d, want %d", txn.GetNonce(), nonce) } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 252fc2f03cd..aec8ebd32b9 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -153,10 +153,7 @@ func TestNewSimulatedBackend(t *testing.T) { } statedb := sim.stateByBlockNumber(tx, new(big.Int).SetUint64(num+1)) - bal, err := statedb.GetBalance(testAddr) - if err != nil { - t.Fatal(err) - } + bal := statedb.GetBalance(testAddr) if !bal.Eq(expectedBal) { t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) } diff --git a/cl/beacon/handler/subscription.go b/cl/beacon/handler/subscription.go index caa4041f32c..63e187fd79c 100644 --- a/cl/beacon/handler/subscription.go +++ b/cl/beacon/handler/subscription.go @@ -84,7 +84,6 @@ func (a *ApiHandler) PostEthV1ValidatorSyncCommitteeSubscriptions(w http.Respons http.Error(w, err.Error(), http.StatusInternalServerError) return } - //cn() } // subscribe to subnets diff --git a/cl/phase1/forkchoice/on_attestation.go b/cl/phase1/forkchoice/on_attestation.go index deeb757442a..7544509b311 100644 --- a/cl/phase1/forkchoice/on_attestation.go +++ b/cl/phase1/forkchoice/on_attestation.go @@ -56,6 +56,7 @@ func (f *ForkChoiceStore) OnAttestation( return err } } + var attestationIndicies []uint64 var err error target := data.Target diff --git a/cl/phase1/forkchoice/on_attester_slashing.go b/cl/phase1/forkchoice/on_attester_slashing.go index 38263819d06..9879ffece91 100644 --- a/cl/phase1/forkchoice/on_attester_slashing.go +++ b/cl/phase1/forkchoice/on_attester_slashing.go @@ -60,6 +60,7 @@ func (f *ForkChoiceStore) onProcessAttesterSlashing(attesterSlashing *cltypes.At if !cltypes.IsSlashableAttestationData(attestation1.Data, attestation2.Data) { return errors.New("attestation data is not slashable") } + attestation1PublicKeys, err := getIndexedAttestationPublicKeys(s, attestation1) if err != nil { return err diff --git a/cl/phase1/network/services/block_service.go b/cl/phase1/network/services/block_service.go index a7fab891c70..56ed8be96e8 100644 --- a/cl/phase1/network/services/block_service.go +++ b/cl/phase1/network/services/block_service.go @@ -156,6 +156,7 @@ func (b *blockService) ProcessMessage(ctx context.Context, _ *uint64, msg *cltyp if msg.Block.Body.BlobKzgCommitments.Len() > int(b.beaconCfg.MaxBlobsPerBlock) { return ErrInvalidCommitmentsCount } + b.publishBlockGossipEvent(msg) // the rest of the validation is done in the forkchoice store if err := b.processAndStoreBlock(ctx, msg); err != nil { diff --git a/cmd/state/exec3/state.go b/cmd/state/exec3/state.go index 43b12c7ea94..75868c51130 100644 --- a/cmd/state/exec3/state.go +++ b/cmd/state/exec3/state.go @@ -132,7 +132,6 @@ func (rw *Worker) ResetTx(chainTx kv.Tx) { func (rw *Worker) Run() error { for txTask, ok := rw.in.Next(rw.ctx); ok; txTask, ok = rw.in.Next(rw.ctx) { - //fmt.Println("RTX", txTask.BlockNum, txTask.TxIndex, txTask.TxNum, txTask.Final) rw.RunTxTask(txTask, rw.isMining) if err := rw.resultCh.Add(rw.ctx, txTask); err != nil { return err diff --git a/consensus/consensus.go b/consensus/consensus.go index 0ed3552cfbd..0429f57e335 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -205,12 +205,9 @@ type PoW interface { } // Transfer subtracts amount from sender and adds amount to recipient using the given Db -func Transfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) error { +func Transfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) { if !bailout { - err := db.SubBalance(sender, amount, tracing.BalanceChangeTransfer) - if err != nil { - return err - } + db.SubBalance(sender, amount, tracing.BalanceChangeTransfer) } - return db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer) + db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer) } diff --git a/consensus/misc/dao.go b/consensus/misc/dao.go index c5671bb08b6..fd02f56bfdc 100644 --- a/consensus/misc/dao.go +++ b/consensus/misc/dao.go @@ -73,24 +73,15 @@ func VerifyDAOHeaderExtraData(config *chain.Config, header *types.Header) error // ApplyDAOHardFork modifies the state database according to the DAO hard-fork // rules, transferring all balances of a set of DAO accounts to a single refund // contract. -func ApplyDAOHardFork(statedb *state.IntraBlockState) error { +func ApplyDAOHardFork(statedb *state.IntraBlockState) { // Retrieve the contract to refund balances into - exist, err := statedb.Exist(params.DAORefundContract) - if err != nil { - return err - } - if !exist { + if !statedb.Exist(params.DAORefundContract) { statedb.CreateAccount(params.DAORefundContract, false) } // Move every DAO account and extra-balance account funds into the refund contract for _, addr := range params.DAODrainList() { - balance, err := statedb.GetBalance(addr) - if err != nil { - return err - } - statedb.AddBalance(params.DAORefundContract, balance, tracing.BalanceIncreaseDaoContract) + statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), tracing.BalanceIncreaseDaoContract) statedb.SetBalance(addr, new(uint256.Int), tracing.BalanceDecreaseDaoAccount) } - return nil } diff --git a/consensus/misc/eip2935.go b/consensus/misc/eip2935.go index de3078e0a34..460c95f4b39 100644 --- a/consensus/misc/eip2935.go +++ b/consensus/misc/eip2935.go @@ -29,25 +29,21 @@ import ( "github.com/erigontech/erigon/params" ) -func StoreBlockHashesEip2935(header *types.Header, state *state.IntraBlockState, config *chain.Config, headerReader consensus.ChainHeaderReader) error { - codeSize, err := state.GetCodeSize(params.HistoryStorageAddress) - if err != nil { - return err - } - if codeSize == 0 { +func StoreBlockHashesEip2935(header *types.Header, state *state.IntraBlockState, config *chain.Config, headerReader consensus.ChainHeaderReader) { + if state.GetCodeSize(params.HistoryStorageAddress) == 0 { log.Debug("[EIP-2935] No code deployed to HistoryStorageAddress before call to store EIP-2935 history") - return nil + return } headerNum := header.Number.Uint64() if headerNum == 0 { // Activation of fork at Genesis - return nil + return } - return storeHash(headerNum-1, header.ParentHash, state) + storeHash(headerNum-1, header.ParentHash, state) } -func storeHash(num uint64, hash libcommon.Hash, state *state.IntraBlockState) error { +func storeHash(num uint64, hash libcommon.Hash, state *state.IntraBlockState) { slotNum := num % params.BlockHashHistoryServeWindow storageSlot := libcommon.BytesToHash(uint256.NewInt(slotNum).Bytes()) parentHashInt := uint256.NewInt(0).SetBytes32(hash.Bytes()) - return state.SetState(params.HistoryStorageAddress, &storageSlot, *parentHashInt) + state.SetState(params.HistoryStorageAddress, &storageSlot, *parentHashInt) } diff --git a/core/chain_makers.go b/core/chain_makers.go index 9c1d9aba3a7..b2c50c9de7d 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -176,18 +176,10 @@ func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) { // TxNonce returns the next valid transaction nonce for the // account at addr. It panics if the account does not exist. func (b *BlockGen) TxNonce(addr libcommon.Address) uint64 { - exist, err := b.ibs.Exist(addr) - if err != nil { - panic(fmt.Sprintf("can't get account: %s", err)) - } - if !exist { + if !b.ibs.Exist(addr) { panic("account does not exist") } - nonce, err := b.ibs.GetNonce(addr) - if err != nil { - panic(fmt.Sprintf("can't get account: %s", err)) - } - return nonce + return b.ibs.GetNonce(addr) } // AddUncle adds an uncle header to the generated block. diff --git a/core/evm.go b/core/evm.go index 2f6dc320a5d..34dcd500316 100644 --- a/core/evm.go +++ b/core/evm.go @@ -138,10 +138,6 @@ func GetHashFn(ref *types.Header, getHeader func(hash libcommon.Hash, number uin // CanTransfer checks whether there are enough funds in the address' account to make a transfer. // This does not take the necessary gas in to account to make the transfer valid. -func CanTransfer(db evmtypes.IntraBlockState, addr libcommon.Address, amount *uint256.Int) (bool, error) { - balance, err := db.GetBalance(addr) - if err != nil { - return false, err - } - return !balance.Lt(amount), nil +func CanTransfer(db evmtypes.IntraBlockState, addr libcommon.Address, amount *uint256.Int) bool { + return !db.GetBalance(addr).Lt(amount) } diff --git a/core/genesis_test.go b/core/genesis_test.go index 413130ad026..83c4820dfc9 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -155,11 +155,9 @@ func TestAllocConstructor(t *testing.T) { reader, err := rpchelper.CreateHistoryStateReader(tx, rawdbv3.TxNums, 1, 0, genSpec.Config.ChainName) require.NoError(err) state := state.New(reader) - balance, err := state.GetBalance(address) - assert.NoError(err) + balance := state.GetBalance(address) assert.Equal(funds, balance.ToBig()) - code, err := state.GetCode(address) - assert.NoError(err) + code := state.GetCode(address) assert.Equal(common.FromHex("5f355f55"), code) key0 := libcommon.HexToHash("0000000000000000000000000000000000000000000000000000000000000000") diff --git a/core/state/database_test.go b/core/state/database_test.go index b173200b8a9..f7a3aca8712 100644 --- a/core/state/database_test.go +++ b/core/state/database_test.go @@ -133,14 +133,10 @@ func TestCreate2Revive(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } return nil @@ -154,9 +150,7 @@ func TestCreate2Revive(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } return nil @@ -172,9 +166,7 @@ func TestCreate2Revive(t *testing.T) { var check2 uint256.Int err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(create2address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(create2address) { t.Error("expected create2address to exist at the block 2", create2address.String()) } // We expect number 0x42 in the position [2], because it is the block number 2 @@ -193,9 +185,7 @@ func TestCreate2Revive(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(create2address); err != nil { - t.Error(err) - } else if exist { + if st.Exist(create2address) { t.Error("expected create2address to be self-destructed at the block 3", create2address.String()) } return nil @@ -208,9 +198,7 @@ func TestCreate2Revive(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(create2address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(create2address) { t.Error("expected create2address to exist at the block 2", create2address.String()) } // We expect number 0x42 in the position [4], because it is the block number 4 @@ -351,14 +339,10 @@ func TestCreate2Polymorth(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } return nil @@ -371,10 +355,9 @@ func TestCreate2Polymorth(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { + st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } return nil @@ -388,25 +371,15 @@ func TestCreate2Polymorth(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(create2address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(create2address) { t.Error("expected create2address to exist at the block 2", create2address.String()) } - code, err := st.GetCode(create2address) - if err != nil { - return err - } - if !bytes.Equal(code, common.FromHex("6002ff")) { - t.Errorf("Expected CREATE2 deployed code 6002ff, got %x", code) + if !bytes.Equal(st.GetCode(create2address), common.FromHex("6002ff")) { + t.Errorf("Expected CREATE2 deployed code 6002ff, got %x", st.GetCode(create2address)) } if !m.HistoryV3 { //AccountsDomain: has no "incarnation" concept - incarnation, err := st.GetIncarnation(create2address) - if err != nil { - return err - } - if incarnation != 1 { - t.Errorf("expected incarnation 1, got %d", incarnation) + if st.GetIncarnation(create2address) != 1 { + t.Errorf("expected incarnation 1, got %d", st.GetIncarnation(create2address)) } } return nil @@ -419,9 +392,7 @@ func TestCreate2Polymorth(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(create2address); err != nil { - t.Error(err) - } else if exist { + if st.Exist(create2address) { t.Error("expected create2address to be self-destructed at the block 3", create2address.String()) } return nil @@ -434,25 +405,15 @@ func TestCreate2Polymorth(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(create2address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(create2address) { t.Error("expected create2address to exist at the block 4", create2address.String()) } - code, err := st.GetCode(create2address) - if err != nil { - return err - } - if !bytes.Equal(code, common.FromHex("6004ff")) { - t.Errorf("Expected CREATE2 deployed code 6004ff, got %x", code) + if !bytes.Equal(st.GetCode(create2address), common.FromHex("6004ff")) { + t.Errorf("Expected CREATE2 deployed code 6004ff, got %x", st.GetCode(create2address)) } if !m.HistoryV3 { //AccountsDomain: has no "incarnation" concept - incarnation, err := st.GetIncarnation(create2address) - if err != nil { - return err - } - if incarnation != 2 { - t.Errorf("expected incarnation 2, got %d", incarnation) + if st.GetIncarnation(create2address) != 2 { + t.Errorf("expected incarnation 2, got %d", st.GetIncarnation(create2address)) } } return nil @@ -465,26 +426,16 @@ func TestCreate2Polymorth(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(create2address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(create2address) { t.Error("expected create2address to exist at the block 5", create2address.String()) } - code, err := st.GetCode(create2address) - if err != nil { - return err - } - if !bytes.Equal(code, common.FromHex("6005ff")) { - t.Errorf("Expected CREATE2 deployed code 6005ff, got %x", code) + if !bytes.Equal(st.GetCode(create2address), common.FromHex("6005ff")) { + t.Errorf("Expected CREATE2 deployed code 6005ff, got %x", st.GetCode(create2address)) } if !m.HistoryV3 { //AccountsDomain: has no "incarnation" concept - incarnation, err := st.GetIncarnation(create2address) - if err != nil { - return err - } - if incarnation != 4 { - t.Errorf("expected incarnation 4 (two self-destructs and two-recreations within a block), got %d", incarnation) + if st.GetIncarnation(create2address) != 4 { + t.Errorf("expected incarnation 4 (two self-destructs and two-recreations within a block), got %d", st.GetIncarnation(create2address)) } } return nil @@ -581,14 +532,10 @@ func TestReorgOverSelfDestruct(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } return nil @@ -603,10 +550,7 @@ func TestReorgOverSelfDestruct(t *testing.T) { var correctValueX uint256.Int err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { - + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } @@ -623,9 +567,7 @@ func TestReorgOverSelfDestruct(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist at the block 3", contractAddress.String()) } return nil @@ -637,9 +579,7 @@ func TestReorgOverSelfDestruct(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 4", contractAddress.String()) } var valueX uint256.Int @@ -732,15 +672,10 @@ func TestReorgOverStateChange(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if exist { - + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } return nil @@ -756,10 +691,7 @@ func TestReorgOverStateChange(t *testing.T) { var correctValueX uint256.Int err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { - + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } @@ -780,9 +712,7 @@ func TestReorgOverStateChange(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 4", contractAddress.String()) } @@ -872,9 +802,7 @@ func TestCreateOnExistingStorage(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } if contractAddress != contractAddr { @@ -893,9 +821,7 @@ func TestCreateOnExistingStorage(t *testing.T) { var check0 uint256.Int err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } @@ -1022,18 +948,14 @@ func TestEip2200Gas(t *testing.T) { var balanceBefore *uint256.Int err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } - balanceBefore, err = st.GetBalance(address) - return err + balanceBefore = st.GetBalance(address) + return nil }) require.NoError(t, err) @@ -1044,15 +966,10 @@ func TestEip2200Gas(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } - balanceAfter, err := st.GetBalance(address) - if err != nil { - return err - } + balanceAfter := st.GetBalance(address) gasSpent := big.NewInt(0).Sub(balanceBefore.ToBig(), balanceAfter.ToBig()) expectedGasSpent := big.NewInt(190373) //(192245) // In the incorrect version, it is 179645 if gasSpent.Cmp(expectedGasSpent) != 0 { @@ -1119,14 +1036,10 @@ func TestWrongIncarnation(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } return nil @@ -1153,9 +1066,7 @@ func TestWrongIncarnation(t *testing.T) { } st := state.New(stateReader) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } return nil @@ -1275,9 +1186,7 @@ func TestWrongIncarnation2(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(address); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } return nil @@ -1296,9 +1205,7 @@ func TestWrongIncarnation2(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(contractAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.String()) } @@ -1623,9 +1530,7 @@ func TestRecreateAndRewind(t *testing.T) { var check0 uint256.Int err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(phoenixAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(phoenixAddress) { t.Errorf("expected phoenix %x to exist after first insert", phoenixAddress) } @@ -1644,9 +1549,7 @@ func TestRecreateAndRewind(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(phoenixAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(phoenixAddress) { t.Errorf("expected phoenix %x to exist after second insert", phoenixAddress) } @@ -1664,9 +1567,7 @@ func TestRecreateAndRewind(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - if exist, err := st.Exist(phoenixAddress); err != nil { - t.Error(err) - } else if !exist { + if !st.Exist(phoenixAddress) { t.Errorf("expected phoenix %x to exist after second insert", phoenixAddress) } diff --git a/core/state/intra_block_state.go b/core/state/intra_block_state.go index dbd3ee0fbfd..030a630bdea 100644 --- a/core/state/intra_block_state.go +++ b/core/state/intra_block_state.go @@ -126,14 +126,12 @@ func (sdb *IntraBlockState) SetTrace(trace bool) { } // setErrorUnsafe sets error but should be called in medhods that already have locks -// Deprecated: The IBS api now returns errors directly func (sdb *IntraBlockState) setErrorUnsafe(err error) { if sdb.savedErr == nil { sdb.savedErr = err } } -// Deprecated: The IBS api now returns errors directly func (sdb *IntraBlockState) Error() error { return sdb.savedErr } @@ -232,47 +230,36 @@ func (sdb *IntraBlockState) SubRefund(gas uint64) { // Exist reports whether the given account address exists in the state. // Notably this also returns true for suicided accounts. -func (sdb *IntraBlockState) Exist(addr libcommon.Address) (bool, error) { - s, err := sdb.getStateObject(addr) - if err != nil { - return false, err - } - return s != nil && !s.deleted, err +func (sdb *IntraBlockState) Exist(addr libcommon.Address) bool { + s := sdb.getStateObject(addr) + return s != nil && !s.deleted } // Empty returns whether the state object is either non-existent // or empty according to the EIP161 specification (balance = nonce = code = 0) -func (sdb *IntraBlockState) Empty(addr libcommon.Address) (bool, error) { - so, err := sdb.getStateObject(addr) - if err != nil { - return false, err - } - return so == nil || so.deleted || so.empty(), nil +func (sdb *IntraBlockState) Empty(addr libcommon.Address) bool { + so := sdb.getStateObject(addr) + return so == nil || so.deleted || so.empty() } // GetBalance retrieves the balance from the given address or 0 if object not found // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) GetBalance(addr libcommon.Address) (*uint256.Int, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return nil, err - } +func (sdb *IntraBlockState) GetBalance(addr libcommon.Address) *uint256.Int { + stateObject := sdb.getStateObject(addr) if stateObject != nil && !stateObject.deleted { - return stateObject.Balance(), nil + return stateObject.Balance() } - return u256.Num0, nil + return u256.Num0 } // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) GetNonce(addr libcommon.Address) (uint64, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return 0, err - } +func (sdb *IntraBlockState) GetNonce(addr libcommon.Address) uint64 { + stateObject := sdb.getStateObject(addr) if stateObject != nil && !stateObject.deleted { - return stateObject.Nonce(), nil + return stateObject.Nonce() } - return 0, nil + + return 0 } // TxIndex returns the current transaction index set by Prepare. @@ -281,160 +268,120 @@ func (sdb *IntraBlockState) TxnIndex() int { } // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) GetCode(addr libcommon.Address) ([]byte, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return nil, err - } +func (sdb *IntraBlockState) GetCode(addr libcommon.Address) []byte { + stateObject := sdb.getStateObject(addr) if stateObject != nil && !stateObject.deleted { if sdb.trace { fmt.Printf("GetCode %x, returned %d\n", addr, len(stateObject.Code())) } - return stateObject.Code(), nil + return stateObject.Code() } if sdb.trace { fmt.Printf("GetCode %x, returned nil\n", addr) } - return nil, nil + return nil } // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) GetCodeSize(addr libcommon.Address) (int, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return 0, err - } +func (sdb *IntraBlockState) GetCodeSize(addr libcommon.Address) int { + stateObject := sdb.getStateObject(addr) if stateObject == nil || stateObject.deleted { - return 0, nil + return 0 } if stateObject.code != nil { - return len(stateObject.code), nil + return len(stateObject.code) } if stateObject.data.CodeHash == emptyCodeHashH { - return 0, nil + return 0 } l, err := sdb.stateReader.ReadAccountCodeSize(addr, stateObject.data.Incarnation) if err != nil { sdb.setErrorUnsafe(err) - return l, err } - return l, err + return l } // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) GetCodeHash(addr libcommon.Address) (libcommon.Hash, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return libcommon.Hash{}, err - } +func (sdb *IntraBlockState) GetCodeHash(addr libcommon.Address) libcommon.Hash { + stateObject := sdb.getStateObject(addr) if stateObject == nil || stateObject.deleted { - return libcommon.Hash{}, nil + return libcommon.Hash{} } - return stateObject.data.CodeHash, nil + return stateObject.data.CodeHash } -func (sdb *IntraBlockState) ResolveCodeHash(addr libcommon.Address) (libcommon.Hash, error) { +func (sdb *IntraBlockState) ResolveCodeHash(addr libcommon.Address) libcommon.Hash { // eip-7702 - dd, ok, err := sdb.GetDelegatedDesignation(addr) - - if ok { + if dd, ok := sdb.GetDelegatedDesignation(addr); ok { return sdb.GetCodeHash(dd) } - if err != nil { - return libcommon.Hash{}, err - } - return sdb.GetCodeHash(addr) } -func (sdb *IntraBlockState) ResolveCode(addr libcommon.Address) ([]byte, error) { +func (sdb *IntraBlockState) ResolveCode(addr libcommon.Address) []byte { // eip-7702 - dd, ok, err := sdb.GetDelegatedDesignation(addr) - if ok { + if dd, ok := sdb.GetDelegatedDesignation(addr); ok { return sdb.GetCode(dd) } - if err != nil { - return nil, err - } + return sdb.GetCode(addr) } -func (sdb *IntraBlockState) ResolveCodeSize(addr libcommon.Address) (int, error) { +func (sdb *IntraBlockState) ResolveCodeSize(addr libcommon.Address) int { // eip-7702 - size, err := sdb.GetCodeSize(addr) - if err != nil { - return 0, err - } + size := sdb.GetCodeSize(addr) if size == types.DelegateDesignationCodeSize { // might be delegated designation - code, err := sdb.ResolveCode(addr) - if err != nil { - return 0, err - } - return len(code), nil + return len(sdb.ResolveCode(addr)) } - return size, nil + return size } -func (sdb *IntraBlockState) GetDelegatedDesignation(addr libcommon.Address) (libcommon.Address, bool, error) { +func (sdb *IntraBlockState) GetDelegatedDesignation(addr libcommon.Address) (libcommon.Address, bool) { // eip-7702 - code, err := sdb.GetCode(addr) - if err != nil { - return EmptyAddress, false, err - } + code := sdb.GetCode(addr) if delegation, ok := types.ParseDelegation(code); ok { - return delegation, true, nil + return delegation, true } - return EmptyAddress, false, nil + return EmptyAddress, false } // GetState retrieves a value from the given account's storage trie. // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) GetState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) error { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) GetState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) { + stateObject := sdb.getStateObject(addr) if stateObject != nil && !stateObject.deleted { stateObject.GetState(key, value) } else { value.Clear() } - return nil } // GetCommittedState retrieves a value from the given account's committed storage trie. // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) GetCommittedState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) error { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) GetCommittedState(addr libcommon.Address, key *libcommon.Hash, value *uint256.Int) { + stateObject := sdb.getStateObject(addr) if stateObject != nil && !stateObject.deleted { stateObject.GetCommittedState(key, value) } else { value.Clear() } - return nil } -func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) (bool, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return false, err - } +func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) bool { + stateObject := sdb.getStateObject(addr) if stateObject == nil { - return false, nil + return false } if stateObject.deleted { - return false, nil + return false } if stateObject.createdContract { - return false, nil + return false } - return stateObject.selfdestructed, nil + return stateObject.selfdestructed } /* @@ -443,7 +390,7 @@ func (sdb *IntraBlockState) HasSelfdestructed(addr libcommon.Address) (bool, err // AddBalance adds amount to the account associated with addr. // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) error { +func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) { if sdb.trace { fmt.Printf("AddBalance %x, %d\n", addr, amount) } @@ -480,117 +427,82 @@ func (sdb *IntraBlockState) AddBalance(addr libcommon.Address, amount *uint256.I bi.increase.Add(&bi.increase, amount) bi.count++ - return nil + return } - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } + stateObject := sdb.GetOrNewStateObject(addr) stateObject.AddBalance(amount, reason) - return nil } // SubBalance subtracts amount from the account associated with addr. // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) SubBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) error { +func (sdb *IntraBlockState) SubBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) { if sdb.trace { fmt.Printf("SubBalance %x, %d\n", addr, amount) } - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } + stateObject := sdb.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SubBalance(amount, reason) } - return nil } // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) SetBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) error { - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) SetBalance(addr libcommon.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) { + stateObject := sdb.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SetBalance(amount, reason) } - return nil } // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) SetNonce(addr libcommon.Address, nonce uint64) error { - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) SetNonce(addr libcommon.Address, nonce uint64) { + stateObject := sdb.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SetNonce(nonce) } - return nil } // DESCRIBED: docs/programmers_guide/guide.md#code-hash // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) SetCode(addr libcommon.Address, code []byte) error { - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) SetCode(addr libcommon.Address, code []byte) { + stateObject := sdb.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SetCode(crypto.Keccak256Hash(code), code) } - return nil } // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account -func (sdb *IntraBlockState) SetState(addr libcommon.Address, key *libcommon.Hash, value uint256.Int) error { - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) SetState(addr libcommon.Address, key *libcommon.Hash, value uint256.Int) { + stateObject := sdb.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SetState(key, value) } - return nil } // SetStorage replaces the entire storage for the specified account with given // storage. This function should only be used for debugging. -func (sdb *IntraBlockState) SetStorage(addr libcommon.Address, storage Storage) error { - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) SetStorage(addr libcommon.Address, storage Storage) { + stateObject := sdb.GetOrNewStateObject(addr) if stateObject != nil { stateObject.SetStorage(storage) } - return nil } // SetIncarnation sets incarnation for account if account exists -func (sdb *IntraBlockState) SetIncarnation(addr libcommon.Address, incarnation uint64) error { - stateObject, err := sdb.GetOrNewStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) SetIncarnation(addr libcommon.Address, incarnation uint64) { + stateObject := sdb.GetOrNewStateObject(addr) if stateObject != nil { stateObject.setIncarnation(incarnation) } - return nil } -func (sdb *IntraBlockState) GetIncarnation(addr libcommon.Address) (uint64, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return 0, err - } +func (sdb *IntraBlockState) GetIncarnation(addr libcommon.Address) uint64 { + stateObject := sdb.getStateObject(addr) if stateObject != nil { - return stateObject.data.Incarnation, nil + return stateObject.data.Incarnation } - return 0, nil + return 0 } // Selfdestruct marks the given account as suicided. @@ -598,13 +510,10 @@ func (sdb *IntraBlockState) GetIncarnation(addr libcommon.Address) (uint64, erro // // The account's state object is still available until the state is committed, // getStateObject will return a non-nil account after Suicide. -func (sdb *IntraBlockState) Selfdestruct(addr libcommon.Address) (bool, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return false, err - } +func (sdb *IntraBlockState) Selfdestruct(addr libcommon.Address) bool { + stateObject := sdb.getStateObject(addr) if stateObject == nil || stateObject.deleted { - return false, nil + return false } prevBalance := *stateObject.Balance() @@ -622,27 +531,19 @@ func (sdb *IntraBlockState) Selfdestruct(addr libcommon.Address) (bool, error) { stateObject.createdContract = false stateObject.data.Balance.Clear() - return true, nil + return true } -func (sdb *IntraBlockState) Selfdestruct6780(addr libcommon.Address) error { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return err - } +func (sdb *IntraBlockState) Selfdestruct6780(addr libcommon.Address) { + stateObject := sdb.getStateObject(addr) if stateObject == nil { - return nil + return } if stateObject.newlyCreated { - code, err := sdb.GetCode(addr) - if err != nil { - return err - } - if _, ok := types.ParseDelegation(code); !ok { + if _, ok := types.ParseDelegation(sdb.GetCode(addr)); !ok { sdb.Selfdestruct(addr) } } - return nil } // SetTransientState sets transient storage for a given account. It @@ -674,36 +575,36 @@ func (sdb *IntraBlockState) GetTransientState(addr libcommon.Address, key libcom return sdb.transientStorage.Get(addr, key) } -func (sdb *IntraBlockState) getStateObject(addr libcommon.Address) (stateObject *stateObject, err error) { +func (sdb *IntraBlockState) getStateObject(addr libcommon.Address) (stateObject *stateObject) { // Prefer 'live' objects. if obj := sdb.stateObjects[addr]; obj != nil { - return obj, nil + return obj } // Load the object from the database. if _, ok := sdb.nilAccounts[addr]; ok { if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred { - return sdb.createObject(addr, nil), nil + return sdb.createObject(addr, nil) } - return nil, nil + return nil } account, err := sdb.stateReader.ReadAccountData(addr) if err != nil { sdb.setErrorUnsafe(err) - return nil, err + return nil } if account == nil { sdb.nilAccounts[addr] = struct{}{} if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred { - return sdb.createObject(addr, nil), nil + return sdb.createObject(addr, nil) } - return nil, nil + return nil } // Insert into the live set. obj := newObject(sdb, addr, account, account) sdb.setStateObject(addr, obj) - return obj, nil + return obj } func (sdb *IntraBlockState) setStateObject(addr libcommon.Address, object *stateObject) { @@ -716,15 +617,12 @@ func (sdb *IntraBlockState) setStateObject(addr libcommon.Address, object *state } // Retrieve a state object or create a new state object if nil. -func (sdb *IntraBlockState) GetOrNewStateObject(addr libcommon.Address) (*stateObject, error) { - stateObject, err := sdb.getStateObject(addr) - if err != nil { - return nil, err - } +func (sdb *IntraBlockState) GetOrNewStateObject(addr libcommon.Address) *stateObject { + stateObject := sdb.getStateObject(addr) if stateObject == nil || stateObject.deleted { stateObject = sdb.createObject(addr, stateObject /* previous */) } - return stateObject, nil + return stateObject } // createObject creates a new state object. If there is an existing account with @@ -760,12 +658,9 @@ func (sdb *IntraBlockState) createObject(addr libcommon.Address, previous *state // 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) // // Carrying over the balance ensures that Ether doesn't disappear. -func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreation bool) error { +func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreation bool) { var prevInc uint64 - previous, err := sdb.getStateObject(addr) - if err != nil { - return err - } + previous := sdb.getStateObject(addr) if previous != nil && previous.selfdestructed { prevInc = previous.data.Incarnation } else { @@ -773,7 +668,6 @@ func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreati prevInc = inc } else { sdb.savedErr = err - return err } } if previous != nil && prevInc < previous.data.PrevIncarnation { @@ -793,7 +687,6 @@ func (sdb *IntraBlockState) CreateAccount(addr libcommon.Address, contractCreati } else { newObj.selfdestructed = false } - return nil } // Snapshot returns an identifier for the current revision of the state. @@ -1017,7 +910,7 @@ func (sdb *IntraBlockState) clearJournalAndRefund() { // - Add authorities to access list (EIP-7702) // - Add delegated designation (if it exists for dst) to access list (EIP-7702) func (sdb *IntraBlockState) Prepare(rules *chain.Rules, sender, coinbase libcommon.Address, dst *libcommon.Address, - precompiles []libcommon.Address, list types.AccessList, authorities []libcommon.Address) error { + precompiles []libcommon.Address, list types.AccessList, authorities []libcommon.Address) { if sdb.trace { fmt.Printf("ibs.Prepare %x, %x, %x, %x, %v, %v, %v\n", sender, coinbase, dst, precompiles, list, rules, authorities) } @@ -1052,18 +945,13 @@ func (sdb *IntraBlockState) Prepare(rules *chain.Rules, sender, coinbase libcomm } if dst != nil { - dd, ok, err := sdb.GetDelegatedDesignation(*dst) - if err != nil { - return err - } - if ok { + if dd, ok := sdb.GetDelegatedDesignation(*dst); ok { sdb.AddAddressToAccessList(dd) } } } // Reset transient storage at the beginning of transaction execution sdb.transientStorage = newTransientStorage() - return nil } // AddAddressToAccessList adds the given address to the access list diff --git a/core/state/intra_block_state_logger_test.go b/core/state/intra_block_state_logger_test.go index cc5fed21804..11c5023c940 100644 --- a/core/state/intra_block_state_logger_test.go +++ b/core/state/intra_block_state_logger_test.go @@ -86,8 +86,7 @@ func TestStateLogger(t *testing.T) { } } - so, err := stateDB.GetOrNewStateObject(libcommon.Address{}) - require.NoError(t, err) + so := stateDB.GetOrNewStateObject(libcommon.Address{}) if !reflect.DeepEqual(so.Balance(), uint256.NewInt(3)) { t.Errorf("Incorrect Balance for %s expectedBalance: %s, got:%s", libcommon.Address{}, uint256.NewInt(3), so.Balance()) } @@ -104,8 +103,7 @@ func TestStateLogger(t *testing.T) { state.SubBalance(libcommon.Address{}, uint256.NewInt(1), tracing.BalanceChangeUnspecified) }, checker: func(t *testing.T, stateDB *IntraBlockState) { - so, err := stateDB.GetOrNewStateObject(libcommon.Address{}) - require.NoError(t, err) + so := stateDB.GetOrNewStateObject(libcommon.Address{}) if !reflect.DeepEqual(so.Balance(), uint256.NewInt(1)) { t.Errorf("Incorrect Balance for %s expectedBalance: %s, got:%s", libcommon.Address{}, uint256.NewInt(1), so.Balance()) } diff --git a/core/state/intra_block_state_test.go b/core/state/intra_block_state_test.go index f7d0767015c..b2c1c5321e6 100644 --- a/core/state/intra_block_state_test.go +++ b/core/state/intra_block_state_test.go @@ -323,77 +323,17 @@ func (test *snapshotTest) checkEqual(state, checkstate *IntraBlockState) error { return true } // Check basic accessor methods. - se, err := state.Exist(addr) - if err != nil { + if !checkeq("Exist", state.Exist(addr), checkstate.Exist(addr)) { return err } - ce, err := checkstate.Exist(addr) - if err != nil { - return err - } - if !checkeq("Exist", se, ce) { - return err - } - ssd, err := state.HasSelfdestructed(addr) - if err != nil { - return err - } - csd, err := checkstate.HasSelfdestructed(addr) - if err != nil { - return err - } - checkeq("HasSelfdestructed", ssd, csd) - sb, err := state.GetBalance(addr) - if err != nil { - return err - } - cb, err := checkstate.GetBalance(addr) - if err != nil { - return err - } - checkeqBigInt("GetBalance", sb.ToBig(), cb.ToBig()) - sn, err := state.GetNonce(addr) - if err != nil { - return err - } - cn, err := checkstate.GetNonce(addr) - if err != nil { - return err - } - checkeq("GetNonce", sn, cn) - sc, err := state.GetCode(addr) - if err != nil { - return err - } - cc, err := checkstate.GetCode(addr) - if err != nil { - return err - } - checkeq("GetCode", sc, cc) - sch, err := state.GetCodeHash(addr) - if err != nil { - return err - } - cch, err := checkstate.GetCodeHash(addr) - if err != nil { - return err - } - checkeq("GetCodeHash", sch, cch) - scs, err := state.GetCodeSize(addr) - if err != nil { - return err - } - ccs, err := checkstate.GetCodeSize(addr) - if err != nil { - return err - } - checkeq("GetCodeSize", scs, ccs) + checkeq("HasSelfdestructed", state.HasSelfdestructed(addr), checkstate.HasSelfdestructed(addr)) + checkeqBigInt("GetBalance", state.GetBalance(addr).ToBig(), checkstate.GetBalance(addr).ToBig()) + checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr)) + checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) + checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr)) + checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr)) // Check storage. - obj, err := state.getStateObject(addr) - if err != nil { - return err - } - if obj != nil { + if obj := state.getStateObject(addr); obj != nil { for key, value := range obj.dirtyStorage { var out uint256.Int checkstate.GetState(addr, &key, &out) @@ -402,11 +342,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *IntraBlockState) error { } } } - obj, err = checkstate.getStateObject(addr) - if err != nil { - return err - } - if obj != nil { + if obj := checkstate.getStateObject(addr); obj != nil { for key, value := range obj.dirtyStorage { var out uint256.Int state.GetState(addr, &key, &out) diff --git a/core/state/journal.go b/core/state/journal.go index fd7dc7fa13a..663f70baeb9 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -29,7 +29,7 @@ import ( // reverted on demand. type journalEntry interface { // revert undoes the changes introduced by this journal entry. - revert(*IntraBlockState) error + revert(*IntraBlockState) // dirtied returns the Ethereum address modified by this journal entry. dirtied() *libcommon.Address @@ -172,35 +172,29 @@ type ( // refundChange | addLogChange | touchChange | accessListAddAccountChange | accessListAddSlotChange | transientStorageChange //} -func (ch createObjectChange) revert(s *IntraBlockState) error { +func (ch createObjectChange) revert(s *IntraBlockState) { delete(s.stateObjects, *ch.account) delete(s.stateObjectsDirty, *ch.account) - return nil } func (ch createObjectChange) dirtied() *libcommon.Address { return ch.account } -func (ch resetObjectChange) revert(s *IntraBlockState) error { +func (ch resetObjectChange) revert(s *IntraBlockState) { s.setStateObject(*ch.account, ch.prev) - return nil } func (ch resetObjectChange) dirtied() *libcommon.Address { return nil } -func (ch selfdestructChange) revert(s *IntraBlockState) error { - obj, err := s.getStateObject(*ch.account) - if err != nil { - return err - } +func (ch selfdestructChange) revert(s *IntraBlockState) { + obj := s.getStateObject(*ch.account) if obj != nil { obj.selfdestructed = ch.prev obj.setBalance(&ch.prevbalance) } - return nil } func (ch selfdestructChange) dirtied() *libcommon.Address { @@ -209,28 +203,22 @@ func (ch selfdestructChange) dirtied() *libcommon.Address { var ripemd = libcommon.HexToAddress("0000000000000000000000000000000000000003") -func (ch touchChange) revert(s *IntraBlockState) error { - return nil +func (ch touchChange) revert(s *IntraBlockState) { } func (ch touchChange) dirtied() *libcommon.Address { return ch.account } -func (ch balanceChange) revert(s *IntraBlockState) error { - obj, err := s.getStateObject(*ch.account) - if err != nil { - return err - } - obj.setBalance(&ch.prev) - return nil +func (ch balanceChange) revert(s *IntraBlockState) { + s.getStateObject(*ch.account).setBalance(&ch.prev) } func (ch balanceChange) dirtied() *libcommon.Address { return ch.account } -func (ch balanceIncrease) revert(s *IntraBlockState) error { +func (ch balanceIncrease) revert(s *IntraBlockState) { if bi, ok := s.balanceInc[*ch.account]; ok { bi.increase.Sub(&bi.increase, &ch.increase) bi.count-- @@ -238,7 +226,6 @@ func (ch balanceIncrease) revert(s *IntraBlockState) error { delete(s.balanceInc, *ch.account) } } - return nil } func (ch balanceIncrease) dirtied() *libcommon.Address { @@ -249,95 +236,71 @@ func (ch balanceIncreaseTransfer) dirtied() *libcommon.Address { return nil } -func (ch balanceIncreaseTransfer) revert(s *IntraBlockState) error { +func (ch balanceIncreaseTransfer) revert(s *IntraBlockState) { ch.bi.transferred = false - return nil } -func (ch nonceChange) revert(s *IntraBlockState) error { - obj, err := s.getStateObject(*ch.account) - if err != nil { - return err - } - obj.setNonce(ch.prev) - return nil +func (ch nonceChange) revert(s *IntraBlockState) { + s.getStateObject(*ch.account).setNonce(ch.prev) } func (ch nonceChange) dirtied() *libcommon.Address { return ch.account } -func (ch codeChange) revert(s *IntraBlockState) error { - obj, err := s.getStateObject(*ch.account) - if err != nil { - return err - } - obj.setCode(ch.prevhash, ch.prevcode) - return nil +func (ch codeChange) revert(s *IntraBlockState) { + s.getStateObject(*ch.account).setCode(ch.prevhash, ch.prevcode) } func (ch codeChange) dirtied() *libcommon.Address { return ch.account } -func (ch storageChange) revert(s *IntraBlockState) error { - obj, err := s.getStateObject(*ch.account) - if err != nil { - return err - } - obj.setState(&ch.key, ch.prevalue) - return nil +func (ch storageChange) revert(s *IntraBlockState) { + s.getStateObject(*ch.account).setState(&ch.key, ch.prevalue) } func (ch storageChange) dirtied() *libcommon.Address { return ch.account } -func (ch fakeStorageChange) revert(s *IntraBlockState) error { - obj, err := s.getStateObject(*ch.account) - if err != nil { - return err - } - obj.fakeStorage[ch.key] = ch.prevalue - return nil +func (ch fakeStorageChange) revert(s *IntraBlockState) { + s.getStateObject(*ch.account).fakeStorage[ch.key] = ch.prevalue } func (ch fakeStorageChange) dirtied() *libcommon.Address { return ch.account } -func (ch transientStorageChange) revert(s *IntraBlockState) error { +func (ch transientStorageChange) revert(s *IntraBlockState) { s.setTransientState(*ch.account, ch.key, ch.prevalue) - return nil } func (ch transientStorageChange) dirtied() *libcommon.Address { return nil } -func (ch refundChange) revert(s *IntraBlockState) error { +func (ch refundChange) revert(s *IntraBlockState) { s.refund = ch.prev - return nil } func (ch refundChange) dirtied() *libcommon.Address { return nil } -func (ch addLogChange) revert(s *IntraBlockState) error { +func (ch addLogChange) revert(s *IntraBlockState) { txnLogs := s.logs[ch.txIndex] s.logs[ch.txIndex] = txnLogs[:len(txnLogs)-1] // revert 1 log if len(s.logs[ch.txIndex]) == 0 { s.logs = s.logs[:len(s.logs)-1] // revert txn } s.logSize-- - return nil } func (ch addLogChange) dirtied() *libcommon.Address { return nil } -func (ch accessListAddAccountChange) revert(s *IntraBlockState) error { +func (ch accessListAddAccountChange) revert(s *IntraBlockState) { /* One important invariant here, is that whenever a (addr, slot) is added, if the addr is not already present, the add causes two journal entries: @@ -348,16 +311,14 @@ func (ch accessListAddAccountChange) revert(s *IntraBlockState) error { a single (addr) change. */ s.accessList.DeleteAddress(*ch.address) - return nil } func (ch accessListAddAccountChange) dirtied() *libcommon.Address { return nil } -func (ch accessListAddSlotChange) revert(s *IntraBlockState) error { +func (ch accessListAddSlotChange) revert(s *IntraBlockState) { s.accessList.DeleteSlot(*ch.address, *ch.slot) - return nil } func (ch accessListAddSlotChange) dirtied() *libcommon.Address { diff --git a/core/state/state_test.go b/core/state/state_test.go index 6ca1639a8f2..3a5665b359b 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -57,18 +57,15 @@ var _ = checker.Suite(&StateSuite{}) func (s *StateSuite) TestDump(c *checker.C) { // generate a few entries - obj1, err := s.state.GetOrNewStateObject(toAddr([]byte{0x01})) - c.Check(err, checker.IsNil) + obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01})) obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified) - obj2, err := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) - c.Check(err, checker.IsNil) + obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) - obj3, err := s.state.GetOrNewStateObject(toAddr([]byte{0x02})) - c.Check(err, checker.IsNil) + obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02})) obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified) // write some of them to the trie - err = s.w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account)) + err := s.w.UpdateAccountData(obj1.address, &obj1.data, new(accounts.Account)) c.Check(err, checker.IsNil) err = s.w.UpdateAccountData(obj2.address, &obj2.data, new(accounts.Account)) c.Check(err, checker.IsNil) @@ -276,10 +273,7 @@ func TestSnapshot2(t *testing.T) { state.SetState(stateobjaddr1, &storageaddr, *data1) // db, trie are already non-empty values - so0, err := state.getStateObject(stateobjaddr0) - if err != nil { - t.Fatal("getting state", err) - } + so0 := state.getStateObject(stateobjaddr0) so0.SetBalance(uint256.NewInt(42), tracing.BalanceChangeUnspecified) so0.SetNonce(43) so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) @@ -298,10 +292,7 @@ func TestSnapshot2(t *testing.T) { } // and one with deleted == true - so1, err := state.getStateObject(stateobjaddr1) - if err != nil { - t.Fatal("getting state", err) - } + so1 := state.getStateObject(stateobjaddr1) so1.SetBalance(uint256.NewInt(52), tracing.BalanceChangeUnspecified) so1.SetNonce(53) so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) @@ -309,10 +300,7 @@ func TestSnapshot2(t *testing.T) { so1.deleted = true state.setStateObject(stateobjaddr1, so1) - so1, err = state.getStateObject(stateobjaddr1) - if err != nil { - t.Fatal("getting state", err) - } + so1 = state.getStateObject(stateobjaddr1) if so1 != nil && !so1.deleted { t.Fatalf("deleted object not nil when getting") } @@ -320,10 +308,7 @@ func TestSnapshot2(t *testing.T) { snapshot := state.Snapshot() state.RevertToSnapshot(snapshot) - so0Restored, err := state.getStateObject(stateobjaddr0) - if err != nil { - t.Fatal("getting restored state", err) - } + so0Restored := state.getStateObject(stateobjaddr0) // Update lazily-loaded values before comparing. var tmp uint256.Int so0Restored.GetState(&storageaddr, &tmp) @@ -332,10 +317,7 @@ func TestSnapshot2(t *testing.T) { compareStateObjects(so0Restored, so0, t) // deleted should be nil, both before and after restore of state copy - so1Restored, err := state.getStateObject(stateobjaddr1) - if err != nil { - t.Fatal("getting restored state", err) - } + so1Restored := state.getStateObject(stateobjaddr1) if so1Restored != nil && !so1Restored.deleted { t.Fatalf("deleted object not nil after restoring snapshot: %+v", so1Restored) } @@ -428,15 +410,12 @@ func TestDump(t *testing.T) { st := New(NewReaderV3(domains)) // generate a few entries - obj1, err := st.GetOrNewStateObject(toAddr([]byte{0x01})) - require.NoError(t, err) + obj1 := st.GetOrNewStateObject(toAddr([]byte{0x01})) obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified) - obj2, err := st.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) - require.NoError(t, err) + obj2 := st.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) obj2.setIncarnation(1) - obj3, err := st.GetOrNewStateObject(toAddr([]byte{0x02})) - require.NoError(t, err) + obj3 := st.GetOrNewStateObject(toAddr([]byte{0x02})) obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified) w := NewWriterV4(domains) diff --git a/core/state/txtask.go b/core/state/txtask.go index 6ea205cbeff..8604c3a38d4 100644 --- a/core/state/txtask.go +++ b/core/state/txtask.go @@ -140,7 +140,7 @@ func (t *TxTask) createReceipt(cumulativeGasUsed uint64) *types.Receipt { //} return receipt } -func (t *TxTask) Reset() *TxTask { +func (t *TxTask) Reset() { t.BalanceIncreaseSet = nil returnReadList(t.ReadLists) t.ReadLists = nil @@ -149,9 +149,6 @@ func (t *TxTask) Reset() *TxTask { t.Logs = nil t.TraceFroms = nil t.TraceTos = nil - t.Error = nil - t.Failed = false - return t } // TxTaskQueue non-thread-safe priority-queue diff --git a/core/state_transition.go b/core/state_transition.go index feadff5e892..fdda38bd87c 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -62,9 +62,6 @@ The state transitioning model does all the necessary work to work out a valid ne 5) Run Script section 6) Derive new state root */ - -var ErrStateTransitionFailed = errors.New("state transitaion failed") - type StateTransition struct { gp *GasPool msg Message @@ -212,11 +209,7 @@ func (st *StateTransition) buyGas(gasBailout bool) error { } } } - balance, err := st.state.GetBalance(st.msg.From()) - if err != nil { - return err - } - if have, want := balance, balanceCheck; have.Cmp(want) < 0 { + if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 { return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want) } st.state.SubBalance(st.msg.From(), gasVal, tracing.BalanceDecreaseGasBuy) @@ -248,10 +241,7 @@ func CheckEip1559TxGasFeeCap(from libcommon.Address, gasFeeCap, tip, baseFee *ui func (st *StateTransition) preCheck(gasBailout bool) error { // Make sure this transaction's nonce is correct. if st.msg.CheckNonce() { - stNonce, err := st.state.GetNonce(st.msg.From()) - if err != nil { - return fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } + stNonce := st.state.GetNonce(st.msg.From()) if msgNonce := st.msg.Nonce(); stNonce < msgNonce { return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh, st.msg.From().Hex(), msgNonce, stNonce) @@ -264,21 +254,13 @@ func (st *StateTransition) preCheck(gasBailout bool) error { } // Make sure the sender is an EOA (EIP-3607) - codeHash, err := st.state.GetCodeHash(st.msg.From()) - if err != nil { - return fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - if codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) { + if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) { // libcommon.Hash{} means that the sender is not in the state. // Historically there were transactions with 0 gas price and non-existing sender, // so we have to allow that. // eip-7702 allows tx origination from accounts having delegated designation code. - _, ok, err := st.state.GetDelegatedDesignation(st.msg.From()) - if err != nil { - return fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - if ok { + if _, ok := st.state.GetDelegatedDesignation(st.msg.From()); !ok { return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, st.msg.From().Hex(), codeHash) } @@ -325,16 +307,8 @@ func (st *StateTransition) preCheck(gasBailout bool) error { // nil evm execution result. func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtypes.ExecutionResult, error) { coinbase := st.evm.Context.Coinbase - senderInitBalance, err := st.state.GetBalance(st.msg.From()) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - senderInitBalance = senderInitBalance.Clone() - coinbaseInitBalance, err := st.state.GetBalance(coinbase) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - coinbaseInitBalance = coinbaseInitBalance.Clone() + senderInitBalance := st.state.GetBalance(st.msg.From()).Clone() + coinbaseInitBalance := st.state.GetBalance(coinbase).Clone() // First check this message satisfies all consensus rules before // applying the message. The rules include these clauses @@ -367,11 +341,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype if !contractCreation { // Increment the nonce for the next transaction - nonce, err := st.state.GetNonce(sender.Address()) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - st.state.SetNonce(msg.From(), nonce+1) + st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) } // set code tx @@ -405,57 +375,37 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype // authority is added to accessed_address in prepare step // 4. authority code should be empty or already delegated - codeHash, err := st.state.GetCodeHash(authority) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - if codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) { + if codeHash := st.state.GetCodeHash(authority); codeHash != emptyCodeHash && codeHash != (libcommon.Hash{}) { // check for delegation - _, ok, err := st.state.GetDelegatedDesignation(authority) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - if !ok { + if _, ok := st.state.GetDelegatedDesignation(authority); ok { + // noop: has delegated designation + } else { log.Debug("authority code is not empty or not delegated, skipping", "auth index", i) continue } - // noop: has delegated designation } // 5. nonce check - authorityNonce, err := st.state.GetNonce(authority) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } + authorityNonce := st.state.GetNonce(authority) if authorityNonce != auth.Nonce { log.Debug("invalid nonce, skipping", "auth index", i) continue } // 6. Add PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST gas to the global refund counter if authority exists in the trie. - exists, err := st.state.Exist(authority) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - if exists { + if st.state.Exist(authority) { st.state.AddRefund(fixedgas.PerEmptyAccountCost - fixedgas.PerAuthBaseCost) } // 7. set authority code if auth.Address == (libcommon.Address{}) { - if err := st.state.SetCode(authority, nil); err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } + st.state.SetCode(authority, nil) } else { - if err := st.state.SetCode(authority, types.AddressToDelegation(auth.Address)); err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } + st.state.SetCode(authority, types.AddressToDelegation(auth.Address)) } // 8. increase the nonce of authority - if err := st.state.SetNonce(authority, authorityNonce+1); err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } + st.state.SetNonce(authority, authorityNonce+1) } } @@ -472,11 +422,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype var bailout bool // Gas bailout (for trace_call) should only be applied if there is not sufficient balance to perform value transfer if gasBailout { - canTransfer, err := st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } - if !msg.Value().IsZero() && !canTransfer { + if !msg.Value().IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) { bailout = true } } @@ -489,9 +435,8 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin; eip-7702) // - reset transient storage(eip 1153) - if err = st.state.Prepare(rules, msg.From(), coinbase, msg.To(), vm.ActivePrecompiles(rules), accessTuples, verifiedAuthorities); err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } + st.state.Prepare(rules, msg.From(), coinbase, msg.To(), vm.ActivePrecompiles(rules), accessTuples, verifiedAuthorities) + var ( ret []byte vmerr error // vm errors do not effect consensus and are therefore not assigned to err @@ -524,9 +469,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype } amount := new(uint256.Int).SetUint64(st.gasUsed()) amount.Mul(amount, effectiveTip) // gasUsed * effectiveTip = how much goes to the block producer (miner, validator) - if err := st.state.AddBalance(coinbase, amount, tracing.BalanceIncreaseRewardTransactionFee); err != nil { - return nil, fmt.Errorf("%w: %w", ErrStateTransitionFailed, err) - } + st.state.AddBalance(coinbase, amount, tracing.BalanceIncreaseRewardTransactionFee) if !msg.IsFree() && rules.IsLondon { burntContractAddress := st.evm.ChainConfig().GetBurntContract(st.evm.Context.BlockNumber) if burntContractAddress != nil { diff --git a/core/vm/eips.go b/core/vm/eips.go index 0625ba8a8d5..e2d17673e21 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -95,10 +95,7 @@ func enable1884(jt *JumpTable) { } func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) { - balance, err := interpreter.evm.IntraBlockState().GetBalance(callContext.Contract.Address()) - if err != nil { - return nil, err - } + balance := interpreter.evm.IntraBlockState().GetBalance(callContext.Contract.Address()) callContext.Stack.Push(balance) return nil, nil } diff --git a/core/vm/errors.go b/core/vm/errors.go index b8fbee9adc8..ce8ff51f1eb 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -49,10 +49,6 @@ var ( // errStopToken is an internal token indicating interpreter loop termination, // never returned to outside callers. errStopToken = errors.New("stop token") - // - // ErrIntraBlockStateFailed indicates a fatal error when processing IBS - // requests - ErrIntraBlockStateFailed = errors.New("ibs fatal error") ) // ErrStackUnderflow wraps an evm error when the items on the stack less diff --git a/core/vm/evm.go b/core/vm/evm.go index 4b85d8c70f1..a01a97d8a2a 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -20,7 +20,6 @@ package vm import ( - "fmt" "sync/atomic" "github.com/holiman/uint256" @@ -190,11 +189,7 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp } if typ == CALL || typ == CALLCODE { // Fail if we're trying to transfer more than the available balance - canTransfer, err := evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) - if err != nil { - return nil, 0, err - } - if !value.IsZero() && !canTransfer { + if !value.IsZero() && !evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) { if !bailout { return nil, gas, ErrInsufficientBalance } @@ -203,20 +198,13 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp p, isPrecompile := evm.precompile(addr) var code []byte if !isPrecompile { - code, err = evm.intraBlockState.ResolveCode(addr) - if err != nil { - return nil, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } + code = evm.intraBlockState.ResolveCode(addr) } snapshot := evm.intraBlockState.Snapshot() if typ == CALL { - exist, err := evm.intraBlockState.Exist(addr) - if err != nil { - return nil, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } - if !exist { + if !evm.intraBlockState.Exist(addr) { if !isPrecompile && evm.chainRules.IsSpuriousDragon && value.IsZero() { if evm.config.Debug { v := value @@ -282,11 +270,7 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp addrCopy := addr // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. - var codeHash libcommon.Hash - codeHash, err = evm.intraBlockState.ResolveCodeHash(addrCopy) - if err != nil { - return nil, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } + codeHash := evm.intraBlockState.ResolveCodeHash(addrCopy) var contract *Contract if typ == CALLCODE { contract = NewContract(caller, caller.Address(), value, gas, evm.config.SkipAnalysis, evm.JumpDestCache) @@ -401,21 +385,14 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemainin err = ErrDepth return nil, libcommon.Address{}, gasRemaining, err } - canTransfer, err := evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) - if err != nil { - return nil, libcommon.Address{}, 0, err - } - if !canTransfer { + if !evm.Context.CanTransfer(evm.intraBlockState, caller.Address(), value) { if !bailout { err = ErrInsufficientBalance return nil, libcommon.Address{}, gasRemaining, err } } if incrementNonce { - nonce, err := evm.intraBlockState.GetNonce(caller.Address()) - if err != nil { - return nil, libcommon.Address{}, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } + nonce := evm.intraBlockState.GetNonce(caller.Address()) if nonce+1 < nonce { err = ErrNonceUintOverflow return nil, libcommon.Address{}, gasRemaining, err @@ -428,15 +405,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gasRemainin evm.intraBlockState.AddAddressToAccessList(address) } // Ensure there's no existing contract already at the designated address - contractHash, err := evm.intraBlockState.ResolveCodeHash(address) - if err != nil { - return nil, libcommon.Address{}, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } - nonce, err := evm.intraBlockState.GetNonce(address) - if err != nil { - return nil, libcommon.Address{}, 0, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } - if nonce != 0 || (contractHash != (libcommon.Hash{}) && contractHash != trie.EmptyCodeHash) { + contractHash := evm.intraBlockState.ResolveCodeHash(address) + if evm.intraBlockState.GetNonce(address) != 0 || (contractHash != (libcommon.Hash{}) && contractHash != trie.EmptyCodeHash) { err = ErrContractAddressCollision return nil, libcommon.Address{}, 0, err } @@ -511,11 +481,7 @@ func (evm *EVM) maxCodeSize() int { // Create creates a new contract using code as deployment code. // DESCRIBED: docs/programmers_guide/guide.md#nonce func (evm *EVM) Create(caller ContractRef, code []byte, gasRemaining uint64, endowment *uint256.Int, bailout bool) (ret []byte, contractAddr libcommon.Address, leftOverGas uint64, err error) { - nonce, err := evm.intraBlockState.GetNonce(caller.Address()) - if err != nil { - return nil, libcommon.Address{}, 0, err - } - contractAddr = crypto.CreateAddress(caller.Address(), nonce) + contractAddr = crypto.CreateAddress(caller.Address(), evm.intraBlockState.GetNonce(caller.Address())) return evm.create(caller, &codeAndHash{code: code}, gasRemaining, endowment, contractAddr, CREATE, true /* incrementNonce */, bailout) } diff --git a/core/vm/evmtypes/evmtypes.go b/core/vm/evmtypes/evmtypes.go index 8e1e46fd271..775c4600acd 100644 --- a/core/vm/evmtypes/evmtypes.go +++ b/core/vm/evmtypes/evmtypes.go @@ -103,10 +103,10 @@ func (result *ExecutionResult) Revert() []byte { type ( // CanTransferFunc is the signature of a transfer guard function - CanTransferFunc func(IntraBlockState, common.Address, *uint256.Int) (bool, error) + CanTransferFunc func(IntraBlockState, common.Address, *uint256.Int) bool // TransferFunc is the signature of a transfer function - TransferFunc func(IntraBlockState, common.Address, common.Address, *uint256.Int, bool) error + TransferFunc func(IntraBlockState, common.Address, common.Address, *uint256.Int, bool) // GetHashFunc returns the nth block hash in the blockchain // and is used by the BLOCKHASH EVM op code. @@ -119,50 +119,50 @@ type ( // IntraBlockState is an EVM database for full state querying. type IntraBlockState interface { - CreateAccount(common.Address, bool) error + CreateAccount(common.Address, bool) - SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) error - AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) error - GetBalance(common.Address) (*uint256.Int, error) + SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) + AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) + GetBalance(common.Address) *uint256.Int - GetNonce(common.Address) (uint64, error) - SetNonce(common.Address, uint64) error + GetNonce(common.Address) uint64 + SetNonce(common.Address, uint64) - GetCodeHash(common.Address) (common.Hash, error) - GetCode(common.Address) ([]byte, error) - SetCode(common.Address, []byte) error - GetCodeSize(common.Address) (int, error) + GetCodeHash(common.Address) common.Hash + GetCode(common.Address) []byte + SetCode(common.Address, []byte) + GetCodeSize(common.Address) int // eip-7702; delegated designations - ResolveCodeHash(common.Address) (common.Hash, error) - ResolveCode(common.Address) ([]byte, error) - ResolveCodeSize(common.Address) (int, error) - GetDelegatedDesignation(common.Address) (common.Address, bool, error) + ResolveCodeHash(common.Address) common.Hash + ResolveCode(common.Address) []byte + ResolveCodeSize(common.Address) int + GetDelegatedDesignation(common.Address) (common.Address, bool) AddRefund(uint64) SubRefund(uint64) GetRefund() uint64 - GetCommittedState(common.Address, *common.Hash, *uint256.Int) error - GetState(address common.Address, slot *common.Hash, outValue *uint256.Int) error - SetState(common.Address, *common.Hash, uint256.Int) error + GetCommittedState(common.Address, *common.Hash, *uint256.Int) + GetState(address common.Address, slot *common.Hash, outValue *uint256.Int) + SetState(common.Address, *common.Hash, uint256.Int) GetTransientState(addr common.Address, key common.Hash) uint256.Int SetTransientState(addr common.Address, key common.Hash, value uint256.Int) - Selfdestruct(common.Address) (bool, error) - HasSelfdestructed(common.Address) (bool, error) - Selfdestruct6780(common.Address) error + Selfdestruct(common.Address) bool + HasSelfdestructed(common.Address) bool + Selfdestruct6780(common.Address) // Exist reports whether the given account exists in state. // Notably this should also return true for suicided accounts. - Exist(common.Address) (bool, error) + Exist(common.Address) bool // Empty returns whether the given account is empty. Empty // is defined according to EIP161 (balance = nonce = code = 0). - Empty(common.Address) (bool, error) + Empty(common.Address) bool Prepare(rules *chain.Rules, sender, coinbase common.Address, dest *common.Address, - precompiles []common.Address, txAccesses types.AccessList, authorities []common.Address) error + precompiles []common.Address, txAccesses types.AccessList, authorities []common.Address) AddressInAccessList(addr common.Address) bool // AddAddressToAccessList adds the given address to the access list. This operation is safe to perform diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 7d98f49529c..ef38856ccfc 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -391,21 +391,11 @@ func gasCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memo address = libcommon.Address(stack.Back(1).Bytes20()) ) if evm.ChainRules().IsSpuriousDragon { - empty, err := evm.IntraBlockState().Empty(address) - if err != nil { - return 0, err - } - if transfersValue && empty { - gas += params.CallNewAccountGas - } - } else { - exists, err := evm.IntraBlockState().Exist(address) - if err != nil { - return 0, err - } - if !exists { + if transfersValue && evm.IntraBlockState().Empty(address) { gas += params.CallNewAccountGas } + } else if !evm.IntraBlockState().Exist(address) { + gas += params.CallNewAccountGas } if transfersValue { gas += params.CallValueTransferGas @@ -509,33 +499,15 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memo if evm.ChainRules().IsSpuriousDragon { // if empty and transfers value - empty, err := evm.IntraBlockState().Empty(address) - if err != nil { - return 0, err - } - balance, err := evm.IntraBlockState().GetBalance(contract.Address()) - if err != nil { - return 0, err - } - if empty && !balance.IsZero() { - gas += params.CreateBySelfdestructGas - } - } else { - exist, err := evm.IntraBlockState().Exist(address) - if err != nil { - return 0, err - } - if !exist { + if evm.IntraBlockState().Empty(address) && !evm.IntraBlockState().GetBalance(contract.Address()).IsZero() { gas += params.CreateBySelfdestructGas } + } else if !evm.IntraBlockState().Exist(address) { + gas += params.CreateBySelfdestructGas } } - hasSelfdestructed, err := evm.IntraBlockState().HasSelfdestructed(contract.Address()) - if err != nil { - return 0, err - } - if !hasSelfdestructed { + if !evm.IntraBlockState().HasSelfdestructed(contract.Address()) { evm.IntraBlockState().AddRefund(params.SelfdestructRefundGas) } return gas, nil diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index fc33308a2eb..4703b81f87f 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -144,10 +144,8 @@ func TestEIP2200(t *testing.T) { _ = s.CommitBlock(params.AllProtocolChanges.Rules(0, 0), w) vmctx := evmtypes.BlockContext{ - CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) (bool, error) { return true, nil }, - Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) error { - return nil - }, + CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) bool { return true }, + Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) {}, } vmenv := vm.NewEVM(vmctx, evmtypes.TxContext{}, s, params.AllProtocolChanges, vm.Config{ExtraEips: []int{2200}}) @@ -209,10 +207,8 @@ func TestCreateGas(t *testing.T) { _ = s.CommitBlock(params.TestChainConfig.Rules(0, 0), stateWriter) vmctx := evmtypes.BlockContext{ - CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) (bool, error) { return true, nil }, - Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) error { - return nil - }, + CanTransfer: func(evmtypes.IntraBlockState, libcommon.Address, *uint256.Int) bool { return true }, + Transfer: func(evmtypes.IntraBlockState, libcommon.Address, libcommon.Address, *uint256.Int, bool) {}, } config := vm.Config{} if tt.eip3860 { diff --git a/core/vm/instructions.go b/core/vm/instructions.go index a3bb8d7a316..17ccb4ae4ef 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -288,11 +288,7 @@ func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.Peek() address := libcommon.Address(slot.Bytes20()) - balance, err := interpreter.evm.IntraBlockState().GetBalance(address) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } - slot.Set(balance) + slot.Set(interpreter.evm.IntraBlockState().GetBalance(address)) return nil, nil } @@ -376,11 +372,7 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.Peek() - codeSize, err := interpreter.evm.IntraBlockState().ResolveCodeSize(slot.Bytes20()) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } - slot.SetUint64(uint64(codeSize)) + slot.SetUint64(uint64(interpreter.evm.IntraBlockState().ResolveCodeSize(slot.Bytes20()))) return nil, nil } @@ -417,11 +409,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) addr := libcommon.Address(a.Bytes20()) len64 := length.Uint64() - code, err := interpreter.evm.IntraBlockState().ResolveCode(addr) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrIntraBlockStateFailed, err) - } - codeCopy := getDataBig(code, &codeOffset, len64) + codeCopy := getDataBig(interpreter.evm.IntraBlockState().ResolveCode(addr), &codeOffset, len64) scope.Memory.Set(memOffset.Uint64(), len64, codeCopy) return nil, nil } @@ -467,18 +455,10 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) slot := scope.Stack.Peek() address := libcommon.Address(slot.Bytes20()) - empty, err := interpreter.evm.IntraBlockState().Empty(address) - if err != nil { - return nil, err - } - if empty { + if interpreter.evm.IntraBlockState().Empty(address) { slot.Clear() } else { - codeHash, err := interpreter.evm.IntraBlockState().ResolveCodeHash(address) - if err != nil { - return nil, err - } - slot.SetBytes(codeHash.Bytes()) + slot.SetBytes(interpreter.evm.IntraBlockState().ResolveCodeHash(address).Bytes()) } return nil, nil } @@ -580,7 +560,8 @@ func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { loc := scope.Stack.Peek() interpreter.hasherBuf = loc.Bytes32() - return nil, interpreter.evm.IntraBlockState().GetState(scope.Contract.Address(), &interpreter.hasherBuf, loc) + interpreter.evm.IntraBlockState().GetState(scope.Contract.Address(), &interpreter.hasherBuf, loc) + return nil, nil } func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { @@ -590,7 +571,8 @@ func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b loc := scope.Stack.Pop() val := scope.Stack.Pop() interpreter.hasherBuf = loc.Bytes32() - return nil, interpreter.evm.IntraBlockState().SetState(scope.Contract.Address(), &interpreter.hasherBuf, val) + interpreter.evm.IntraBlockState().SetState(scope.Contract.Address(), &interpreter.hasherBuf, val) + return nil, nil } func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { @@ -898,10 +880,7 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext beneficiary := scope.Stack.Pop() callerAddr := scope.Contract.Address() beneficiaryAddr := libcommon.Address(beneficiary.Bytes20()) - balance, err := interpreter.evm.IntraBlockState().GetBalance(callerAddr) - if err != nil { - return nil, err - } + balance := interpreter.evm.IntraBlockState().GetBalance(callerAddr) if interpreter.evm.Config().Debug { if interpreter.cfg.Debug { interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, callerAddr, beneficiaryAddr, false /* precompile */, false /* create */, []byte{}, 0, balance, nil /* code */) @@ -920,11 +899,7 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon beneficiary := scope.Stack.Pop() callerAddr := scope.Contract.Address() beneficiaryAddr := libcommon.Address(beneficiary.Bytes20()) - pbalance, err := interpreter.evm.IntraBlockState().GetBalance(callerAddr) - if err != nil { - return nil, err - } - balance := *pbalance + balance := *interpreter.evm.IntraBlockState().GetBalance(callerAddr) interpreter.evm.IntraBlockState().SubBalance(callerAddr, &balance, tracing.BalanceDecreaseSelfdestruct) interpreter.evm.IntraBlockState().AddBalance(beneficiaryAddr, &balance, tracing.BalanceIncreaseSelfdestruct) interpreter.evm.IntraBlockState().Selfdestruct6780(callerAddr) diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index fe1817e8013..a8c3fec9b33 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -231,22 +231,10 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { gas = params.ColdAccountAccessCostEIP2929 } // if empty and transfers value - empty, err := evm.IntraBlockState().Empty(address) - if err != nil { - return 0, err - } - balance, err := evm.IntraBlockState().GetBalance(contract.Address()) - if err != nil { - return 0, err - } - if empty && !balance.IsZero() { + if evm.IntraBlockState().Empty(address) && !evm.IntraBlockState().GetBalance(contract.Address()).IsZero() { gas += params.CreateBySelfdestructGas } - hasSelfdestructed, err := evm.IntraBlockState().HasSelfdestructed(contract.Address()) - if err != nil { - return 0, err - } - if refundsEnabled && !hasSelfdestructed { + if refundsEnabled && !evm.IntraBlockState().HasSelfdestructed(contract.Address()) { evm.IntraBlockState().AddRefund(params.SelfdestructRefundGas) } return gas, nil @@ -278,11 +266,7 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc { } // Check if code is a delegation and if so, charge for resolution. - dd, ok, err := evm.intraBlockState.GetDelegatedDesignation(addr) - if err != nil { - return 0, err - } - if ok { + if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok { var ddCost uint64 if evm.intraBlockState.AddAddressToAccessList(dd) { ddCost = params.ColdAccountAccessCostEIP2929 @@ -327,11 +311,8 @@ func gasEip7702CodeCheck(evm *EVM, contract *Contract, stack *stack.Stack, mem * // Check if code is a delegation and if so, charge for resolution cost = params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929 } - dd, ok, err := evm.intraBlockState.GetDelegatedDesignation(addr) - if err != nil { - return 0, err - } - if ok { + + if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok { if evm.intraBlockState.AddAddressToAccessList(dd) { cost += params.ColdAccountAccessCostEIP2929 } else { @@ -359,11 +340,7 @@ func gasExtCodeCopyEIP7702(evm *EVM, contract *Contract, stack *stack.Stack, mem } // Check if addr has a delegation and if so, charge for resolution - dd, ok, err := evm.intraBlockState.GetDelegatedDesignation(addr) - if err != nil { - return 0, err - } - if ok { + if dd, ok := evm.intraBlockState.GetDelegatedDesignation(addr); ok { var overflow bool if evm.intraBlockState.AddAddressToAccessList(dd) { if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929); overflow { diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 77748306170..5515933f389 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -244,10 +244,7 @@ func Call(address libcommon.Address, input []byte, cfg *Config) ([]byte, uint64, vmenv := NewEnv(cfg) - sender, err := cfg.State.GetOrNewStateObject(cfg.Origin) - if err != nil { - return nil, 0, err - } + sender := cfg.State.GetOrNewStateObject(cfg.Origin) statedb := cfg.State rules := vmenv.ChainRules() statedb.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil, nil) diff --git a/eth/stagedsync/exec3.go b/eth/stagedsync/exec3.go index d148f3a249d..c632b188631 100644 --- a/eth/stagedsync/exec3.go +++ b/eth/stagedsync/exec3.go @@ -132,71 +132,6 @@ func (p *Progress) Log(suffix string, rs *state.StateV3, in *state.QueueWithRetr p.prevRepeatCount = repeatCount } -// Cases: -// 1. Snapshots > ExecutionStage: snapshots can have half-block data `10.4`. Get right txNum from SharedDomains (after SeekCommitment) -// 2. ExecutionStage > Snapshots: no half-block data possible. Rely on DB. -func restoreTxNum(ctx context.Context, cfg *ExecuteBlockCfg, applyTx kv.Tx, doms *state2.SharedDomains, maxBlockNum uint64) ( - inputTxNum uint64, maxTxNum uint64, offsetFromBlockBeginning uint64, err error) { - - txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, cfg.blockReader)) - - inputTxNum = doms.TxNum() - - if nothing, err := nothingToExec(applyTx, txNumsReader, inputTxNum); err != nil { - return 0, 0, 0, err - } else if nothing { - return 0, 0, 0, err - } - - maxTxNum, err = txNumsReader.Max(applyTx, maxBlockNum) - if err != nil { - return 0, 0, 0, err - } - - ok, _blockNum, err := txNumsReader.FindBlockNum(applyTx, doms.TxNum()) - if err != nil { - return 0, 0, 0, err - } - if !ok { - _lb, _lt, _ := txNumsReader.Last(applyTx) - _fb, _ft, _ := txNumsReader.First(applyTx) - return 0, 0, 0, fmt.Errorf("seems broken TxNums index not filled. can't find blockNum of txNum=%d; in db: (%d-%d, %d-%d)", inputTxNum, _fb, _lb, _ft, _lt) - } - { - _max, _ := txNumsReader.Max(applyTx, _blockNum) - if doms.TxNum() == _max { - _blockNum++ - } - } - - _min, err := txNumsReader.Min(applyTx, _blockNum) - if err != nil { - return 0, 0, 0, err - } - - if doms.TxNum() > _min { - // if stopped in the middle of the block: start from beginning of block. - // first part will be executed in HistoryExecution mode - offsetFromBlockBeginning = doms.TxNum() - _min - } - - inputTxNum = _min - - //_max, _ := txNumsReader.Max(applyTx, blockNum) - //fmt.Printf("[commitment] found domain.txn %d, inputTxn %d, offset %d. DB found block %d {%d, %d}\n", doms.TxNum(), inputTxNum, offsetFromBlockBeginning, blockNum, _min, _max) - doms.SetBlockNum(_blockNum) - doms.SetTxNum(inputTxNum) - return inputTxNum, maxTxNum, offsetFromBlockBeginning, nil -} - -func nothingToExec(applyTx kv.Tx, txNumsReader rawdbv3.TxNumsReader, inputTxNum uint64) (bool, error) { - _, lastTxNum, err := txNumsReader.Last(applyTx) - if err != nil { - return false, err - } - return lastTxNum == inputTxNum, nil -} - func ExecV3(ctx context.Context, execStage *StageState, u Unwinder, workerCount int, cfg ExecuteBlockCfg, txc wrap.TxContainer, parallel bool, //nolint @@ -263,17 +198,100 @@ func ExecV3(ctx context.Context, } txNumInDB := doms.TxNum() + txNumsReader := rawdbv3.TxNums.WithCustomReadTxNumFunc(freezeblocks.ReadTxNumFuncFromBlockReader(ctx, cfg.blockReader)) + var ( - inputTxNum = doms.TxNum() - stageProgress = execStage.BlockNumber - outputTxNum = atomic.Uint64{} - blockComplete = atomic.Bool{} - outputBlockNum = stages.SyncMetrics[stages.Execution] - inputBlockNum = &atomic.Uint64{} + inputTxNum = doms.TxNum() + stageProgress = execStage.BlockNumber + outputTxNum = atomic.Uint64{} + blockComplete = atomic.Bool{} + offsetFromBlockBeginning uint64 blockNum, maxTxNum uint64 ) + blockComplete.Store(true) + nothingToExec := func(applyTx kv.Tx) (bool, error) { + _, lastTxNum, err := txNumsReader.Last(applyTx) + if err != nil { + return false, err + } + return lastTxNum == inputTxNum, nil + } + // Cases: + // 1. Snapshots > ExecutionStage: snapshots can have half-block data `10.4`. Get right txNum from SharedDomains (after SeekCommitment) + // 2. ExecutionStage > Snapshots: no half-block data possible. Rely on DB. + restoreTxNum := func(applyTx kv.Tx) error { + var err error + maxTxNum, err = txNumsReader.Max(applyTx, maxBlockNum) + if err != nil { + return err + } + ok, _blockNum, err := txNumsReader.FindBlockNum(applyTx, doms.TxNum()) + if err != nil { + return err + } + if !ok { + _lb, _lt, _ := txNumsReader.Last(applyTx) + _fb, _ft, _ := txNumsReader.First(applyTx) + return fmt.Errorf("seems broken TxNums index not filled. can't find blockNum of txNum=%d; in db: (%d-%d, %d-%d)", inputTxNum, _fb, _lb, _ft, _lt) + } + { + _max, _ := txNumsReader.Max(applyTx, _blockNum) + if doms.TxNum() == _max { + _blockNum++ + } + } + + _min, err := txNumsReader.Min(applyTx, _blockNum) + if err != nil { + return err + } + + if doms.TxNum() > _min { + // if stopped in the middle of the block: start from beginning of block. + // first part will be executed in HistoryExecution mode + offsetFromBlockBeginning = doms.TxNum() - _min + } + + inputTxNum = _min + outputTxNum.Store(inputTxNum) + + //_max, _ := txNumsReader.Max(applyTx, blockNum) + //fmt.Printf("[commitment] found domain.txn %d, inputTxn %d, offset %d. DB found block %d {%d, %d}\n", doms.TxNum(), inputTxNum, offsetFromBlockBeginning, blockNum, _min, _max) + doms.SetBlockNum(_blockNum) + doms.SetTxNum(inputTxNum) + return nil + } + if applyTx != nil { + if _nothing, err := nothingToExec(applyTx); err != nil { + return err + } else if _nothing { + return nil + } + + if err := restoreTxNum(applyTx); err != nil { + return err + } + } else { + var _nothing bool + if err := cfg.db.View(ctx, func(tx kv.Tx) (err error) { + if _nothing, err = nothingToExec(applyTx); err != nil { + return err + } else if _nothing { + return nil + } + + return restoreTxNum(applyTx) + }); err != nil { + return err + } + if _nothing { + return nil + } + } + + ts := time.Duration(0) blockNum = doms.BlockNum() outputTxNum.Store(doms.TxNum()) @@ -293,6 +311,8 @@ func ExecV3(ctx context.Context, agg.BuildFilesInBackground(outputTxNum.Load()) + var outputBlockNum = stages.SyncMetrics[stages.Execution] + inputBlockNum := &atomic.Uint64{} var count uint64 shouldReportToTxPool := cfg.notifications != nil && !isMining && maxBlockNum <= blockNum+64 @@ -309,37 +329,22 @@ func ExecV3(ctx context.Context, // Now rwLoop closing both (because applyLoop we completely restart) // Maybe need split channels? Maybe don't exit from ApplyLoop? Maybe current way is also ok? - if applyTx != nil { - if inputTxNum, maxTxNum, offsetFromBlockBeginning, err = restoreTxNum(ctx, &cfg, applyTx, doms, maxBlockNum); err != nil { - return err - } - } else { - if err := cfg.db.View(ctx, func(tx kv.Tx) (err error) { - inputTxNum, maxTxNum, offsetFromBlockBeginning, err = restoreTxNum(ctx, &cfg, tx, doms, maxBlockNum) - return err - }); err != nil { - return err - } - } + // input queue + in := state.NewQueueWithRetry(100_000) + defer in.Close() - if maxTxNum == 0 { - return nil - } + rwsConsumed := make(chan struct{}, 1) + defer close(rwsConsumed) applyWorker := cfg.applyWorker if isMining { applyWorker = cfg.applyWorkerMining } - defer applyWorker.LogLRUStats() - applyWorker.ResetState(rs, accumulator) + defer applyWorker.LogLRUStats() commitThreshold := cfg.batchSize.Bytes() - - // TODO are these dups ? - processed := NewProgress(blockNum, commitThreshold, workerCount, true, execStage.LogPrefix(), logger) progress := NewProgress(blockNum, commitThreshold, workerCount, false, execStage.LogPrefix(), logger) - logEvery := time.NewTicker(20 * time.Second) defer logEvery.Stop() pruneEvery := time.NewTicker(2 * time.Second) @@ -347,27 +352,27 @@ func ExecV3(ctx context.Context, var logGas uint64 var stepsInDB float64 + + processed := NewProgress(blockNum, commitThreshold, workerCount, true, execStage.LogPrefix(), logger) + var executor executor if parallel { pe := ¶llelExecutor{ - txExecutor: txExecutor{ - cfg: cfg, - execStage: execStage, - rs: rs, - doms: doms, - agg: agg, - accumulator: accumulator, - isMining: isMining, - inMemExec: inMemExec, - applyTx: applyTx, - applyWorker: applyWorker, - outputTxNum: &outputTxNum, - outputBlockNum: stages.SyncMetrics[stages.Execution], - logger: logger, - }, + execStage: execStage, + chainDb: cfg.db, + applyWorker: applyWorker, + applyTx: applyTx, + outputTxNum: &outputTxNum, + in: in, + rs: rs, + agg: agg, + rwsConsumed: rwsConsumed, + isMining: isMining, + inMemExec: inMemExec, shouldGenerateChangesets: shouldGenerateChangesets, workerCount: workerCount, + accumulator: accumulator, pruneEvery: pruneEvery, logEvery: logEvery, progress: progress, @@ -377,7 +382,7 @@ func ExecV3(ctx context.Context, defer executorCancel() defer func() { - processed.Log("Done", executor.readState(), nil, pe.rws, 0 /*txCount - TODO*/, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec) + processed.Log("Done", executor.readState(), in, pe.rws, 0 /*txCount - TODO*/, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec) }() executor = pe @@ -386,47 +391,31 @@ func ExecV3(ctx context.Context, doms.SetTx(applyTx) se := &serialExecutor{ - txExecutor: txExecutor{ - cfg: cfg, - execStage: execStage, - rs: rs, - doms: doms, - agg: agg, - u: u, - isMining: isMining, - inMemExec: inMemExec, - applyTx: applyTx, - applyWorker: applyWorker, - outputTxNum: &outputTxNum, - outputBlockNum: stages.SyncMetrics[stages.Execution], - logger: logger, - }, + cfg: cfg, + execStage: execStage, + rs: rs, + doms: doms, + agg: agg, + u: u, + isMining: isMining, + inMemExec: inMemExec, + applyTx: applyTx, + worker: applyWorker, + outputTxNum: &outputTxNum, + logger: logger, } defer func() { - processed.Log("Done", executor.readState(), nil, nil, se.txCount, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec) + processed.Log("Done", executor.readState(), in, nil, se.txCount, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec) }() executor = se } - blockComplete.Store(true) - - ts := time.Duration(0) - blockNum = executor.domains().BlockNum() - outputTxNum.Store(executor.domains().TxNum()) - - if maxBlockNum < blockNum { - return nil + getHeaderFunc := func(hash common.Hash, number uint64) (h *types.Header) { + return executor.getHeader(ctx, hash, number) } - if maxBlockNum > blockNum+16 { - log.Info(fmt.Sprintf("[%s] starting", execStage.LogPrefix()), - "from", blockNum, "to", maxBlockNum, "fromTxNum", executor.domains().TxNum(), "offsetFromBlockBeginning", offsetFromBlockBeginning, "initialCycle", initialCycle, "useExternalTx", useExternalTx) - } - - agg.BuildFilesInBackground(outputTxNum.Load()) - var readAhead chan uint64 if !parallel { // snapshots are often stored on chaper drives. don't expect low-read-latency and manually read-ahead. @@ -489,12 +478,13 @@ Loop: skipAnalysis := core.SkipAnalysis(chainConfig, blockNum) signer := *types.MakeSigner(chainConfig, blockNum, header.Time) + f := core.GetHashFn(header, getHeaderFunc) getHashFnMute := &sync.Mutex{} - getHashFn := core.GetHashFn(header, func(hash common.Hash, number uint64) (h *types.Header) { + getHashFn := func(n uint64) common.Hash { getHashFnMute.Lock() defer getHashFnMute.Unlock() - return executor.getHeader(ctx, hash, number) - }) + return f(n) + } totalGasUsed += b.GasUsed() blockContext := core.NewEVMBlockContext(header, getHashFn, cfg.engine, cfg.author /* author */, chainConfig) // print type of engine @@ -502,7 +492,7 @@ Loop: if err := executor.status(ctx, commitThreshold); err != nil { return err } - } else if accumulator != nil { + } else if shouldReportToTxPool { txs, err := blockReader.RawTransactions(context.Background(), executor.tx(), b.NumberU64(), b.NumberU64()) if err != nil { return err @@ -620,16 +610,9 @@ Loop: aggTx := executor.tx().(state2.HasAggTx).AggTx().(*state2.AggregatorRoTx) aggTx.RestrictSubsetFileDeletions(true) start := time.Now() - _ /*rh*/, err := executor.domains().ComputeCommitment(ctx, true, blockNum, execStage.LogPrefix()) - if err != nil { + if _, err := executor.domains().ComputeCommitment(ctx, true, blockNum, execStage.LogPrefix()); err != nil { return err } - - //if !bytes.Equal(rh, header.Root.Bytes()) { - // logger.Error(fmt.Sprintf("[%s] Wrong trie root of block %d: %x, expected (from header): %x. Block hash: %x", execStage.LogPrefix(), header.Number.Uint64(), rh, header.Root.Bytes(), header.Hash())) - // return errors.New("wrong trie root") - //} - ts += time.Since(start) aggTx.RestrictSubsetFileDeletions(false) executor.domains().SavePastChangesetAccumulator(b.Hash(), blockNum, changeset) @@ -654,6 +637,8 @@ Loop: metrics2.UpdateBlockConsumerPostExecutionDelay(b.Time(), blockNum, logger) } + outputBlockNum.SetUint64(blockNum) + select { case <-logEvery.C: if inMemExec || isMining { @@ -661,7 +646,7 @@ Loop: } stepsInDB := rawdbhelpers.IdxStepsCountV3(executor.tx()) - progress.Log("", executor.readState(), nil, nil, count, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec) + progress.Log("", executor.readState(), in, nil, count, logGas, inputBlockNum.Load(), outputBlockNum.GetValueUint64(), outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, shouldGenerateChangesets, inMemExec) //TODO: https://github.com/erigontech/erigon/issues/10724 //if executor.tx().(state2.HasAggTx).AggTx().(*state2.AggregatorRoTx).CanPrune(executor.tx(), outputTxNum.Load()) { @@ -727,7 +712,6 @@ Loop: //log.Info("Executed", "blocks", inputBlockNum.Load(), "txs", outputTxNum.Load(), "repeats", mxExecRepeats.GetValueUint64()) - //fmt.Println("WAIT") executor.wait() if u != nil && !u.HasUnwindPoint() { diff --git a/eth/stagedsync/exec3_parallel.go b/eth/stagedsync/exec3_parallel.go index 26d06c369f5..4ca19d50142 100644 --- a/eth/stagedsync/exec3_parallel.go +++ b/eth/stagedsync/exec3_parallel.go @@ -13,16 +13,14 @@ import ( "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/kv" "github.com/erigontech/erigon-lib/log/v3" - "github.com/erigontech/erigon-lib/metrics" state2 "github.com/erigontech/erigon-lib/state" "github.com/erigontech/erigon/cmd/state/exec3" "github.com/erigontech/erigon/consensus" - "github.com/erigontech/erigon/core" "github.com/erigontech/erigon/core/rawdb" "github.com/erigontech/erigon/core/rawdb/rawdbhelpers" "github.com/erigontech/erigon/core/state" "github.com/erigontech/erigon/core/types" - "github.com/erigontech/erigon/core/vm" + "github.com/erigontech/erigon/eth/stagedsync/stages" "github.com/erigontech/erigon/turbo/shards" "golang.org/x/sync/errgroup" ) @@ -80,48 +78,54 @@ type executor interface { domains() *state2.SharedDomains } -type txExecutor struct { +type parallelExecutor struct { sync.RWMutex - cfg ExecuteBlockCfg - execStage *StageState - agg *state2.Aggregator - rs *state.StateV3 - doms *state2.SharedDomains - accumulator *shards.Accumulator - u Unwinder - isMining bool - inMemExec bool - applyTx kv.RwTx - applyWorker *exec3.Worker - outputTxNum *atomic.Uint64 - outputBlockNum metrics.Gauge - logger log.Logger + rwLoopErrCh chan error + rwLoopG *errgroup.Group + applyLoopWg sync.WaitGroup + chainDb kv.RwDB + applyTx kv.RwTx + applyWorker *exec3.Worker + execWorkers []*exec3.Worker + stopWorkers func() + waitWorkers func() + execStage *StageState + cfg ExecuteBlockCfg + lastBlockNum atomic.Uint64 + outputTxNum *atomic.Uint64 + in *state.QueueWithRetry + rws *state.ResultsQueue + rs *state.StateV3 + doms *state2.SharedDomains + agg *state2.Aggregator + rwsConsumed chan struct{} + isMining bool + inMemExec bool + shouldGenerateChangesets bool + accumulator *shards.Accumulator + workerCount int + pruneEvery *time.Ticker + logEvery *time.Ticker + slowDownLimit *time.Ticker + progress *Progress } -func (te *txExecutor) tx() kv.RwTx { - return te.applyTx +func (pe *parallelExecutor) tx() kv.RwTx { + return pe.applyTx } -func (te *txExecutor) readState() *state.StateV3 { - return te.rs +func (pe *parallelExecutor) readState() *state.StateV3 { + return pe.rs } -func (te *txExecutor) domains() *state2.SharedDomains { - return te.doms +func (pe *parallelExecutor) domains() *state2.SharedDomains { + return pe.doms } -func (te *txExecutor) getHeader(ctx context.Context, hash common.Hash, number uint64) (h *types.Header) { +func (pe *parallelExecutor) getHeader(ctx context.Context, hash common.Hash, number uint64) (h *types.Header) { var err error - if te.applyTx != nil { - h, err = te.cfg.blockReader.Header(ctx, te.applyTx, hash, number) - if err != nil { - panic(err) - } - return h - } - - if err = te.cfg.db.View(ctx, func(tx kv.Tx) error { - h, err = te.cfg.blockReader.Header(ctx, tx, hash, number) + if err = pe.chainDb.View(ctx, func(tx kv.Tx) error { + h, err = pe.cfg.blockReader.Header(ctx, tx, hash, number) if err != nil { return err } @@ -132,39 +136,19 @@ func (te *txExecutor) getHeader(ctx context.Context, hash common.Hash, number ui return h } -type parallelExecutor struct { - txExecutor - rwLoopErrCh chan error - rwLoopG *errgroup.Group - applyLoopWg sync.WaitGroup - execWorkers []*exec3.Worker - stopWorkers func() - waitWorkers func() - lastBlockNum atomic.Uint64 - in *state.QueueWithRetry - rws *state.ResultsQueue - rwsConsumed chan struct{} - shouldGenerateChangesets bool - workerCount int - pruneEvery *time.Ticker - logEvery *time.Ticker - slowDownLimit *time.Ticker - progress *Progress -} - func (pe *parallelExecutor) applyLoop(ctx context.Context, maxTxNum uint64, blockComplete *atomic.Bool, errCh chan error) { defer pe.applyLoopWg.Done() defer func() { if rec := recover(); rec != nil { - pe.logger.Warn("[dbg] apply loop panic", "rec", rec) + log.Warn("[dbg] apply loop panic", "rec", rec) } - pe.logger.Warn("[dbg] apply loop exit") + log.Warn("[dbg] apply loop exit") }() - //fmt.Println("applyLoop started") - //defer fmt.Println("applyLoop done") + + outputBlockNum := stages.SyncMetrics[stages.Execution] applyLoopInner := func(ctx context.Context) error { - tx, err := pe.cfg.db.BeginRo(ctx) + tx, err := pe.chainDb.BeginRo(ctx) if err != nil { return err } @@ -177,15 +161,18 @@ func (pe *parallelExecutor) applyLoop(ctx context.Context, maxTxNum uint64, bloc return err } - processedTxNum, conflicts, triggers, _ /*processedBlockNum*/, stoppedAtBlockEnd, err := - pe.processResultQueue(ctx, pe.outputTxNum.Load(), pe.rwsConsumed, true, false) + processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err := + pe.processResultQueue(ctx, pe.outputTxNum.Load(), tx, pe.rwsConsumed, true, false) if err != nil { return err } - //fmt.Println("QR", processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err) + mxExecRepeats.AddInt(conflicts) mxExecTriggers.AddInt(triggers) - + if processedBlockNum > pe.lastBlockNum.Load() { + outputBlockNum.SetUint64(processedBlockNum) + pe.lastBlockNum.Store(processedBlockNum) + } if processedTxNum > 0 { pe.outputTxNum.Store(processedTxNum) blockComplete.Store(stoppedAtBlockEnd) @@ -208,17 +195,11 @@ func (pe *parallelExecutor) applyLoop(ctx context.Context, maxTxNum uint64, bloc // Maybe need split channels? Maybe don't exit from ApplyLoop? Maybe current way is also ok? func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger log.Logger) error { - //fmt.Println("rwLoop started", maxTxNum) - //defer fmt.Println("rwLoop done") - - tx := pe.applyTx - if tx == nil { - tx, err := pe.cfg.db.BeginRw(ctx) - if err != nil { - return err - } - defer tx.Rollback() + tx, err := pe.chainDb.BeginRw(ctx) + if err != nil { + return err } + defer tx.Rollback() pe.doms.SetTx(tx) @@ -232,6 +213,8 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger go pe.applyLoop(applyCtx, maxTxNum, &blockComplete, pe.rwLoopErrCh) + outputBlockNum := stages.SyncMetrics[stages.Execution] + for pe.outputTxNum.Load() <= maxTxNum { select { case <-ctx.Done(): @@ -239,16 +222,16 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger case <-pe.logEvery.C: stepsInDB := rawdbhelpers.IdxStepsCountV3(tx) - pe.progress.Log("", pe.rs, pe.in, pe.rws, pe.rs.DoneCount(), 0 /* TODO logGas*/, pe.lastBlockNum.Load(), pe.outputBlockNum.GetValueUint64(), pe.outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, pe.shouldGenerateChangesets, pe.inMemExec) + pe.progress.Log("", pe.rs, pe.in, pe.rws, pe.rs.DoneCount(), 0 /* TODO logGas*/, pe.lastBlockNum.Load(), outputBlockNum.GetValueUint64(), pe.outputTxNum.Load(), mxExecRepeats.GetValueUint64(), stepsInDB, pe.shouldGenerateChangesets, pe.inMemExec) if pe.agg.HasBackgroundFilesBuild() { logger.Info(fmt.Sprintf("[%s] Background files build", pe.execStage.LogPrefix()), "progress", pe.agg.BackgroundProgress()) } case <-pe.pruneEvery.C: if pe.rs.SizeEstimate() < pe.cfg.batchSize.Bytes() { - if pe.doms.BlockNum() != pe.outputBlockNum.GetValueUint64() { - panic(fmt.Errorf("%d != %d", pe.doms.BlockNum(), pe.outputBlockNum.GetValueUint64())) + if pe.doms.BlockNum() != outputBlockNum.GetValueUint64() { + panic(fmt.Errorf("%d != %d", pe.doms.BlockNum(), outputBlockNum.GetValueUint64())) } - _, err := pe.doms.ComputeCommitment(ctx, true, pe.outputBlockNum.GetValueUint64(), pe.execStage.LogPrefix()) + _, err := pe.doms.ComputeCommitment(ctx, true, outputBlockNum.GetValueUint64(), pe.execStage.LogPrefix()) if err != nil { return err } @@ -281,7 +264,7 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger pe.applyWorker.ResetTx(tx) processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err := - pe.processResultQueue(ctx, pe.outputTxNum.Load(), nil, false, true) + pe.processResultQueue(ctx, pe.outputTxNum.Load(), tx, nil, false, true) if err != nil { return err } @@ -289,7 +272,7 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger mxExecRepeats.AddInt(conflicts) mxExecTriggers.AddInt(triggers) if processedBlockNum > 0 { - pe.outputBlockNum.SetUint64(processedBlockNum) + outputBlockNum.SetUint64(processedBlockNum) } if processedTxNum > 0 { pe.outputTxNum.Store(processedTxNum) @@ -326,16 +309,16 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger pe.doms.ClearRam(true) t3 = time.Since(tt) - if err := pe.execStage.Update(tx, pe.outputBlockNum.GetValueUint64()); err != nil { + if err = pe.execStage.Update(tx, outputBlockNum.GetValueUint64()); err != nil { return err } - if _, err := rawdb.IncrementStateVersion(tx); err != nil { + if _, err = rawdb.IncrementStateVersion(pe.applyTx); err != nil { return fmt.Errorf("writing plain state version: %w", err) } tx.CollectMetrics() tt = time.Now() - if err := tx.Commit(); err != nil { + if err = tx.Commit(); err != nil { return err } t4 = time.Since(tt) @@ -347,8 +330,7 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger }(); err != nil { return err } - var err error - if tx, err = pe.cfg.db.BeginRw(ctx); err != nil { + if tx, err = pe.chainDb.BeginRw(ctx); err != nil { return err } defer tx.Rollback() @@ -362,35 +344,29 @@ func (pe *parallelExecutor) rwLoop(ctx context.Context, maxTxNum uint64, logger logger.Info("Committed", "time", time.Since(commitStart), "drain", t0, "drain_and_lock", t1, "rs.flush", t2, "agg.flush", t3, "tx.commit", t4) } } - if err := pe.doms.Flush(ctx, tx); err != nil { + if err = pe.doms.Flush(ctx, tx); err != nil { return err } - if err := pe.execStage.Update(tx, pe.outputBlockNum.GetValueUint64()); err != nil { + if err = pe.execStage.Update(tx, outputBlockNum.GetValueUint64()); err != nil { return err } - if err := tx.Commit(); err != nil { + if err = tx.Commit(); err != nil { return err } return nil } -func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum uint64, backPressure chan<- struct{}, canRetry, forceStopAtBlockEnd bool) (outputTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) { +func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum uint64, applyTx kv.Tx, backPressure chan<- struct{}, canRetry, forceStopAtBlockEnd bool) (outputTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) { rwsIt := pe.rws.Iter() defer rwsIt.Close() - //defer fmt.Println("PRQ", "Done") var i int outputTxNum = inputTxNum for rwsIt.HasNext(outputTxNum) { txTask := rwsIt.PopNext() - //fmt.Println("PRQ", txTask.BlockNum, txTask.TxIndex, txTask.TxNum) if txTask.Error != nil || !pe.rs.ReadsValid(txTask.ReadLists) { conflicts++ - //fmt.Println(txTask.TxNum, txTask.Error) - if errors.Is(txTask.Error, vm.ErrIntraBlockStateFailed) || - errors.Is(txTask.Error, core.ErrStateTransitionFailed) { - return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("%w: %v", consensus.ErrInvalidBlock, txTask.Error) - } + if i > 0 && canRetry { //send to re-exex pe.rs.ReTry(txTask, pe.in) @@ -398,9 +374,8 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u } // resolve first conflict right here: it's faster and conflict-free - pe.applyWorker.RunTxTaskNoLock(txTask.Reset(), pe.isMining) + pe.applyWorker.RunTxTask(txTask, pe.isMining) if txTask.Error != nil { - //fmt.Println("RETRY", txTask.TxNum, txTask.Error) return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("%w: %v", consensus.ErrInvalidBlock, txTask.Error) } if pe.cfg.syncCfg.ChaosMonkey { @@ -420,11 +395,6 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u if err != nil { return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err) } - - if processedBlockNum > pe.lastBlockNum.Load() { - pe.outputBlockNum.SetUint64(processedBlockNum) - pe.lastBlockNum.Store(processedBlockNum) - } //if !bytes.Equal(rh, txTask.BlockRoot[:]) { // log.Error("block hash mismatch", "rh", hex.EncodeToString(rh), "blockRoot", hex.EncodeToString(txTask.BlockRoot[:]), "bn", txTask.BlockNum, "txn", txTask.TxNum) // return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("block hashk mismatch: %x != %x bn =%d, txn= %d", rh, txTask.BlockRoot[:], txTask.BlockNum, txTask.TxNum) @@ -442,9 +412,7 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err) } processedBlockNum = txTask.BlockNum - if !stopedAtBlockEnd { - stopedAtBlockEnd = txTask.Final - } + stopedAtBlockEnd = txTask.Final if forceStopAtBlockEnd && txTask.Final { break } @@ -454,12 +422,8 @@ func (pe *parallelExecutor) processResultQueue(ctx context.Context, inputTxNum u func (pe *parallelExecutor) run(ctx context.Context, maxTxNum uint64, logger log.Logger) context.CancelFunc { pe.slowDownLimit = time.NewTicker(time.Second) - pe.rwsConsumed = make(chan struct{}, 1) - pe.rwLoopErrCh = make(chan error) - pe.in = state.NewQueueWithRetry(100_000) - pe.execWorkers, _, pe.rws, pe.stopWorkers, pe.waitWorkers = exec3.NewWorkersPool( - pe.RWMutex.RLocker(), pe.accumulator, logger, ctx, true, pe.cfg.db, pe.rs, pe.in, + pe.RWMutex.RLocker(), pe.accumulator, logger, ctx, true, pe.chainDb, pe.rs, pe.in, pe.cfg.blockReader, pe.cfg.chainConfig, pe.cfg.genesis, pe.cfg.engine, pe.workerCount+1, pe.cfg.dirs, pe.isMining) rwLoopCtx, rwLoopCtxCancel := context.WithCancel(ctx) @@ -469,7 +433,7 @@ func (pe *parallelExecutor) run(ctx context.Context, maxTxNum uint64, logger log defer pe.in.Close() defer pe.applyLoopWg.Wait() defer func() { - logger.Warn("[dbg] rwloop exit") + log.Warn("[dbg] rwloop exit") }() return pe.rwLoop(rwLoopCtx, maxTxNum, logger) }) @@ -479,8 +443,6 @@ func (pe *parallelExecutor) run(ctx context.Context, maxTxNum uint64, logger log pe.slowDownLimit.Stop() pe.wait() pe.stopWorkers() - close(pe.rwsConsumed) - pe.in.Close() } } diff --git a/eth/stagedsync/exec3_serial.go b/eth/stagedsync/exec3_serial.go index cb271284533..2a59dc12099 100644 --- a/eth/stagedsync/exec3_serial.go +++ b/eth/stagedsync/exec3_serial.go @@ -4,22 +4,40 @@ import ( "context" "errors" "fmt" + "sync/atomic" "time" chaos_monkey "github.com/erigontech/erigon/tests/chaos-monkey" + "github.com/erigontech/erigon-lib/common" + "github.com/erigontech/erigon-lib/kv" "github.com/erigontech/erigon-lib/log/v3" state2 "github.com/erigontech/erigon-lib/state" + "github.com/erigontech/erigon/cmd/state/exec3" "github.com/erigontech/erigon/consensus" "github.com/erigontech/erigon/core" "github.com/erigontech/erigon/core/rawdb/rawtemporaldb" "github.com/erigontech/erigon/core/state" "github.com/erigontech/erigon/core/types" + "github.com/erigontech/erigon/turbo/shards" ) type serialExecutor struct { - txExecutor + cfg ExecuteBlockCfg + execStage *StageState + agg *state2.Aggregator + rs *state.StateV3 + doms *state2.SharedDomains + accumulator *shards.Accumulator + u Unwinder + isMining bool + inMemExec bool skipPostEvaluation bool + applyTx kv.RwTx + worker *exec3.Worker + outputTxNum *atomic.Uint64 + logger log.Logger + // outputs txCount uint64 usedGas uint64 @@ -40,7 +58,7 @@ func (se *serialExecutor) execute(ctx context.Context, tasks []*state.TxTask) (c return false, nil } - se.applyWorker.RunTxTaskNoLock(txTask, se.isMining) + se.worker.RunTxTaskNoLock(txTask, se.isMining) if err := func() error { if errors.Is(txTask.Error, context.Canceled) { return txTask.Error @@ -73,8 +91,6 @@ func (se *serialExecutor) execute(ctx context.Context, tasks []*state.TxTask) (c return fmt.Errorf("%w, txnIdx=%d, %v", consensus.ErrInvalidBlock, txTask.TxIndex, err) //same as in stage_exec.go } } - - se.outputBlockNum.SetUint64(txTask.BlockNum) } if se.cfg.syncCfg.ChaosMonkey { chaosErr := chaos_monkey.ThrowRandomConsensusError(se.execStage.CurrentSyncCycle.IsInitialCycle, txTask.TxIndex, se.cfg.badBlockHalt, txTask.Error) @@ -133,6 +149,27 @@ func (se *serialExecutor) execute(ctx context.Context, tasks []*state.TxTask) (c return true, nil } +func (se *serialExecutor) tx() kv.RwTx { + return se.applyTx +} + +func (se *serialExecutor) readState() *state.StateV3 { + return se.rs +} + +func (se *serialExecutor) domains() *state2.SharedDomains { + return se.doms +} + +func (se *serialExecutor) getHeader(ctx context.Context, hash common.Hash, number uint64) (h *types.Header) { + var err error + h, err = se.cfg.blockReader.Header(ctx, se.applyTx, hash, number) + if err != nil { + panic(err) + } + return h +} + func (se *serialExecutor) commit(ctx context.Context, txNum uint64, blockNum uint64, useExternalTx bool) (t2 time.Duration, err error) { se.doms.Close() if err = se.execStage.Update(se.applyTx, blockNum); err != nil { @@ -162,8 +199,8 @@ func (se *serialExecutor) commit(ctx context.Context, txNum uint64, blockNum uin se.doms.SetTxNum(txNum) se.rs = state.NewStateV3(se.doms, se.logger) - se.applyWorker.ResetTx(se.applyTx) - se.applyWorker.ResetState(se.rs, se.accumulator) + se.worker.ResetTx(se.applyTx) + se.worker.ResetState(se.rs, se.accumulator) return t2, nil } diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index ba223d598f9..e8f84ce44bf 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -676,12 +676,8 @@ func (do *dbObj) GetBalance(addrSlice goja.Value) goja.Value { return nil } addr := libcommon.BytesToAddress(a) - value, err := do.ibs.GetBalance(addr) - if err != nil { - do.vm.Interrupt(err) - return nil - } - res, err := do.toBig(do.vm, value.ToBig().String()) + value := do.ibs.GetBalance(addr).ToBig() + res, err := do.toBig(do.vm, value.String()) if err != nil { do.vm.Interrupt(err) return nil @@ -696,12 +692,7 @@ func (do *dbObj) GetNonce(addrSlice goja.Value) uint64 { return 0 } addr := libcommon.BytesToAddress(a) - nonce, err := do.ibs.GetNonce(addr) - if err != nil { - do.vm.Interrupt(err) - return 0 - } - return nonce + return do.ibs.GetNonce(addr) } func (do *dbObj) GetCode(addrSlice goja.Value) goja.Value { @@ -711,11 +702,7 @@ func (do *dbObj) GetCode(addrSlice goja.Value) goja.Value { return nil } addr := libcommon.BytesToAddress(a) - code, err := do.ibs.GetCode(addr) - if err != nil { - do.vm.Interrupt(err) - return nil - } + code := do.ibs.GetCode(addr) res, err := do.toBuf(do.vm, code) if err != nil { do.vm.Interrupt(err) @@ -754,12 +741,7 @@ func (do *dbObj) Exists(addrSlice goja.Value) bool { return false } addr := libcommon.BytesToAddress(a) - exists, err := do.ibs.Exist(addr) - if err != nil { - do.vm.Interrupt(err) - return false - } - return exists + return do.ibs.Exist(addr) } func (do *dbObj) setupObject() *goja.Object { diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index 8e43dd6a44a..96624bca385 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -56,10 +56,8 @@ type dummyStatedb struct { state.IntraBlockState } -func (*dummyStatedb) GetRefund() uint64 { return 1337 } -func (*dummyStatedb) GetBalance(addr libcommon.Address) (*uint256.Int, error) { - return &uint256.Int{}, nil -} +func (*dummyStatedb) GetRefund() uint64 { return 1337 } +func (*dummyStatedb) GetBalance(addr libcommon.Address) *uint256.Int { return &uint256.Int{} } type vmContext struct { blockCtx evmtypes.BlockContext diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index 9dbfe7d8ebc..882bb51955b 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -222,7 +222,7 @@ func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint6 if op == vm.CREATE { // contract address for CREATE can only be generated with state if a.state != nil { - nonce, _ := a.state.GetNonce(caller) + nonce := a.state.GetNonce(caller) addr := crypto.CreateAddress(caller, nonce) if _, ok := a.excl[addr]; !ok { a.createdContracts[addr] = struct{}{} @@ -240,6 +240,7 @@ func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint6 a.createdContracts[addr] = struct{}{} } } + } func (*AccessListTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 0a896748906..e32084d263f 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -171,7 +171,7 @@ func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, addr := libcommon.Address(stackData[stackLen-2].Bytes20()) t.lookupAccount(addr) case op == vm.CREATE: - nonce, _ := t.env.IntraBlockState().GetNonce(caller) + nonce := t.env.IntraBlockState().GetNonce(caller) addr := crypto.CreateAddress(caller, nonce) t.lookupAccount(addr) t.created[addr] = true @@ -203,12 +203,12 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) { } modified := false postAccount := &account{Storage: make(map[libcommon.Hash]libcommon.Hash)} - newBalance, _ := t.env.IntraBlockState().GetBalance(addr) - newNonce, _ := t.env.IntraBlockState().GetNonce(addr) + newBalance := t.env.IntraBlockState().GetBalance(addr).ToBig() + newNonce := t.env.IntraBlockState().GetNonce(addr) - if newBalance.ToBig().Cmp(t.pre[addr].Balance) != 0 { + if newBalance.Cmp(t.pre[addr].Balance) != 0 { modified = true - postAccount.Balance = newBalance.ToBig() + postAccount.Balance = newBalance } if newNonce != t.pre[addr].Nonce { modified = true @@ -216,7 +216,7 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) { } if !t.config.DisableCode { - newCode, _ := t.env.IntraBlockState().GetCode(addr) + newCode := t.env.IntraBlockState().GetCode(addr) if !bytes.Equal(newCode, t.pre[addr].Code) { modified = true postAccount.Code = newCode @@ -292,17 +292,13 @@ func (t *prestateTracer) lookupAccount(addr libcommon.Address) { return } - balance, _ := t.env.IntraBlockState().GetBalance(addr) - nonce, _ := t.env.IntraBlockState().GetNonce(addr) - code, _ := t.env.IntraBlockState().GetCode(addr) - t.pre[addr] = &account{ - Balance: balance.ToBig(), - Nonce: nonce, + Balance: t.env.IntraBlockState().GetBalance(addr).ToBig(), + Nonce: t.env.IntraBlockState().GetNonce(addr), } if !t.config.DisableCode { - t.pre[addr].Code = code + t.pre[addr].Code = t.env.IntraBlockState().GetCode(addr) } if !t.config.DisableStorage { t.pre[addr].Storage = make(map[libcommon.Hash]libcommon.Hash) diff --git a/polygon/bor/bor.go b/polygon/bor/bor.go index 1bba50d515d..36337ac941c 100644 --- a/polygon/bor/bor.go +++ b/polygon/bor/bor.go @@ -1673,42 +1673,22 @@ func (c *Bor) getNextHeimdallSpanForTest( } // BorTransfer transfer in Bor -func BorTransfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) error { +func BorTransfer(db evmtypes.IntraBlockState, sender, recipient libcommon.Address, amount *uint256.Int, bailout bool) { // get inputs before - input1, err := db.GetBalance(sender) - if err != nil { - return err - } - input1 = input1.Clone() - input2, err := db.GetBalance(recipient) - if err != nil { - return err - } - input2 = input2.Clone() + input1 := db.GetBalance(sender).Clone() + input2 := db.GetBalance(recipient).Clone() + if !bailout { - err := db.SubBalance(sender, amount, tracing.BalanceChangeTransfer) - if err != nil { - return err - } - } - err = db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer) - if err != nil { - return err + db.SubBalance(sender, amount, tracing.BalanceChangeTransfer) } + db.AddBalance(recipient, amount, tracing.BalanceChangeTransfer) + // get outputs after - output1, err := db.GetBalance(sender) - if err != nil { - return err - } - output1 = output1.Clone() - output2, err := db.GetBalance(recipient) - if err != nil { - return err - } - output2 = output2.Clone() + output1 := db.GetBalance(sender).Clone() + output2 := db.GetBalance(recipient).Clone() + // add transfer log into state addTransferLog(db, transferLogSig, sender, recipient, amount, input1, input2, output1, output2) - return nil } func (c *Bor) GetTransferFunc() evmtypes.TransferFunc { diff --git a/tests/block_test_util.go b/tests/block_test_util.go index c7241381b04..079da8e4280 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -320,18 +320,9 @@ func (bt *BlockTest) validatePostState(statedb *state.IntraBlockState) error { // validate post state accounts in test file against what we have in state db for addr, acct := range bt.json.Post { // address is indirectly verified by the other fields, as it's the db key - code2, err := statedb.GetCode(addr) - if err != nil { - return err - } - balance2, err := statedb.GetBalance(addr) - if err != nil { - return err - } - nonce2, err := statedb.GetNonce(addr) - if err != nil { - return err - } + code2 := statedb.GetCode(addr) + balance2 := statedb.GetBalance(addr) + nonce2 := statedb.GetNonce(addr) if nonce2 != acct.Nonce { return fmt.Errorf("account nonce mismatch for addr: %x want: %d have: %d", addr, acct.Nonce, nonce2) } diff --git a/tests/execution-spec-tests b/tests/execution-spec-tests new file mode 160000 index 00000000000..c53c43d7efe --- /dev/null +++ b/tests/execution-spec-tests @@ -0,0 +1 @@ +Subproject commit c53c43d7efe94c5e972252533b1aee3669323fe1 diff --git a/tests/statedb_chain_test.go b/tests/statedb_chain_test.go index 525b3c0f12c..7449ea92215 100644 --- a/tests/statedb_chain_test.go +++ b/tests/statedb_chain_test.go @@ -105,18 +105,10 @@ func TestSelfDestructReceive(t *testing.T) { if err := m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(address) - if err != nil { - return err - } - if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } return nil @@ -139,25 +131,13 @@ func TestSelfDestructReceive(t *testing.T) { // and that means that the state of the accounts written in the first block was correct. // This test checks that the storage root of the account is properly set to the root of the empty tree st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(address) - if err != nil { - t.Error(err) - } - if !exist { + if !st.Exist(address) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - t.Error(err) - } - if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 2", contractAddress.String()) } - code, err := st.GetCode(contractAddress) - if err != nil { - t.Error(err) - } - if len(code) != 0 { + if len(st.GetCode(contractAddress)) != 0 { t.Error("expected empty code in contract at block 2", contractAddress.String()) } return nil diff --git a/tests/statedb_insert_chain_transaction_test.go b/tests/statedb_insert_chain_transaction_test.go index a2d3eddd264..e9f28a610d2 100644 --- a/tests/statedb_insert_chain_transaction_test.go +++ b/tests/statedb_insert_chain_transaction_test.go @@ -93,33 +93,17 @@ func TestInsertIncorrectStateRootDifferentAccounts(t *testing.T) { defer tx.Rollback() st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(to) - if err != nil { - t.Error(err) - } - if !exist { + if !st.Exist(to) { t.Error("expected account to exist") } - balance, err := st.GetBalance(from) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 1000000000 { + if balance := st.GetBalance(from); balance.Uint64() != 1000000000 { t.Fatalf("got %v, expected %v", balance, 1000000000) } - balance, err = st.GetBalance(data.addresses[1]) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 999995000 { + if balance := st.GetBalance(data.addresses[1]); balance.Uint64() != 999995000 { t.Fatalf("got %v, expected %v", balance, 999995000) } - balance, err = st.GetBalance(to) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 5000 { + if balance := st.GetBalance(to); balance.Uint64() != 5000 { t.Fatalf("got %v, expected %v", balance, 5000) } } @@ -177,26 +161,14 @@ func TestInsertIncorrectStateRootSameAccount(t *testing.T) { defer tx.Rollback() st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(to) - if err != nil { - t.Error(err) - } - if !exist { + if !st.Exist(to) { t.Error("expected account to exist") } - balance, err := st.GetBalance(from) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 999995000 { + if balance := st.GetBalance(from); balance.Uint64() != 999995000 { t.Fatalf("got %v, expected %v", balance, 999995000) } - balance, err = st.GetBalance(to) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 5000 { + if balance := st.GetBalance(to); balance.Uint64() != 5000 { t.Fatalf("got %v, expected %v", balance, 5000) } } @@ -251,26 +223,14 @@ func TestInsertIncorrectStateRootSameAccountSameAmount(t *testing.T) { defer tx.Rollback() st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(to) - if err != nil { - t.Error(err) - } - if !exist { + if !st.Exist(to) { t.Error("expected account to exist") } - balance, err := st.GetBalance(from) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 999999000 { + if balance := st.GetBalance(from); balance.Uint64() != 999999000 { t.Fatalf("got %v, expected %v", balance, 999999000) } - balance, err = st.GetBalance(to) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 1000 { + if balance := st.GetBalance(to); balance.Uint64() != 1000 { t.Fatalf("got %v, expected %v", balance, 1000) } } @@ -325,26 +285,14 @@ func TestInsertIncorrectStateRootAllFundsRoot(t *testing.T) { defer tx.Rollback() st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(to) - if err != nil { - t.Error(err) - } - if !exist { + if !st.Exist(to) { t.Error("expected account to exist") } - balance, err := st.GetBalance(from) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 2000 { + if balance := st.GetBalance(from); balance.Uint64() != 2000 { t.Fatalf("got %v, expected %v", balance, 2000) } - balance, err = st.GetBalance(to) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 1000 { + if balance := st.GetBalance(to); balance.Uint64() != 1000 { t.Fatalf("got %v, expected %v", balance, 1000) } } @@ -399,26 +347,14 @@ func TestInsertIncorrectStateRootAllFunds(t *testing.T) { defer tx.Rollback() st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(to) - if err != nil { - t.Error(err) - } - if !exist { + if !st.Exist(to) { t.Error("expected account to exist") } - balance, err := st.GetBalance(from) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 2000 { + if balance := st.GetBalance(from); balance.Uint64() != 2000 { t.Fatalf("got %v, expected %v", balance, 2000) } - balance, err = st.GetBalance(to) - if err != nil { - t.Error(err) - } - if balance.Uint64() != 1000 { + if balance := st.GetBalance(to); balance.Uint64() != 1000 { t.Fatalf("got %v, expected %v", balance, 1000) } } @@ -452,18 +388,11 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if exist { + + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String()) } return nil @@ -482,19 +411,11 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist at the block 1", contractAddress.Hash().String()) } return nil @@ -508,19 +429,11 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to not exist at the block 1", contractAddress.Hash().String()) } return nil @@ -562,19 +475,11 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String()) } @@ -588,19 +493,11 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 2", contractAddress.Hash().String()) } @@ -662,19 +559,11 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String()) } @@ -689,19 +578,11 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 2", contractAddress.Hash().String()) } return nil @@ -767,19 +648,11 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if exist { + if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist at the block 0", contractAddress.Hash().String()) } return nil @@ -793,19 +666,11 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { err = m.DB.View(context.Background(), func(tx kv.Tx) error { st := state.New(m.NewStateReader(tx)) - exist, err := st.Exist(from) - if err != nil { - return err - } - if !exist { + if !st.Exist(from) { t.Error("expected account to exist") } - exist, err = st.Exist(contractAddress) - if err != nil { - return err - } - if !exist { + if !st.Exist(contractAddress) { t.Error("expected contractAddress to exist at the block 1", contractAddress.Hash().String()) } return nil diff --git a/turbo/jsonrpc/eth_call.go b/turbo/jsonrpc/eth_call.go index 2f9cd154068..cc6d8dc748a 100644 --- a/turbo/jsonrpc/eth_call.go +++ b/turbo/jsonrpc/eth_call.go @@ -205,10 +205,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs return 0, errors.New("can't get the current state") } - balance, err := state.GetBalance(*args.From) // from can't be nil - if err != nil { - return 0, err - } + balance := state.GetBalance(*args.From) // from can't be nil available := balance.ToBig() if args.Value != nil { if args.Value.ToInt().Cmp(available) >= 0 { diff --git a/turbo/jsonrpc/eth_call_test.go b/turbo/jsonrpc/eth_call_test.go index c8dfee1d378..b78c18a4a02 100644 --- a/turbo/jsonrpc/eth_call_test.go +++ b/turbo/jsonrpc/eth_call_test.go @@ -553,17 +553,13 @@ func chainWithDeployedContract(t *testing.T) (*mock.MockSentry, libcommon.Addres assert.NoError(t, err) st := state.New(stateReader) assert.NoError(t, err) - exist, err := st.Exist(contractAddr) - assert.NoError(t, err) - assert.False(t, exist, "Contract should not exist at block #1") + assert.False(t, st.Exist(contractAddr), "Contract should not exist at block #1") stateReader, err = rpchelper.CreateHistoryStateReader(tx, rawdbv3.TxNums, 2, 0, "") assert.NoError(t, err) st = state.New(stateReader) assert.NoError(t, err) - exist, err = st.Exist(contractAddr) - assert.NoError(t, err) - assert.True(t, exist, "Contract should exist at block #2") + assert.True(t, st.Exist(contractAddr), "Contract should exist at block #2") return m, bankAddress, contractAddr } diff --git a/turbo/jsonrpc/overlay_api.go b/turbo/jsonrpc/overlay_api.go index dead2ff8405..ba4e970f01b 100644 --- a/turbo/jsonrpc/overlay_api.go +++ b/turbo/jsonrpc/overlay_api.go @@ -237,10 +237,7 @@ func (api *OverlayAPIImpl) CallConstructor(ctx context.Context, address common.A if err != nil { return nil, err } - code, err := evm.IntraBlockState().GetCode(address) - if err != nil { - return nil, err - } + code := evm.IntraBlockState().GetCode(address) if len(code) > 0 { c := hexutility.Bytes(code) resultCode.Code = &c @@ -509,16 +506,7 @@ func (api *OverlayAPIImpl) replayBlock(ctx context.Context, blockNum uint64, sta if !contractCreation { // bump the nonce of the sender sender := vm.AccountRef(msg.From()) - nonce, err := statedb.GetNonce(sender.Address()) - if err != nil { - log.Error(err.Error()) - return nil, err - } - err = statedb.SetNonce(msg.From(), nonce+1) - if err != nil { - log.Error(err.Error()) - return nil, err - } + statedb.SetNonce(msg.From(), statedb.GetNonce(sender.Address())+1) continue } } diff --git a/turbo/jsonrpc/overlay_create_tracer.go b/turbo/jsonrpc/overlay_create_tracer.go index c80641a5465..29be53228a8 100644 --- a/turbo/jsonrpc/overlay_create_tracer.go +++ b/turbo/jsonrpc/overlay_create_tracer.go @@ -55,11 +55,7 @@ func (ct *OverlayCreateTracer) CaptureEnter(typ vm.OpCode, from libcommon.Addres if err != nil { ct.err = err } else { - if result, err := ct.evm.IntraBlockState().GetCode(ct.contractAddress); err != nil { - ct.resultCode = result - } else { - ct.err = err - } + ct.resultCode = ct.evm.IntraBlockState().GetCode(ct.contractAddress) } } } diff --git a/turbo/jsonrpc/trace_adhoc.go b/turbo/jsonrpc/trace_adhoc.go index 0a24f0beca4..86c2ba0db9d 100644 --- a/turbo/jsonrpc/trace_adhoc.go +++ b/turbo/jsonrpc/trace_adhoc.go @@ -662,30 +662,16 @@ func (sd *StateDiff) CreateContract(address libcommon.Address) error { } // CompareStates uses the addresses accumulated in the sdMap and compares balances, nonces, and codes of the accounts, and fills the rest of the sdMap -func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) error { +func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) { var toRemove []libcommon.Address for addr, accountDiff := range sd.sdMap { - initialExist, err := initialIbs.Exist(addr) - if err != nil { - return err - } - exist, err := ibs.Exist(addr) - if err != nil { - return err - } + initialExist := initialIbs.Exist(addr) + exist := ibs.Exist(addr) if initialExist { if exist { var allEqual = len(accountDiff.Storage) == 0 - ifromBalance, err := initialIbs.GetBalance(addr) - if err != nil { - return err - } - fromBalance := ifromBalance.ToBig() - itoBalance, err := ibs.GetBalance(addr) - if err != nil { - return err - } - toBalance := itoBalance.ToBig() + fromBalance := initialIbs.GetBalance(addr).ToBig() + toBalance := ibs.GetBalance(addr).ToBig() if fromBalance.Cmp(toBalance) == 0 { accountDiff.Balance = "=" } else { @@ -694,14 +680,8 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) error accountDiff.Balance = m allEqual = false } - fromCode, err := initialIbs.GetCode(addr) - if err != nil { - return err - } - toCode, err := ibs.GetCode(addr) - if err != nil { - return err - } + fromCode := initialIbs.GetCode(addr) + toCode := ibs.GetCode(addr) if bytes.Equal(fromCode, toCode) { accountDiff.Code = "=" } else { @@ -710,14 +690,8 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) error accountDiff.Code = m allEqual = false } - fromNonce, err := initialIbs.GetNonce(addr) - if err != nil { - return err - } - toNonce, err := ibs.GetNonce(addr) - if err != nil { - return err - } + fromNonce := initialIbs.GetNonce(addr) + toNonce := ibs.GetNonce(addr) if fromNonce == toNonce { accountDiff.Nonce = "=" } else { @@ -731,59 +705,35 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) error } } else { { - balance, err := initialIbs.GetBalance(addr) - if err != nil { - return err - } m := make(map[string]*hexutil.Big) - m["-"] = (*hexutil.Big)(balance.ToBig()) + m["-"] = (*hexutil.Big)(initialIbs.GetBalance(addr).ToBig()) accountDiff.Balance = m } { - code, err := initialIbs.GetCode(addr) - if err != nil { - return err - } m := make(map[string]hexutility.Bytes) - m["-"] = code + m["-"] = initialIbs.GetCode(addr) accountDiff.Code = m } { - nonce, err := initialIbs.GetNonce(addr) - if err != nil { - return err - } m := make(map[string]hexutil.Uint64) - m["-"] = hexutil.Uint64(nonce) + m["-"] = hexutil.Uint64(initialIbs.GetNonce(addr)) accountDiff.Nonce = m } } } else if exist { { - balance, err := ibs.GetBalance(addr) - if err != nil { - return err - } m := make(map[string]*hexutil.Big) - m["+"] = (*hexutil.Big)(balance.ToBig()) + m["+"] = (*hexutil.Big)(ibs.GetBalance(addr).ToBig()) accountDiff.Balance = m } { - code, err := ibs.GetCode(addr) - if err != nil { - return err - } m := make(map[string]hexutility.Bytes) - m["+"] = code + m["+"] = ibs.GetCode(addr) accountDiff.Code = m } { - nonce, err := ibs.GetNonce(addr) - if err != nil { - return err - } m := make(map[string]hexutil.Uint64) - m["+"] = hexutil.Uint64(nonce) + m["+"] = hexutil.Uint64(ibs.GetNonce(addr)) accountDiff.Nonce = m } // Transform storage @@ -799,7 +749,6 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) error for _, addr := range toRemove { delete(sd.sdMap, addr) } - return nil } func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool, traceConfig *config.TraceConfig) (*TraceCallResult, error) { diff --git a/turbo/stages/blockchain_test.go b/turbo/stages/blockchain_test.go index a37243413bc..3c58f35a1b4 100644 --- a/turbo/stages/blockchain_test.go +++ b/turbo/stages/blockchain_test.go @@ -1015,11 +1015,7 @@ func TestEIP161AccountRemoval(t *testing.T) { return } defer tx.Rollback() - exist, err := state.New(m.NewStateReader(tx)).Exist(theAddr) - if err != nil { - t.Fatal(err) - } - if !exist { + if st := state.New(m.NewStateReader(tx)); !st.Exist(theAddr) { t.Error("expected account to exist") } tx.Rollback() @@ -1029,11 +1025,7 @@ func TestEIP161AccountRemoval(t *testing.T) { t.Fatal(err) } if err = m.DB.View(m.Ctx, func(tx kv.Tx) error { - exist, err := state.New(m.NewStateReader(tx)).Exist(theAddr) - if err != nil { - return err - } - if exist { + if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } return nil @@ -1046,11 +1038,7 @@ func TestEIP161AccountRemoval(t *testing.T) { t.Fatal(err) } if err = m.DB.View(m.Ctx, func(tx kv.Tx) error { - exist, err := state.New(m.NewStateReader(tx)).Exist(theAddr) - if err != nil { - return err - } - if exist { + if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } return nil @@ -1116,27 +1104,19 @@ func TestDoubleAccountRemoval(t *testing.T) { st := state.New(m.NewStateReader(tx)) assert.NoError(t, err) - exist, err := st.Exist(theAddr) - assert.NoError(t, err) - assert.False(t, exist, "Contract should've been removed") + assert.False(t, st.Exist(theAddr), "Contract should've been removed") st = state.New(m.NewHistoryStateReader(1, tx)) assert.NoError(t, err) - exist, err = st.Exist(theAddr) - assert.NoError(t, err) - assert.False(t, exist, "Contract should not exist at block #0") + assert.False(t, st.Exist(theAddr), "Contract should not exist at block #0") st = state.New(m.NewHistoryStateReader(2, tx)) assert.NoError(t, err) - exist, err = st.Exist(theAddr) - assert.NoError(t, err) - assert.True(t, exist, "Contract should exist at block #1") + assert.True(t, st.Exist(theAddr), "Contract should exist at block #1") st = state.New(m.NewHistoryStateReader(3, tx)) assert.NoError(t, err) - exist, err = st.Exist(theAddr) - assert.NoError(t, err) - assert.True(t, exist, "Contract should exist at block #2") + assert.True(t, st.Exist(theAddr), "Contract should exist at block #2") } // This is a regression test (i.e. as weird as it is, don't delete it ever), which @@ -1628,10 +1608,7 @@ func TestCVE2020_26265(t *testing.T) { reader := m.NewHistoryStateReader(2, tx) statedb := state.New(reader) - got, err := statedb.GetBalance(aa) - if err != nil { - t.Fatal(err) - } + got := statedb.GetBalance(aa) if !got.Eq(new(uint256.Int).SetUint64(5)) { t.Errorf("got %x exp %x", got, 5) } @@ -1893,11 +1870,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) { } exp := expectations[i] if exp.exist { - exist, err := statedb.Exist(aa) - if err != nil { - t.Fatal(err) - } - if !exist { + if !statedb.Exist(aa) { t.Fatalf("block %d, expected %x to exist, it did not", blockNum, aa) } for slot, val := range exp.values { @@ -1909,11 +1882,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) { } } } else { - exist, err := statedb.Exist(aa) - if err != nil { - t.Fatal(err) - } - if exist { + if statedb.Exist(aa) { t.Fatalf("block %d, expected %x to not exist, it did", blockNum, aa) } } @@ -2019,11 +1988,7 @@ func TestInitThenFailCreateContract(t *testing.T) { // Import the canonical chain statedb := state.New(m.NewHistoryStateReader(2, tx)) - got, err := statedb.GetBalance(aa) - if err != nil { - return err - } - if exp := uint64(100000); got.Uint64() != exp { + if got, exp := statedb.GetBalance(aa), uint64(100000); got.Uint64() != exp { t.Fatalf("Genesis err, got %v exp %v", got, exp) } // First block tries to create, but fails @@ -2033,11 +1998,7 @@ func TestInitThenFailCreateContract(t *testing.T) { t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err) } statedb = state.New(m.NewHistoryStateReader(1, tx)) - got, err := statedb.GetBalance(aa) - if err != nil { - return err - } - if exp := uint64(100000); got.Uint64() != exp { + if got, exp := statedb.GetBalance(aa), uint64(100000); got.Uint64() != exp { t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp) } } @@ -2237,10 +2198,7 @@ func TestEIP1559Transition(t *testing.T) { statedb := state.New(m.NewHistoryStateReader(1, tx)) // 3: Ensure that miner received only the tx's tip. - actual, err := statedb.GetBalance(block.Coinbase()) - if err != nil { - return err - } + actual := statedb.GetBalance(block.Coinbase()) expected := new(uint256.Int).Add( new(uint256.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GetPrice().Uint64()), ethash.ConstantinopleBlockReward, @@ -2250,11 +2208,7 @@ func TestEIP1559Transition(t *testing.T) { } // 4: Ensure the txn sender paid for the gasUsed * (tip + block baseFee). - balance, err := statedb.GetBalance(addr1) - if err != nil { - return err - } - actual = new(uint256.Int).Sub(funds, balance) + actual = new(uint256.Int).Sub(funds, statedb.GetBalance(addr1)) expected = new(uint256.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GetPrice().Uint64() + block.BaseFee().Uint64())) if actual.Cmp(expected) != 0 { t.Fatalf("sender expenditure incorrect: expected %d, got %d", expected, actual) @@ -2286,10 +2240,7 @@ func TestEIP1559Transition(t *testing.T) { effectiveTip := block.Transactions()[0].GetPrice().Uint64() - block.BaseFee().Uint64() // 6+5: Ensure that miner received only the tx's effective tip. - actual, err := statedb.GetBalance(block.Coinbase()) - if err != nil { - return err - } + actual := statedb.GetBalance(block.Coinbase()) expected := new(uint256.Int).Add( new(uint256.Int).SetUint64(block.GasUsed()*effectiveTip), ethash.ConstantinopleBlockReward, @@ -2299,11 +2250,7 @@ func TestEIP1559Transition(t *testing.T) { } // 4: Ensure the txn sender paid for the gasUsed * (effectiveTip + block baseFee). - balance, err := statedb.GetBalance(addr2) - if err != nil { - return err - } - actual = new(uint256.Int).Sub(funds, balance) + actual = new(uint256.Int).Sub(funds, statedb.GetBalance(addr2)) expected = new(uint256.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64())) if actual.Cmp(expected) != 0 { t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual) diff --git a/turbo/stages/chain_makers_test.go b/turbo/stages/chain_makers_test.go index e33f34ef5dd..08dcd772cc2 100644 --- a/turbo/stages/chain_makers_test.go +++ b/turbo/stages/chain_makers_test.go @@ -118,26 +118,14 @@ func TestGenerateChain(t *testing.T) { if big.NewInt(5).Cmp(current(m, tx).Number()) != 0 { t.Errorf("wrong block number: %d", current(m, tx).Number()) } - balance, err := st.GetBalance(addr1) - if err != nil { - t.Error(err) - } - if !uint256.NewInt(989000).Eq(balance) { - t.Errorf("wrong balance of addr1: %s", balance) - } - balance, err = st.GetBalance(addr2) - if err != nil { - t.Error(err) - } - if !uint256.NewInt(10000).Eq(balance) { - t.Errorf("wrong balance of addr2: %s", balance) + if !uint256.NewInt(989000).Eq(st.GetBalance(addr1)) { + t.Errorf("wrong balance of addr1: %s", st.GetBalance(addr1)) } - balance, err = st.GetBalance(addr3) - if err != nil { - t.Error(err) + if !uint256.NewInt(10000).Eq(st.GetBalance(addr2)) { + t.Errorf("wrong balance of addr2: %s", st.GetBalance(addr2)) } - if fmt.Sprintf("%s", balance) != "19687500000000001000" { //nolint - t.Errorf("wrong balance of addr3: %s", balance) + if fmt.Sprintf("%s", st.GetBalance(addr3)) != "19687500000000001000" { //nolint + t.Errorf("wrong balance of addr3: %s", st.GetBalance(addr3)) } if sentry_multi_client.EnableP2PReceipts {