From 56819e1de563e163b5c1ed981091248f4da28e20 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 23 May 2018 12:41:33 +0200 Subject: [PATCH] core/evm: refactor CALL --- core/vm/evm.go | 79 +++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/core/vm/evm.go b/core/vm/evm.go index 3d1de43fe0..82002c71b7 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -168,9 +168,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas snapshot = evm.StateDB.Snapshot() ) exists := evm.StateDB.Exist(addr) + precompile, isPrecompile := evm.BlockContext.Precompiles[addr] + if !exists{ - if evm.BlockContext.Precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockContext.BlockNumber) && value.Sign() == 0 { - // Calling a non existing account, don't do antything, but ping the tracer + if !isPrecompile && evm.ChainConfig().IsEIP158(evm.BlockContext.BlockNumber) && value.Sign() == 0 { + // Calling a non existing account, don't do anything, but ping the tracer 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) @@ -181,49 +183,48 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas } evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value) - precompile, isPrecompile := evm.BlockContext.Precompiles[addr] - - if !exists && !isPrecompile{ - // Shortcut execution -- account didn't exist, - // so no need to lookup the code - // but make sure to set returndata to nil - evm.interpreter.returnData = nil - return nil, gas, nil - } - code := evm.StateDB.GetCode(addr) - codeHash := evm.StateDB.GetCodeHash(addr) - - if !isPrecompile && len(code) == 0 { - // Shortcut execution if there is no code, - // but make sure to set returndata to nil - evm.interpreter.returnData = nil - return nil, gas, nil - } - - // Initialise a new contract and set the code that is to be used by the EVM. - // The contract is a scoped environment for this execution context only. var contract *Contract - - if!isPrecompile { + if isPrecompile{ + // A 'contract' is needed for gas accounting + contract = NewPrecompiledContract(caller, to, value, gas) + ret, err = RunPrecompiledContract(precompile, input, contract) + // Capture the tracer start/end events in debug mode + if evm.vmConfig.Debug && evm.depth == 0 { + start := time.Now() + evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) + defer func() { // Lazy evaluation of the parameters + evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) + }() + } + }else{ + if !exists{ + // Shortcut execution -- account didn't exist, + // so no need to lookup the code + // but make sure to set returndata to nil + evm.interpreter.returnData = nil + return nil, gas, nil + } + code := evm.StateDB.GetCode(addr) + if len(code) == 0 { + // Shortcut execution if there is no code, + // but make sure to set returndata to nil + evm.interpreter.returnData = nil + return nil, gas, nil + } + codeHash := evm.StateDB.GetCodeHash(addr) contract = NewContract(caller, to, value, gas) contract.SetCallCode(&addr, codeHash, code) - }else{ - contract = NewPrecompiledContract(caller, to, value, gas) - } - // Capture the tracer start/end events in debug mode - if evm.vmConfig.Debug && evm.depth == 0 { - start := time.Now() - evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) - defer func() { // Lazy evaluation of the parameters - evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) - }() - } + // Capture the tracer start/end events in debug mode + if evm.vmConfig.Debug && evm.depth == 0 { + start := time.Now() + evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) - if!isPrecompile{ + defer func() { // Lazy evaluation of the parameters + evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) + }() + } ret, err = evm.interpreter.Run(contract, input) - }else{ - ret, err = RunPrecompiledContract(precompile, input, contract) } // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally