From 583fb9bff8fa0fe61a38ca3e9511a71c4e1c1d75 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 23 Nov 2023 10:25:06 +0100 Subject: [PATCH] cmd/evm: remove deprecated flags, refactor tracewriter --- cmd/evm/internal/t8ntool/execution.go | 11 +--- cmd/evm/internal/t8ntool/flags.go | 10 --- cmd/evm/internal/t8ntool/tracewriter.go | 81 +++++++++++++++++++++++++ cmd/evm/internal/t8ntool/transition.go | 77 +++++------------------ cmd/evm/main.go | 2 - 5 files changed, 98 insertions(+), 83 deletions(-) create mode 100644 cmd/evm/internal/t8ntool/tracewriter.go diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index be737c0da7..a4ffd09e4f 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -117,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) (*traceWriter, error)) (*state.StateDB, *ExecutionResult, []byte, error) { + getTracerFn func(txIndex int, txHash common.Hash) (vm.EVMLogger, error)) (*state.StateDB, *ExecutionResult, []byte, error) { // Capture errors for BLOCKHASH operation, if we haven't been supplied the // required blockhashes var hashError error @@ -224,9 +224,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, if err != nil { return nil, nil, nil, err } - if tracer != nil { - vmConfig.Tracer = tracer - } + vmConfig.Tracer = tracer statedb.SetTxContext(tx.Hash(), txIndex) var ( @@ -250,11 +248,6 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return nil, nil, nil, NewError(ErrorMissingBlockhash, hashError) } gasUsed += msgResult.UsedGas - if tracer != nil { - 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 ce82eb234d..6a8c39159f 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -38,11 +38,6 @@ var ( Name: "trace.tracer.config", Usage: "The configurations of --trace.tracer, in JSON encoded format", } - TraceDisableMemoryFlag = &cli.BoolFlag{ - Name: "trace.nomemory", - Value: true, - Usage: "Disable full memory dump in traces (deprecated)", - } TraceEnableMemoryFlag = &cli.BoolFlag{ Name: "trace.memory", Usage: "Enable full memory dump in traces", @@ -51,11 +46,6 @@ var ( Name: "trace.nostack", Usage: "Disable stack output in traces", } - TraceDisableReturnDataFlag = &cli.BoolFlag{ - Name: "trace.noreturndata", - Value: true, - Usage: "Disable return data output in traces (deprecated)", - } TraceEnableReturnDataFlag = &cli.BoolFlag{ Name: "trace.returndata", Usage: "Enable return data output in traces", diff --git a/cmd/evm/internal/t8ntool/tracewriter.go b/cmd/evm/internal/t8ntool/tracewriter.go new file mode 100644 index 0000000000..e4efad112f --- /dev/null +++ b/cmd/evm/internal/t8ntool/tracewriter.go @@ -0,0 +1,81 @@ +// Copyright 2020 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package t8ntool + +import ( + "encoding/json" + "io" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/log" +) + +// traceWriter is an vm.EVMLogger which also holds an inner logger/tracer. +// When the TxEnd event happens, the inner tracer result is written to the file, and +// the file is closed. +type traceWriter struct { + inner vm.EVMLogger + f io.WriteCloser +} + +// Compile-time interface check +var _ = vm.EVMLogger((*traceWriter)(nil)) + +func (t *traceWriter) CaptureTxEnd(restGas uint64) { + t.inner.CaptureTxEnd(restGas) + defer t.f.Close() + + if tracer, ok := t.inner.(tracers.Tracer); ok { + result, err := tracer.GetResult() + if err != nil { + log.Warn("Error in tracer", "err", err) + return + } + err = json.NewEncoder(t.f).Encode(result) + if err != nil { + log.Warn("Error writing tracer output", "err", err) + return + } + } +} + +func (t *traceWriter) CaptureTxStart(gasLimit uint64) { t.inner.CaptureTxStart(gasLimit) } +func (t *traceWriter) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { + t.inner.CaptureStart(env, from, to, create, input, gas, value) +} + +func (t *traceWriter) CaptureEnd(output []byte, gasUsed uint64, err error) { + t.inner.CaptureEnd(output, gasUsed, err) +} + +func (t *traceWriter) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { + t.inner.CaptureEnter(typ, from, to, input, gas, value) +} + +func (t *traceWriter) CaptureExit(output []byte, gasUsed uint64, err error) { + t.inner.CaptureExit(output, gasUsed, err) +} + +func (t *traceWriter) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { + t.inner.CaptureState(pc, op, gas, cost, scope, rData, depth, err) +} +func (t *traceWriter) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { + t.inner.CaptureFault(pc, op, gas, cost, scope, depth, err) +} diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index f8d0737524..819c7eca86 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -80,97 +80,50 @@ 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))) glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name))) log.Root().SetHandler(glogger) + var getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { return nil, nil } + baseDir, err := createBasedir(ctx) if err != nil { return NewError(ErrorIO, fmt.Errorf("failed creating output basedir: %v", err)) } - getTracer := func(txIndex int, txHash common.Hash) (*traceWriter, error) { return nil, nil } if ctx.Bool(TraceFlag.Name) { if ctx.IsSet(TraceTracerFlag.Name) { var config json.RawMessage if ctx.IsSet(TraceTracerConfigFlag.Name) { config = []byte(ctx.String(TraceTracerConfigFlag.Name)) } - tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config) - if err != nil { - return NewError(ErrorConfig, fmt.Errorf("can't instantiate a trace instance: %w", err)) - } - - getTracer = func(txIndex int, txHash common.Hash) (*traceWriter, error) { - traceFile := path.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String())) + getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { + traceFile, err := os.Create(path.Join(baseDir, fmt.Sprintf("trace-%d-%v.json", txIndex, txHash.String()))) + if err != nil { + return nil, NewError(ErrorIO, fmt.Errorf("failed creating trace-file: %v", err)) + } + tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), nil, config) + if err != nil { + return nil, NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %w", err)) + } 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), + EnableMemory: ctx.Bool(TraceEnableMemoryFlag.Name), + EnableReturnData: 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() - } + getTracer = func(txIndex int, txHash common.Hash) (vm.EVMLogger, error) { 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 + return &traceWriter{logger.NewJSONLogger(logConfig, traceFile), traceFile}, nil } } } diff --git a/cmd/evm/main.go b/cmd/evm/main.go index f82b2d1e44..26127431a5 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -149,10 +149,8 @@ var stateTransitionCommand = &cli.Command{ t8ntool.TraceFlag, t8ntool.TraceTracerFlag, t8ntool.TraceTracerConfigFlag, - t8ntool.TraceDisableMemoryFlag, t8ntool.TraceEnableMemoryFlag, t8ntool.TraceDisableStackFlag, - t8ntool.TraceDisableReturnDataFlag, t8ntool.TraceEnableReturnDataFlag, t8ntool.OutputBasedir, t8ntool.OutputAllocFlag,