Skip to content

Commit d46370a

Browse files
committed
cmd/evm: add --workers flag to statetest for parallel file processing
1 parent 58fe592 commit d46370a

File tree

1 file changed

+68
-11
lines changed

1 file changed

+68
-11
lines changed

cmd/evm/staterunner.go

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"os"
2424
"regexp"
2525
"slices"
26+
"sync"
2627

2728
"github.com/ethereum/go-ethereum/common"
2829
"github.com/ethereum/go-ethereum/core/rawdb"
@@ -57,6 +58,7 @@ var stateTestCommand = &cli.Command{
5758
HumanReadableFlag,
5859
idxFlag,
5960
RunFlag,
61+
WorkersFlag,
6062
}, traceFlags),
6163
}
6264

@@ -65,16 +67,14 @@ func stateTestCmd(ctx *cli.Context) error {
6567

6668
// If path is provided, run the tests at that path.
6769
if len(path) != 0 {
68-
var (
69-
collected = collectFiles(path)
70-
results []testResult
71-
)
72-
for _, fname := range collected {
73-
r, err := runStateTest(ctx, fname)
74-
if err != nil {
75-
return err
76-
}
77-
results = append(results, r...)
70+
collected := collectFiles(path)
71+
workers := ctx.Int(WorkersFlag.Name)
72+
if workers <= 0 {
73+
workers = 1
74+
}
75+
results, err := runStateTestsParallel(ctx, collected, workers)
76+
if err != nil {
77+
return err
7878
}
7979
report(ctx, results)
8080
return nil
@@ -95,6 +95,63 @@ func stateTestCmd(ctx *cli.Context) error {
9595
return nil
9696
}
9797

98+
func runStateTestsParallel(ctx *cli.Context, files []string, workers int) ([]testResult, error) {
99+
if workers == 1 {
100+
var results []testResult
101+
for _, fname := range files {
102+
r, err := runStateTest(ctx, fname)
103+
if err != nil {
104+
return nil, err
105+
}
106+
results = append(results, r...)
107+
}
108+
return results, nil
109+
}
110+
var (
111+
wg sync.WaitGroup
112+
fileCh = make(chan struct {
113+
index int
114+
fname string
115+
}, len(files))
116+
resultCh = make(chan fileResult, len(files))
117+
)
118+
for i, fname := range files {
119+
fileCh <- struct {
120+
index int
121+
fname string
122+
}{i, fname}
123+
}
124+
close(fileCh)
125+
126+
for w := 0; w < workers; w++ {
127+
wg.Add(1)
128+
go func() {
129+
defer wg.Done()
130+
for item := range fileCh {
131+
r, err := runStateTest(ctx, item.fname)
132+
resultCh <- fileResult{index: item.index, results: r, err: err}
133+
}
134+
}()
135+
}
136+
go func() {
137+
wg.Wait()
138+
close(resultCh)
139+
}()
140+
141+
ordered := make([]fileResult, len(files))
142+
for fr := range resultCh {
143+
if fr.err != nil {
144+
return nil, fr.err
145+
}
146+
ordered[fr.index] = fr
147+
}
148+
var results []testResult
149+
for _, fr := range ordered {
150+
results = append(results, fr.results...)
151+
}
152+
return results, nil
153+
}
154+
98155
// runStateTest loads the state-test given by fname, and executes the test.
99156
func runStateTest(ctx *cli.Context, fname string) ([]testResult, error) {
100157
src, err := os.ReadFile(fname)
@@ -103,7 +160,7 @@ func runStateTest(ctx *cli.Context, fname string) ([]testResult, error) {
103160
}
104161
var testsByName map[string]tests.StateTest
105162
if err := json.Unmarshal(src, &testsByName); err != nil {
106-
return nil, fmt.Errorf("unable to read test file %s: %w", fname, err)
163+
return nil, nil // Skip non-fixture JSON files
107164
}
108165

109166
cfg := vm.Config{Tracer: tracerFromFlags(ctx)}

0 commit comments

Comments
 (0)