Skip to content

eels: optionally consume pre-staged local fixtures - #2

Merged
lystopad merged 1 commit into
yperbasis/client-poolfrom
lystopad/eels-local-fixtures
Jun 17, 2026
Merged

eels: optionally consume pre-staged local fixtures#2
lystopad merged 1 commit into
yperbasis/client-poolfrom
lystopad/eels-local-fixtures

Conversation

@lystopad

@lystopad lystopad commented Jun 8, 2026

Copy link
Copy Markdown
Member

Why

The eels/consume-engine and eels/consume-rlp simulators download the fixtures tarball at image-build time via uv run consume cache --input "$FIXTURES". Because hive is invoked with --docker.nocache, that download repeats on every run, which is slow and exposed to transient GitHub release-CDN failures (e.g. HTTP 504s).

What

Let a caller provide the fixtures locally instead of by URL:

  • Stage a fixtures.tar.gz into the simulator build context and pass --build-arg fixtures=/fixtures.
  • The tarball is extracted in a throwaway build stage; only the extracted directory is COPY --from'd into the final image, so the tarball never lands in the final image (no size doubling).
  • consume then reads --input /fixtures (a local directory), which it accepts and recursively indexes — verified against execution-specs/consume (FixturesSource.validate_local_path + generate_fixtures_index).

Backward compatible

With no fixtures.tar.gz staged and fixtures=<release/url> (the default, and how it's invoked today), the optional COPY matches only the Dockerfile anchor, /fixtures stays empty, FIXTURES remains the URL/release, and consume downloads exactly as before. The new path activates only when both a tarball is staged and fixtures=/fixtures is passed.

Consumer

This unblocks erigon's test-hive-eest.yml to restore the fixtures from its existing actions/cache (warmed out-of-band) and pass them in locally, removing the per-run CDN download. Only consume-engine and consume-rlp are changed (the two simulators erigon's matrix uses); the other eels simulators are untouched and can adopt the same pattern later if needed.

The consume-engine/consume-rlp simulators download the fixtures tarball at
image-build time (uv run consume cache --input <url>). With hive's
--docker.nocache that re-downloads on every run, which is slow and exposed to
transient release-CDN failures.

Allow a caller to provide fixtures locally instead: stage a fixtures.tar.gz in
the simulator build context and pass --build-arg fixtures=/fixtures. The
tarball is extracted in a throwaway build stage and only the extracted dir is
copied into the final image, so the tarball never doubles the image size.

Backward compatible: with no fixtures.tar.gz staged and fixtures=<release/url>
(the default), the optional COPY grabs only the Dockerfile anchor, /fixtures
stays empty, and consume downloads exactly as before.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the EELS consume-engine and consume-rlp simulator images to optionally use pre-staged fixtures from the local Docker build context (instead of always downloading fixtures at image-build time), improving build reliability and avoiding repeated CDN fetches when Hive is run with --docker.nocache.

Changes:

  • Refactors both simulator Dockerfiles into multi-stage builds with an optional “fixtures extraction” stage.
  • Adds logic to COPY and extract an optionally-staged fixtures.tar.gz into /fixtures, then copies only the extracted directory into the final image.
  • Moves uv sync earlier so dependencies are installed before running consume cache.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
simulators/ethereum/eels/consume-rlp/Dockerfile Adds a multi-stage build to optionally extract and bake local fixtures into the image.
simulators/ethereum/eels/consume-engine/Dockerfile Same pattern as consume-rlp, enabling optional local fixtures for the engine simulator.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# the container starts.
# If newer version of the fixtures is needed, the image needs to be rebuilt.
# Use `--docker.nocache` flag to force rebuild.
RUN uv run consume cache --input "$FIXTURES"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already handled upstream, so no extra Dockerfile guard is needed here. consume cache --input /fixtures resolves the source through FixturesSource.validate_local_path:

if not any(path.glob("**/*.json")):
    pytest.exit(f"Specified fixture directory '{path}' does not contain any JSON files.")

pytest.exit() with no returncode exits non-zero, so an empty /fixtures fails the image build at this exact step with a clear message — Specified fixture directory '/fixtures' does not contain any JSON files. — rather than a confusing error. That is already the "fail early with a clear message" being suggested.

On the "fall back to remote fixtures" alternative: we specifically don't want that. A silent fallback would mask a fixtures-staging / cache-miss bug and reintroduce the per-run CDN download this change removes. Failing loudly at build time is the intended behavior.

