Skip to content

feat: state_actor_params — pre-populate EL databases with state-actor - #1455

Open
qu0b wants to merge 2 commits into
ethpandaops:mainfrom
qu0b:qu0b/state-actor-integration
Open

feat: state_actor_params — pre-populate EL databases with state-actor#1455
qu0b wants to merge 2 commits into
ethpandaops:mainfrom
qu0b:qu0b/state-actor-integration

Conversation

@qu0b

@qu0b qu0b commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

Adds an opt-in state_actor_params package arg that pre-populates EL client databases with state-actor before the EL clients launch.

When enabled, one state-actor generation run happens per unique el_type among the participants — after genesis generation, driven by the network's own genesis.json (state-actor --genesis) — so the produced database's genesis hash matches the hash the CL genesis was built against, and no CL-side changes are needed. Each run's output datadir is stored as a files artifact named state-actor-<el_type>-data and registered so participants can opt in by mounting it at their execution data dir:

participants:
  - el_type: geth
    cl_type: lighthouse
    el_extra_mounts:
      /data/geth/execution-data: state-actor-geth-data
state_actor_params:
  enabled: true

This follows the shadowfork pattern (pre-launch step fills the EL data location before the client starts), but generates state instead of downloading a snapshot.

Why

state-actor writes client-native databases (Pebble for geth, MDBX/RocksDB for reth, Bonsai RocksDB for besu, flat-state for nethermind, RocksDB for ethrex, Erigon v3 snapshots) without going through each client's init path — useful for state-bloat experiments and cross-client determinism testing. This PR wires its output into participant startup. Alloc-verbatim mode (no target_size) is fully supported today; bloated-state mode additionally requires anchoring the CL genesis to the state-actor genesis hash, which is left for a follow-up (state-actor exports an eth_getBlockByNumber-shaped genesis_block.json for exactly that purpose).

Changes

  • src/state_actor/state_actor_launcher.star (new): runs the per-el_type generation via plan.run_sh, stores + registers the datadir artifacts
  • src/participant_network.star: invoke the launcher after el_cl_data is generated, before EL launch
  • src/package_io/input_parser.star, src/package_io/sanity_check.star: state_actor_params plumbing (enabled, seed, target_size, images)
  • README.md: config reference entry

Testing

Tested with one single-node enclave per supported EL (geth, reth, besu, nethermind, ethrex, erigon), each paired with lighthouse, using state-actor images built from ethereum/state-actor compare: qu0b/ethereum-package-integration (adds the --genesis flag; not yet upstream — until it merges, state_actor_params.images must point at images built from that branch):

  • all six ELs booted directly from the pre-populated database (verified via manifest/DB files in the datadir and rotated RocksDB logs) with no init step
  • every client's RPC eth_getBlockByNumber(0x0) hash equals the hash state-actor exported, so the existing CL genesis stayed valid
  • all six clients produced the identical genesis state root for the same 283-account alloc
  • all networks produced blocks with lighthouse (heads observed: geth 20, reth 12, besu 17, nethermind 14, ethrex 15, erigon 13) with no EL errors

Per-client notes surfaced by testing (documented in the README entry): nethermind participants need --Init.BaseDbPath=<datadir> + --FlatDb.Enabled=true; erigon's pre-launch erigon init coexists cleanly with the pre-seeded datadir.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TJoWPhxuJVSwvzpZr494X1

qu0b and others added 2 commits July 24, 2026 14:44
Adds an opt-in pre-launch step that runs state-actor (--genesis mode)
against the network's own genesis.json per unique el_type, stores the
produced client-native datadir as a files artifact
(state-actor-<el_type>-data), and registers it in extra_files_artifacts
so participants mount it via el_extra_mounts. Alloc-verbatim generation
keeps the genesis hash identical to what CL genesis was built against,
so no CL-side changes are needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJoWPhxuJVSwvzpZr494X1
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJoWPhxuJVSwvzpZr494X1
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