Skip to content

feat(tdx-init)!: require reth genesis in InitConfig#199

Merged
samlaf merged 1 commit into
seismicfrom
tdx-init-reth-genesis
Jul 2, 2026
Merged

feat(tdx-init)!: require reth genesis in InitConfig#199
samlaf merged 1 commit into
seismicfrom
tdx-init-reth-genesis

Conversation

@samlaf

@samlaf samlaf commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

The reth chain spec was baked into the node image (mkosi copied seismic-reth's dev.json to /usr/share/seismic-reth/genesis.json), so any network-shape change forced an image rebuild and one measured image could only serve one network. The genesis is fully deploy-time- computable (no TEE-born data) and needed by every node's reth — joiners included — so it rides in the per-boot config POST next to the manifest, not in the image.

[network] gains a required reth_genesis_base64: base64 of the exact reth-genesis.json bytes, written verbatim to
/run/seismic/conf/reth-genesis.json for reth's --chain (the reth.service flip and un-baking land in seismic-images). Required, not optional: a node booted without it has no chain spec and reth crash-loops, so an older deploy CLI's POST now 400s at deploy time instead — same rationale as requiring [network] itself.

POST-time validation is structural: valid JSON whose config.chainId matches the manifest's eth.chain_id. tdx-init can't recompute eth.genesis_hash (that needs reth's own chain-spec parse path — and the hash pins the genesis block, not the file's config section anyway); the block-hash commitment stays deploy-side (manifest assemble) and at ceremony time (the block-0 assert against every node's reth).

The reth chain spec was baked into the node image (mkosi copied
seismic-reth's dev.json to /usr/share/seismic-reth/genesis.json), so any
network-shape change forced an image rebuild and one measured image
could only serve one network. The genesis is fully deploy-time-
computable (no TEE-born data) and needed by every node's reth — joiners
included — so it rides in the per-boot config POST next to the
manifest, not in the image.

[network] gains a required reth_genesis_base64: base64 of the exact
reth-genesis.json bytes, written verbatim to
/run/seismic/conf/reth-genesis.json for reth's --chain (the reth.service
flip and un-baking land in seismic-images). Required, not optional: a
node booted without it has no chain spec and reth crash-loops, so an
older deploy CLI's POST now 400s at deploy time instead — same
rationale as requiring [network] itself.

POST-time validation is structural: valid JSON whose config.chainId
matches the manifest's eth.chain_id. tdx-init can't recompute
eth.genesis_hash (that needs reth's own chain-spec parse path — and the
hash pins the genesis block, not the file's config section anyway); the
block-hash commitment stays deploy-side (manifest assemble) and at
ceremony time (the block-0 assert against every node's reth).

- reth_genesis.rs: decode + chainId cross-check, verbatim bytes out.
- manifest.rs: decode_and_validate now returns ValidatedManifest
  {bytes, chain_id} so downstream checks never re-parse the schema.
- writer.rs: decode each artifact once, write both files verbatim.
- server.rs: raise the axum body limit to 16 MiB — a mainnet-sized
  alloc is ~1.4 MiB as base64, too close to the 2 MiB default.
@samlaf samlaf requested a review from cdrappi as a code owner July 2, 2026 18:01
@samlaf samlaf merged commit 4e35c2d into seismic Jul 2, 2026
5 of 6 checks passed
@samlaf samlaf deleted the tdx-init-reth-genesis branch July 2, 2026 18:05
samlaf added a commit to SeismicSystems/seismic-images that referenced this pull request Jul 2, 2026
…#39)

The image baked seismic-reth's dev.json at
/usr/share/seismic-reth/genesis.json, so one measured image could only
ever serve one network and any network-shape change forced a rebuild.
The chain spec is deploy-time data: tdx-init now receives it in the
operator's config POST ([network].reth_genesis_base64,
SeismicSystems/enclave#199 — included in the pin
bump) and writes it verbatim to
/run/seismic/conf/reth-genesis.json, re-delivered every boot like the
rest of the tmpfs config. Flip reth.service's --chain to that path and
drop the dev.json copy from mkosi.build; the existing Requires= chain
(reth -> enclave -> tdx-init) already guarantees the file exists before
reth starts.

Images built from this commit reject a config POST without the genesis
(400 at deploy), so nodes must be configured with a deploy CLI that
sends [network].reth_genesis_base64 (deploy repo: configure
--reth-genesis, defaulting to the reth-genesis.json beside the
manifest).
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.

1 participant