-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathconfig.example.yaml
More file actions
673 lines (657 loc) · 35.5 KB
/
Copy pathconfig.example.yaml
File metadata and controls
673 lines (657 loc) · 35.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
# Environment variables can be used anywhere in the config using ${VAR} or $VAR syntax.
# Example: ${MY_SECRET} or ${DATA_DIR:-/default/path} (with default value).
#
# Multiple config files can be merged with: --config base.yaml --config overrides.yaml
# Later files override earlier ones.
global:
log_level: ${LOG_LEVEL:-info}
# Optional directory configurations shared by the build and run commands.
# directories:
# # On-disk cache: executor git/archive clones (run) and the EEST repo clone
# # (build). Defaults to ~/.cache/benchmarkoor.
# cachedir: ${TMP_DIR:-/tmp}/benchmarkoor-cache
runner:
# Container runtime: "docker" (default) or "podman".
# Podman is required for the "container-checkpoint-restore" rollback strategy.
# When using Podman, ensure the socket is active: sudo systemctl start podman.socket
# container_runtime: docker
client_logs_to_stdout: true
container_network: benchmarkoor
cleanup_on_start: false
# Optional: Global timeout for the entire run (all instances, setup, teardown).
# If the run exceeds this duration, it will be cancelled.
# Uses Go duration format (e.g., "1h", "30m", "2h30m").
# Can also be set via BENCHMARKOOR_RUNNER_RUN_TIMEOUT environment variable.
# run_timeout: 4h
# Optional directory configurations.
# directories:
# # Directory for temporary datadir copies (defaults to system temp).
# tmp_datadir: ${TMP_DIR:-/tmp}/benchmarkoor
# # (The shared cache dir lives under global.directories.cachedir.)
# Optional: Override path to drop_caches file (default: /proc/sys/vm/drop_caches).
# Useful when running in containers where the file is mounted at a different path.
# drop_caches_path: /proc/sys/vm/drop_caches
# Optional: Override sysfs base path for CPU frequency control (default: /sys/devices/system/cpu).
# Useful when running in containers where /sys is read-only and the host path is bind-mounted
# at a different location (e.g., -v /sys/devices/system/cpu:/host_sys_cpu).
# cpu_sysfs_path: /sys/devices/system/cpu
# Optional: GitHub token for downloading GitHub Actions artifacts via the REST API.
# If the gh CLI is installed and authenticated, no token is needed.
# Otherwise, provide a GitHub token with actions:read scope.
# Can also be set via BENCHMARKOOR_RUNNER_GITHUB_TOKEN environment variable.
# github_token: ${GITHUB_TOKEN:-}
# Optional: Stream periodic run-status reports to a benchmarkoor API
# instance so the UI can show in-progress runs. The API must have a
# matching `api.ingest.token` configured.
# live_reporting:
# enabled: true
# endpoint: https://benchmarkoor.example.com
# token: my-shared-secret
# discovery_path: my-host/benchmarks
# interval: 1m
# jitter_fraction: 0.2
# timeout: 10s
# # Live log streaming. When enabled, the runner opens a WebSocket to
# # the API for the lifetime of the run. Log bytes only flow while at
# # least one UI client has the log panel open — zero traffic otherwise.
# logs_enabled: true # default true; set false to disable entirely
# logs_interval: 200ms # file-tail push cadence while streaming
benchmark:
results_dir: ${RESULTS_DIR:-./results}
# Optional: Set ownership (user:group) for results files. Useful when running as root.
# results_owner: "1000:1000"
# Optional: Skip test execution entirely. When enabled, only post-run operations
# (index generation, suite stats) are performed. Useful for regenerating stats from
# S3-backed results without needing Docker or test infrastructure.
# skip_test_run: false
# Optional: Enable/disable system resource collection (cgroups/Docker Stats API).
# When disabled, no CPU/memory/disk metrics will be collected during tests.
# Useful when running in environments without cgroup access. Default: true
# system_resource_collection_enabled: true
# Optional: Generate index.json after benchmark (aggregates all run metadata).
# generate_results_index: true
# Optional: Method for index generation: "local" (default, filesystem) or "s3"
# (read runs from S3, upload index.json back to the bucket).
# Requires results_upload.s3 to be configured when set to "s3".
# generate_results_index_method: local
# Optional: Generate stats.json per suite after benchmark (aggregates test durations
# across runs for the UI heatmap).
# generate_suite_stats: true
# Optional: Method for suite stats generation: "local" (default, filesystem) or "s3"
# (read runs from S3, upload stats.json back to the bucket).
# Requires results_upload.s3 to be configured when set to "s3".
# generate_suite_stats_method: local
# Optional: Upload results to S3-compatible storage after each instance run.
# A preflight check verifies connectivity before any benchmarks start.
# results_upload:
# s3:
# enabled: true
# # Endpoint URL (scheme + host only, no path or bucket name).
# # Examples:
# # AWS: https://s3.us-east-1.amazonaws.com
# # R2: https://<account_id>.r2.cloudflarestorage.com
# # MinIO: http://localhost:9000
# endpoint_url: https://s3.us-east-1.amazonaws.com
# region: us-east-1
# bucket: my-benchmark-results
# access_key_id: ${AWS_ACCESS_KEY_ID}
# secret_access_key: ${AWS_SECRET_ACCESS_KEY}
# prefix: results # Base key prefix (runs at prefix/runs/, suites at prefix/suites/)
# # storage_class: STANDARD # Optional: S3 storage class
# # acl: private # Optional: Canned ACL
# # Path-style addressing: required for MinIO and Cloudflare R2.
# force_path_style: false
# # parallel_uploads: 50 # Number of concurrent file uploads
# Optional test execution configuration.
# tests:
# # Optional filter to run only tests matching this pattern.
# filter: ""
# # Optional: Metadata labels for the test suite.
# # Labels appear in the suite's summary.json and are shown in the UI.
# # The special "name" label is used as the display name for the suite.
# # metadata:
# # labels:
# # name: "EIP-7934 BN128 Benchmarks"
# # category: precompile
# source:
# # Option 1: Local directory source.
# # local:
# # base_dir: ./benchmark-tests
# # # Optional: Pre-run steps executed before tests (glob patterns).
# # pre_run_steps:
# # - "warmup/*.txt"
# # # Test step patterns (glob patterns for setup/test/cleanup phases).
# # steps:
# # setup:
# # - "tests/setup/*.txt"
# # test:
# # - "tests/test/*.txt"
# # cleanup:
# # - "tests/cleanup/*.txt"
#
# # Option 2: Git repository source.
# # git:
# # repo: https://github.com/example/gas-benchmarks.git
# # version: main # branch, tag, or commit hash
# # # Optional: Pre-run steps executed before tests (glob patterns).
# # pre_run_steps:
# # - "funding/*.txt"
# # # Test step patterns (glob patterns for setup/test/cleanup phases).
# # steps:
# # setup:
# # - "tests/setup/*.txt"
# # test:
# # - "tests/test/*.txt"
# # cleanup:
# # - "tests/cleanup/*.txt"
#
# # Option 3: Archive source (ZIP or tar.gz, local or remote URL).
# # Downloads (if URL), extracts, and discovers tests from the archive contents.
# # GitHub Actions artifact URLs are auto-converted to API download endpoints.
# # archive:
# # file: https://github.com/NethermindEth/gas-benchmarks/actions/runs/23847558369/artifacts/6222084759
# # # Alternative to `file`: a list of parts to download and concatenate.
# # # Useful when the archive is split across multiple files because of
# # # per-asset size limits. Mutually exclusive with `file`.
# # # parts:
# # # - https://example.com/tests.tar.gz.00.part
# # # - https://example.com/tests.tar.gz.01.part
# # pre_run_steps:
# # - "perf-devnet-3/gas-bump.txt"
# # - "perf-devnet-3/funding.txt"
# # steps:
# # setup:
# # - "perf-devnet-3/setup/*.txt"
# # test:
# # - "perf-devnet-3/testing/*.txt"
#
# # Option 4: EEST (Ethereum Execution Spec Tests) fixtures from GitHub releases.
# # Downloads fixtures directly from ethereum/execution-spec-tests releases.
# # Genesis files are auto-resolved per client type from the release.
# # eest_fixtures:
# # github_repo: ethereum/execution-specs
# # github_release: tests-benchmark@v0.0.9
# # # Optional: Override the subdirectory within fixtures tarball.
# # # fixtures_subdir: fixtures/blockchain_tests_engine_x # default
# # # Optional: Override URLs for fixtures/genesis tarballs.
# # # fixtures_url: https://example.com/fixtures_benchmark.tar.gz
# # # genesis_url: https://example.com/benchmark_genesis.tar.gz
#
# # Option 4b: EEST fixtures from GitHub Actions artifacts.
# # Alternative to releases - downloads from workflow run artifacts.
# # Uses the gh CLI if available, otherwise falls back to the GitHub REST API
# # (requires runner.github_token or BENCHMARKOOR_RUNNER_GITHUB_TOKEN).
# # eest_fixtures:
# # github_repo: ethereum/execution-spec-tests
# # fixtures_artifact_name: fixtures_benchmark_fast # Required (instead of github_release)
# # genesis_artifact_name: benchmark_genesis # Optional, defaults to 'benchmark_genesis'
# # # Optional: Specify a specific workflow run ID (uses latest if not specified)
# # # fixtures_artifact_run_id: "12345678901"
# # # genesis_artifact_run_id: "12345678901"
# # # fixtures_subdir also works with artifacts
#
# # Option 4c: EEST fixtures from local directories.
# # Points directly at already-extracted fixtures and genesis directories.
# # No downloading or caching — useful for local development with locally-built EEST fixtures.
# # eest_fixtures:
# # local_fixtures_dir: /home/user/eest-output/fixtures
# # local_genesis_dir: /home/user/eest-output/genesis
# # # fixtures_subdir also works with local directories
# # # fixtures_subdir: fixtures/blockchain_tests_engine_x # default
#
# # Option 4d: EEST fixtures from local .tar.gz tarballs.
# # Extracts tarballs to a cache directory (keyed by content hash, re-extraction skipped
# # if already cached). Useful when you have locally-built tarballs but haven't extracted them.
# # eest_fixtures:
# # local_fixtures_tarball: /home/user/eest-output/fixtures_benchmark.tar.gz
# # local_genesis_tarball: /home/user/eest-output/benchmark_genesis.tar.gz
# # # fixtures_subdir also works with local tarballs
#
# # Optional: External opcode metadata for the test suite.
# # A JSON file mapping test names to opcode counts: {"test_name": {"OPCODE": count, ...}}
# # Two modes:
# # 1. Direct JSON file (local path or URL):
# # opcode_source:
# # file: opcodes_tracing.json
# #
# # 2. Archive (.zip / .tar.gz / GitHub Actions artifact) containing the JSON file.
# # `file` is the filename to look up inside the extracted archive.
# # opcode_source:
# # archive: https://github.com/NethermindEth/gas-benchmarks/actions/runs/24460911828/artifacts/6456466898
# # file: opcodes_tracing.json
# Optional: Pre-populated client datadirs via state-actor.
# Build with: benchmarkoor build --config config.yaml
# Targets are decoupled from runner.instances; produced datadirs are
# consumed by `run` through the normal datadir.method providers.
# See https://github.com/ethereum/state-actor for spec authoring.
# builder:
# # Global timeout capping the entire `benchmarkoor build` (all builders and
# # targets). Go duration; empty = no timeout. Env: BENCHMARKOOR_BUILDER_RUN_TIMEOUT.
# # run_timeout: 2h
# state_actor:
# # Per-client docker images. Every active target's client needs an entry —
# # state-actor needs a different cgo build per EL.
# images:
# geth: ghcr.io/ethereum/state-actor:latest
# reth: ghcr.io/ethereum/state-actor-reth:latest
# besu: ghcr.io/ethereum/state-actor-besu:latest
# nethermind: ghcr.io/ethereum/state-actor-nethermind:latest
# # pull_policy: always # always | if-not-present | never
# # container_runtime: docker # defaults to runner.container_runtime, then docker
# # Top-level spec source — shared across every target that doesn't set its own
# # target_size. Pick at most one of spec (inline YAML) or spec_file (host path).
# # spec: |
# # genesis:
# # chain_id: 1337
# # spec_file: /etc/benchmarkoor/state-spec.yaml
# # Shared per-target defaults. Anything set here is used by every target
# # unless that target sets the same field, in which case the target wins.
# # config:
# # target_size: 5GB # complements top-level spec/spec_file (headroom budget)
# # seed: 1
# # fork: prague
# # chain_id: 1337
# # gas_limit: 30000000
# targets:
# - client: geth # geth | reth | besu | nethermind
# output_dir: /srv/state/geth-5g
# target_size: 5GB # complements any top-level spec; required if no spec is configured
# # force: true # wipe output_dir before building (per-target override of the CLI --force)
# # seed: 42 # overrides config.seed
# # fork: osaka # overrides config.fork
# # chain_id: 1337
# # gas_limit: 30000000
# # archive: false # geth + reth only; set false to opt out of config.archive=true
# # binary_trie: false # geth only; pair with optional group_depth (1..8)
# - name: reth-inherit # optional, defaults to `client`; used by --target
# client: reth
# output_dir: /srv/state/reth-spec
# # inherits the top-level spec/spec_file and every field from `config`
#
# # Optional: generate stateful EEST benchmark fixtures with fill-stateful.
# # Boots a filler client on a copy of a snapshot datadir (e.g. a state_actor
# # output_dir above), records engine-API payloads, and writes fixtures that
# # `run` consumes via tests.source.eest_fixtures. Runs after state_actor.
# # The fill image (uv/python toolchain) is built from a Dockerfile embedded in
# # the binary by default — nothing to publish. Optionally pull or customise it.
# eest_payloads:
# # fill_image: ghcr.io/your-org/eest-fill-stateful:latest # pull a pre-built image instead
# # fill_dockerfile: pkg/builder/Dockerfile.eest-filler # or build from a custom Dockerfile
# # pull_policy: always # always | if-not-present | never
# # container_runtime: docker # defaults to runner.container_runtime, then docker
# # jwt: <hex> # Engine API secret shared with the filler (default: built-in)
# # fill_command: [uv, run, fill-stateful] # argv prefix inside fill_image (default)
# # EEST checkout cloned at build time and mounted into the fill container at
# # /eest (fill_image is just the uv/python toolchain). Cached on disk; re-cloned
# # only when the ref changes. Both default as shown.
# # eest_repo: https://github.com/ethereum/execution-specs.git
# # eest_ref: forks/amsterdam # branch, tag, or commit to check out
# config: # shared per-target defaults; targets override when set
# filler_image: ethpandaops/geth:master
# fork: Osaka
# gas_benchmark_values: [10, 30] # millions of gas to parametrise against
# # fixed_opcode_count parametrises by opcode count (thousands) instead of gas;
# # mutually exclusive with gas_benchmark_values. [] passes the flag bare, which
# # uses the fill image's .fixed_opcode_counts.json default.
# # fixed_opcode_count: [0.5, 1, 2]
# datadir_method: copy # copy | overlayfs | fuse-overlayfs | zfs | direct | schelk
# targets:
# - name: compute-geth
# filler_client: geth # only geth is supported today
# source_dir: /srv/state/geth-5g # PRISTINE snapshot (never mutated)
# genesis_file: /srv/state/geth-5g/genesis.json # chain config for the filler boot
# output_dir: /srv/fixtures/compute
# tests:
# - tests/benchmark/compute # pytest paths inside the fill image
# # filter: bn128 # optional pytest -k expression
# # force: true # wipe output_dir before filling
# # address_stubs_file: /etc/benchmarkoor/stubs.json # for stub-dependent tests
# Optional: API server for authentication and user management.
# When configured, the UI can integrate with the API for login, admin, and role-based access.
# Start with: benchmarkoor api --config config.yaml
# api:
# server:
# listen: ":9090"
# # CORS origins for the UI. Required when the UI is served from a different origin.
# # When using credentials (cookies), wildcard "*" is not allowed — list specific origins.
# # cors_origins:
# # - http://localhost:5173
# # - https://benchmarkoor.example.com
# # Optional: Per-IP rate limiting.
# # rate_limit:
# # enabled: true
# # auth:
# # requests_per_minute: 10 # Login/logout endpoints (strict)
# # public:
# # requests_per_minute: 60 # Health/config endpoints
# # authenticated:
# # requests_per_minute: 120 # Admin endpoints
# auth:
# session_ttl: 24h # How long sessions last before expiring
# # Allow unauthenticated users to access /files/ endpoints (default: false).
# # When true, the UI allows browsing without login. When false, users must sign in.
# # anonymous_read: false
# # Basic (username/password) authentication.
# basic:
# enabled: true
# users:
# - username: admin
# password: ${ADMIN_PASSWORD:-changeme}
# role: admin # "admin" or "readonly"
# - username: viewer
# password: ${VIEWER_PASSWORD:-changeme}
# role: readonly
# # GitHub OAuth authentication.
# # github:
# # enabled: true
# # client_id: ${GITHUB_CLIENT_ID}
# # client_secret: ${GITHUB_CLIENT_SECRET}
# # redirect_url: http://localhost:9090/api/v1/auth/github/callback
# # # Map GitHub orgs to roles (users in these orgs get this role).
# # org_role_mapping:
# # my-org: admin
# # another-org: readonly
# # # Map specific GitHub users to roles (takes precedence over org mapping).
# # user_role_mapping:
# # admin-user: admin
# database:
# driver: sqlite # "sqlite" or "postgres"
# sqlite:
# path: benchmarkoor.db
# # postgres:
# # host: localhost
# # port: 5432
# # user: benchmarkoor
# # password: ${DB_PASSWORD}
# # database: benchmarkoor
# # ssl_mode: disable # disable, require, verify-ca, verify-full
# # Optional: S3 storage for serving benchmark results via presigned URLs.
# # This is separate from runner.benchmark.results_upload.s3 (which handles uploads during runs).
# # The API uses this to generate presigned GET URLs so the UI can fetch files directly from S3.
# # storage:
# # s3:
# # enabled: true
# # endpoint_url: https://s3.us-east-1.amazonaws.com
# # region: us-east-1
# # bucket: my-benchmark-results
# # access_key_id: ${AWS_ACCESS_KEY_ID}
# # secret_access_key: ${AWS_SECRET_ACCESS_KEY}
# # force_path_style: false # Required for MinIO/R2
# # presigned_urls:
# # expiry: 1h # How long presigned URLs are valid
# # # S3 key prefixes the UI can browse. Each path should contain an index.json.
# # discovery_paths:
# # - results
# # # Alternative: Serve files directly from local filesystem directories.
# # # Only one backend (s3 or local) may be enabled at a time.
# # local:
# # enabled: true
# # # Named prefixes mapping URL path segments to absolute directories.
# # # Each directory should contain an index.json and run/suite sub-dirs.
# # # Keys become URL prefixes (e.g. /api/v1/files/results/...).
# # discovery_paths:
# # results: /data/benchmarkoor/results
# # Optional: Accept live status reports from benchmarkoor runners.
# # When configured, runners can POST snapshots to /api/v1/ingest/runs
# # using `Authorization: Bearer <token>`. Live reports are stored in a
# # separate live_runs table and shown in the UI alongside indexed runs.
# # The token here MUST match `runner.live_reporting.token` on each runner.
# # ingest:
# # token: ${INGEST_TOKEN:-changeme}
# # stale_threshold: 5m # remove live runs that haven't reported within this window
client:
config:
# JWT secret for Engine API authentication (optional, has a default).
# Can be set via environment variable for security.
# jwt: ${JWT_SECRET:-5a64f13bfb41a147711492237995b437433bcbec80a7eb2daae11132098d7bae}
# Optional: Drop memory caches during benchmark execution (Linux only, requires root).
# Values: "disabled" (default), "tests" (between tests), "steps" (between setup/test/cleanup steps)
# drop_memory_caches: "disabled"
# Optional: Rollback strategy to reset client state after each test.
# Values:
# "none" - Do not rollback
# "rpc-debug-setHead" - Capture block number before test, rollback via debug_setHead after (default)
# "container-recreate" - Stop and remove the container after each test, recreate from same datadir
# "container-checkpoint-restore" - Podman CRIU checkpoint/restore for instant per-test restore.
# Requires: container_runtime: "podman"
# With datadir: requires datadir.method: "zfs" (ZFS snapshot rollback)
# Without datadir: uses copy-based rollback (cp -a + rsync)
# rollback_strategy: "rpc-debug-setHead"
# Optional: Checkpoint-restore strategy options. Only apply to the "container-checkpoint-restore"
# rollback strategy.
# checkpoint_restore_strategy_options:
# # Store checkpoint on tmpfs (RAM) when container memory is under this threshold.
# # Uses the same format as resource_limits.memory (e.g., "8g", "512m").
# tmpfs_threshold: "8g"
# # Maximum size of the tmpfs mount for checkpoint storage.
# # Defaults to 2x tmpfs_threshold if not set. Same format (e.g., "16g", "512m").
# # tmpfs_max_size: "16g"
# # How long to wait after dropping TCP connections before the CRIU checkpoint.
# # After blocking new outgoing TCP connections and killing existing sockets, this
# # delay gives the process time to close the file descriptors.
# # Default: 10s. Go duration string (e.g., "10s", "5s", "30s").
# wait_after_tcp_drop_connections: "10s"
# # Whether to restart the container before taking a CRIU checkpoint.
# # Restarting ensures a clean process state (cold caches, clean DB shutdown).
# restart_container: false
# Optional: Wait duration after RPC becomes ready before running tests.
# Useful for clients like Erigon that need time to complete internal sync pipelines
# after their RPC endpoint becomes available.
# wait_after_rpc_ready: 30s
# Optional: Maximum duration for the test execution phase.
# If exceeded, the run is cancelled with "timed_out" status. Partial results are kept.
# run_timeout: 2h
# Optional: Sleep duration after each test (e.g. "200ms", "1s"). Default: 0 (disabled).
# Useful for clients that need a brief pause between tests to let internal cleanup finish.
# post_test_sleep_duration: 200ms
# Optional: Retry engine_newPayload calls when client returns SYNCING status.
# Useful for clients with internal sync pipelines (e.g., Erigon) that may return
# SYNCING while still processing blocks internally.
# retry_new_payloads_syncing_state:
# enabled: true
# max_retries: 10
# backoff: 1s
# Optional: Arbitrary RPC calls to execute after each test step.
# These calls are NOT timed and do NOT affect test results. Useful for collecting
# debug traces or other post-test data from the client.
# Template variables are available in params:
# {{.BlockHash}} - Hash of the latest block (e.g., "0xabc...")
# {{.BlockNumber}} - Decimal block number (e.g., "1234")
# {{.BlockNumberHex}} - Hex block number with 0x prefix (e.g., "0x4d2")
# post_test_rpc_calls:
# - method: debug_traceBlockByNumber
# params: ["{{.BlockNumberHex}}", {"tracer": "callTracer"}]
# dump:
# enabled: true
# filename: debug_traceBlockByNumber # Written to {resultsDir}/{testName}/post_test_rpc_calls/{filename}.json
# - method: debug_traceBlockByHash
# params: ["{{.BlockHash}}"]
# timeout: 2m # Per-call timeout (default: 30s)
# dump:
# enabled: true
# filename: debug_traceBlockByHash
# Optional: Send an engine_forkchoiceUpdatedV3 call after RPC is ready.
# Uses the latest block hash from eth_getBlockByNumber("latest").
# Retries until the client accepts the FCU with VALID status, confirming
# it has finished internal initialization and is ready for test execution.
# Supports shorthand: `bootstrap_fcu: true` (defaults to max_retries: 30, backoff: 1s)
# bootstrap_fcu:
# enabled: true
# max_retries: 30
# backoff: 1s
# Optional: Run debug_traceBlockByNumber against every engine_newPayload* in
# the test step with a JS opcode-counting tracer, sum per-tx counts (uppercased)
# and write a `test-opcodes.json` at the run results dir in the same shape that
# `runner.benchmark.tests.opcode_source` consumes. Per-instance override allowed.
# opcode_extraction:
# enabled: true
# timeout: 2m # per-block trace timeout; default 2m
# Optional: Container resource limits (applied to all instances by default).
# resource_limits:
# # CPU pinning - use ONE of the following:
# # cpuset_count: N - Pick N random CPUs (new random selection each run)
# # cpuset: [0, 1, 2] - Pin to specific CPUs
# cpuset_count: 4
# # Memory limit (supports units: b, k, m, g, e.g., "16g", "4096m")
# memory: "16g"
# # Disable swap for the container (sets memory-swap equal to memory and swappiness to 0)
# swap_disabled: true
# # Block I/O throttling (optional)
# blkio_config:
# # Limit device read bandwidth (supports units: b, k, m, g)
# device_read_bps:
# - path: /dev/sdb
# rate: '12mb'
# # Limit device read IOPS (integer)
# device_read_iops:
# - path: /dev/sdb
# rate: '120'
# # Limit device write bandwidth
# device_write_bps:
# - path: /dev/sdb
# rate: '1024k'
# # Limit device write IOPS
# device_write_iops:
# - path: /dev/sdb
# rate: '30'
# # CPU frequency management (Linux only, requires root and cpufreq subsystem)
# # These settings are applied to the CPUs specified by cpuset/cpuset_count,
# # or all online CPUs if neither is specified.
# # Fixed CPU frequency (supports: "2000MHz", "2.4GHz", "MAX")
# cpu_freq: "2000MHz"
# # Enable/disable turbo boost (Intel: no_turbo, AMD: boost)
# cpu_turboboost: false
# # CPU frequency governor (common: performance, powersave, schedutil)
# # Defaults to "performance" when cpu_freq is set
# cpu_freq_governor: performance
# Optional: Default metadata labels for all instances.
# Labels appear in each run's config.json and can be used for filtering/organization.
# Can also be set via CLI: --metadata.label=env=production --metadata.label=team=platform
# Instance-level labels (see instances below) are merged and take precedence.
# metadata:
# labels:
# env: production
# team: platform
# Genesis file URLs per client type
genesis:
besu: https://github.com/nethermindeth/gas-benchmarks/raw/refs/heads/main/scripts/genesisfiles/besu/zkevmgenesis.json
erigon: https://github.com/nethermindeth/gas-benchmarks/raw/refs/heads/main/scripts/genesisfiles/geth/zkevmgenesis.json
geth: https://github.com/nethermindeth/gas-benchmarks/raw/refs/heads/main/scripts/genesisfiles/geth/zkevmgenesis.json
nethermind: https://github.com/nethermindeth/gas-benchmarks/raw/refs/heads/main/scripts/genesisfiles/nethermind/zkevmgenesis.json
nimbus: https://github.com/nethermindeth/gas-benchmarks/raw/refs/heads/main/scripts/genesisfiles/geth/zkevmgenesis.json
reth: https://github.com/nethermindeth/gas-benchmarks/raw/refs/heads/main/scripts/genesisfiles/geth/zkevmgenesis.json
# Default images per client (used when 'image' is not specified):
# geth: ethpandaops/geth:performance
# nethermind: ethpandaops/nethermind:performance
# besu: ethpandaops/besu:performance
# erigon: ethpandaops/erigon:performance
# nimbus: statusim/nimbus-eth1:performance
# reth: ethpandaops/reth:performance
# Optional: Pre-populated data directories per client type.
# When configured, the source directory is prepared and mounted into the container,
# and the init container is skipped (data is already initialized).
# datadirs:
# geth:
# source_dir: ./data/snapshots/geth
# # container_dir: /data # defaults to client's data directory if omitted
# # Method for preparing the data directory:
# # copy - parallel Go copy (default, works everywhere, has progress)
# # overlayfs - uses Linux overlayfs for near-instant setup (requires root)
# # fuse-overlayfs - uses fuse-overlayfs for near-instant setup (no root required)
# # Requires: apt install fuse-overlayfs (or equivalent)
# # Requires: user_allow_other in /etc/fuse.conf if Docker runs as root
# # WARNING: fuse-overlayfs is SLOW compared to overlayfs. You'll get
# # 3x Worse results.
# # zfs - uses ZFS snapshots and clones for near-instant, copy-on-write setup
# # Requires: source_dir must be on a ZFS filesystem
# # Requires: root access OR ZFS delegations configured:
# # zfs allow -u <user> clone,create,destroy,mount,snapshot <dataset>
# # The dataset is auto-detected from the source_dir mount point.
# # direct - bind-mount source_dir directly into the container with no copy or snapshot.
# # Changes persist after the run. Intended for inspection / resume workflows,
# # not normal benchmarking.
# # schelk - use a schelk-managed scratch volume (https://github.com/tempoxyz/schelk)
# # restored from a virgin baseline between iterations via dm-era.
# # Requires: `schelk` binary on PATH (override with BENCHMARKOOR_SCHELK_BIN)
# # Requires: schelk already initialised via `schelk init-new` / `init-from`
# # Requires: root access
# # `source_dir` must be the schelk mount point or a subdirectory of it.
# # Pairs naturally with rollback_strategy: container-recreate so each
# # iteration starts from a clean baseline. Not compatible with
# # rollback_strategy: container-checkpoint-restore (that requires ZFS).
# # Optional env var BENCHMARKOOR_SCHELK_BIN overrides the binary path
# # (useful under sudo with a sanitised PATH); SCHELK_STATE overrides the
# # schelk state-file path (default /var/lib/schelk/state.json).
# method: copy
# reth:
# source_dir: ./data/snapshots/reth
# # container_dir defaults to /var/lib/reth for reth
# method: fuse-overlayfs # near-instant, no root required
# # Example: ZFS-backed data directory
# # nethermind:
# # source_dir: /tank/benchmarkoor/nethermind-snapshot # Must be on ZFS
# # container_dir: /nethermind/data
# # method: zfs # near-instant via ZFS clones
# # Example: schelk-backed data directory
# # reth:
# # source_dir: /schelk/eth/reth # Must be under the schelk mount point
# # method: schelk
instances:
- id: geth-latest
client: geth
# image: ${GETH_IMAGE:-ethpandaops/geth:performance}
# pull_policy: always (default)
# Optional overrides:
# entrypoint: []
# command: []
# extra_args: # Additional arguments appended to command
# - --verbosity=5
# restart: never
# environment:
# SOME_VAR: ${MY_ENV_VAR}
# genesis: <override-url>
# datadir: # Instance-level datadir (overrides global datadirs)
# source_dir: ${DATA_SNAPSHOTS_DIR}/geth
# container_dir: /data
# drop_memory_caches: "steps" # Instance-level override (optional)
# rollback_strategy: "rpc-debug-setHead" # Instance-level override (optional)
# checkpoint_restore_strategy_options: # Instance-level override (optional, replaces global)
# tmpfs_threshold: "8g"
# tmpfs_max_size: "16g"
# wait_after_tcp_drop_connections: "10s"
# wait_after_rpc_ready: 60s # Instance-level override (optional)
# run_timeout: 1h # Instance-level override (optional)
# post_test_sleep_duration: 500ms # Instance-level override (optional)
# retry_new_payloads_syncing_state: # Instance-level override (optional)
# enabled: true
# max_retries: 10
# backoff: 1s
# resource_limits: # Instance-level override (optional)
# cpuset_count: 2 # Override global with fewer CPUs
# memory: "8g" # Override global memory limit
# post_test_rpc_calls: # Instance-level override (optional, replaces global)
# - method: debug_traceBlockByNumber
# params: ["{{.BlockNumberHex}}"]
# dump:
# enabled: true
# filename: trace
# bootstrap_fcu: true # Instance-level override (optional)
# metadata: # Instance-level labels (optional, merged with client defaults, instance wins)
# labels:
# variant: snap-sync
# Example: running multiple clients
# - id: nethermind-latest
# client: nethermind
# # image: ethpandaops/nethermind:performance (default)
# - id: besu-latest
# client: besu
# # image: ethpandaops/besu:performance (default)
# - id: reth-latest
# client: reth
# # image: ethpandaops/reth:performance (default)
# - id: erigon-latest
# client: erigon
# # image: ethpandaops/erigon:performance (default)
# - id: nimbus-latest
# client: nimbus
# # image: statusim/nimbus-eth1:performance (default)