core/evm: refactor CALL

This commit is contained in:
Martin Holst Swende 2018-05-23 12:41:33 +02:00
parent c3c07bc755
commit 56819e1de5
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -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,9 +183,21 @@ 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{
var contract *Contract
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
@ -191,25 +205,16 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
return nil, gas, nil
}
code := evm.StateDB.GetCode(addr)
codeHash := evm.StateDB.GetCodeHash(addr)
if !isPrecompile && len(code) == 0 {
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
}
// 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 {
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()
@ -219,11 +224,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
}()
}
if!isPrecompile{
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