diff --git a/core/state/statedb_logger.go b/core/state/statedb_logger.go index 987dbe117d77c..6e200ddc2e134 100644 --- a/core/state/statedb_logger.go +++ b/core/state/statedb_logger.go @@ -251,3 +251,8 @@ func (s *stateDBLogger) GetTrie() Trie { func (s *stateDBLogger) AccessEvents() *AccessEvents { return s.inner.AccessEvents() } + +// Error returns any memorized database failure occurred previously. +func (s *stateDBLogger) Error() error { + return s.inner.Error() +} diff --git a/core/vm/interface.go b/core/vm/interface.go index 6adc449e9d8cb..13bb17adb0eeb 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -114,6 +114,9 @@ type StateDB interface { GetTrie() state.Trie // AccessEvents returns the access-events collected for verkle-witness processing. AccessEvents() *state.AccessEvents + + // Error returns any memorized database failure occurred previously. + Error() error } // CallContext provides a basic interface for the EVM calling conventions. The EVM diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index d66e32b8c21ee..00b3d28b969f2 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1212,7 +1212,7 @@ func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *s return applyMessageWithEVM(ctx, evm, msg, state, timeout, gp) } -func applyMessageWithEVM(ctx context.Context, evm *vm.EVM, msg *core.Message, state *state.StateDB, timeout time.Duration, gp *core.GasPool) (*core.ExecutionResult, error) { +func applyMessageWithEVM(ctx context.Context, evm *vm.EVM, msg *core.Message, state vm.StateDB, timeout time.Duration, gp *core.GasPool) (*core.ExecutionResult, error) { // Wait for the context to be done and cancel the evm. Even if the // EVM has finished, cancelling may be done (repeatedly) go func() { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 384ca9f1cc731..6d17a6c5afb84 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -2195,6 +2195,7 @@ func TestSimulateV1(t *testing.T) { t.Fatalf("failed to unmarshal result: %v", err) } if !reflect.DeepEqual(have, tc.want) { + t.Log(string(resBytes)) t.Errorf("test %s, result mismatch, have\n%v\n, want\n%v\n", tc.name, have, tc.want) } }) diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 4371a42464803..5474ceefe5b02 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -188,6 +188,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, evm = vm.NewEVM(blockContext, vm.TxContext{GasPrice: new(big.Int)}, sim.state, sim.chainConfig, *vmConfig) ) sim.state.SetLogger(tracer.Hooks()) + logState := vm.StateDB(sim.state.Wrapped()) + if logState == nil { + logState = vm.StateDB(sim.state) + } // It is possible to override precompiles with EVM bytecode, or // move them to another address. if precompiles != nil { @@ -205,8 +209,8 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, tracer.reset(tx.Hash(), uint(i)) // EoA check is always skipped, even in validation mode. msg := call.ToMessage(header.BaseFee, !sim.validate, true) - evm.Reset(core.NewEVMTxContext(msg), sim.state) - result, err := applyMessageWithEVM(ctx, evm, msg, sim.state, timeout, sim.gp) + evm.Reset(core.NewEVMTxContext(msg), logState) + result, err := applyMessageWithEVM(ctx, evm, msg, logState, timeout, sim.gp) if err != nil { txErr := txValidationError(err) return nil, nil, txErr