mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
core/evm: refactor CALL
This commit is contained in:
parent
c3c07bc755
commit
56819e1de5
1 changed files with 40 additions and 39 deletions
|
|
@ -168,9 +168,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
snapshot = evm.StateDB.Snapshot()
|
snapshot = evm.StateDB.Snapshot()
|
||||||
)
|
)
|
||||||
exists := evm.StateDB.Exist(addr)
|
exists := evm.StateDB.Exist(addr)
|
||||||
|
precompile, isPrecompile := evm.BlockContext.Precompiles[addr]
|
||||||
|
|
||||||
if !exists{
|
if !exists{
|
||||||
if evm.BlockContext.Precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockContext.BlockNumber) && value.Sign() == 0 {
|
if !isPrecompile && evm.ChainConfig().IsEIP158(evm.BlockContext.BlockNumber) && value.Sign() == 0 {
|
||||||
// Calling a non existing account, don't do antything, but ping the tracer
|
// 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.CaptureStart(caller.Address(), addr, false, input, gas, value)
|
||||||
evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
|
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)
|
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
|
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 = NewContract(caller, to, value, gas)
|
||||||
contract.SetCallCode(&addr, codeHash, code)
|
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
|
// Capture the tracer start/end events in debug mode
|
||||||
evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
|
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)
|
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
|
// 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
|
// above we revert to the snapshot and consume any gas remaining. Additionally
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue