diff options
Diffstat (limited to 'core/vm/evm')
-rw-r--r-- | core/vm/evm/evm.go | 114 | ||||
-rw-r--r-- | core/vm/evm/evm_test.go | 13 | ||||
-rw-r--r-- | core/vm/evm/gas_table.go | 16 | ||||
-rw-r--r-- | core/vm/evm/instructions.go | 196 | ||||
-rw-r--r-- | core/vm/evm/instructions_test.go | 102 | ||||
-rw-r--r-- | core/vm/evm/interpreter.go | 51 | ||||
-rw-r--r-- | core/vm/evm/logger_test.go | 7 | ||||
-rw-r--r-- | core/vm/evm/oracle_contracts_test.go | 9 | ||||
-rw-r--r-- | core/vm/evm/runtime/env.go | 10 | ||||
-rw-r--r-- | core/vm/evm/runtime/runtime.go | 20 | ||||
-rw-r--r-- | core/vm/evm/runtime/runtime_test.go | 50 |
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"}]` |