Skip to content

chore(docker): use patched Erigon v3.3.0 image for Linea from-scratch sync - #3698

Open
Othryades wants to merge 3 commits into
mainfrom
chore/erigon-linea-patched-image
Open

chore(docker): use patched Erigon v3.3.0 image for Linea from-scratch sync#3698
Othryades wants to merge 3 commits into
mainfrom
chore/erigon-linea-patched-image

Conversation

@Othryades

@Othryades Othryades commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Updates the getting-started Docker Compose files (mainnet + sepolia) to reference a patched Erigon image linea-erigon:v3.3.0-linea-patched, built locally from a Dockerfile shipped in the repo.
  • Adds the erigon-linea/ build directory (Dockerfile, Makefile, README) under docs/getting-started/linea-mainnet/.
  • The erigon-node service now runs with --externalcl so Maru drives block delivery over the Engine API; genesis is mounted directly from ./geth/geth-genesis.json so no manual copy is needed.
  • Switches the prune flag from the Erigon 2 --prune=hrtc to the Erigon 3 --prune.mode=full (the patched image is built from Erigon v3.3.0, which no longer accepts the old flag and would abort startup).
  • Hardens the Dockerfile: pins Erigon source to commit a0c55b4 (the v3.3.0 tag) instead of the mutable tag; pins the golang and debian base images by @sha256 digest; verifies each sed patch actually applied (so upstream drift fails the build loudly instead of shipping unpatched); and runs the final image as a non-root user (UID 1000), with erigon-init chowning /data so the node can write the chain-data volume.

Why

Stock Erigon does not sync current Linea from scratch:

  • erigontech/erigon:v3.5.0 with --externalcl + Maru hangs at block 0 (erigontech/erigon#22081).
  • Earlier versions hit [EIP-7002] Syscall failure: Empty Code at the Fusaka fork because Linea's genesis allocates no code at the withdrawal/consolidation contract addresses (erigontech/erigon#18160).

The patched image applies three fixes on top of Erigon v3.3.0:

  • sentryMcDisableBlockDownload = false (enables EL-driven bootstrap from genesis)
  • EIP-7002 empty-code syscall returns nil instead of erroring (Fusaka fix)
  • EIP-7251 empty-code syscall returns nil instead of erroring (Fusaka fix)

Test plan

  • make build from docs/getting-started/linea-mainnet/erigon-linea/ produces linea-erigon:v3.3.0-linea-patched (SHA-pinned, digest-pinned, sed patches verified at build time)
  • docker compose up erigon-init writes genesis into /data (owned 1000:1000); erigon-node then starts as uid=1000 with no permission errors
  • docker compose up erigon-init erigon-node maru-node from docs/getting-started/linea-mainnet/ begins syncing
  • Same for Sepolia (docs/getting-started/linea-sepolia/)

Note

Low Risk
Documentation and local Docker getting-started only; no production app or auth changes, though operators must build the image locally before compose will run.

Overview
Adds a local build for linea-erigon:v3.3.0-linea-patched under docs/getting-started/linea-mainnet/erigon-linea/ (Dockerfile, Makefile, README). The image pins Erigon v3.3.0 (by commit SHA) and applies three Linea-specific patches (block download flag, EIP-7002/7251 empty-code handling) plus a nosilkworm build; base images are pinned by digest, each sed patch is verified, and the final image runs as a non-root user.

Mainnet and Sepolia docker-compose.yml Erigon services switch from stock erigontech/erigon:2.61.0 to that patched image. erigon-init initializes /data from ./geth/geth-genesis.json and chowns the volume for UID 1000. erigon-node is wired for Maru: --externalcl, Engine API on 8550 with JWT from ./engine-jwt, --prune.mode=full, and hostname: el-client.

Reviewed by Cursor Bugbot for commit 6448a60. Bugbot is set up for automated code reviews on this repo. Configure here.

… sync

Stock Erigon does not sync current Linea from scratch: v3.5.0 hangs at
block 0 with --externalcl + Maru (erigontech/erigon#22081), and earlier
versions hit [EIP-7002] Syscall failure: Empty Code at the Fusaka fork
because Linea's genesis allocates no code at the withdrawal/consolidation
contract addresses (erigontech/erigon#18160).

Update the getting-started compose files (mainnet + sepolia) to reference
a patched Erigon image, linea-erigon:v3.3.0-linea-patched, built locally
from a Dockerfile shipped in the repo at
docs/getting-started/linea-mainnet/erigon-linea/. The Dockerfile clones
erigontech/erigon v3.3.0 and applies three patches:

- sentryMcDisableBlockDownload = false (enables EL-driven bootstrap)
- EIP-7002 empty-code syscall returns nil (Fusaka fix)
- EIP-7251 empty-code syscall returns nil (Fusaka fix)

The erigon-node service now runs with --externalcl so Maru drives block
delivery over the Engine API, while Erigon bootstraps its execution stage
from genesis via its own block downloader.

Signed-off-by: Othryades <Othryades@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@Othryades
Othryades requested a review from thedarkjester August 3, 2026 19:23
@Othryades Othryades self-assigned this Aug 3, 2026
@Othryades Othryades added the documentation Improvements or additions to documentation label Aug 3, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 8901f79. Configure here.

Comment thread docs/getting-started/linea-mainnet/docker-compose.yml
The getting-started compose files still carried the Erigon 2 flag
--prune=hrtc, but the patched image is built from Erigon v3.3.0, which
replaced --prune with --prune.mode (values: full, archive, minimal,
blocks). The unknown flag would abort erigon startup before sync.

Switch both mainnet and sepolia to --prune.mode=full, which preserves
the original hrtc intent (pruned full node, saves disk) and matches the
Erigon 3 default.

Signed-off-by: Othryades <Othryades@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…ify, non-root)

Address review findings on the patched Erigon image:

- Pin Erigon source to commit a0c55b4 (the v3.3.0 tag) instead of the
  mutable lightweight tag, so a moved tag cannot silently change what
  gets built.
- Pin the golang and debian base images by @sha256 digest for
  reproducible, tamper-resistant builds.
- Verify each sed patch actually applied (sed exits 0 on no-match):
  grep for the patched constant / absence of the original error string,
  so upstream drift fails the build loudly instead of shipping unpatched.
- Run the final image as a non-root user (UID 1000), matching the repo
  convention for runtime images. erigon-init now runs as root and
  chowns /data to 1000:1000 so the node can write the chain-data volume.

Also move --datadir before the init subcommand in erigon-init: Erigon
v3.3.0 does not apply --datadir when placed after the positional genesis
arg, so the previous shell form silently wrote genesis to the default
datadir instead of /data.

Verified: image builds, init writes to /data (owned 1000:1000), and
erigon-node starts as uid=1000 with no permission errors.

Signed-off-by: Othryades <Othryades@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@Othryades

Copy link
Copy Markdown
Contributor Author

Hey @thedarkjester, does it look good to merge now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant