EELS Fixture Releases¶
Test fixtures are published as feature-scoped releases on the
ethereum/execution-specs
repository: tests@vX.Y.Z, <feat>-devnet@vX.Y.Z, and benchmark@vX.Y.Z. Each release is
a self-contained .tar.gz of JSON fixtures that execution clients consume in CI.
This page describes the release types, their versioning, the fixture formats they contain, and how to consume them. To cut a new release, see Releasing Test Fixtures.
Fixture releases vs. the spec-package vX.Y.Z tags
ethereum/execution-specs also publishes Python spec package releases tagged
vX.Y.Z (e.g. v2.20.0).
Those contain no test fixtures, only the executable specification package.
Fixture releases are the feature-scoped tags described on this page, and are never
attached to the vX.Y.Z package tags. Every fixture tag starts with tests
(tests@vX.Y.Z, or tests-<feature>@vX.Y.Z for the other features), which is the
quickest way to tell the two apart on the releases page.
Test Release Types¶
Fixtures are released as independent types. Each type has its own tag namespace, artifact, and cadence.
| Type | Release name | Artifact | Scope | Built from |
|---|---|---|---|---|
| Tests | tests@vX.Y.Z |
fixtures.tar.gz |
All forks, all tests (eventually including ethereum/tests state tests) |
latest forks/* branch |
| Devnet | <feat>-devnet@vX.Y.Z |
fixtures_<feat>-devnet.tar.gz |
All forks, all tests, for an upcoming-fork feature under active devnet testing | the devnet branch |
| Benchmark | benchmark@vX.Y.Z |
fixtures_benchmark.tar.gz |
EVM benchmarking tests | latest forks/* branch |
- "Tests" releases track clients' production branches and are tagged frequently (roughly
once or twice a week). They are the "must pass" release for mainnet CI, and supersede the
old
fixtures_stable/fixtures_developartifacts. - "Devnet" releases target a specific feature under active development (e.g.
bal-devnet). They are advisory/non-blocking and may not yet cover every EIP; see the corresponding release notes for the coverage provided. - "Benchmark" (and, in future, zkEVM) releases are produced separately for their specialized consumers.
Versioning Scheme¶
Each release has a name of the form <feature>@v<X>.<Y>.<Z> (e.g. bal-devnet@v7.0.0),
which is the identifier consume cache accepts. The git tag, and the matching GitHub release
title, add a tests- prefix to keep fixture releases separate from the spec-package vX.Y.Z
tags, so the release bal-devnet@v7.0.0 is tagged tests-bal-devnet@v7.0.0. The default
tests feature is the exception, tagging as tests@v<X>.<Y>.<Z> directly with no doubled
prefix.
X identifies the fork or devnet a release targets; Y and Z order changes within that
target:
| Component | Tests | Devnet | Benchmark |
|---|---|---|---|
X |
Fork number | Devnet number | Fork number (mirrors target) |
Y |
Consensus-breaking spec change targeting fork X |
Consensus-breaking spec change targeting devnet X |
Mirrors the targeted feature |
Z |
Non-breaking change (refactor), new/modified tests | Non-breaking change (refactor), new/modified tests | Moves freely at its own pace |
A client targeting fork/devnet X should take the release with major == X, the latest
minor, and ideally the latest patch. The major alone tells you whether a release is
relevant to you, and a bump in Y (e.g. v7.0.0 to v7.1.0) signals a consensus-breaking
spec change in your target, so read the release notes before adopting it.
This also lets two devnets of the same feature be maintained in parallel (e.g. v3.0.1
alongside v7.0.0) without ambiguity, the same way 2.x and 3.x coexist under semver.
Fixture Formats¶
Fixture releases contain JSON test fixtures in various formats. Note that transaction type
tests are executed directly from Python source using the execute
command.
| Format | Consumed by the client | Location in .tar.gz release |
|---|---|---|
| State Tests | - directly via a statetest-like command(e.g., go-ethereum/cmd/evm/staterunner.go) |
./fixtures/state_tests/ |
| Blockchain Tests | - directly via a blocktest-like command(e.g., go-ethereum/cmd/evm/blockrunner.go) - using the eels/consume-rlp Simulator via block import |
./fixtures/blockchain_tests/ |
| Blockchain Engine Tests | - using the eels/consume-engine Simulator and the Engine API | ./fixtures/blockchain_tests_engine/ |
| Blockchain Engine X Tests | - using the eels/consume-enginex Simulator and the Engine API, reusing a client per pre-allocation group | ./fixtures/blockchain_tests_engine_x/ |
| Transaction Tests | - using a new simulator coming soon | None; executed directly from Python source, using a release tag |
| Blob Transaction Tests | - using the eels/execute-blobs Simulator | None; executed directly from Python source, using a release tag |
Fixture Output Directory Structure¶
Inside each format directory, fixtures are grouped by target fork.
The top-level subdirectory identifies the fork under test. Below it,
fixtures mirror the ./tests/ source layout: each directory corresponds
to the fork where the functionality was originally introduced. Because
tests declare valid_from, a single target fork directory contains
fixtures from every prior fork whose tests are still valid at that fork.
Consensus fixture layout¶
fixtures/
└── blockchain_tests/
├── for_prague/ # filled targeting Prague
│ ├── istanbul/ # tests introduced in Istanbul
│ │ └── eip1344_chainid/...
│ ├── cancun/ # tests introduced in Cancun
│ │ └── eip4844_blobs/...
│ └── prague/ # tests introduced in Prague
│ └── eip7702_set_code_tx/...
└── for_osaka/ # filled targeting Osaka
├── istanbul/
│ └── eip1344_chainid/...
├── cancun/
│ └── eip4844_blobs/...
├── prague/
│ └── eip7702_set_code_tx/...
└── osaka/ # tests introduced in Osaka
└── eip7692_eof_v1/...
Other format directories (state_tests/, blockchain_tests_engine/)
follow the same layout.
Benchmark fixture layout¶
When filling with --gas-benchmark-values, benchmark tests additionally
include the gas limit in the subdirectory name (for_{fork}_at_{gas}M,
where {gas} is in millions, zero-padded to four digits), with one
subdirectory per gas value:
fixtures/
└── blockchain_tests/
├── for_osaka_at_0001M/ # 1M gas benchmark
│ └── benchmark/compute/...
└── for_osaka_at_0002M/ # 2M gas benchmark
└── benchmark/compute/...
When filling with --fixed-opcode-count, the opcode count replaces the
gas limit in the subdirectory name (for_{fork}_at_opcount_{N}K, where
{N} is in thousands and may include decimals):
fixtures/
└── blockchain_tests/
├── for_osaka_at_opcount_10K/ # 10K opcodes
│ └── benchmark/compute/...
└── for_osaka_at_opcount_20K/ # 20K opcodes
└── benchmark/compute/...
Pinning Guidance¶
Mapped to a typical client CI setup:
- Blocking gate (current + past forks): Pin a specific
tests@vX.Y.Zfor reproducible, no-rug-pull CI on yourmaster/production branch, or follow the latesttestsrelease if a moving target is acceptable. This supersedes the oldfixtures_develop/fixtures_stableartifacts. - Non-blocking gate (next fork): Use the current
<feat>-devnet@vX.Y.Zrelease for the upcoming fork's active devnet (e.g.bal-devnet@vX.Y.Z). Treat it as advisory, since devnet coverage changes rapidly and should not block merges.
Devnet vs. tests overlap
Devnet releases are filled for all forks/tests, so they overlap with the tests release.
If your blocking gate already runs a tests release, the devnet gate re-runs that shared
coverage. Deduplicating that overlap is a consumer-side concern handled when
resolving/consuming releases.
Downloading Releases¶
The consume cache command resolves EELS release and pre-release tags
to release URLs and downloads them. For example:
uv run consume cache --input=latest # shorthand for tests@latest
uv run consume cache --input=tests@latest
uv run consume cache --input=bal-devnet@v7.0.0
Raw tarballs can also be fetched directly with the GitHub CLI:
gh release download tests-bal-devnet@v7.0.0 --repo ethereum/execution-specs --pattern '*.tar.gz'
To create a release, see Releasing Test Fixtures.