mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 07:36:44 +00:00
Move up CaptureStart/CaptureEnd as well as CaptureEnter/CaptureExit higher directly when function starts
This commit is contained in:
parent
751b984c9b
commit
dd86f19df4
2 changed files with 36 additions and 96 deletions
127
core/vm/evm.go
127
core/vm/evm.go
|
|
@ -176,11 +176,19 @@ func (evm *EVM) SetBlockContext(blockCtx BlockContext) {
|
|||
// the necessary steps to create accounts and reverses the state in case of an
|
||||
// execution error or failed value transfer.
|
||||
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
||||
if v, ok := evm.Config.Tracer.(EVMLoggerExtended); evm.Config.Tracer != nil && ok {
|
||||
v.CaptureCallStart(CALL, caller.Address(), addr, input, gas, value)
|
||||
defer func(startGas uint64) {
|
||||
v.CaptureCallEnd(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
if evm.depth == 0 {
|
||||
tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
|
||||
defer func(startGas uint64) { // Lazy evaluation of the parameters
|
||||
tracer.CaptureEnd(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
} else {
|
||||
// Handle tracer events for entering and exiting a call frame
|
||||
tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
|
||||
defer func(startGas uint64) {
|
||||
tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
}
|
||||
|
||||
// Fail if we're trying to execute above the call depth limit
|
||||
|
|
@ -193,42 +201,15 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
}
|
||||
snapshot := evm.StateDB.Snapshot()
|
||||
p, isPrecompile := evm.precompile(addr)
|
||||
debug := evm.Config.Tracer != nil
|
||||
|
||||
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 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)
|
||||
}
|
||||
}
|
||||
return nil, gas, nil
|
||||
}
|
||||
evm.StateDB.CreateAccount(addr)
|
||||
}
|
||||
evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)
|
||||
|
||||
// Capture the tracer start/end events in debug mode
|
||||
if debug {
|
||||
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)
|
||||
}(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)
|
||||
}(gas)
|
||||
}
|
||||
}
|
||||
|
||||
if isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
||||
} else {
|
||||
|
|
@ -270,10 +251,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
|||
// CallCode differs from Call in the sense that it executes the given address'
|
||||
// code with the caller as context.
|
||||
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
|
||||
if v, ok := evm.Config.Tracer.(EVMLoggerExtended); evm.Config.Tracer != nil && ok {
|
||||
v.CaptureCallStart(CALLCODE, caller.Address(), addr, input, gas, value)
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
|
||||
defer func(startGas uint64) {
|
||||
v.CaptureCallEnd(ret, startGas-gas, err)
|
||||
tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
|
|
@ -290,14 +272,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.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)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
// It is allowed to call precompiles, even via delegatecall
|
||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
||||
|
|
@ -325,12 +299,15 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
|
|||
// DelegateCall differs from CallCode in the sense that it executes the given address'
|
||||
// code with the caller as context and the caller is set to the caller of the caller.
|
||||
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
||||
if v, ok := evm.Config.Tracer.(EVMLoggerExtended); evm.Config.Tracer != nil && ok {
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
// NOTE: caller must, at all times be a contract. It should never happen
|
||||
// that caller is something other than a Contract.
|
||||
parent := caller.(*Contract)
|
||||
|
||||
v.CaptureCallStart(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
|
||||
// DELEGATECALL inherits value from parent call
|
||||
tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
|
||||
defer func(startGas uint64) {
|
||||
v.CaptureCallEnd(ret, startGas-gas, err)
|
||||
tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
|
|
@ -340,18 +317,6 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
|||
}
|
||||
var snapshot = evm.StateDB.Snapshot()
|
||||
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if evm.Config.Tracer != nil {
|
||||
// NOTE: caller must, at all times be a contract. It should never happen
|
||||
// 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)
|
||||
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 {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
||||
|
|
@ -377,10 +342,11 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
|
|||
// Opcodes that attempt to perform such modifications will result in exceptions
|
||||
// instead of performing the modifications.
|
||||
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
|
||||
if v, ok := evm.Config.Tracer.(EVMLoggerExtended); evm.Config.Tracer != nil && ok {
|
||||
v.CaptureCallStart(STATICCALL, caller.Address(), addr, input, gas, nil)
|
||||
// Invoke tracer hooks that signal entering/exiting a call frame
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
|
||||
defer func(startGas uint64) {
|
||||
v.CaptureCallEnd(ret, startGas-gas, err)
|
||||
tracer.CaptureExit(ret, startGas-gas, err)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
|
|
@ -401,14 +367,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.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)
|
||||
}(gas)
|
||||
}
|
||||
|
||||
if p, isPrecompile := evm.precompile(addr); isPrecompile {
|
||||
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
|
||||
} else {
|
||||
|
|
@ -449,11 +407,14 @@ 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, created common.Address, leftOverGas uint64, err error) {
|
||||
if v, ok := evm.Config.Tracer.(EVMLoggerExtended); evm.Config.Tracer != nil && ok {
|
||||
v.CaptureCallStart(typ, caller.Address(), address, codeAndHash.code, gas, nil)
|
||||
defer func(startGas uint64) {
|
||||
v.CaptureCallEnd(ret, startGas-leftOverGas, err)
|
||||
}(gas)
|
||||
if tracer := evm.Config.Tracer; tracer != nil {
|
||||
if evm.depth == 0 {
|
||||
tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
|
||||
defer tracer.CaptureEnd(ret, gas-leftOverGas, err)
|
||||
} else {
|
||||
tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
|
||||
defer tracer.CaptureExit(ret, gas-leftOverGas, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Depth check execution. Fail if we're trying to execute above the
|
||||
|
|
@ -492,14 +453,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.Tracer != nil {
|
||||
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.
|
||||
|
|
@ -535,14 +488,6 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
|||
}
|
||||
}
|
||||
|
||||
if evm.Config.Tracer != nil {
|
||||
if evm.depth == 0 {
|
||||
evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, err)
|
||||
} else {
|
||||
evm.Config.Tracer.CaptureExit(ret, gas-contract.Gas, err)
|
||||
}
|
||||
}
|
||||
|
||||
leftOverGas = contract.Gas
|
||||
return ret, address, contract.Gas, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,3 @@ type EVMLogger interface {
|
|||
// Misc
|
||||
OnGasConsumed(gas, amount uint64)
|
||||
}
|
||||
|
||||
type EVMLoggerExtended interface {
|
||||
CaptureCallStart(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int)
|
||||
CaptureCallEnd(output []byte, gasUsed uint64, err error)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue