diff --git a/core/vm/evm.go b/core/vm/evm.go index 6639e0b9a83f..cf8dbb158160 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -176,26 +176,10 @@ func (evm *EVM) SetBlockContext(blockCtx BlockContext) { func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { // Capture the tracer start/end events in debug mode if evm.Config.Tracer != nil { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) - evm.Config.Tracer.OnGasChange(0, gas, GasChangeCallInitialBalance) - defer func(startGas uint64) { // Lazy evaluation of the parameters - if leftOverGas != 0 { - evm.Config.Tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) - } - evm.Config.Tracer.CaptureEnd(ret, startGas-leftOverGas, err) - }(gas) - } else { - // Handle tracer events for entering and exiting a call frame - evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value) - evm.Config.Tracer.OnGasChange(0, gas, GasChangeCallInitialBalance) - defer func(startGas uint64) { - if leftOverGas != 0 { - evm.Config.Tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) - } - evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err) - }(gas) - } + evm.captureBegin(evm.depth == 0, CALL, caller.Address(), addr, input, gas, value) + defer func(startGas uint64) { + evm.captureEnd(evm.depth == 0, CALL, startGas, leftOverGas, ret, err) + }(gas) } // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { @@ -264,13 +248,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Tracer != nil { - evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value) - evm.Config.Tracer.OnGasChange(0, gas, GasChangeCallInitialBalance) + evm.captureBegin(false, CALLCODE, caller.Address(), addr, input, gas, value) defer func(startGas uint64) { - if leftOverGas != 0 { - evm.Config.Tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) - } - evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err) + evm.captureEnd(false, CALLCODE, startGas, leftOverGas, ret, err) }(gas) } // Fail if we're trying to execute above the call depth limit @@ -323,13 +303,9 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by // that caller is something other than a Contract. parent := caller.(*Contract) // DELEGATECALL inherits value from parent call - evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value) - evm.Config.Tracer.OnGasChange(0, gas, GasChangeCallInitialBalance) + evm.captureBegin(false, DELEGATECALL, caller.Address(), addr, input, gas, parent.value) defer func(startGas uint64) { - if leftOverGas != 0 { - evm.Config.Tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) - } - evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err) + evm.captureEnd(false, DELEGATECALL, startGas, leftOverGas, ret, err) }(gas) } // Fail if we're trying to execute above the call depth limit @@ -369,13 +345,9 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { // Invoke tracer hooks that signal entering/exiting a call frame if evm.Config.Tracer != nil { - evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil) - evm.Config.Tracer.OnGasChange(0, gas, GasChangeCallInitialBalance) + evm.captureBegin(false, STATICCALL, caller.Address(), addr, input, gas, nil) defer func(startGas uint64) { - if leftOverGas != 0 { - evm.Config.Tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) - } - evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err) + evm.captureEnd(false, STATICCALL, startGas, leftOverGas, ret, err) }(gas) } // Fail if we're trying to execute above the call depth limit @@ -440,25 +412,10 @@ func (c *codeAndHash) Hash() common.Hash { // create creates a new contract using code as deployment code. func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas uint64, err error) { if evm.Config.Tracer != nil { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value) - evm.Config.Tracer.OnGasChange(0, gas, GasChangeCallInitialBalance) - defer func(startGas uint64) { - if leftOverGas != 0 { - evm.Config.Tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) - } - evm.Config.Tracer.CaptureEnd(ret, startGas-leftOverGas, err) - }(gas) - } else { - evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value) - evm.Config.Tracer.OnGasChange(0, gas, GasChangeCallInitialBalance) - defer func(startGas uint64) { - if leftOverGas != 0 { - evm.Config.Tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) - } - evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err) - }(gas) - } + evm.captureBegin(evm.depth == 0, typ, caller.Address(), address, codeAndHash.code, gas, value) + defer func(startGas uint64) { + evm.captureEnd(evm.depth == 0, typ, startGas, leftOverGas, ret, err) + }(gas) } // Depth check execution. Fail if we're trying to execute above the // limit. @@ -556,3 +513,29 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment * // ChainConfig returns the environment's chain configuration func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } + +func (evm *EVM) captureBegin(isRoot bool, typ OpCode, from common.Address, to common.Address, input []byte, startGas uint64, value *big.Int) { + tracer := evm.Config.Tracer + + if isRoot { + tracer.CaptureStart(from, to, typ == CREATE || typ == CREATE2, input, startGas, value) + } else { + tracer.CaptureEnter(typ, from, to, input, startGas, value) + } + + tracer.OnGasChange(0, startGas, GasChangeCallInitialBalance) +} + +func (evm *EVM) captureEnd(isRoot bool, typ OpCode, startGas uint64, leftOverGas uint64, ret []byte, err error) { + tracer := evm.Config.Tracer + + if leftOverGas != 0 { + tracer.OnGasChange(leftOverGas, 0, GasChangeCallLeftOverReturned) + } + + if isRoot { + tracer.CaptureEnd(ret, startGas-leftOverGas, err) + } else { + tracer.CaptureExit(ret, startGas-leftOverGas, err) + } +}