From 850013414be66778d59c8cf7aa452af40e1ce4fa Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Wed, 15 Oct 2025 11:28:03 +0200 Subject: [PATCH] cmd/evm: address PR feedback on blocktest stdin support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit addresses all feedback from @rjl493456442: 1. Result printing location: Removed duplicate report() call from inside test loop. Now uses dedicated traceEndMarker on stderr instead of printing full results mid-execution. 2. Fork assignment: Fork now always assigned regardless of tracer or pass/fail status. Root only assigned when test succeeds, following correct semantics. 3. Log suppression: Removed automatic log suppression. Users can control logging via standard --verbosity and --log.file flags. Only one rare INFO log exists in blocktest path. The traceEndMarker provides clear delimiter for trace parsers (e.g., goevmlab) without duplicating test results. Format: {"testEnd":{"name":"...","pass":true,"fork":"...","root":"..."}} This follows precedent from Nethermind PR #9432. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- cmd/evm/blockrunner.go | 55 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/cmd/evm/blockrunner.go b/cmd/evm/blockrunner.go index b2c64d6d83..df37d34f31 100644 --- a/cmd/evm/blockrunner.go +++ b/cmd/evm/blockrunner.go @@ -28,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/tests" "github.com/urfave/cli/v2" ) @@ -81,6 +80,41 @@ func blockTestCmd(ctx *cli.Context) error { return nil } +// traceEndMarker represents the final status of a blocktest when tracing is enabled. +// It is written as the last line of trace output in JSONL format to signal completion. +type traceEndMarker struct { + TestEnd traceEndDetails `json:"testEnd"` +} + +type traceEndDetails struct { + Name string `json:"name"` + Pass bool `json:"pass"` + Fork string `json:"fork"` + Root string `json:"root,omitempty"` + Error string `json:"error,omitempty"` +} + +// writeTraceEndMarker writes a blocktest end marker to stderr in JSONL format. +// This provides a clear delimiter for trace parsers (e.g., goevmlab) to know when +// the trace output for a specific test is complete, enabling proper batched processing. +func writeTraceEndMarker(name string, pass bool, fork string, root *common.Hash, errMsg string) { + details := traceEndDetails{ + Name: name, + Pass: pass, + Fork: fork, + } + if root != nil { + details.Root = root.Hex() + } + if !pass && errMsg != "" { + details.Error = errMsg + } + marker := traceEndMarker{TestEnd: details} + if data, err := json.Marshal(marker); err == nil { + fmt.Fprintf(os.Stderr, "%s\n", data) + } +} + func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) { src, err := os.ReadFile(fname) if err != nil { @@ -96,11 +130,6 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) { } tracer := tracerFromFlags(ctx) - // Suppress INFO logs when tracing to avoid polluting stderr - if tracer != nil { - log.SetDefault(log.NewLogger(log.DiscardHandler())) - } - // Pull out keys to sort and ensure tests are run in order. keys := slices.Sorted(maps.Keys(tests)) @@ -128,12 +157,18 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) { result.Pass, result.Error = false, err.Error() } - // Write result between transactions when tracing is enabled - if tracer != nil { - result.Fork = test.Network() + // Always assign fork (regardless of pass/fail or tracer) + result.Fork = test.Network() + // Assign root if test succeeded + if result.Pass && finalRoot != nil { result.Root = finalRoot - report(ctx, []testResult{*result}) } + + // When tracing, write end marker to delimit trace output for this test + if tracer != nil { + writeTraceEndMarker(result.Name, result.Pass, result.Fork, finalRoot, result.Error) + } + results = append(results, *result) } return results, nil