core/vm: removed context.Context from evm ENV (review change)

Removed the context.Context cancellation approach from vm.Environment
and added a Cancel method instead; this however makes the environment a
one shot object due to the `evm.abort` being set to 1, disallowing any
further operation to be done using that environment.
This commit is contained in:
Jeffrey Wilcke 2016-12-23 09:29:42 +01:00
parent 4e777fb7aa
commit 85921bbb85
5 changed files with 6 additions and 45 deletions

View file

@ -17,7 +17,6 @@
package core package core
import ( import (
"context"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -34,8 +33,6 @@ type HeaderFetcher interface {
// NewEVMContext creates a new context for use in the EVM. // NewEVMContext creates a new context for use in the EVM.
func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Context { func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Context {
return vm.Context{ return vm.Context{
Context: context.TODO(),
CanTransfer: CanTransfer, CanTransfer: CanTransfer,
Transfer: Transfer, Transfer: Transfer,
GetHash: GetHashFn(header, chain), GetHash: GetHashFn(header, chain),

View file

@ -17,7 +17,6 @@
package vm package vm
import ( import (
"context"
"fmt" "fmt"
"math/big" "math/big"
"sync/atomic" "sync/atomic"
@ -37,7 +36,6 @@ type (
// Context provides the EVM with auxilary information. Once provided it shouldn't be modified. // Context provides the EVM with auxilary information. Once provided it shouldn't be modified.
type Context struct { type Context struct {
context.Context
// CanTransfer returns whether the account contains // CanTransfer returns whether the account contains
// sufficient ether to transfer the value // sufficient ether to transfer the value
CanTransfer CanTransferFunc CanTransfer CanTransferFunc
@ -80,8 +78,6 @@ type EVM struct {
// abort is used to abort the EVM calling operations // abort is used to abort the EVM calling operations
// NOTE: must be set atomically // NOTE: must be set atomically
abort int32 abort int32
quit chan struct{}
} }
// NewEVM retutrns a new EVM evmironment. // NewEVM retutrns a new EVM evmironment.
@ -97,27 +93,16 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon
return evm return evm
} }
func (evm *EVM) init() { // Cancel cancels any running EVM operation. This may be called concurrently and it's safe to be
evm.quit = make(chan struct{}) // called multiple times.
go func() { func (evm *EVM) Cancel() {
select { atomic.StoreInt32(&evm.abort, 1)
case <-evm.quit:
return
case <-evm.Context.Done():
atomic.StoreInt32(&evm.abort, 1)
}
}()
} }
// Call executes the contract associated with the addr with the given input as paramaters. It also handles any // Call executes the contract associated with the addr with the given input as paramaters. It also handles any
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in // necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
// case of an execution error or failed value transfer. // case of an execution error or failed value transfer.
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) { func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
if evm.depth == 0 {
evm.init()
defer close(evm.quit)
}
if evm.vmConfig.NoRecursion && evm.depth > 0 { if evm.vmConfig.NoRecursion && evm.depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
@ -178,11 +163,6 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas,
// //
// CallCode differs from Call in the sense that it executes the given address' code with the caller as context. // CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) { func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
if evm.depth == 0 {
evm.init()
defer close(evm.quit)
}
if evm.vmConfig.NoRecursion && evm.depth > 0 { if evm.vmConfig.NoRecursion && evm.depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
@ -229,11 +209,6 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context // DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context
// and the caller is set to the caller of the caller. // and the caller is set to the caller of the caller.
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error) { func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error) {
if evm.depth == 0 {
evm.init()
defer close(evm.quit)
}
if evm.vmConfig.NoRecursion && evm.depth > 0 { if evm.vmConfig.NoRecursion && evm.depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)
@ -269,11 +244,6 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// Create creates a new contract using code as deployment code. // Create creates a new contract using code as deployment code.
func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error) { func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error) {
if evm.depth == 0 {
evm.init()
defer close(evm.quit)
}
if evm.vmConfig.NoRecursion && evm.depth > 0 { if evm.vmConfig.NoRecursion && evm.depth > 0 {
caller.ReturnGas(gas) caller.ReturnGas(gas)

View file

@ -17,7 +17,6 @@
package vm package vm
import ( import (
"context"
"math/big" "math/big"
"testing" "testing"
@ -53,7 +52,7 @@ func (d dummyStateDB) GetAccount(common.Address) Account {
func TestStoreCapture(t *testing.T) { func TestStoreCapture(t *testing.T) {
var ( var (
env = NewEVM(Context{Context: context.TODO()}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) env = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
logger = NewStructLogger(nil) logger = NewStructLogger(nil)
mem = NewMemory() mem = NewMemory()
stack = newstack() stack = newstack()
@ -80,7 +79,7 @@ func TestStorageCapture(t *testing.T) {
var ( var (
ref = &dummyContractRef{} ref = &dummyContractRef{}
contract = NewContract(ref, ref, new(big.Int), new(big.Int)) contract = NewContract(ref, ref, new(big.Int), new(big.Int))
env = NewEVM(Context{Context: context.TODO()}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false}) env = NewEVM(Context{}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
logger = NewStructLogger(nil) logger = NewStructLogger(nil)
mem = NewMemory() mem = NewMemory()
stack = newstack() stack = newstack()

View file

@ -17,7 +17,6 @@
package runtime package runtime
import ( import (
"context"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -28,7 +27,6 @@ import (
func NewEnv(cfg *Config, state *state.StateDB) *vm.EVM { func NewEnv(cfg *Config, state *state.StateDB) *vm.EVM {
context := vm.Context{ context := vm.Context{
Context: context.TODO(),
CanTransfer: core.CanTransfer, CanTransfer: core.CanTransfer,
Transfer: core.Transfer, Transfer: core.Transfer,
GetHash: func(uint64) common.Hash { return common.Hash{} }, GetHash: func(uint64) common.Hash { return common.Hash{} },

View file

@ -18,7 +18,6 @@ package tests
import ( import (
"bytes" "bytes"
"context"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"math/big" "math/big"
@ -191,8 +190,6 @@ func NewEVMEnvironment(vmTest bool, chainConfig *params.ChainConfig, statedb *st
} }
context := vm.Context{ context := vm.Context{
Context: context.TODO(),
CanTransfer: canTransfer, CanTransfer: canTransfer,
Transfer: transfer, Transfer: transfer,
GetHash: func(n uint64) common.Hash { GetHash: func(n uint64) common.Hash {