Comment on lines +31 to +32
RUN mkdir -p /fixtures && \
if [ -f /staged/fixtures.tar.gz ]; then tar -xzf /staged/fixtures.tar.gz -C /fixtures; fi

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — will add --no-same-owner to the extraction. Impact is low in this setup (both the build and the simulator entrypoint run as root, and the tarball comes from our own CI cache rather than untrusted input), but it's cheap and makes extraction deterministic regardless of the uid/gid baked into the archive, so it's worth doing. Leaving --no-same-permissions off — more intrusive with no clear benefit here.

# If newer version of the fixtures is needed, the image needs to be rebuilt.
# Use `--docker.nocache` flag to force rebuild.
RUN uv sync
RUN uv run consume cache --input "$FIXTURES"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already handled upstream, so no extra Dockerfile guard is needed here. consume cache --input /fixtures resolves the source through FixturesSource.validate_local_path:

if not any(path.glob("**/*.json")):
    pytest.exit(f"Specified fixture directory '{path}' does not contain any JSON files.")

pytest.exit() with no returncode exits non-zero, so an empty /fixtures fails the image build at this exact step with a clear message — Specified fixture directory '/fixtures' does not contain any JSON files. — rather than a confusing error. That is already the "fail early with a clear message" being suggested.

On the "fall back to remote fixtures" alternative: we specifically don't want that. A silent fallback would mask a fixtures-staging / cache-miss bug and reintroduce the per-run CDN download this change removes. Failing loudly at build time is the intended behavior.

Comment on lines +31 to +32
RUN mkdir -p /fixtures && \
if [ -f /staged/fixtures.tar.gz ]; then tar -xzf /staged/fixtures.tar.gz -C /fixtures; fi

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — will add --no-same-owner to the extraction. Impact is low in this setup (both the build and the simulator entrypoint run as root, and the tarball comes from our own CI cache rather than untrusted input), but it's cheap and makes extraction deterministic regardless of the uid/gid baked into the archive, so it's worth doing. Leaving --no-same-permissions off — more intrusive with no clear benefit here.

@lystopad
lystopad merged commit 9afe5f1 into yperbasis/client-pool Jun 17, 2026
1 check passed
@lystopad
lystopad deleted the lystopad/eels-local-fixtures branch June 18, 2026 09:39
lystopad added a commit to erigontech/erigon that referenced this pull request Jun 18, 2026
…-fixtures

erigontech/hive#2 merged into yperbasis/client-pool; pin to that merge commit
(9afe5f15) instead of the now-merged feature branch HEAD.
pull Bot pushed a commit to Dustin4444/erigon that referenced this pull request Jun 18, 2026
…run CDN download (erigontech#21882)

## Problem

`test-hive-eest`'s `eels` simulators download the fixtures tarball from
the GitHub release CDN **inside the image build** (`consume cache
--input <url>`). With hive's `--docker.nocache`, that download repeats
on **every run** — slow, exposed to transient release-CDN 504s, and
bypassing the hardened `tools/test-fixtures.sh` entirely.

## Change

Feed the fixtures from cache + a hardened fetch, and hand them to the
sim locally:

- **Restore** the EEST tarballs from the base-branch cache warmed by
`cache-warming-eest-fixtures.yml` — **restore-only** (the warmer owns
saving, so no per-ref duplicates).
- **Fallback** on a cache miss: the hardened `tools/test-fixtures.sh`
(5-min exponential backoff).
- **Stage** the matrix tarball into the eels sim build context and pass
`--sim.buildarg fixtures=/fixtures`, so the sim's `consume` reads a
local directory instead of downloading.

The `branch` build-arg (devnet `consume`/execution-specs selection) is
unchanged.

## Hive dependency (now merged)

The local-fixtures eels Dockerfiles landed in **erigontech/hive#2**
(merged into `yperbasis/client-pool`). The hive `ref` is pinned to that
merge commit (`9afe5f15`).

## Validation

End-to-end verified on a real runner via `workflow_dispatch` (run
27152648786): exact-key **cache hit** (no CDN download), staged tarball
picked up by the eels build, and `consume engine` ran the full
`paris+shanghai` shard — **3573 tests, 0 failed**. The
fixtures-directory layout was also confirmed against
`execution-specs`/`consume` locally (it accepts the extracted dir and
recursively builds its index).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants