Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all: Add an error return value to NewEVM #19175

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,10 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})
vmenv, err := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})
if err != nil {
return nil, 0, false, err
}
gaspool := new(core.GasPool).AddGas(math.MaxUint64)

return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
Expand Down
5 changes: 4 additions & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
context := NewEVMContext(msg, header, bc, author)
// Create a new environment which holds all relevant information
// about the transaction and calling mechanisms.
vmenv := vm.NewEVM(context, statedb, config, cfg)
vmenv, err := vm.NewEVM(context, statedb, config, cfg)
if err != nil {
return nil, 0, err
}
// Apply the transaction to the current state (included in the env)
_, gas, failed, err := ApplyMessage(vmenv, msg, gp)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ type EVM struct {

// NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*.
func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) (*EVM, error) {
evm := &EVM{
Context: ctx,
StateDB: statedb,
Expand Down Expand Up @@ -160,7 +160,7 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig))
evm.interpreter = evm.interpreters[0]

return evm
return evm, nil
}

// Cancel cancels any running EVM operation. This may be called concurrently and
Expand Down
31 changes: 25 additions & 6 deletions core/vm/instructions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ type twoOperandTest struct {
}

func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) {
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
if err != nil {
t.Fatalf("error creating the EVM object: %v", err)
}

var (
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
stack = newstack()
pc = uint64(0)
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
Expand Down Expand Up @@ -74,8 +78,11 @@ func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64
}

func TestByteOp(t *testing.T) {
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
if err != nil {
t.Fatalf("error creating the EVM object: %v", err)
}
var (
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
stack = newstack()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
)
Expand Down Expand Up @@ -209,8 +216,11 @@ func TestSLT(t *testing.T) {
}

func opBenchmark(bench *testing.B, op func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) {
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
if err != nil {
bench.Fatalf("error creating the EVM object: %v", err)
}
var (
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
stack = newstack()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
)
Expand Down Expand Up @@ -444,8 +454,11 @@ func BenchmarkOpIsZero(b *testing.B) {
}

func TestOpMstore(t *testing.T) {
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
if err != nil {
t.Fatalf("error creating the EVM object: %v", err)
}
var (
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
stack = newstack()
mem = NewMemory()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
Expand All @@ -470,8 +483,11 @@ func TestOpMstore(t *testing.T) {
}

func BenchmarkOpMstore(bench *testing.B) {
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
if err != nil {
bench.Fatalf("error creating the EVM object: %v", err)
}
var (
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
stack = newstack()
mem = NewMemory()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
Expand All @@ -493,8 +509,11 @@ func BenchmarkOpMstore(bench *testing.B) {
}

func BenchmarkOpSHA3(bench *testing.B) {
env, err := NewEVM(Context{}, nil, params.TestChainConfig, Config{})
if err != nil {
bench.Fatalf("error creating the EVM object: %v", err)
}
var (
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{})
stack = newstack()
mem = NewMemory()
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
Expand Down
6 changes: 5 additions & 1 deletion core/vm/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ type dummyStatedb struct {
func (*dummyStatedb) GetRefund() uint64 { return 1337 }

func TestStoreCapture(t *testing.T) {
env, err := NewEVM(Context{}, &dummyStatedb{}, params.TestChainConfig, Config{})
if err != nil {
t.Errorf("failed to create an EVM: %v", err)
}

var (
env = NewEVM(Context{}, &dummyStatedb{}, params.TestChainConfig, Config{})
logger = NewStructLogger(nil)
mem = NewMemory()
stack = newstack()
Expand Down
2 changes: 1 addition & 1 deletion core/vm/runtime/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
)

func NewEnv(cfg *Config) *vm.EVM {
func NewEnv(cfg *Config) (*vm.EVM, error) {
context := vm.Context{
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
Expand Down
21 changes: 15 additions & 6 deletions core/vm/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,12 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
}
var (
address = common.BytesToAddress([]byte("contract"))
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
)
vmenv, err := NewEnv(cfg)
if err != nil {
return nil, nil, err
}
cfg.State.CreateAccount(address)
// set the receiver's (the executing contract) code for execution.
cfg.State.SetCode(address, code)
Expand All @@ -131,10 +134,13 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
if cfg.State == nil {
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
}
var (
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
)

sender := vm.AccountRef(cfg.Origin)

vmenv, err := NewEnv(cfg)
if err != nil {
return nil, common.Address{}, 0, err
}

// Call the code with the given configuration.
code, address, leftOverGas, err := vmenv.Create(
Expand All @@ -154,7 +160,10 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) {
setDefaults(cfg)

vmenv := NewEnv(cfg)
vmenv, err := NewEnv(cfg)
if err != nil {
return nil, 0, err
}

sender := cfg.State.GetOrNewStateObject(cfg.Origin)
// Call the code with the given configuration.
Expand Down
4 changes: 3 additions & 1 deletion eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,14 @@ func (b *EthAPIBackend) GetTd(blockHash common.Hash) *big.Int {
return b.eth.blockchain.GetTdByHash(blockHash)
}

// GetEVM creates a new EVM object
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
state.SetBalance(msg.From(), math.MaxBig256)
vmError := func() error { return nil }

context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil)
return vm.NewEVM(context, state, b.eth.chainConfig, *b.eth.blockchain.GetVMConfig()), vmError, nil
evm, err := vm.NewEVM(context, state, b.eth.chainConfig, *b.eth.blockchain.GetVMConfig())
return evm, vmError, err
}

func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
Expand Down
20 changes: 16 additions & 4 deletions eth/api_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,10 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
msg, _ := tx.AsMessage(signer)
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)

vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{})
vmenv, err := vm.NewEVM(vmctx, statedb, api.config, vm.Config{})
if err != nil {
return nil, err
}
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
failed = err
break
Expand Down Expand Up @@ -595,7 +598,10 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
}
}
// Execute the transaction and flush any traces to disk
vmenv := vm.NewEVM(vmctx, statedb, api.config, vmConf)
vmenv, err := vm.NewEVM(vmctx, statedb, api.config, vmConf)
if err != nil {
return dumps, err
}
_, _, _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
if writer != nil {
writer.Flush()
Expand Down Expand Up @@ -756,7 +762,10 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
tracer = vm.NewStructLogger(config.LogConfig)
}
// Run the transaction with tracing enabled.
vmenv := vm.NewEVM(vmctx, statedb, api.config, vm.Config{Debug: true, Tracer: tracer})
vmenv, err := vm.NewEVM(vmctx, statedb, api.config, vm.Config{Debug: true, Tracer: tracer})
if err != nil {
return nil, fmt.Errorf("EVM creation failed: %v", err)
}

ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
if err != nil {
Expand Down Expand Up @@ -806,7 +815,10 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
return msg, context, statedb, nil
}
// Not yet the searched for transaction, execute on top of the current state
vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{})
vmenv, err := vm.NewEVM(context, statedb, api.config, vm.Config{})
if err != nil {
return nil, vm.Context{}, nil, fmt.Errorf("EVM creation failed: %v", err)
}
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
return nil, vm.Context{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
}
Expand Down
12 changes: 9 additions & 3 deletions eth/tracers/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ type dummyStatedb struct {
func (*dummyStatedb) GetRefund() uint64 { return 1337 }

func runTrace(tracer *Tracer) (json.RawMessage, error) {
env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
env, err := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
if err != nil {
return nil, err
}

contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000)
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}

_, err := env.Interpreter().Run(contract, []byte{}, false)
_, err = env.Interpreter().Run(contract, []byte{}, false)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -133,7 +136,10 @@ func TestHaltBetweenSteps(t *testing.T) {
t.Fatal(err)
}

env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
env, err := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
if err != nil {
t.Fatalf("error creating EVM object: %v", err)
}
contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0)

tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil)
Expand Down
10 changes: 8 additions & 2 deletions eth/tracers/tracers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ func TestPrestateTracerCreate2(t *testing.T) {
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
evm := vm.NewEVM(context, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
evm, err := vm.NewEVM(context, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
if err != nil {
t.Fatalf("failed to create EVM: %v", err)
}

msg, err := tx.AsMessage(signer)
if err != nil {
Expand Down Expand Up @@ -247,7 +250,10 @@ func TestCallTracer(t *testing.T) {
if err != nil {
t.Fatalf("failed to create call tracer: %v", err)
}
evm := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
evm, err := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
if err != nil {
t.Fatalf("failed to create EVM: %v", err)
}

msg, err := tx.AsMessage(signer)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion les/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,12 @@ func (b *LesApiBackend) GetTd(hash common.Hash) *big.Int {
return b.eth.blockchain.GetTdByHash(hash)
}

// GetEVM creates a new EVM object
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
state.SetBalance(msg.From(), math.MaxBig256)
context := core.NewEVMContext(msg, header, b.eth.blockchain, nil)
return vm.NewEVM(context, state, b.eth.chainConfig, vm.Config{}), state.Error, nil
vm, err := vm.NewEVM(context, state, b.eth.chainConfig, vm.Config{})
return vm, state.Error, err
}

func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
Expand Down
Loading