Merge branch 'extended-tracer' into feature/firehose-extended-tracer

# Conflicts:
#	core/vm/evm.go
This commit is contained in:
Matthieu Vachon 2023-08-02 09:49:36 -04:00
commit 09df0e0c95
10 changed files with 125 additions and 53 deletions

View file

@ -256,7 +256,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
if vmConfig.Tracer != nil {
l, ok := vmConfig.Tracer.(BlockchainLogger)
if !ok {
return nil, fmt.Errorf("only extended tracers are supported for live mode")
return nil, errors.New("only extended tracers are supported for live mode")
}
logger = l
}

View file

@ -17,9 +17,7 @@
package vm
import (
"fmt"
"math/big"
"os"
"sync/atomic"
"github.com/ethereum/go-ethereum/common"
@ -181,24 +179,24 @@ 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 tracer := evm.Config.Tracer; tracer != nil {
// Capture the tracer start/end events in debug mode
if evm.Config.Tracer != nil {
if evm.depth == 0 {
tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
evm.Config.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
defer func(startGas uint64) { // Lazy evaluation of the parameters
tracer.CaptureEnd(ret, startGas-leftOverGas, err)
evm.Config.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)
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
defer func(startGas uint64) {
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
tracer.CaptureExit(ret, startGas-leftOverGas, err)
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
}
// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
@ -212,6 +210,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if !evm.StateDB.Exist(addr) {
if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
// Calling a non-existing account, don't do anything.
return nil, gas, nil
}
evm.StateDB.CreateAccount(addr)
@ -237,7 +236,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
}
}
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// above we revert to the snapshot and consume any gas remaining. Additionally,
// when we're in homestead this also counts for code storage gas errors.
if err != nil {
evm.StateDB.RevertToSnapshot(snapshot)
@ -264,16 +263,15 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// 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) {
// 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)
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
if evm.Config.Tracer != nil {
evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
defer func(startGas uint64) {
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
tracer.CaptureExit(ret, startGas-leftOverGas, err)
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
@ -319,20 +317,19 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// 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) {
// Invoke tracer hooks that signal entering/exiting a call frame
if tracer := evm.Config.Tracer; tracer != nil {
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
tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value)
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
defer func(startGas uint64) {
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
tracer.CaptureExit(ret, startGas-leftOverGas, err)
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
@ -369,16 +366,15 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// instead of performing the modifications.
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 tracer := evm.Config.Tracer; tracer != nil {
tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
if evm.Config.Tracer != nil {
evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
defer func(startGas uint64) {
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
tracer.CaptureExit(ret, startGas-leftOverGas, err)
evm.Config.Tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
evm.Config.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
@ -439,24 +435,23 @@ 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 tracer := evm.Config.Tracer; tracer != nil {
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 {
tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
defer func(startGas uint64) {
tracer.CaptureEnd(ret, startGas-leftOverGas, err)
}(gas)
evm.Config.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value)
defer func() {
evm.Config.Tracer.CaptureEnd(ret, gas-leftoverGas, err)
}()
} else {
tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
tracer.OnGasConsumed(0, -gas, GasInitialBalance)
evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
evm.Config.Tracer.OnGasConsumed(0, -gas, GasInitialBalance)
defer func(startGas uint64) {
tracer.OnGasConsumed(leftOverGas, leftOverGas, GasBuyBack)
tracer.CaptureExit(ret, startGas-leftOverGas, err)
}(gas)
defer func() {
evm.Config.Tracer.OnGasConsumed(leftoverGas, leftoverGas, GasBuyBack)
evm.Config.Tracer.CaptureExit(ret, gas-leftoverGas, err)
}()
}
}
// Depth check execution. Fail if we're trying to execute above the
// limit.
if evm.depth > int(params.CallCreateDepth) {
@ -523,7 +518,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// above we revert to the snapshot and consume any gas remaining. Additionally,
// when we're in homestead this also counts for code storage gas errors.
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
evm.StateDB.RevertToSnapshot(snapshot)

View file

@ -562,7 +562,6 @@ func TestTracingWithOverrides(t *testing.T) {
From: &accounts[0].addr,
// BLOCKNUMBER PUSH1 MSTORE
Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")),
//&hexutil.Bytes{0x43}, // blocknumber
},
config: &TraceCallConfig{
BlockOverrides: &ethapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},

View file

@ -131,7 +131,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
return fmt.Errorf("failed to unmarshal trace result: %v", err)
}
if !jsonEqualFlat(ret, test.Result) {
t.Logf("tracer name: %s", tracerName)
t.Logf("test %s failed", filename)
// uncomment this for easier debugging
// have, _ := json.MarshalIndent(ret, "", " ")

View file

@ -56,6 +56,16 @@
"value": "0x0",
"gas": "0x1f97e",
"gasUsed": "0x72de",
"input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000"
"input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000",
"calls": [{
"from":"0x6c06b16512b332e6cd8293a2974872674716ce18",
"gas":"0x8fc",
"gasUsed":"0x0",
"to":"0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
"input":"0x",
"error":"insufficient balance for transfer",
"value":"0x14d1120d7b160000",
"type":"CALL"
}]
}
}

View file

@ -63,12 +63,27 @@
"address": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224"
},
"traceAddress": [],
"subtraces": 0,
"subtraces": 1,
"transactionPosition": 74,
"transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4",
"blockNumber": 1555279,
"blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46",
"time": "209.346µs"
},
{
"action": {
"balance": "0x0",
"callType": "callcode",
"from": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224",
"gas": "0xaf64",
"to": "0x0000000000000000000000000000000000000004",
"value": "0x13"
},
"error": "insufficient balance for transfer",
"result": {},
"subtraces": 0,
"traceAddress": [0],
"type": "call"
}
]
}

View file

@ -64,9 +64,23 @@
"gasUsed": "0x72de",
"output": "0x"
},
"subtraces": 0,
"subtraces": 1,
"traceAddress": [],
"type": "call"
},
{
"action": {
"callType": "call",
"from": "0x6c06b16512b332e6cd8293a2974872674716ce18",
"gas": "0x8fc",
"to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
"value": "0x14d1120d7b160000"
},
"error": "insufficient balance for transfer",
"result": {},
"subtraces": 0,
"traceAddress": [0],
"type": "call"
}
]
}

View file

@ -70,12 +70,25 @@
"output": "0x"
},
"traceAddress": [],
"subtraces": 0,
"subtraces": 1,
"transactionPosition": 26,
"transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4",
"blockNumber": 839247,
"blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c",
"time": "182.267µs"
},
{
"action": {
"from": "0x76554b33410b6d90b7dc889bfed0451ad195f27e",
"gas": "0x25a18",
"init": "0x0000000000000000000000000000000000000000000000000000000000000000",
"value": "0xa"
},
"error": "insufficient balance for transfer",
"result": {},
"subtraces": 0,
"traceAddress": [0],
"type": "create"
}
]
}

View file

@ -63,13 +63,26 @@
"address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca"
},
"traceAddress": [],
"subtraces": 1,
"subtraces": 2,
"transactionPosition": 14,
"transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
"blockNumber": 1555146,
"blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e",
"time": "187.145µs"
},
{
"action": {
"from": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca",
"gas": "0x50ac",
"init": "0x5a",
"value": "0x1"
},
"error": "insufficient balance for transfer",
"result": {},
"subtraces": 0,
"traceAddress": [0],
"type": "create"
},
{
"type": "suicide",
"action": {
@ -79,7 +92,7 @@
},
"result": null,
"traceAddress": [
0
1
],
"subtraces": 0,
"transactionPosition": 14,

File diff suppressed because one or more lines are too long