aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/evm
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm/evm')
-rw-r--r--core/vm/evm/evm.go114
-rw-r--r--core/vm/evm/evm_test.go13
-rw-r--r--core/vm/evm/gas_table.go16
-rw-r--r--core/vm/evm/instructions.go196
-rw-r--r--core/vm/evm/instructions_test.go102
-rw-r--r--core/vm/evm/interpreter.go51
-rw-r--r--core/vm/evm/logger_test.go7
-rw-r--r--core/vm/evm/oracle_contracts_test.go9
-rw-r--r--core/vm/evm/runtime/env.go10
-rw-r--r--core/vm/evm/runtime/runtime.go20
-rw-r--r--core/vm/evm/runtime/runtime_test.go50
11 files changed, 300 insertions, 288 deletions
diff --git a/core/vm/evm/evm.go b/core/vm/evm/evm.go
index e1c8c02ed..679d70b64 100644
--- a/core/vm/evm/evm.go
+++ b/core/vm/evm/evm.go
@@ -32,54 +32,7 @@ import (
var emptyCodeHash = crypto.Keccak256Hash(nil)
func init() {
- vm.Register(vm.EVM, &EVMImplement{})
-}
-
-type EVMImplement struct{}
-
-func (evmImpl *EVMImplement) Create(caller vm.ContractRef, code []byte, gas uint64,
- value *big.Int, interpreter vm.Interpreter) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
- i := interpreter.(*EVMInterpreter)
- return i.evm.Create(caller, code, gas, value)
-}
-
-func (evmImpl *EVMImplement) Create2(caller vm.ContractRef, code []byte, gas uint64,
- endowment *big.Int, salt *big.Int,
- interpreter vm.Interpreter) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
-
- i := interpreter.(*EVMInterpreter)
- return i.evm.Create2(caller, code, gas, endowment, salt)
-}
-
-func (evmImpl *EVMImplement) Call(caller vm.ContractRef, addr common.Address,
- input []byte, gas uint64, value *big.Int,
- interpreter vm.Interpreter) (ret []byte, leftOverGas uint64, err error) {
- i := interpreter.(*EVMInterpreter)
- return i.evm.Call(caller, addr, input, gas, value)
-
-}
-func (evmImpl *EVMImplement) CallCode(caller vm.ContractRef, addr common.Address,
- input []byte, gas uint64, value *big.Int,
- interpreter vm.Interpreter) (ret []byte, leftOverGas uint64, err error) {
-
- i := interpreter.(*EVMInterpreter)
- return i.evm.CallCode(caller, addr, input, gas, value)
-}
-
-func (evmImpl *EVMImplement) DelegateCall(caller vm.ContractRef, addr common.Address,
- input []byte, gas uint64,
- interpreter vm.Interpreter) (ret []byte, leftOverGas uint64, err error) {
-
- i := interpreter.(*EVMInterpreter)
- return i.evm.DelegateCall(caller, addr, input, gas)
-}
-
-func (evmImpl *EVMImplement) StaticCall(caller vm.ContractRef, addr common.Address,
- input []byte, gas uint64,
- interpreter vm.Interpreter) (ret []byte, leftovergas uint64, err error) {
-
- i := interpreter.(*EVMInterpreter)
- return i.evm.StaticCall(caller, addr, input, gas)
+ vm.Register(vm.EVM, NewEVM)
}
// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
@@ -123,11 +76,9 @@ func run(evm *EVM, contract *vm.Contract, input []byte, readOnly bool) ([]byte,
// The EVM should never be reused and is not thread safe.
type EVM struct {
// Context provides auxiliary blockchain related information
- vm.Context
+ *vm.Context
// StateDB gives access to the underlying state
StateDB vm.StateDB
- // Depth is the current call stack
- depth int
// chainConfig contains information about the current chain
chainConfig *params.ChainConfig
@@ -143,19 +94,16 @@ type EVM struct {
// abort is used to abort the EVM calling operations
// NOTE: must be set atomically
abort int32
- // callGasTemp holds the gas available for the current call. This is needed because the
- // available gas is calculated in gasCall* according to the 63/64 rule and later
- // applied in opCall*.
- callGasTemp uint64
}
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*.
-func NewEVM(ctx vm.Context, statedb vm.StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
+func NewEVM(ctx *vm.Context, statedb vm.StateDB, chainConfig *params.ChainConfig, vmConfig interface{}) vm.VM {
+ cfg := vmConfig.(Config)
evm := &EVM{
Context: ctx,
StateDB: statedb,
- vmConfig: vmConfig,
+ vmConfig: cfg,
chainConfig: chainConfig,
chainRules: chainConfig.Rules(ctx.BlockNumber),
interpreters: make([]Interpreter, 0, 1),
@@ -179,7 +127,7 @@ func NewEVM(ctx vm.Context, statedb vm.StateDB, chainConfig *params.ChainConfig,
// vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here
// as we always want to have the built-in EVM as the failover option.
- evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig))
+ evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, cfg))
evm.interpreter = evm.interpreters[0]
return evm
@@ -200,17 +148,17 @@ func (evm *EVM) Interpreter() Interpreter {
// parameters. It also handles any 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.
-func (evm *EVM) Call(caller vm.ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+func (evm *EVM) Call(caller vm.ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int, pack *vm.ExecPack) (ret []byte, leftOverGas uint64, err error) {
+ if evm.NoRecursion && evm.Depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
- if evm.depth > int(params.CallCreateDepth) {
+ if evm.Depth > int(params.CallCreateDepth) {
return nil, gas, vm.ErrDepth
}
// Fail if we're trying to transfer more than the available balance
- if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
+ if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, gas, vm.ErrInsufficientBalance
}
@@ -226,7 +174,7 @@ func (evm *EVM) Call(caller vm.ContractRef, addr common.Address, input []byte, g
if precompiles[addr] == nil && OracleContracts[addr] == nil &&
evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 {
// Calling a non existing account, don't do anything, but ping the tracer
- if evm.vmConfig.Debug && evm.depth == 0 {
+ if evm.vmConfig.Debug && evm.Depth == 0 {
evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
}
@@ -248,7 +196,7 @@ func (evm *EVM) Call(caller vm.ContractRef, addr common.Address, input []byte, g
start := time.Now()
// Capture the tracer start/end events in debug mode
- if evm.vmConfig.Debug && evm.depth == 0 {
+ if evm.vmConfig.Debug && evm.Depth == 0 {
evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
defer func() { // Lazy evaluation of the parameters
@@ -276,13 +224,13 @@ func (evm *EVM) Call(caller vm.ContractRef, addr common.Address, input []byte, g
//
// CallCode differs from Call in the sense that it executes the given address'
// code with the caller as context.
-func (evm *EVM) CallCode(caller vm.ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+func (evm *EVM) CallCode(caller vm.ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int, pack *vm.ExecPack) (ret []byte, leftOverGas uint64, err error) {
+ if evm.NoRecursion && evm.Depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
- if evm.depth > int(params.CallCreateDepth) {
+ if evm.Depth > int(params.CallCreateDepth) {
return nil, gas, vm.ErrDepth
}
// Fail if we're trying to transfer more than the available balance
@@ -320,12 +268,12 @@ func (evm *EVM) CallCode(caller vm.ContractRef, addr common.Address, input []byt
//
// 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.
-func (evm *EVM) DelegateCall(caller vm.ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+func (evm *EVM) DelegateCall(caller vm.ContractRef, addr common.Address, input []byte, gas uint64, pack *vm.ExecPack) (ret []byte, leftOverGas uint64, err error) {
+ if evm.NoRecursion && evm.Depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
- if evm.depth > int(params.CallCreateDepth) {
+ if evm.Depth > int(params.CallCreateDepth) {
return nil, gas, vm.ErrDepth
}
@@ -357,12 +305,17 @@ func (evm *EVM) DelegateCall(caller vm.ContractRef, addr common.Address, input [
// as parameters while disallowing any modifications to the state during the call.
// Opcodes that attempt to perform such modifications will result in exceptions
// instead of performing the modifications.
-func (evm *EVM) StaticCall(caller vm.ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+func (evm *EVM) StaticCall(caller vm.ContractRef, addr common.Address, input []byte, gas uint64, pack *vm.ExecPack) (ret []byte, leftOverGas uint64, err error) {
+ oldReadOnly := pack.Context.ReadOnly
+ pack.Context.ReadOnly = true
+ defer func() {
+ pack.Context.ReadOnly = oldReadOnly
+ }()
+ if evm.NoRecursion && evm.Depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
- if evm.depth > int(params.CallCreateDepth) {
+ if evm.Depth > int(params.CallCreateDepth) {
return nil, gas, vm.ErrDepth
}
@@ -404,7 +357,7 @@ func (evm *EVM) StaticCall(caller vm.ContractRef, addr common.Address, input []b
func (evm *EVM) create(caller vm.ContractRef, codeAndHash *vm.CodeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) {
// Depth check execution. Fail if we're trying to execute above the
// limit.
- if evm.depth > int(params.CallCreateDepth) {
+ if evm.Depth > int(params.CallCreateDepth) {
return nil, common.Address{}, gas, vm.ErrDepth
}
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
@@ -432,11 +385,11 @@ func (evm *EVM) create(caller vm.ContractRef, codeAndHash *vm.CodeAndHash, gas u
contract := vm.NewContract(caller, vm.AccountRef(address), value, gas)
contract.SetCodeOptionalHash(&address, codeAndHash)
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+ if evm.NoRecursion && evm.Depth > 0 {
return nil, address, gas, nil
}
- if evm.vmConfig.Debug && evm.depth == 0 {
+ if evm.vmConfig.Debug && evm.Depth == 0 {
evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.Code, gas, value)
}
start := time.Now()
@@ -470,7 +423,7 @@ func (evm *EVM) create(caller vm.ContractRef, codeAndHash *vm.CodeAndHash, gas u
if maxCodeSizeExceeded && err == nil {
err = errMaxCodeSizeExceeded
}
- if evm.vmConfig.Debug && evm.depth == 0 {
+ if evm.vmConfig.Debug && evm.Depth == 0 {
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
}
return ret, address, contract.Gas, err
@@ -478,7 +431,7 @@ func (evm *EVM) create(caller vm.ContractRef, codeAndHash *vm.CodeAndHash, gas u
}
// Create creates a new contract using code as deployment code.
-func (evm *EVM) Create(caller vm.ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
+func (evm *EVM) Create(caller vm.ContractRef, code []byte, gas uint64, value *big.Int, pack *vm.ExecPack) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
return evm.create(caller, &vm.CodeAndHash{Code: code}, gas, value, contractAddr)
}
@@ -487,7 +440,7 @@ func (evm *EVM) Create(caller vm.ContractRef, code []byte, gas uint64, value *bi
//
// The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:]
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
-func (evm *EVM) Create2(caller vm.ContractRef, code []byte, gas uint64, endowment *big.Int, salt *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
+func (evm *EVM) Create2(caller vm.ContractRef, code []byte, gas uint64, endowment *big.Int, salt *big.Int, pack *vm.ExecPack) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
codeAndHash := &vm.CodeAndHash{Code: code}
contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), codeAndHash.Hash().Bytes())
return evm.create(caller, codeAndHash, gas, endowment, contractAddr)
@@ -496,5 +449,8 @@ func (evm *EVM) Create2(caller vm.ContractRef, code []byte, gas uint64, endowmen
// ChainConfig returns the environment's chain configuration
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
+// VMConfig returns the vm configuration.
+func (evm *EVM) VMConfig() Config { return evm.vmConfig }
+
// IsBlockProposer returns whether or not we are a block proposer.
func (evm *EVM) IsBlockProposer() bool { return evm.vmConfig.IsBlockProposer }
diff --git a/core/vm/evm/evm_test.go b/core/vm/evm/evm_test.go
index ef5e8a6b0..7fee1d435 100644
--- a/core/vm/evm/evm_test.go
+++ b/core/vm/evm/evm_test.go
@@ -91,15 +91,14 @@ func newTestVM() *testVM {
Time: big.NewInt(time.Now().UnixNano() / 1000000000),
BlockNumber: big.NewInt(0),
}
-
- env := NewEVM(context, stateDB, params.TestChainConfig, Config{})
- evmInterpreter := NewEVMInterpreter(env, env.vmConfig)
-
- env.interpreter = evmInterpreter
+ vmConfig := [vmlib.NUMS]interface{}{}
+ vmConfig[vmlib.EVM] = Config{}
+ p := vmlib.NewExecPack(&context, stateDB, params.TestChainConfig, vmConfig)
+ evm := p.VMList[vmlib.EVM].(*EVM)
return &testVM{
- evm: env,
- interpreter: evmInterpreter,
+ evm: evm,
+ interpreter: NewEVMInterpreter(evm, evm.vmConfig),
}
}
diff --git a/core/vm/evm/gas_table.go b/core/vm/evm/gas_table.go
index 242494537..f0bf26726 100644
--- a/core/vm/evm/gas_table.go
+++ b/core/vm/evm/gas_table.go
@@ -415,11 +415,11 @@ func gasCall(gt params.GasTable, evm *EVM, contract *vm.Contract, stack *vm.Stac
return 0, errGasUintOverflow
}
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.CallGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
- if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
+ if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, errGasUintOverflow
}
return gas, nil
@@ -439,11 +439,11 @@ func gasCallCode(gt params.GasTable, evm *EVM, contract *vm.Contract, stack *vm.
return 0, errGasUintOverflow
}
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.CallGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
- if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
+ if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, errGasUintOverflow
}
return gas, nil
@@ -493,11 +493,11 @@ func gasDelegateCall(gt params.GasTable, evm *EVM, contract *vm.Contract, stack
return 0, errGasUintOverflow
}
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.CallGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
- if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
+ if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, errGasUintOverflow
}
return gas, nil
@@ -513,11 +513,11 @@ func gasStaticCall(gt params.GasTable, evm *EVM, contract *vm.Contract, stack *v
return 0, errGasUintOverflow
}
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.CallGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
- if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
+ if gas, overflow = math.SafeAdd(gas, evm.CallGasTemp); overflow {
return 0, errGasUintOverflow
}
return gas, nil
diff --git a/core/vm/evm/instructions.go b/core/vm/evm/instructions.go
index ce95d2446..23e59aa4b 100644
--- a/core/vm/evm/instructions.go
+++ b/core/vm/evm/instructions.go
@@ -55,7 +55,7 @@ func opAdd(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
x, y := stack.Pop(), stack.Peek()
math.U256(y.Add(x, y))
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -63,7 +63,7 @@ func opSub(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
x, y := stack.Pop(), stack.Peek()
math.U256(y.Sub(x, y))
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -71,7 +71,7 @@ func opMul(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
x, y := stack.Pop(), stack.Pop()
stack.Push(math.U256(x.Mul(x, y)))
- interpreter.intPool.Put(y)
+ interpreter.evm.IntPool.Put(y)
return nil, nil
}
@@ -83,13 +83,13 @@ func opDiv(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
} else {
y.SetUint64(0)
}
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
func opSdiv(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
x, y := math.S256(stack.Pop()), math.S256(stack.Pop())
- res := interpreter.intPool.GetZero()
+ res := interpreter.evm.IntPool.GetZero()
if y.Sign() == 0 || x.Sign() == 0 {
stack.Push(res)
@@ -102,7 +102,7 @@ func opSdiv(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
}
stack.Push(math.U256(res))
}
- interpreter.intPool.Put(x, y)
+ interpreter.evm.IntPool.Put(x, y)
return nil, nil
}
@@ -113,13 +113,13 @@ func opMod(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
} else {
stack.Push(math.U256(x.Mod(x, y)))
}
- interpreter.intPool.Put(y)
+ interpreter.evm.IntPool.Put(y)
return nil, nil
}
func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
x, y := math.S256(stack.Pop()), math.S256(stack.Pop())
- res := interpreter.intPool.GetZero()
+ res := interpreter.evm.IntPool.GetZero()
if y.Sign() == 0 {
stack.Push(res)
@@ -132,7 +132,7 @@ func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
}
stack.Push(math.U256(res))
}
- interpreter.intPool.Put(x, y)
+ interpreter.evm.IntPool.Put(x, y)
return nil, nil
}
@@ -140,12 +140,12 @@ func opExp(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
base, exponent := stack.Pop(), stack.Pop()
if base.Cmp(big2) == 0 && exponent.Cmp(big256) == -1 {
exp := exponent.Int64()
- stack.Push(interpreter.intPool.Get().Set(power2[exp]))
+ stack.Push(interpreter.evm.IntPool.Get().Set(power2[exp]))
} else {
stack.Push(math.Exp(base, exponent))
}
- interpreter.intPool.Put(base, exponent)
+ interpreter.evm.IntPool.Put(base, exponent)
return nil, nil
}
@@ -166,7 +166,7 @@ func opSignExtend(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract
stack.Push(math.U256(num))
}
- interpreter.intPool.Put(back)
+ interpreter.evm.IntPool.Put(back)
return nil, nil
}
@@ -183,7 +183,7 @@ func opLt(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory
} else {
y.SetUint64(0)
}
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -194,7 +194,7 @@ func opGt(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory
} else {
y.SetUint64(0)
}
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -218,7 +218,7 @@ func opSlt(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
y.SetUint64(0)
}
}
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -242,7 +242,7 @@ func opSgt(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
y.SetUint64(0)
}
}
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -253,7 +253,7 @@ func opEq(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory
} else {
y.SetUint64(0)
}
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -271,7 +271,7 @@ func opAnd(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
x, y := stack.Pop(), stack.Pop()
stack.Push(x.And(x, y))
- interpreter.intPool.Put(y)
+ interpreter.evm.IntPool.Put(y)
return nil, nil
}
@@ -279,7 +279,7 @@ func opOr(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory
x, y := stack.Pop(), stack.Peek()
y.Or(x, y)
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -287,7 +287,7 @@ func opXor(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
x, y := stack.Pop(), stack.Peek()
y.Xor(x, y)
- interpreter.intPool.Put(x)
+ interpreter.evm.IntPool.Put(x)
return nil, nil
}
@@ -299,7 +299,7 @@ func opByte(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
} else {
val.SetUint64(0)
}
- interpreter.intPool.Put(th)
+ interpreter.evm.IntPool.Put(th)
return nil, nil
}
@@ -312,7 +312,7 @@ func opAddmod(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
} else {
stack.Push(x.SetUint64(0))
}
- interpreter.intPool.Put(y, z)
+ interpreter.evm.IntPool.Put(y, z)
return nil, nil
}
@@ -325,7 +325,7 @@ func opMulmod(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
} else {
stack.Push(x.SetUint64(0))
}
- interpreter.intPool.Put(y, z)
+ interpreter.evm.IntPool.Put(y, z)
return nil, nil
}
@@ -335,7 +335,7 @@ func opMulmod(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
func opSHL(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
shift, value := math.U256(stack.Pop()), math.U256(stack.Peek())
- defer interpreter.intPool.Put(shift) // First operand back into the pool
+ defer interpreter.evm.IntPool.Put(shift) // First operand back into the pool
if shift.Cmp(common.Big256) >= 0 {
value.SetUint64(0)
@@ -353,7 +353,7 @@ func opSHL(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
func opSHR(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
shift, value := math.U256(stack.Pop()), math.U256(stack.Peek())
- defer interpreter.intPool.Put(shift) // First operand back into the pool
+ defer interpreter.evm.IntPool.Put(shift) // First operand back into the pool
if shift.Cmp(common.Big256) >= 0 {
value.SetUint64(0)
@@ -371,7 +371,7 @@ func opSHR(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memor
func opSAR(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
// Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one
shift, value := math.U256(stack.Pop()), math.S256(stack.Pop())
- defer interpreter.intPool.Put(shift) // First operand back into the pool
+ defer interpreter.evm.IntPool.Put(shift) // First operand back into the pool
if shift.Cmp(common.Big256) >= 0 {
if value.Sign() >= 0 {
@@ -405,9 +405,9 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
if evm.vmConfig.EnablePreimageRecording {
evm.StateDB.AddPreimage(interpreter.hasherBuf, data)
}
- stack.Push(interpreter.intPool.Get().SetBytes(interpreter.hasherBuf[:]))
+ stack.Push(interpreter.evm.IntPool.Get().SetBytes(interpreter.hasherBuf[:]))
- interpreter.intPool.Put(offset, size)
+ interpreter.evm.IntPool.Put(offset, size)
return nil, nil
}
@@ -421,7 +421,7 @@ func opRand(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
binaryUsedIndex := make([]byte, binary.MaxVarintLen64)
binary.PutUvarint(binaryUsedIndex, evm.RandCallIndex)
- evm.RandCallIndex += 1
+ evm.RandCallIndex++
hash := crypto.Keccak256(
evm.Randomness,
@@ -429,7 +429,7 @@ func opRand(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
binaryOriginNonce,
binaryUsedIndex)
- stack.Push(interpreter.intPool.Get().SetBytes(hash))
+ stack.Push(interpreter.evm.IntPool.Get().SetBytes(hash))
return nil, nil
}
@@ -455,17 +455,17 @@ func opCaller(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
}
func opCallValue(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().Set(contract.Value))
+ stack.Push(interpreter.evm.IntPool.Get().Set(contract.Value))
return nil, nil
}
func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().SetBytes(vm.GetDataBig(contract.Input, stack.Pop(), big32)))
+ stack.Push(interpreter.evm.IntPool.Get().SetBytes(vm.GetDataBig(contract.Input, stack.Pop(), big32)))
return nil, nil
}
func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().SetInt64(int64(len(contract.Input))))
+ stack.Push(interpreter.evm.IntPool.Get().SetInt64(int64(len(contract.Input))))
return nil, nil
}
@@ -477,12 +477,12 @@ func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contra
)
memory.Set(memOffset.Uint64(), length.Uint64(), vm.GetDataBig(contract.Input, dataOffset, length))
- interpreter.intPool.Put(memOffset, dataOffset, length)
+ interpreter.evm.IntPool.Put(memOffset, dataOffset, length)
return nil, nil
}
func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().SetUint64(uint64(len(interpreter.returnData))))
+ stack.Push(interpreter.evm.IntPool.Get().SetUint64(uint64(len(interpreter.returnData))))
return nil, nil
}
@@ -491,9 +491,9 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *vm.Cont
memOffset = stack.Pop()
dataOffset = stack.Pop()
length = stack.Pop()
- end = interpreter.intPool.Get().Add(dataOffset, length)
+ end = interpreter.evm.IntPool.Get().Add(dataOffset, length)
)
- defer interpreter.intPool.Put(memOffset, dataOffset, length, end)
+ defer interpreter.evm.IntPool.Put(memOffset, dataOffset, length, end)
if end.BitLen() > 64 || uint64(len(interpreter.returnData)) < end.Uint64() {
return nil, errReturnDataOutOfBounds
@@ -511,7 +511,7 @@ func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contrac
}
func opCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- l := interpreter.intPool.Get().SetInt64(int64(len(contract.Code)))
+ l := interpreter.evm.IntPool.Get().SetInt64(int64(len(contract.Code)))
stack.Push(l)
return nil, nil
@@ -526,7 +526,7 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract,
codeCopy := vm.GetDataBig(contract.Code, codeOffset, length)
memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
- interpreter.intPool.Put(memOffset, codeOffset, length)
+ interpreter.evm.IntPool.Put(memOffset, codeOffset, length)
return nil, nil
}
@@ -540,7 +540,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contrac
codeCopy := vm.GetDataBig(interpreter.evm.StateDB.GetCode(addr), codeOffset, length)
memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
- interpreter.intPool.Put(memOffset, codeOffset, length)
+ interpreter.evm.IntPool.Put(memOffset, codeOffset, length)
return nil, nil
}
@@ -582,20 +582,20 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contrac
}
func opGasprice(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().Set(interpreter.evm.GasPrice))
+ stack.Push(interpreter.evm.IntPool.Get().Set(interpreter.evm.GasPrice))
return nil, nil
}
func opBlockhash(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
num := stack.Pop()
- n := interpreter.intPool.Get().Sub(interpreter.evm.BlockNumber, common.Big257)
+ n := interpreter.evm.IntPool.Get().Sub(interpreter.evm.BlockNumber, common.Big257)
if num.Cmp(n) > 0 && num.Cmp(interpreter.evm.BlockNumber) < 0 {
stack.Push(interpreter.evm.GetHash(num.Uint64()).Big())
} else {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
}
- interpreter.intPool.Put(num, n)
+ interpreter.evm.IntPool.Put(num, n)
return nil, nil
}
@@ -605,36 +605,36 @@ func opCoinbase(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract,
}
func opTimestamp(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(math.U256(interpreter.intPool.Get().Set(interpreter.evm.Time)))
+ stack.Push(math.U256(interpreter.evm.IntPool.Get().Set(interpreter.evm.Time)))
return nil, nil
}
func opNumber(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(math.U256(interpreter.intPool.Get().Set(interpreter.evm.BlockNumber)))
+ stack.Push(math.U256(interpreter.evm.IntPool.Get().Set(interpreter.evm.BlockNumber)))
return nil, nil
}
func opDifficulty(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(math.U256(interpreter.intPool.Get().Set(interpreter.evm.Difficulty)))
+ stack.Push(math.U256(interpreter.evm.IntPool.Get().Set(interpreter.evm.Difficulty)))
return nil, nil
}
func opGasLimit(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(math.U256(interpreter.intPool.Get().SetUint64(interpreter.evm.GasLimit)))
+ stack.Push(math.U256(interpreter.evm.IntPool.Get().SetUint64(interpreter.evm.GasLimit)))
return nil, nil
}
func opPop(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- interpreter.intPool.Put(stack.Pop())
+ interpreter.evm.IntPool.Put(stack.Pop())
return nil, nil
}
func opMload(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
offset := stack.Pop()
- val := interpreter.intPool.Get().SetBytes(memory.Get(offset.Int64(), 32))
+ val := interpreter.evm.IntPool.Get().SetBytes(memory.Get(offset.Int64(), 32))
stack.Push(val)
- interpreter.intPool.Put(offset)
+ interpreter.evm.IntPool.Put(offset)
return nil, nil
}
@@ -643,7 +643,7 @@ func opMstore(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
mStart, val := stack.Pop(), stack.Pop()
memory.Set32(mStart.Uint64(), val)
- interpreter.intPool.Put(mStart, val)
+ interpreter.evm.IntPool.Put(mStart, val)
return nil, nil
}
@@ -666,7 +666,7 @@ func opSstore(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
val := stack.Pop()
interpreter.evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
- interpreter.intPool.Put(val)
+ interpreter.evm.IntPool.Put(val)
return nil, nil
}
@@ -678,7 +678,7 @@ func opJump(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
}
*pc = pos.Uint64()
- interpreter.intPool.Put(pos)
+ interpreter.evm.IntPool.Put(pos)
return nil, nil
}
@@ -694,7 +694,7 @@ func opJumpi(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, mem
*pc++
}
- interpreter.intPool.Put(pos, cond)
+ interpreter.evm.IntPool.Put(pos, cond)
return nil, nil
}
@@ -703,17 +703,17 @@ func opJumpdest(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract,
}
func opPc(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().SetUint64(*pc))
+ stack.Push(interpreter.evm.IntPool.Get().SetUint64(*pc))
return nil, nil
}
func opMsize(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().SetInt64(int64(memory.Len())))
+ stack.Push(interpreter.evm.IntPool.Get().SetInt64(int64(memory.Len())))
return nil, nil
}
func opGas(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Push(interpreter.intPool.Get().SetUint64(contract.Gas))
+ stack.Push(interpreter.evm.IntPool.Get().SetUint64(contract.Gas))
return nil, nil
}
@@ -729,20 +729,20 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
gas -= gas / 64
}
contract.UseGas(gas)
- res, addr, returnGas, suberr := vm.Create(contract, input, gas, value, interpreter)
+ res, addr, returnGas, suberr := vm.Create(contract, input, gas, value, interpreter.evm.ExecPack)
// Push item on the stack based on the returned error. If the ruleset is
// homestead we must check for CodeStoreOutOfGasError (homestead only
// rule) and treat as an error, if the ruleset is frontier we must
// ignore this error and pretend the operation was successful.
if interpreter.evm.ChainConfig().IsHomestead(interpreter.evm.BlockNumber) && suberr == vm.ErrCodeStoreOutOfGas {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
} else if suberr != nil && suberr != vm.ErrCodeStoreOutOfGas {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
} else {
stack.Push(addr.Big())
}
contract.Gas += returnGas
- interpreter.intPool.Put(value, offset, size)
+ interpreter.evm.IntPool.Put(value, offset, size)
if suberr == errExecutionReverted {
return res, nil
@@ -762,15 +762,15 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, m
// Apply EIP150
gas -= gas / 64
contract.UseGas(gas)
- res, addr, returnGas, suberr := vm.Create2(contract, input, gas, endowment, salt, interpreter)
+ res, addr, returnGas, suberr := vm.Create2(contract, input, gas, endowment, salt, interpreter.evm.ExecPack)
// Push item on the stack based on the returned error.
if suberr != nil {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
} else {
stack.Push(addr.Big())
}
contract.Gas += returnGas
- interpreter.intPool.Put(endowment, offset, size, salt)
+ interpreter.evm.IntPool.Put(endowment, offset, size, salt)
if suberr == errExecutionReverted {
return res, nil
@@ -779,9 +779,9 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, m
}
func opCall(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- // Pop gas. The actual gas in interpreter.evm.callGasTemp.
- interpreter.intPool.Put(stack.Pop())
- gas := interpreter.evm.callGasTemp
+ // Pop gas. The actual gas in interpreter.evm.CallGasTemp.
+ interpreter.evm.IntPool.Put(stack.Pop())
+ gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, value, inOffset, inSize, retOffset, retSize := stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop()
toAddr := common.BigToAddress(addr)
@@ -792,25 +792,25 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memo
if value.Sign() != 0 {
gas += params.CallStipend
}
- ret, returnGas, err := vm.Call(contract, toAddr, args, gas, value, interpreter)
+ ret, returnGas, err := vm.Call(contract, toAddr, args, gas, value, interpreter.evm.ExecPack)
if err != nil {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
} else {
- stack.Push(interpreter.intPool.Get().SetUint64(1))
+ stack.Push(interpreter.evm.IntPool.Get().SetUint64(1))
}
if err == nil || err == errExecutionReverted {
memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
contract.Gas += returnGas
- interpreter.intPool.Put(addr, value, inOffset, inSize, retOffset, retSize)
+ interpreter.evm.IntPool.Put(addr, value, inOffset, inSize, retOffset, retSize)
return ret, nil
}
func opCallCode(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- // Pop gas. The actual gas is in interpreter.evm.callGasTemp.
- interpreter.intPool.Put(stack.Pop())
- gas := interpreter.evm.callGasTemp
+ // Pop gas. The actual gas is in interpreter.evm.CallGasTemp.
+ interpreter.evm.IntPool.Put(stack.Pop())
+ gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, value, inOffset, inSize, retOffset, retSize := stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop()
toAddr := common.BigToAddress(addr)
@@ -821,68 +821,68 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract,
if value.Sign() != 0 {
gas += params.CallStipend
}
- ret, returnGas, err := vm.CallCode(contract, toAddr, args, gas, value, interpreter)
+ ret, returnGas, err := vm.CallCode(contract, toAddr, args, gas, value, interpreter.evm.ExecPack)
if err != nil {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
} else {
- stack.Push(interpreter.intPool.Get().SetUint64(1))
+ stack.Push(interpreter.evm.IntPool.Get().SetUint64(1))
}
if err == nil || err == errExecutionReverted {
memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
contract.Gas += returnGas
- interpreter.intPool.Put(addr, value, inOffset, inSize, retOffset, retSize)
+ interpreter.evm.IntPool.Put(addr, value, inOffset, inSize, retOffset, retSize)
return ret, nil
}
func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- // Pop gas. The actual gas is in interpreter.evm.callGasTemp.
- interpreter.intPool.Put(stack.Pop())
- gas := interpreter.evm.callGasTemp
+ // Pop gas. The actual gas is in interpreter.evm.CallGasTemp.
+ interpreter.evm.IntPool.Put(stack.Pop())
+ gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, inOffset, inSize, retOffset, retSize := stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop()
toAddr := common.BigToAddress(addr)
// Get arguments from the memory.
args := memory.Get(inOffset.Int64(), inSize.Int64())
- ret, returnGas, err := vm.DelegateCall(contract, toAddr, args, gas, interpreter)
+ ret, returnGas, err := vm.DelegateCall(contract, toAddr, args, gas, interpreter.evm.ExecPack)
if err != nil {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
} else {
- stack.Push(interpreter.intPool.Get().SetUint64(1))
+ stack.Push(interpreter.evm.IntPool.Get().SetUint64(1))
}
if err == nil || err == errExecutionReverted {
memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
contract.Gas += returnGas
- interpreter.intPool.Put(addr, inOffset, inSize, retOffset, retSize)
+ interpreter.evm.IntPool.Put(addr, inOffset, inSize, retOffset, retSize)
return ret, nil
}
func opStaticCall(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- // Pop gas. The actual gas is in interpreter.evm.callGasTemp.
- interpreter.intPool.Put(stack.Pop())
- gas := interpreter.evm.callGasTemp
+ // Pop gas. The actual gas is in interpreter.evm.CallGasTemp.
+ interpreter.evm.IntPool.Put(stack.Pop())
+ gas := interpreter.evm.CallGasTemp
// Pop other call parameters.
addr, inOffset, inSize, retOffset, retSize := stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop()
toAddr := common.BigToAddress(addr)
// Get arguments from the memory.
args := memory.Get(inOffset.Int64(), inSize.Int64())
- ret, returnGas, err := vm.StaticCall(contract, toAddr, args, gas, interpreter)
+ ret, returnGas, err := vm.StaticCall(contract, toAddr, args, gas, interpreter.evm.ExecPack)
if err != nil {
- stack.Push(interpreter.intPool.GetZero())
+ stack.Push(interpreter.evm.IntPool.GetZero())
} else {
- stack.Push(interpreter.intPool.Get().SetUint64(1))
+ stack.Push(interpreter.evm.IntPool.Get().SetUint64(1))
}
if err == nil || err == errExecutionReverted {
memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
}
contract.Gas += returnGas
- interpreter.intPool.Put(addr, inOffset, inSize, retOffset, retSize)
+ interpreter.evm.IntPool.Put(addr, inOffset, inSize, retOffset, retSize)
return ret, nil
}
@@ -890,7 +890,7 @@ func opReturn(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
offset, size := stack.Pop(), stack.Pop()
ret := memory.GetPtr(offset.Int64(), size.Int64())
- interpreter.intPool.Put(offset, size)
+ interpreter.evm.IntPool.Put(offset, size)
return ret, nil
}
@@ -898,7 +898,7 @@ func opRevert(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, me
offset, size := stack.Pop(), stack.Pop()
ret := memory.GetPtr(offset.Int64(), size.Int64())
- interpreter.intPool.Put(offset, size)
+ interpreter.evm.IntPool.Put(offset, size)
return ret, nil
}
@@ -935,7 +935,7 @@ func makeLog(size int) executionFunc {
BlockNumber: interpreter.evm.BlockNumber.Uint64(),
})
- interpreter.intPool.Put(mStart, mSize)
+ interpreter.evm.IntPool.Put(mStart, mSize)
return nil, nil
}
}
@@ -955,7 +955,7 @@ func makePush(size uint64, pushByteSize int) executionFunc {
endMin = startMin + pushByteSize
}
- integer := interpreter.intPool.Get()
+ integer := interpreter.evm.IntPool.Get()
stack.Push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))
*pc += size
@@ -966,7 +966,7 @@ func makePush(size uint64, pushByteSize int) executionFunc {
// make dup instruction function
func makeDup(size int64) executionFunc {
return func(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error) {
- stack.Dup(interpreter.intPool, int(size))
+ stack.Dup(interpreter.evm.IntPool, int(size))
return nil, nil
}
}
diff --git a/core/vm/evm/instructions_test.go b/core/vm/evm/instructions_test.go
index bd3df271d..78d175aa9 100644
--- a/core/vm/evm/instructions_test.go
+++ b/core/vm/evm/instructions_test.go
@@ -35,14 +35,15 @@ type twoOperandTest struct {
func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error)) {
var (
- env = NewEVM(vm.Context{}, nil, params.TestChainConfig, Config{})
- stack = NewStack()
- pc = uint64(0)
- evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ stack = NewStack()
+ pc = uint64(0)
)
-
- env.interpreter = evmInterpreter
- evmInterpreter.intPool = vm.PoolOfIntPools.Get()
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{}
+ vmctx := &vm.Context{IntPool: vm.NewIntPool()}
+ pack := vm.NewExecPack(vmctx, nil, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*EVM)
+ evmInterpreter := NewEVMInterpreter(evm, vmConfig[vm.EVM].(Config))
for i, test := range tests {
x := new(big.Int).SetBytes(common.Hex2Bytes(test.x))
shift := new(big.Int).SetBytes(common.Hex2Bytes(test.y))
@@ -57,13 +58,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 evmInterpreter.intPool.Pool.Len() > 0 {
+ if evm.IntPool.Pool.Len() > 0 {
poolvals := make(map[*big.Int]struct{})
poolvals[actual] = struct{}{}
- for evmInterpreter.intPool.Pool.Len() > 0 {
- key := evmInterpreter.intPool.Get()
+ for evm.IntPool.Pool.Len() > 0 {
+ key := evm.IntPool.Get()
if _, exist := poolvals[key]; exist {
t.Errorf("Testcase %d, pool contains double-entry", i)
}
@@ -71,18 +72,19 @@ func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64
}
}
}
- vm.PoolOfIntPools.Put(evmInterpreter.intPool)
+ vm.PoolOfIntPools.Put(evm.IntPool)
}
func TestByteOp(t *testing.T) {
var (
- env = NewEVM(vm.Context{}, nil, params.TestChainConfig, Config{})
- stack = NewStack()
- evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ stack = NewStack()
)
-
- env.interpreter = evmInterpreter
- evmInterpreter.intPool = vm.PoolOfIntPools.Get()
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{}
+ vmctx := &vm.Context{IntPool: vm.NewIntPool()}
+ pack := vm.NewExecPack(vmctx, nil, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*EVM)
+ evmInterpreter := NewEVMInterpreter(evm, vmConfig[vm.EVM].(Config))
tests := []struct {
v string
th uint64
@@ -109,7 +111,7 @@ func TestByteOp(t *testing.T) {
t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.v, test.th, test.expected, actual)
}
}
- vm.PoolOfIntPools.Put(evmInterpreter.intPool)
+ vm.PoolOfIntPools.Put(evm.IntPool)
}
func TestSHL(t *testing.T) {
@@ -211,13 +213,15 @@ func TestSLT(t *testing.T) {
func opBenchmark(bench *testing.B, op func(pc *uint64, interpreter *EVMInterpreter, contract *vm.Contract, memory *vm.Memory, stack *vm.Stack) ([]byte, error), args ...string) {
var (
- env = NewEVM(vm.Context{}, nil, params.TestChainConfig, Config{})
- stack = NewStack()
- evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ stack = NewStack()
)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{}
+ vmctx := &vm.Context{IntPool: vm.NewIntPool()}
+ pack := vm.NewExecPack(vmctx, nil, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*EVM)
+ evmInterpreter := NewEVMInterpreter(evm, vmConfig[vm.EVM].(Config))
- env.interpreter = evmInterpreter
- evmInterpreter.intPool = vm.PoolOfIntPools.Get()
// convert args
byteArgs := make([][]byte, len(args))
for i, arg := range args {
@@ -233,7 +237,7 @@ func opBenchmark(bench *testing.B, op func(pc *uint64, interpreter *EVMInterpret
op(&pc, evmInterpreter, nil, nil, stack)
stack.Pop()
}
- vm.PoolOfIntPools.Put(evmInterpreter.intPool)
+ vm.PoolOfIntPools.Put(evm.IntPool)
}
func BenchmarkOpAdd64(b *testing.B) {
@@ -446,14 +450,16 @@ func BenchmarkOpIsZero(b *testing.B) {
func TestOpMstore(t *testing.T) {
var (
- env = NewEVM(vm.Context{}, nil, params.TestChainConfig, Config{})
- stack = NewStack()
- mem = vm.NewMemory()
- evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ stack = NewStack()
+ mem = vm.NewMemory()
)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{}
+ ctx := &vm.Context{IntPool: vm.NewIntPool()}
+ pack := vm.NewExecPack(ctx, nil, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*EVM)
+ evmInterpreter := NewEVMInterpreter(evm, vmConfig[vm.EVM].(Config))
- env.interpreter = evmInterpreter
- evmInterpreter.intPool = vm.PoolOfIntPools.Get()
mem.Resize(64)
pc := uint64(0)
v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700"
@@ -467,19 +473,22 @@ func TestOpMstore(t *testing.T) {
if common.Bytes2Hex(mem.Get(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" {
t.Fatalf("Mstore failed to overwrite previous value")
}
- vm.PoolOfIntPools.Put(evmInterpreter.intPool)
+ vm.PoolOfIntPools.Put(evm.IntPool)
}
func BenchmarkOpMstore(bench *testing.B) {
var (
- env = NewEVM(vm.Context{}, nil, params.TestChainConfig, Config{})
- stack = NewStack()
- mem = vm.NewMemory()
- evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ stack = NewStack()
+ mem = vm.NewMemory()
)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{}
+ vmctx := &vm.Context{}
+ vmctx.IntPool = vm.NewIntPool()
+ pack := vm.NewExecPack(vmctx, nil, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*EVM)
+ evmInterpreter := NewEVMInterpreter(evm, vmConfig[vm.EVM].(Config))
- env.interpreter = evmInterpreter
- evmInterpreter.intPool = vm.PoolOfIntPools.Get()
mem.Resize(64)
pc := uint64(0)
memStart := big.NewInt(0)
@@ -490,18 +499,21 @@ func BenchmarkOpMstore(bench *testing.B) {
stack.PushN(value, memStart)
opMstore(&pc, evmInterpreter, nil, mem, stack)
}
- vm.PoolOfIntPools.Put(evmInterpreter.intPool)
+ vm.PoolOfIntPools.Put(evm.Context.IntPool)
}
func BenchmarkOpSHA3(bench *testing.B) {
var (
- env = NewEVM(vm.Context{}, nil, params.TestChainConfig, Config{})
- stack = NewStack()
- mem = vm.NewMemory()
- evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
+ stack = NewStack()
+ mem = vm.NewMemory()
)
- env.interpreter = evmInterpreter
- evmInterpreter.intPool = vm.PoolOfIntPools.Get()
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{}
+ vmctx := &vm.Context{}
+ vmctx.IntPool = vm.NewIntPool()
+ pack := vm.NewExecPack(vmctx, nil, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*EVM)
+ evmInterpreter := NewEVMInterpreter(evm, vmConfig[vm.EVM].(Config))
mem.Resize(32)
pc := uint64(0)
start := big.NewInt(0)
@@ -511,7 +523,7 @@ func BenchmarkOpSHA3(bench *testing.B) {
stack.PushN(big.NewInt(32), start)
opSha3(&pc, evmInterpreter, nil, mem, stack)
}
- vm.PoolOfIntPools.Put(evmInterpreter.intPool)
+ vm.PoolOfIntPools.Put(evm.IntPool)
}
func TestCreate2Addreses(t *testing.T) {
diff --git a/core/vm/evm/interpreter.go b/core/vm/evm/interpreter.go
index 9ed647c00..bcbd8b024 100644
--- a/core/vm/evm/interpreter.go
+++ b/core/vm/evm/interpreter.go
@@ -27,15 +27,11 @@ import (
"github.com/dexon-foundation/dexon/params"
)
-// Config are the configuration options for the Interpreter
type Config struct {
// Debug enabled debugging Interpreter options
Debug bool
// Tracer is the op code logger
Tracer Tracer
- // NoRecursion disabled Interpreter call, callcode,
- // delegate call and create.
- NoRecursion bool
// Enable recording of SHA3/keccak preimages
EnablePreimageRecording bool
// JumpTable contains the EVM instruction table. This
@@ -88,12 +84,9 @@ type EVMInterpreter struct {
cfg Config
gasTable params.GasTable
- intPool *vm.IntPool
-
hasher keccakState // Keccak256 hasher instance shared across opcodes
hasherBuf common.Hash // Keccak256 hasher result array shared aross opcodes
- readOnly bool // Whether to throw on stateful modifications
returnData []byte // Last CALL's return data for subsequent reuse
}
@@ -114,17 +107,16 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
cfg.JumpTable = frontierInstructionSet
}
}
-
return &EVMInterpreter{
evm: evm,
- cfg: cfg,
gasTable: evm.ChainConfig().GasTable(evm.BlockNumber),
+ cfg: cfg,
}
}
func (in *EVMInterpreter) enforceRestrictions(op OpCode, operation operation, stack *vm.Stack) error {
if in.evm.chainRules.IsByzantium {
- if in.readOnly {
+ if in.evm.ReadOnly {
// If the interpreter is operating in readonly mode, make sure no
// state-modifying operation is performed. The 3rd stack item
// for a call operation is the value. Transferring value from one
@@ -145,23 +137,23 @@ func (in *EVMInterpreter) enforceRestrictions(op OpCode, operation operation, st
// considered a revert-and-consume-all-gas operation except for
// errExecutionReverted which means revert-and-keep-gas-left.
func (in *EVMInterpreter) Run(contract *vm.Contract, input []byte, readOnly bool) (ret []byte, err error) {
- if in.intPool == nil {
- in.intPool = vm.PoolOfIntPools.Get()
+ if in.evm.IntPool == nil {
+ in.evm.IntPool = vm.PoolOfIntPools.Get()
defer func() {
- vm.PoolOfIntPools.Put(in.intPool)
- in.intPool = nil
+ vm.PoolOfIntPools.Put(in.evm.IntPool)
+ in.evm.IntPool = nil
}()
}
// Increment the call depth which is restricted to 1024
- in.evm.depth++
- defer func() { in.evm.depth-- }()
+ in.evm.Depth++
+ defer func() { in.evm.Depth-- }()
// Make sure the readOnly is only set if we aren't in readOnly yet.
// This makes also sure that the readOnly flag isn't removed for child calls.
- if readOnly && !in.readOnly {
- in.readOnly = true
- defer func() { in.readOnly = false }()
+ if readOnly && !in.evm.ReadOnly {
+ in.evm.ReadOnly = true
+ defer func() { in.evm.ReadOnly = false }()
}
// Reset the previous call's return data. It's unimportant to preserve the old buffer
@@ -189,17 +181,17 @@ func (in *EVMInterpreter) Run(contract *vm.Contract, input []byte, readOnly bool
contract.Input = input
// Reclaim the stack as an int pool when the execution stops
defer func() {
- in.intPool.Put(stack.Data...)
+ in.evm.IntPool.Put(stack.Data...)
Recyclestack(stack)
}()
- if in.cfg.Debug {
+ if in.evm.vmConfig.Debug {
defer func() {
if err != nil {
if !logged {
- in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err)
+ in.evm.vmConfig.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.Depth, err)
} else {
- in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err)
+ in.evm.vmConfig.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.Depth, err)
}
}
}()
@@ -209,7 +201,7 @@ func (in *EVMInterpreter) Run(contract *vm.Contract, input []byte, readOnly bool
// the execution of one of the operations or until the done flag is set by the
// parent context.
for atomic.LoadInt32(&in.evm.abort) == 0 {
- if in.cfg.Debug {
+ if in.evm.vmConfig.Debug {
// Capture pre-execution values for tracing.
logged, pcCopy, gasCopy = false, pc, contract.Gas
}
@@ -254,8 +246,8 @@ func (in *EVMInterpreter) Run(contract *vm.Contract, input []byte, readOnly bool
mem.Resize(memorySize)
}
- if in.cfg.Debug {
- in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err)
+ if in.evm.vmConfig.Debug {
+ in.evm.vmConfig.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, contract, in.evm.Depth, err)
logged = true
}
@@ -264,7 +256,7 @@ func (in *EVMInterpreter) Run(contract *vm.Contract, input []byte, readOnly bool
// verifyPool is a build flag. Pool verification makes sure the integrity
// of the integer pool by comparing values to a default value.
if vm.VerifyPool {
- vm.VerifyIntegerPool(in.intPool)
+ vm.VerifyIntegerPool(in.evm.IntPool)
}
// if the operation clears the return data (e.g. it has returning data)
// set the last return to the result of the operation.
@@ -292,8 +284,3 @@ func (in *EVMInterpreter) Run(contract *vm.Contract, input []byte, readOnly bool
func (in *EVMInterpreter) CanRun(code []byte) bool {
return true
}
-
-// StateDB return StateDB stored in evm
-func (in *EVMInterpreter) StateDB() vm.StateDB {
- return in.evm.StateDB
-}
diff --git a/core/vm/evm/logger_test.go b/core/vm/evm/logger_test.go
index 3a293675b..782fcd11f 100644
--- a/core/vm/evm/logger_test.go
+++ b/core/vm/evm/logger_test.go
@@ -51,16 +51,19 @@ func (*dummyStatedb) GetRefund() uint64 { return 1337 }
func TestStoreCapture(t *testing.T) {
var (
- env = NewEVM(vm.Context{}, &dummyStatedb{}, params.TestChainConfig, Config{})
logger = NewStructLogger(nil)
mem = vm.NewMemory()
stack = NewStack()
contract = vm.NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 0)
)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{}
+ vmctx := &vm.Context{IntPool: vm.NewIntPool()}
+ pack := vm.NewExecPack(vmctx, &dummyStatedb{}, params.TestChainConfig, vmConfig)
stack.Push(big.NewInt(1))
stack.Push(big.NewInt(0))
var index common.Hash
- logger.CaptureState(env, 0, SSTORE, 0, 0, mem, stack, contract, 0, nil)
+ logger.CaptureState(pack.VMList[vm.EVM].(*EVM), 0, SSTORE, 0, 0, mem, stack, contract, 0, nil)
if len(logger.changedValues[contract.Address()]) == 0 {
t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(), len(logger.changedValues[contract.Address()]))
}
diff --git a/core/vm/evm/oracle_contracts_test.go b/core/vm/evm/oracle_contracts_test.go
index 41bf0fb58..55a011f33 100644
--- a/core/vm/evm/oracle_contracts_test.go
+++ b/core/vm/evm/oracle_contracts_test.go
@@ -249,8 +249,11 @@ func (g *OracleContractsTestSuite) call(
g.context.Time = big.NewInt(time.Now().UnixNano() / 1000000)
- evm := NewEVM(g.context, g.stateDB, params.TestChainConfig, Config{IsBlockProposer: true})
- ret, _, err := evm.Call(vm.AccountRef(caller), contractAddr, input, 10000000, value)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = Config{IsBlockProposer: true}
+ pack := vm.NewExecPack(&g.context, g.stateDB, params.TestChainConfig, vmConfig)
+ evm := pack.VMList[vm.EVM].(*EVM)
+ ret, _, err := evm.Call(vm.AccountRef(caller), contractAddr, input, 10000000, value, &pack)
return ret, err
}
@@ -1102,7 +1105,7 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
g.s.PutDKGSuccess(addr, true)
g.s.IncDKGSuccessesCount()
}
- i += 1
+ i++
}
dkgSetSize := len(dkgSet)
g.Require().Len(g.s.DKGMasterPublicKeys(), dkgSetSize)
diff --git a/core/vm/evm/runtime/env.go b/core/vm/evm/runtime/env.go
index 92cc8681c..a7a8f6b6c 100644
--- a/core/vm/evm/runtime/env.go
+++ b/core/vm/evm/runtime/env.go
@@ -20,15 +20,14 @@ import (
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/core"
"github.com/dexon-foundation/dexon/core/vm"
- "github.com/dexon-foundation/dexon/core/vm/evm"
)
-func NewEnv(cfg *Config) *evm.EVM {
+// NewExecPack is a wrapper for creating ExecPack.
+func NewExecPack(cfg *Config) vm.ExecPack {
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,
@@ -37,6 +36,7 @@ func NewEnv(cfg *Config) *evm.EVM {
GasLimit: cfg.GasLimit,
GasPrice: cfg.GasPrice,
}
-
- return evm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
+ vmConfig := [vm.NUMS]interface{}{}
+ vmConfig[vm.EVM] = cfg.EVMConfig
+ return vm.NewExecPack(&context, cfg.State, cfg.ChainConfig, vmConfig)
}
diff --git a/core/vm/evm/runtime/runtime.go b/core/vm/evm/runtime/runtime.go
index c89f9dd11..3745f001b 100644
--- a/core/vm/evm/runtime/runtime.go
+++ b/core/vm/evm/runtime/runtime.go
@@ -5,8 +5,7 @@
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
+// // The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
@@ -104,19 +103,20 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
}
var (
address = common.BytesToAddress([]byte("contract"))
- vmenv = NewEnv(cfg)
+ pack = NewExecPack(cfg)
sender = vm.AccountRef(cfg.Origin)
)
cfg.State.CreateAccount(address)
// set the receiver's (the executing contract) code for execution.
cfg.State.SetCode(address, code)
// Call the code with the given configuration.
- ret, _, err := vmenv.Call(
+ ret, _, err := pack.VMList[vm.EVM].(*evm.EVM).Call(
sender,
common.BytesToAddress([]byte("contract")),
input,
cfg.GasLimit,
cfg.Value,
+ &pack,
)
return ret, cfg.State, err
@@ -133,16 +133,17 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
}
var (
- vmenv = NewEnv(cfg)
+ pack = NewExecPack(cfg)
sender = vm.AccountRef(cfg.Origin)
)
// Call the code with the given configuration.
- code, address, leftOverGas, err := vmenv.Create(
+ code, address, leftOverGas, err := pack.VMList[vm.EVM].(*evm.EVM).Create(
sender,
input,
cfg.GasLimit,
cfg.Value,
+ &pack,
)
return code, address, leftOverGas, err
}
@@ -155,16 +156,17 @@ 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)
-
+ pack := NewExecPack(cfg)
+ e := pack.VMList[vm.EVM].(*evm.EVM)
sender := cfg.State.GetOrNewStateObject(cfg.Origin)
// Call the code with the given configuration.
- ret, leftOverGas, err := vmenv.Call(
+ ret, leftOverGas, err := e.Call(
sender,
address,
input,
cfg.GasLimit,
cfg.Value,
+ &pack,
)
return ret, leftOverGas, err
diff --git a/core/vm/evm/runtime/runtime_test.go b/core/vm/evm/runtime/runtime_test.go
index 762f3601d..46e4a934d 100644
--- a/core/vm/evm/runtime/runtime_test.go
+++ b/core/vm/evm/runtime/runtime_test.go
@@ -29,6 +29,7 @@ import (
"github.com/dexon-foundation/dexon/core/vm/tools"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/params"
+ "github.com/stretchr/testify/assert"
)
func TestDefaults(t *testing.T) {
@@ -121,6 +122,55 @@ func TestCall(t *testing.T) {
}
}
+func TestStaticCallAndRand(t *testing.T) {
+ state, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
+ address := common.HexToAddress("0x0a")
+ address2 := common.HexToAddress("0x0b")
+ code := []byte{
+ byte(vm.EVM),
+ byte(evm.PUSH1), 0, // StaticCall retSize
+ byte(evm.PUSH1), 0, // StaticCall retOffset
+ byte(evm.PUSH1), 0, // StaticCall inputSize
+ byte(evm.PUSH1), 0, // StaticCall inputOffset
+ byte(evm.PUSH20),
+ }
+ code = append(code, address2.Bytes()...)
+ code = append(code,
+ byte(evm.PUSH1), 0xff, // StaticCall gas
+ byte(evm.STATICCALL),
+ byte(evm.RAND),
+ byte(evm.RETURN),
+ )
+ state.SetCode(address, code)
+
+ state.SetCode(address2, []byte{
+ byte(vm.EVM),
+ byte(evm.RAND),
+ byte(evm.RETURN),
+ })
+
+ cfg := &Config{
+ State: state,
+ }
+ setDefaults(cfg)
+ cfg.ChainConfig.ByzantiumBlock = new(big.Int).SetUint64(0)
+
+ pack := NewExecPack(cfg)
+ e := pack.VMList[vm.EVM]
+ sender := cfg.State.GetOrNewStateObject(cfg.Origin)
+ _, _, err := e.Call(
+ sender,
+ address,
+ nil,
+ cfg.GasLimit,
+ cfg.Value,
+ &pack,
+ )
+ assert.Equal(t, nil, err)
+ assert.Equal(t, uint64(2), pack.Context.RandCallIndex)
+ assert.Equal(t, false, pack.Context.ReadOnly)
+}
+
func BenchmarkCall(b *testing.B) {
var definition = `[{"constant":true,"inputs":[],"name":"seller","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"abort","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"value","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"refund","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"buyer","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"confirmReceived","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"state","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":false,"inputs":[],"name":"confirmPurchase","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"},{"anonymous":false,"inputs":[],"name":"Aborted","type":"event"},{"anonymous":false,"inputs":[],"name":"PurchaseConfirmed","type":"event"},{"anonymous":false,"inputs":[],"name":"ItemReceived","type":"event"},{"anonymous":false,"inputs":[],"name":"Refunded","type":"event"}]`