Skip to content

Commit

Permalink
Merge branch 'feature/refactored-evm-call-tracing-code' into feature/…
Browse files Browse the repository at this point in the history
…gas-full-cycle-and-reason
  • Loading branch information
maoueh committed Sep 12, 2023
2 parents a6e17c4 + 2d3f14a commit 3b9e781
Showing 1 changed file with 40 additions and 57 deletions.
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)
}
}

0 comments on commit 3b9e781

Please sign in to comment.