diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 7f3feed2fc..1182339fc7 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -282,7 +282,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM // Execute the call. msg := callmsg{call} - evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil) + evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain) // Ignore error, we're past header validation beneficiary, _ := b.blockchain.Engine().Author(block.Header()) blockContext := core.NewBlockContext(block.Header(), beneficiary, b.config) diff --git a/core/state/statedb.go b/core/state/statedb.go index 23cf8c991e..3ac0683a56 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -18,12 +18,12 @@ package state import ( + "bytes" "fmt" "math/big" "sort" "sync" - "bytes" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" diff --git a/core/vm/contract.go b/core/vm/contract.go index e3346073a9..b7db9dc66b 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -65,7 +65,7 @@ type Contract struct { } // NewPrecompiledContract returns a new contract environment for the execution of a precompiled contract -func NewPrecompiledContract( caller ContractRef, object ContractRef,value *big.Int, gas uint64) *Contract{ +func NewPrecompiledContract(caller ContractRef, object ContractRef, value *big.Int, gas uint64) *Contract { c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil} // Gas should be a pointer so it can safely be reduced through the run diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index 0de558612c..7c97f727a6 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -32,9 +32,10 @@ type twoOperandTest struct { func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - pc = uint64(0) + blockContext = &BlockContext{Coinbase: common.Address{}, BlockNumber: big.NewInt(1337), Intpool: NewIntpool()} + env = NewEVM(&Context{}, nil, params.TestChainConfig, &Config{}, blockContext) + stack = newstack() + pc = uint64(0) ) for i, test := range tests { x := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) @@ -50,13 +51,13 @@ func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64 // Check pool usage // 1.pool is not allowed to contain anything on the stack // 2.pool is not allowed to contain the same pointers twice - if env.interpreter.intPool.pool.len() > 0 { + if env.BlockContext.Intpool.pool.len() > 0 { poolvals := make(map[*big.Int]struct{}) poolvals[actual] = struct{}{} - for env.interpreter.intPool.pool.len() > 0 { - key := env.interpreter.intPool.get() + for env.BlockContext.Intpool.pool.len() > 0 { + key := env.BlockContext.Intpool.get() if _, exist := poolvals[key]; exist { t.Errorf("Testcase %d, pool contains double-entry", i) } @@ -68,8 +69,9 @@ func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64 func TestByteOp(t *testing.T) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) - stack = newstack() + blockContext = &BlockContext{Coinbase: common.Address{}, BlockNumber: big.NewInt(1337), Intpool: NewIntpool()} + env = NewEVM(&Context{}, nil, params.TestChainConfig, &Config{}, blockContext) + stack = newstack() ) tests := []struct { v string @@ -198,8 +200,9 @@ func TestSLT(t *testing.T) { func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) - stack = newstack() + blockContext = &BlockContext{Coinbase: common.Address{}, BlockNumber: big.NewInt(1337), Intpool: NewIntpool()} + env = NewEVM(&Context{}, nil, params.TestChainConfig, &Config{}, blockContext) + stack = newstack() ) // convert args byteArgs := make([][]byte, len(args)) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 18e342bef9..766244884a 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -50,13 +50,13 @@ type Interpreter struct { cfg *Config gasTable params.GasTable - readOnly bool // Whether to throw on stateful modifications - returnData []byte // Last CALL's return data for subsequent reuse + readOnly bool // Whether to throw on stateful modifications + returnData []byte // Last CALL's return data for subsequent reuse blockContext *BlockContext } // NewInterpreter returns a new instance of the Interpreter. -func NewInterpreter(evm *EVM, cfg *Config,blockContext *BlockContext) *Interpreter { +func NewInterpreter(evm *EVM, cfg *Config, blockContext *BlockContext) *Interpreter { // We use the STOP instruction whether to see // the jump table was initialised. If it was not // we'll set the default jump table. @@ -74,9 +74,9 @@ func NewInterpreter(evm *EVM, cfg *Config,blockContext *BlockContext) *Interpret } return &Interpreter{ - evm: evm, - cfg: cfg, - gasTable: evm.ChainConfig().GasTable(blockContext.BlockNumber), + evm: evm, + cfg: cfg, + gasTable: evm.ChainConfig().GasTable(blockContext.BlockNumber), blockContext: blockContext, } } diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go index 28830c445c..65d1eae38d 100644 --- a/core/vm/logger_test.go +++ b/core/vm/logger_test.go @@ -48,7 +48,10 @@ type dummyStateDB struct { func TestStoreCapture(t *testing.T) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + blkCtx = &BlockContext{ + Intpool: NewIntpool(), + } + env = NewEVM(&Context{}, nil, params.TestChainConfig, &Config{}, blkCtx) logger = NewStructLogger(nil) mem = NewMemory() stack = newstack() diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index 31c9b9cf9d..8c331123ff 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -19,23 +19,24 @@ package runtime import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" ) func NewEnv(cfg *Config) *vm.EVM { - context := vm.Context{ + context := &vm.Context{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, GetHash: func(uint64) common.Hash { return common.Hash{} }, - Origin: cfg.Origin, - Coinbase: cfg.Coinbase, - BlockNumber: cfg.BlockNumber, - Time: cfg.Time, - Difficulty: cfg.Difficulty, - GasLimit: cfg.GasLimit, GasPrice: cfg.GasPrice, } - - return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig) + header := &types.Header{ + Number: cfg.BlockNumber, + Time: cfg.Time, + Difficulty: cfg.Difficulty, + GasLimit: cfg.GasLimit, + } + blockContext := core.NewBlockContext(header, cfg.Coinbase, cfg.ChainConfig) + return vm.NewEVM(context, cfg.State, cfg.ChainConfig, &cfg.EVMConfig, blockContext) } diff --git a/eth/api_tracer.go b/eth/api_tracer.go index ca03dd6a2e..ef8d04fc14 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -17,15 +17,17 @@ package eth import ( + "bytes" + "context" "errors" "fmt" + "io/ioutil" + "runtime" + "sync" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - - "bytes" - "context" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" @@ -37,9 +39,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" - "io/ioutil" - "runtime" - "sync" ) const ( diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go index 117c376b81..07b796d49a 100644 --- a/eth/tracers/tracer_test.go +++ b/eth/tracers/tracer_test.go @@ -25,6 +25,8 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" ) @@ -43,8 +45,19 @@ func (account) ReturnGas(*big.Int) {} func (account) SetCode(common.Hash, []byte) {} func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} +func getEvm(tracer *Tracer) *vm.EVM { + header := &types.Header{ + Number: new(big.Int).SetUint64(1), + Time: new(big.Int).SetUint64(0), + Coinbase: common.Address{}, + Difficulty: big.NewInt(1000000), + } + blockContext := core.NewBlockContext(header, header.Coinbase, params.MainnetChainConfig) + return vm.NewEVM(&vm.Context{}, nil, params.TestChainConfig, &vm.Config{Debug: true, Tracer: tracer}, blockContext) + +} func runTrace(tracer *Tracer) (json.RawMessage, error) { - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + env := getEvm(tracer) contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} @@ -125,8 +138,7 @@ func TestHaltBetweenSteps(t *testing.T) { if err != nil { t.Fatal(err) } - - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + env := getEvm(tracer) contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index d25fc459a1..ccbe8c4a1a 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/tests" ) @@ -152,13 +153,16 @@ func TestCallTracer(t *testing.T) { CanTransfer: core.CanTransfer, Transfer: core.Transfer, Origin: origin, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: new(big.Int).SetUint64(uint64(test.Context.Time)), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), GasPrice: tx.GasPrice(), } + header := &types.Header{ + Coinbase: test.Context.Miner, + Number: new(big.Int).SetUint64(uint64(test.Context.Number)), + Time: new(big.Int).SetUint64(uint64(test.Context.Time)), + GasLimit: uint64(test.Context.GasLimit), + Difficulty: (*big.Int)(test.Context.Difficulty), + } + blockContext := core.NewBlockContext(header, header.Coinbase, params.MainnetChainConfig) statedb := tests.MakePreState(ethdb.NewMemDatabase(), test.Genesis.Alloc) // Create the tracer, the EVM environment and run it @@ -166,7 +170,7 @@ 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 := vm.NewEVM(&context, statedb, test.Genesis.Config, &vm.Config{Debug: true, Tracer: tracer}, blockContext) msg, err := tx.AsMessage(signer) if err != nil { diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index cb81c5b94e..45b648e999 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" @@ -135,15 +136,18 @@ func (t *VMTest) newEVM(statedb *state.StateDB, vmconfig vm.Config) *vm.EVM { Transfer: transfer, GetHash: vmTestBlockHash, Origin: t.json.Exec.Origin, - Coinbase: t.json.Env.Coinbase, - BlockNumber: new(big.Int).SetUint64(t.json.Env.Number), - Time: new(big.Int).SetUint64(t.json.Env.Timestamp), - GasLimit: t.json.Env.GasLimit, - Difficulty: t.json.Env.Difficulty, GasPrice: t.json.Exec.GasPrice, } + header := &types.Header{ + Coinbase: t.json.Env.Coinbase, + Number: new(big.Int).SetUint64(t.json.Env.Number), + Time: new(big.Int).SetUint64(t.json.Env.Timestamp), + GasLimit: t.json.Env.GasLimit, + Difficulty: t.json.Env.Difficulty, + } + blockContext := core.NewBlockContext(header, header.Coinbase, params.MainnetChainConfig) vmconfig.NoRecursion = true - return vm.NewEVM(context, statedb, params.MainnetChainConfig, vmconfig) + return vm.NewEVM(&context, statedb, params.MainnetChainConfig, &vmconfig, blockContext) } func vmTestBlockHash(n uint64) common.Hash {