eth/tracers: Add optional call frame enter print

This commit is contained in:
Mario Vega 2024-03-11 01:37:46 +00:00
parent e31709db65
commit eaced5e80e
3 changed files with 127 additions and 0 deletions

View file

@ -0,0 +1,72 @@
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
package logger
import (
"encoding/json"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/vm"
)
var _ = (*callFrameLogMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (c CallFrameLog) MarshalJSON() ([]byte, error) {
type CallFrameLog struct {
Op *vm.OpCode `json:"op,omitempty"`
From common.Address `json:"from"`
To common.Address `json:"to"`
Input hexutil.Bytes `json:"input,omitempty"`
Gas math.HexOrDecimal64 `json:"gas"`
Value *hexutil.Big `json:"value"`
OpName *string `json:"opName,omitempty"`
}
var enc CallFrameLog
enc.Op = c.Op
enc.From = c.From
enc.To = c.To
enc.Input = c.Input
enc.Gas = math.HexOrDecimal64(c.Gas)
enc.Value = (*hexutil.Big)(c.Value)
enc.OpName = c.OpName()
return json.Marshal(&enc)
}
// UnmarshalJSON unmarshals from JSON.
func (c *CallFrameLog) UnmarshalJSON(input []byte) error {
type CallFrameLog struct {
Op *vm.OpCode `json:"op,omitempty"`
From *common.Address `json:"from"`
To *common.Address `json:"to"`
Input *hexutil.Bytes `json:"input,omitempty"`
Gas *math.HexOrDecimal64 `json:"gas"`
Value *hexutil.Big `json:"value"`
}
var dec CallFrameLog
if err := json.Unmarshal(input, &dec); err != nil {
return err
}
if dec.Op != nil {
c.Op = dec.Op
}
if dec.From != nil {
c.From = *dec.From
}
if dec.To != nil {
c.To = *dec.To
}
if dec.Input != nil {
c.Input = *dec.Input
}
if dec.Gas != nil {
c.Gas = uint64(*dec.Gas)
}
if dec.Value != nil {
c.Value = (*big.Int)(dec.Value)
}
return nil
}

View file

@ -52,6 +52,7 @@ type Config struct {
DisableStack bool // disable stack capture
DisableStorage bool // disable storage capture
EnableReturnData bool // enable return data capture
EnableCallFrame bool // enable call frame enter capture
Debug bool // print output during capture end
Limit int // maximum length of output, but zero means unlimited
// Chain overrides, can be used to execute a trace using future fork rules
@ -101,6 +102,35 @@ func (s *StructLog) ErrorString() string {
return ""
}
//go:generate go run github.com/fjl/gencodec -type CallFrameLog -field-override callFrameLogMarshaling -out gen_callframelog.go
// CallFrameLog is emitted every call frame entered.
type CallFrameLog struct {
Op *vm.OpCode `json:"op,omitempty"`
From common.Address `json:"from"`
To common.Address `json:"to"`
Input []byte `json:"input,omitempty"`
Gas uint64 `json:"gas"`
Value *big.Int `json:"value"`
}
// overrides for gencodec
type callFrameLogMarshaling struct {
Input hexutil.Bytes
Gas math.HexOrDecimal64
Value *hexutil.Big
OpName *string `json:"opName,omitempty"` // adds call to OpName() in MarshalJSON
}
// OpName formats the operand name in a human-readable format.
func (c *CallFrameLog) OpName() *string {
if c.Op != nil {
op := c.Op.String()
return &op
}
return nil
}
// StructLogger is an EVM state logger and implements EVMLogger.
//
// StructLogger can capture state based on the given Log configuration and also keeps

View file

@ -44,6 +44,18 @@ func NewJSONLogger(cfg *Config, writer io.Writer) *JSONLogger {
func (l *JSONLogger) CaptureStart(env *vm.EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
l.env = env
if l.cfg.EnableCallFrame {
log := CallFrameLog{
From: from,
To: to,
Gas: gas,
Value: value,
}
if l.cfg.EnableMemory {
log.Input = input
}
l.encoder.Encode(log)
}
}
func (l *JSONLogger) CaptureFault(pc uint64, op vm.OpCode, gas uint64, cost uint64, scope *vm.ScopeContext, depth int, err error) {
@ -93,6 +105,19 @@ func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) {
}
func (l *JSONLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
if l.cfg.EnableCallFrame {
log := CallFrameLog{
Op: &typ,
From: from,
To: to,
Gas: gas,
Value: value,
}
if l.cfg.EnableMemory {
log.Input = input
}
l.encoder.Encode(log)
}
}
func (l *JSONLogger) CaptureExit(output []byte, gasUsed uint64, err error) {}