From 4c332a793547024be693adc4c92f60bf9c3dd068 Mon Sep 17 00:00:00 2001 From: jsvisa Date: Mon, 20 Nov 2023 04:21:37 +0000 Subject: [PATCH] cmd/evm: add --trace.tracer Signed-off-by: jsvisa --- cmd/evm/internal/t8ntool/execution.go | 6 +- cmd/evm/internal/t8ntool/flags.go | 4 + cmd/evm/internal/t8ntool/transition.go | 112 +++++++++++++++++-------- cmd/evm/main.go | 5 ++ 4 files changed, 89 insertions(+), 38 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 40b0fa638f..41c2913a47 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -118,7 +117,7 @@ type rejectedTx struct { // Apply applies a set of transactions to a pre-state func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txIt txIterator, miningReward int64, - getTracerFn func(txIndex int, txHash common.Hash) (tracer tracers.Tracer, err error)) (*state.StateDB, *ExecutionResult, []byte, error) { + getTracerFn func(txIndex int, txHash common.Hash) (*traceWriter, error)) (*state.StateDB, *ExecutionResult, []byte, error) { // Capture errors for BLOCKHASH operation, if we haven't been supplied the // required blockhashes var hashError error @@ -249,6 +248,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return nil, nil, nil, NewError(ErrorMissingBlockhash, hashError) } gasUsed += msgResult.UsedGas + if err := tracer.Write(); err != nil { + return nil, nil, nil, err + } // Receipt: { diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index de19dbc851..4e6428bbef 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -30,6 +30,10 @@ var ( Name: "trace", Usage: "Output full trace logs to files .jsonl", } + TraceTracerFlag = &cli.StringFlag{ + Name: "trace.tracer", + Usage: "Tracer name", + } TraceDisableMemoryFlag = &cli.BoolFlag{ Name: "trace.nomemory", Value: true, diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 5bca170a1f..9013687943 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -80,6 +80,33 @@ type input struct { TxRlp string `json:"txsRlp,omitempty"` } +type traceWriter struct { + tracers.Tracer + filename string +} + +func (t *traceWriter) Write() error { + if len(t.filename) == 0 { + return nil + } + file, err := os.Create(t.filename) + if err != nil { + return NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) + } + defer file.Close() + + result, err := t.GetResult() + if err != nil { + return err + } + if result == nil { + return nil + } + encoder := json.NewEncoder(file) + encoder.SetIndent("", " ") + return encoder.Encode(result) +} + func Transition(ctx *cli.Context) error { // Configure the go-ethereum logger glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) @@ -90,52 +117,65 @@ func Transition(ctx *cli.Context) error { err error tracer vm.EVMLogger ) - var getTracer func(txIndex int, txHash common.Hash) (tracers.Tracer, error) + var getTracer func(txIndex int, txHash common.Hash) (*traceWriter, error) baseDir, err := createBasedir(ctx) if err != nil { return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err)) } if ctx.Bool(TraceFlag.Name) { - if ctx.IsSet(TraceDisableMemoryFlag.Name) && ctx.IsSet(TraceEnableMemoryFlag.Name) { - return NewError(ErrorConfig, fmt.Errorf("can't use both flags --%s and --%s", TraceDisableMemoryFlag.Name, TraceEnableMemoryFlag.Name)) - } - if ctx.IsSet(TraceDisableReturnDataFlag.Name) && ctx.IsSet(TraceEnableReturnDataFlag.Name) { - return NewError(ErrorConfig, fmt.Errorf("can't use both flags --%s and --%s", TraceDisableReturnDataFlag.Name, TraceEnableReturnDataFlag.Name)) - } - if ctx.IsSet(TraceDisableMemoryFlag.Name) { - log.Warn(fmt.Sprintf("--%s has been deprecated in favour of --%s", TraceDisableMemoryFlag.Name, TraceEnableMemoryFlag.Name)) - } - if ctx.IsSet(TraceDisableReturnDataFlag.Name) { - log.Warn(fmt.Sprintf("--%s has been deprecated in favour of --%s", TraceDisableReturnDataFlag.Name, TraceEnableReturnDataFlag.Name)) - } - // Configure the EVM logger - logConfig := &logger.Config{ - DisableStack: ctx.Bool(TraceDisableStackFlag.Name), - EnableMemory: !ctx.Bool(TraceDisableMemoryFlag.Name) || ctx.Bool(TraceEnableMemoryFlag.Name), - EnableReturnData: !ctx.Bool(TraceDisableReturnDataFlag.Name) || ctx.Bool(TraceEnableReturnDataFlag.Name), - Debug: true, - } - var prevFile *os.File - // This one closes the last file - defer func() { - if prevFile != nil { - prevFile.Close() - } - }() - getTracer = func(txIndex int, txHash common.Hash) (tracers.Tracer, error) { - if prevFile != nil { - prevFile.Close() - } - traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String()))) + if ctx.IsSet(TraceTracerFlag.Name) { + config := &tracers.TraceConfig{} + tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config.TracerConfig) if err != nil { - return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) + return NewError(ErrorConfig, fmt.Errorf("%w unknown value of --%s", err, TraceTracerFlag)) + } + + getTracer = func(txIndex int, txHash common.Hash) (*traceWriter, error) { + traceFile := path.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String())) + return &traceWriter{tracer, traceFile}, nil + } + } else { + if ctx.IsSet(TraceDisableMemoryFlag.Name) && ctx.IsSet(TraceEnableMemoryFlag.Name) { + return NewError(ErrorConfig, fmt.Errorf("can't use both flags --%s and --%s", TraceDisableMemoryFlag.Name, TraceEnableMemoryFlag.Name)) + } + if ctx.IsSet(TraceDisableReturnDataFlag.Name) && ctx.IsSet(TraceEnableReturnDataFlag.Name) { + return NewError(ErrorConfig, fmt.Errorf("can't use both flags --%s and --%s", TraceDisableReturnDataFlag.Name, TraceEnableReturnDataFlag.Name)) + } + if ctx.IsSet(TraceDisableMemoryFlag.Name) { + log.Warn(fmt.Sprintf("--%s has been deprecated in favour of --%s", TraceDisableMemoryFlag.Name, TraceEnableMemoryFlag.Name)) + } + if ctx.IsSet(TraceDisableReturnDataFlag.Name) { + log.Warn(fmt.Sprintf("--%s has been deprecated in favour of --%s", TraceDisableReturnDataFlag.Name, TraceEnableReturnDataFlag.Name)) + } + // Configure the EVM logger + logConfig := &logger.Config{ + DisableStack: ctx.Bool(TraceDisableStackFlag.Name), + EnableMemory: !ctx.Bool(TraceDisableMemoryFlag.Name) || ctx.Bool(TraceEnableMemoryFlag.Name), + EnableReturnData: !ctx.Bool(TraceDisableReturnDataFlag.Name) || ctx.Bool(TraceEnableReturnDataFlag.Name), + Debug: true, + } + var prevFile *os.File + // This one closes the last file + defer func() { + if prevFile != nil { + prevFile.Close() + } + }() + getTracer = func(txIndex int, txHash common.Hash) (*traceWriter, error) { + if prevFile != nil { + prevFile.Close() + } + traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.jsonl", txIndex, txHash.String()))) + if err != nil { + return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) + } + prevFile = traceFile + return &traceWriter{logger.NewJSONLogger(logConfig, traceFile), ""}, nil } - prevFile = traceFile - return logger.NewJSONLogger(logConfig, traceFile), nil } } else { - getTracer = func(txIndex int, txHash common.Hash) (tracer tracers.Tracer, err error) { + getTracer = func(txIndex int, txHash common.Hash) (*traceWriter, error) { return nil, nil } } diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 1f6500b78c..8a1c886990 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -26,6 +26,10 @@ import ( "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/internal/flags" "github.com/urfave/cli/v2" + + // Force-load the tracer engines to trigger registration + _ "github.com/ethereum/go-ethereum/eth/tracers/js" + _ "github.com/ethereum/go-ethereum/eth/tracers/native" ) var ( @@ -143,6 +147,7 @@ var stateTransitionCommand = &cli.Command{ Action: t8ntool.Transition, Flags: []cli.Flag{ t8ntool.TraceFlag, + t8ntool.TraceTracerFlag, t8ntool.TraceDisableMemoryFlag, t8ntool.TraceEnableMemoryFlag, t8ntool.TraceDisableStackFlag,