Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 40 additions & 57 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
}
}