From dbc1d04f5e4a6e466e32db08ed03678624a93307 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Tue, 6 Aug 2024 05:51:48 -0600 Subject: [PATCH] core/vm/runtime: ensure tracer benchmark calls `OnTxStart` (#30257) The struct-based tracing added in #29189 seems to have caused an issue with the benchmark `BenchmarkTracerStepVsCallFrame`. On master we see the following panic: ```console BenchmarkTracerStepVsCallFrame panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x2 addr=0x40 pc=0x1019782f0] goroutine 37 [running]: github.com/ethereum/go-ethereum/eth/tracers/js.(*jsTracer).OnOpcode(0x140004c4000, 0x0, 0x10?, 0x989680, 0x1, {0x101ea2298, 0x1400000e258}, {0x1400000e258?, 0x14000155928?, 0x10173020c?}, ...) /Users/matt/dev/go-ethereum/eth/tracers/js/goja.go:328 +0x140 github.com/ethereum/go-ethereum/core/vm.(*EVMInterpreter).Run(0x14000307da0, 0x140003cc0d0, {0x0, 0x0, 0x0}, 0x0) ... FAIL github.com/ethereum/go-ethereum/core/vm/runtime 0.420s FAIL ``` The issue seems to be that `OnOpcode` expects that `OnTxStart` has already been called to initialize the `env` value in the tracer. The JS tracer uses it in `OnOpcode` for the `GetRefund()` method. This patch resolves the issue by reusing the `Call` method already defined in `runtime_test.go` which correctly calls `OnTxStart`. --- core/vm/runtime/runtime_test.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 04abc5480e..a49eca25d3 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -38,7 +38,6 @@ import ( // force-load js tracers to trigger registration _ "github.com/ethereum/go-ethereum/eth/tracers/js" - "github.com/holiman/uint256" ) func TestDefaults(t *testing.T) { @@ -339,11 +338,7 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode Tracer: tracer.Hooks, } } - var ( - destination = common.BytesToAddress([]byte("contract")) - vmenv = NewEnv(cfg) - sender = vm.AccountRef(cfg.Origin) - ) + destination := common.BytesToAddress([]byte("contract")) cfg.State.CreateAccount(destination) eoa := common.HexToAddress("E0") { @@ -363,12 +358,12 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode //cfg.State.CreateAccount(cfg.Origin) // set the receiver's (the executing contract) code for execution. cfg.State.SetCode(destination, code) - vmenv.Call(sender, destination, nil, gas, uint256.MustFromBig(cfg.Value)) + Call(destination, nil, cfg) b.Run(name, func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - vmenv.Call(sender, destination, nil, gas, uint256.MustFromBig(cfg.Value)) + Call(destination, nil, cfg) } }) }