Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add live chain-aware tracing (single squashed commit) #5

Closed
wants to merge 11 commits into from
Prev Previous commit
Next Next commit
fix typo causing InsufficientFunds, tracer
  • Loading branch information
sduchesneau committed Aug 3, 2023
commit cb7348edf67e08832337de47db7d85438ca482a3
64 changes: 16 additions & 48 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,46 +189,38 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if evm.depth == 0 {
evm.Config.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
defer func(startGas uint64) { // Lazy evaluation of the parameters
evm.Config.Tracer.CaptureEnd(ret, startGas-gas, err)
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)
defer func(startGas uint64) {
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err)
}(gas)
}
}

// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
// Fail if we're trying to transfer more than the available balance
if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, gas, ErrInsufficientBalance
}

snapshot := evm.StateDB.Snapshot()
p, isPrecompile := evm.precompile(addr)

if !evm.StateDB.Exist(addr) {
if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
// Calling a non existing account, don't do anything, but ping the tracer
if evm.Config.Debug {
if evm.depth == 0 {
evm.Config.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
evm.Config.Tracer.CaptureEnd(ret, 0, nil)
} else {
evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
evm.Config.Tracer.CaptureExit(ret, 0, nil)
}
}
// Calling a non existing account, don't do anything
return nil, gas, nil
}
evm.StateDB.CreateAccount(addr)
}
evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)

// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
}
// Fail if we're trying to transfer more than the available balance
if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
return nil, gas, ErrInsufficientBalance
}

if isPrecompile {
info := &AdvancedPrecompileCall{
PrecompileAddress: addr,
Expand Down Expand Up @@ -282,7 +274,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
if evm.Config.Tracer != nil {
evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
defer func(startGas uint64) {
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err)
}(gas)
}
// Fail if we're trying to execute above the call depth limit
Expand All @@ -298,14 +290,6 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
}
var snapshot = evm.StateDB.Snapshot()

// Invoke tracer hooks that signal entering/exiting a call frame
if evm.Config.Debug {
evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
defer func(startGas uint64) {
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}

// It is allowed to call precompiles, even via delegatecall
if p, isPrecompile := evm.precompile(addr); isPrecompile {
info := &AdvancedPrecompileCall{
Expand Down Expand Up @@ -349,7 +333,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// DELEGATECALL inherits value from parent call
evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
defer func(startGas uint64) {
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err)
}(gas)
}
// Fail if we're trying to execute above the call depth limit
Expand Down Expand Up @@ -396,7 +380,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
if evm.Config.Tracer != nil {
evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
defer func(startGas uint64) {
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
evm.Config.Tracer.CaptureExit(ret, startGas-leftOverGas, err)
}(gas)
}
// Fail if we're trying to execute above the call depth limit
Expand All @@ -416,14 +400,6 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
// future scenarios
evm.StateDB.AddBalance(addr, big0, state.BalanceChangeTouchAccount)

// Invoke tracer hooks that signal entering/exiting a call frame
if evm.Config.Debug {
evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
defer func(startGas uint64) {
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}

if p, isPrecompile := evm.precompile(addr); isPrecompile {
info := &AdvancedPrecompileCall{
PrecompileAddress: addr,
Expand Down Expand Up @@ -521,14 +497,6 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
contract := NewContract(caller, AccountRef(address), value, gas)
contract.SetCodeOptionalHash(&address, codeAndHash)

if evm.Config.Debug {
if evm.depth == 0 {
evm.Config.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
} else {
evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
}
}

ret, err = evm.interpreter.Run(contract, nil, false)

// Check whether the max code size has been exceeded, assign err if the case.
Expand Down