From 880535c7302fee3d1489e83bd41423c866c5ef76 Mon Sep 17 00:00:00 2001 From: lmittmann <3458786+lmittmann@users.noreply.github.com> Date: Sat, 6 May 2023 05:16:27 +0200 Subject: [PATCH] eth/tracers, core/vm: remove `time` from trace output and tracing interface (#1488) This removes the 'time' field from logs, as well as from the tracer interface. This change makes the trace output deterministic. If a tracer needs the time they can measure it themselves. No need for evm to do this. Co-authored-by: Martin Holst Swende Co-authored-by: Sina Mahmoodi --- core/vm/evm.go | 13 +++++-------- core/vm/logger.go | 3 +-- eth/tracers/js/goja.go | 4 +--- .../js/internal/tracers/call_tracer_legacy.js | 1 - eth/tracers/js/tracer_test.go | 4 ++-- eth/tracers/logger/access_list_tracer.go | 3 +-- eth/tracers/logger/logger.go | 5 ++--- eth/tracers/logger/logger_json.go | 6 ++---- eth/tracers/native/4byte.go | 3 +-- eth/tracers/native/call.go | 3 +-- eth/tracers/native/noop.go | 3 +-- eth/tracers/native/prestate.go | 3 +-- 12 files changed, 18 insertions(+), 33 deletions(-) diff --git a/core/vm/evm.go b/core/vm/evm.go index 26842900b6..ae33238105 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -20,7 +20,6 @@ import ( "math/big" "sync" "sync/atomic" - "time" "github.com/holiman/uint256" @@ -205,7 +204,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if evm.Config.Debug { if evm.depth == 0 { evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) - evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil) + 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) @@ -221,9 +220,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if evm.Config.Debug { if evm.depth == 0 { evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) - defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters - evm.Config.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err) - }(gas, time.Now()) + 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) @@ -470,8 +469,6 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, } } - start := time.Now() - ret, err := evm.interpreter.Run(contract, nil, false) // Check whether the max code size has been exceeded, assign err if the case. @@ -509,7 +506,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if evm.Config.Debug { if evm.depth == 0 { - evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) + evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, err) } else { evm.Config.Tracer.CaptureExit(ret, gas-contract.Gas, err) } diff --git a/core/vm/logger.go b/core/vm/logger.go index 1067947d47..8b5b81d60d 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -18,7 +18,6 @@ package vm import ( "math/big" - "time" "github.com/ethereum/go-ethereum/common" ) @@ -34,7 +33,7 @@ type EVMLogger interface { CaptureTxEnd(restGas uint64) // Top call frame CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) - CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) + CaptureEnd(output []byte, gasUsed uint64, err error) // Rest of call frames CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) CaptureExit(output []byte, gasUsed uint64, err error) diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index e91e222a67..2af81a83c8 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "math/big" - "time" "github.com/dop251/goja" @@ -278,9 +277,8 @@ func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope } // CaptureEnd is called after the call finishes to finalize the tracing. -func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, duration time.Duration, err error) { +func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { t.ctx["output"] = t.vm.ToValue(output) - t.ctx["time"] = t.vm.ToValue(duration.String()) t.ctx["gasUsed"] = t.vm.ToValue(gasUsed) if err != nil { t.ctx["error"] = t.vm.ToValue(err.Error()) diff --git a/eth/tracers/js/internal/tracers/call_tracer_legacy.js b/eth/tracers/js/internal/tracers/call_tracer_legacy.js index 3ca7377738..05f72042c9 100644 --- a/eth/tracers/js/internal/tracers/call_tracer_legacy.js +++ b/eth/tracers/js/internal/tracers/call_tracer_legacy.js @@ -234,7 +234,6 @@ input: call.input, output: call.output, error: call.error, - time: call.time, calls: call.calls, } for (var key in sorted) { diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index b58b5ae94a..1d42dc319c 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -73,7 +73,7 @@ func runTrace(tracer tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCon tracer.CaptureTxStart(gasLimit) tracer.CaptureStart(env, contract.Caller(), contract.Address(), false, []byte{}, startGas, value) ret, err := env.Interpreter().Run(contract, []byte{}, false) - tracer.CaptureEnd(ret, startGas-contract.Gas, 1, err) + tracer.CaptureEnd(ret, startGas-contract.Gas, err) // Rest gas assumes no refund tracer.CaptureTxEnd(startGas - contract.Gas) if err != nil { @@ -193,7 +193,7 @@ func TestNoStepExec(t *testing.T) { } env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) tracer.CaptureStart(env, common.Address{}, common.Address{}, false, []byte{}, 1000, big.NewInt(0)) - tracer.CaptureEnd(nil, 0, 1, nil) + tracer.CaptureEnd(nil, 0, nil) ret, err := tracer.GetResult() if err != nil { t.Fatal(err) diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index a8908094eb..766ee4e4b9 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -18,7 +18,6 @@ package logger import ( "math/big" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -162,7 +161,7 @@ func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint6 func (*AccessListTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { } -func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {} +func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {} func (*AccessListTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { } diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index aea44801d8..48d03b6df0 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -24,7 +24,6 @@ import ( "math/big" "strings" "sync/atomic" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -220,7 +219,7 @@ func (l *StructLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, s } // CaptureEnd is called after the call finishes to finalize the tracing. -func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) { +func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { l.output = output l.err = err if l.cfg.Debug { @@ -386,7 +385,7 @@ func (t *mdLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err) } -func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, tm time.Duration, err error) { +func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { fmt.Fprintf(t.out, "\nOutput: `0x%x`\nConsumed gas: `%d`\nError: `%v`\n", output, gasUsed, err) } diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go index 72ad0199c9..37f1371d05 100644 --- a/eth/tracers/logger/logger_json.go +++ b/eth/tracers/logger/logger_json.go @@ -20,7 +20,6 @@ import ( "encoding/json" "io" "math/big" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" @@ -80,18 +79,17 @@ func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco } // CaptureEnd is triggered at end of execution. -func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) { +func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { type endLog struct { Output string `json:"output"` GasUsed math.HexOrDecimal64 `json:"gasUsed"` - Time time.Duration `json:"time"` Err string `json:"error,omitempty"` } var errMsg string if err != nil { errMsg = err.Error() } - l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, errMsg}) + l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), errMsg}) } func (l *JSONLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 7fb1c5e6c6..e6d1a6728c 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -21,7 +21,6 @@ import ( "math/big" "strconv" "sync/atomic" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" @@ -129,7 +128,7 @@ func (t *fourByteTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, } // CaptureEnd is called after the call finishes to finalize the tracing. -func (t *fourByteTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Duration, err error) { +func (t *fourByteTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { } func (*fourByteTracer) CaptureTxStart(gasLimit uint64) {} diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 0ac4029bca..ed26a79c80 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -21,7 +21,6 @@ import ( "errors" "math/big" "sync/atomic" - "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -142,7 +141,7 @@ func (t *callTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Ad } // CaptureEnd is called after the call finishes to finalize the tracing. -func (t *callTracer) CaptureEnd(output []byte, gasUsed uint64, d time.Duration, err error) { +func (t *callTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { t.callstack[0].processOutput(output, err) } diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go index c252b2408f..c1035bd1b7 100644 --- a/eth/tracers/native/noop.go +++ b/eth/tracers/native/noop.go @@ -19,7 +19,6 @@ package native import ( "encoding/json" "math/big" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" @@ -44,7 +43,7 @@ func (t *noopTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Ad } // CaptureEnd is called after the call finishes to finalize the tracing. -func (t *noopTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Duration, err error) { +func (t *noopTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { } // CaptureState implements the EVMLogger interface to trace a single step of VM execution. diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index b513f383b9..6f32af09a9 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -20,7 +20,6 @@ import ( "encoding/json" "math/big" "sync/atomic" - "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -82,7 +81,7 @@ func (t *prestateTracer) CaptureStart(env *vm.EVM, from common.Address, to commo } // CaptureEnd is called after the call finishes to finalize the tracing. -func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Duration, err error) { +func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { if t.create { // Exclude created contract. delete(t.prestate, t.to)