Skip to content

Commit 9d2a754

Browse files
committed
Add end marker
1 parent 2dfae90 commit 9d2a754

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

cmd/evm/blockrunner.go

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ import (
2525
"regexp"
2626
"slices"
2727

28+
"github.com/ethereum/go-ethereum/common"
2829
"github.com/ethereum/go-ethereum/core"
2930
"github.com/ethereum/go-ethereum/core/rawdb"
31+
"github.com/ethereum/go-ethereum/log"
3032
"github.com/ethereum/go-ethereum/tests"
3133
"github.com/urfave/cli/v2"
3234
)
@@ -79,6 +81,42 @@ func blockTestCmd(ctx *cli.Context) error {
7981
return nil
8082
}
8183

84+
// blocktestEndMarker represents the final status of a blocktest execution.
85+
// It is written as the last line of trace output in JSONL format (single-line JSON).
86+
type blocktestEndMarker struct {
87+
TestEnd blocktestEndDetails `json:"testEnd"`
88+
}
89+
90+
type blocktestEndDetails struct {
91+
Name string `json:"name"`
92+
Pass bool `json:"pass"`
93+
Fork string `json:"fork,omitempty"`
94+
Root string `json:"root,omitempty"`
95+
Error string `json:"error,omitempty"`
96+
V int `json:"v"` // Version: 1
97+
}
98+
99+
// writeEndMarker writes the blocktest end marker to stderr in JSONL format.
100+
// This marker indicates the final outcome of the test as a single-line JSON object.
101+
func writeEndMarker(result *testResult, fork string, root *common.Hash) {
102+
details := blocktestEndDetails{
103+
Name: result.Name,
104+
Pass: result.Pass,
105+
Fork: fork,
106+
V: 1,
107+
}
108+
if !result.Pass && result.Error != "" {
109+
details.Error = result.Error
110+
}
111+
if root != nil {
112+
details.Root = root.Hex()
113+
}
114+
marker := blocktestEndMarker{TestEnd: details}
115+
if data, err := json.Marshal(marker); err == nil {
116+
fmt.Fprintf(os.Stderr, "%s\n", data)
117+
}
118+
}
119+
82120
func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) {
83121
src, err := os.ReadFile(fname)
84122
if err != nil {
@@ -94,6 +132,11 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) {
94132
}
95133
tracer := tracerFromFlags(ctx)
96134

135+
// Suppress INFO logs when tracing to avoid polluting stderr
136+
if tracer != nil {
137+
log.SetDefault(log.NewLogger(log.DiscardHandler()))
138+
}
139+
97140
// Pull out keys to sort and ensure tests are run in order.
98141
keys := slices.Sorted(maps.Keys(tests))
99142

@@ -103,17 +146,30 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) {
103146
if !re.MatchString(name) {
104147
continue
105148
}
149+
test := tests[name]
106150
result := &testResult{Name: name, Pass: true}
107-
if err := tests[name].Run(false, rawdb.PathScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) {
151+
var finalRoot *common.Hash
152+
if err := test.Run(false, rawdb.PathScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) {
108153
if ctx.Bool(DumpFlag.Name) {
109154
if s, _ := chain.State(); s != nil {
110155
result.State = dump(s)
111156
}
112157
}
158+
// Capture final state root for end marker
159+
if chain != nil {
160+
root := chain.CurrentBlock().Root
161+
finalRoot = &root
162+
}
113163
}); err != nil {
114164
result.Pass, result.Error = false, err.Error()
115165
}
116166
results = append(results, *result)
167+
168+
// Write end marker when tracing is enabled
169+
if tracer != nil {
170+
fork := test.Network()
171+
writeEndMarker(result, fork, finalRoot)
172+
}
117173
}
118174
return results, nil
119175
}

tests/block_test_util.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import (
3838
"github.com/ethereum/go-ethereum/core/tracing"
3939
"github.com/ethereum/go-ethereum/core/types"
4040
"github.com/ethereum/go-ethereum/core/vm"
41-
"github.com/ethereum/go-ethereum/log"
4241
"github.com/ethereum/go-ethereum/params"
4342
"github.com/ethereum/go-ethereum/rlp"
4443
"github.com/ethereum/go-ethereum/triedb"
@@ -116,6 +115,15 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t
116115
if !ok {
117116
return UnsupportedForkError{t.json.Network}
118117
}
118+
return t.run(config, snapshotter, scheme, witness, tracer, postCheck)
119+
}
120+
121+
// Network returns the network/fork name for this test.
122+
func (t *BlockTest) Network() string {
123+
return t.json.Network
124+
}
125+
126+
func (t *BlockTest) run(config *params.ChainConfig, snapshotter bool, scheme string, witness bool, tracer *tracing.Hooks, postCheck func(error, *core.BlockChain)) (result error) {
119127
// import pre accounts & construct test genesis block & state root
120128
var (
121129
db = rawdb.NewMemoryDatabase()
@@ -241,7 +249,7 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error)
241249
cb, err := b.decode()
242250
if err != nil {
243251
if b.BlockHeader == nil {
244-
log.Info("Block decoding failed", "index", bi, "err", err)
252+
fmt.Fprintf(os.Stdout, "INFO: Block decoding failed, index=%d err=%v\n", bi, err)
245253
continue // OK - block is supposed to be invalid, continue with next block
246254
} else {
247255
return nil, fmt.Errorf("block RLP decoding failed when expected to succeed: %v", err)
@@ -259,7 +267,7 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error)
259267
}
260268
if b.BlockHeader == nil {
261269
if data, err := json.MarshalIndent(cb.Header(), "", " "); err == nil {
262-
fmt.Fprintf(os.Stderr, "block (index %d) insertion should have failed due to: %v:\n%v\n",
270+
fmt.Fprintf(os.Stdout, "block (index %d) insertion should have failed due to: %v:\n%v\n",
263271
bi, b.ExpectException, string(data))
264272
}
265273
return nil, fmt.Errorf("block (index %d) insertion should have failed due to: %v",

0 commit comments

Comments
 (0)