Skip to content

feat: add miden-genesis tool for canonical genesis state#1797

Merged
mmagician merged 14 commits intorelease/v0.14.0-alphafrom
mmagician-default-genesis
Mar 19, 2026
Merged

feat: add miden-genesis tool for canonical genesis state#1797
mmagician merged 14 commits intorelease/v0.14.0-alphafrom
mmagician-default-genesis

Conversation

@mmagician
Copy link
Contributor

@mmagician mmagician commented Mar 16, 2026

Summary

  • Adds a new miden-genesis binary crate that generates canonical AggLayer genesis accounts and a genesis.toml config file
  • Generates three accounts: bridge admin & GER manager (BasicWallets), and AggLayerBridge
  • Only the bridge account (nonce=1) is included in genesis.toml for the genesis block; bridge admin and GER manager are local accounts (nonce=0) to be deployed later via transactions. But, they are "implicitly" included in the genesis block in that the AggLayerBridge account makes reference to them in its storage.

Closes #1788

Operator workflow

# Generate canonical genesis accounts
miden-genesis --output-dir ./genesis

# Bootstrap the node
miden-node validator bootstrap \
  --genesis-block-directory ./data \
  --accounts-directory ./accounts \
  --genesis-config-file ./genesis/genesis.toml \
  --validator.key.hex <key>

🤖 Generated by hand & with Claude Code


I wanted to add this as a separate minimal binary (non-publishable) because I do see this as a separate role from the validator (even though for now they'll be run by the same entity). But it should be trivial to move this in a new command on the validator if desired.

@mmagician mmagician marked this pull request as ready for review March 17, 2026 17:38
@mmagician mmagician requested a review from sergerad March 18, 2026 10:29
@mmagician
Copy link
Contributor Author

While reviewing #1774, I came to realize that there is a split between what the miden-genesis tool would generate (agglayer accounts) vs. what the validator bootstrap would generate (native faucet, plus wallet accounts specified in the TOML).

I think eventually it might make sense to merge these two so that all account generation happens in a single step. The proposed split:

  • validator genesis - generates ALL accounts (native faucet, TOML-defined wallets/faucets, AggLayer bridge/admin/GER manager), builds the unsigned genesis block, writes genesis.dat + .mac secret files to an output directory. Takes the validator's public key to embed in the header, making the output deterministic and verifiable by anyone with the same config.
  • validator bootstrap - takes the unsigned genesis.dat, signs it with the validator's secret key, and initializes the validator DB (chain tip) (@sergerad 's PR Validator chain invariants #1774)
  • store bootstrap - stays as-is

This way genesis is purely about preparing the genesis state (accounts + unsigned block), and bootstrap is about signing and initializing node state. Anyone can run genesis with the same config and verify they obtain the same genesis block, which is desirable.

Copy link
Collaborator

@Mirko-von-Leipzig Mirko-von-Leipzig left a comment

Choose a reason for hiding this comment

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

Code looks good; some bikeshedding to resolve.

- `bridge.mac` - AggLayer bridge account (nonce=1, included in genesis block)
- `genesis.toml` - Genesis configuration referencing only `bridge.mac`

When public keys are omitted, the `.mac` files for bridge admin and GER manager include generated secret keys. When public keys are provided, no secret keys are included.
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is intended for internal use only, why do we have two different "modes"?

@@ -0,0 +1,60 @@
# Miden Genesis

A tool for generating canonical Miden genesis accounts and configuration.
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is intended for internal use only, then I would add that disclaimer here, and repeat it where applicable.

I'm concerned that local node users will attempt to use this.


The bridge account always uses NoAuth and has no secret keys.

## Bootstrapping a node
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is going to get outdated pretty often and we'll forget to update this.

It would be better to keep this in our operator docs.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you describe the different deployment flows and where this fits in?

  1. Local node
  2. Testnet deploy
  3. Automated devnet deploy
  4. ...

Some bikeshedding

Should this be miden-node make-genesis? Bear in mind that we probably want to access this binary somewhere where we can't (or don't want to) compile code. And therefore this should likely be installable and versionable.

Some thought experiments

Maybe we should have a miden-node genesis subcommand?

# This binary
miden-node genesis generate-accounts ...

# miden-node validator bootstrap
miden-node genesis sign

# miden-node store bootstrap
miden-node genesis bootstrap-store

@mmagician mmagician changed the base branch from next to release/v0.14.0-alpha March 19, 2026 15:48
@mmagician mmagician changed the base branch from release/v0.14.0-alpha to next March 19, 2026 15:49
@mmagician mmagician force-pushed the mmagician-default-genesis branch from c57f34b to 00218d6 Compare March 19, 2026 15:54
@mmagician mmagician changed the base branch from next to release/v0.14.0-alpha March 19, 2026 15:55
@mmagician mmagician force-pushed the mmagician-default-genesis branch 2 times, most recently from 4463961 to 350a82d Compare March 19, 2026 16:00
claude and others added 14 commits March 19, 2026 16:01
New binary crate that generates canonical AggLayer genesis accounts
(bridge, bridge admin, GER manager) and a genesis.toml config file.
Only the bridge account is included in the genesis block; bridge admin
and GER manager are generated as local accounts to be deployed later.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add description, keywords, and exclude to match other bin/ crate
conventions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GenesisConfig and BlockHeader use u32 timestamps. Cast to u32 using the
same pattern as proposed_block.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Decorator stripping was needed in build.rs for deterministic .mac files
checked into the repo. The genesis tool generates files at runtime so
stripping is unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verifies that the tool generates all expected files with correct
properties: bridge has nonce=1, admin/GER manager have nonce=0 with
secret keys, and genesis.toml only references bridge.mac.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Validate that either both --bridge-admin-public-key and
--ger-manager-public-key are provided, or neither. Add integration
tests for both default mode (generated keypairs with secrets) and
custom mode (provided public keys without secrets).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace manual match-based validation with clap's requires attribute,
so clap handles the error message when only one public key is provided.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verifies the full round-trip: generate files, parse genesis.toml with
GenesisConfig, build genesis state, confirm bridge account is present
with nonce=1, and build the actual genesis block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both tests now verify the full round-trip through GenesisConfig and
genesis block creation via a shared helper, removing redundant checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mmagician mmagician force-pushed the mmagician-default-genesis branch from 350a82d to 693ee9c Compare March 19, 2026 16:01
@mmagician mmagician merged commit ce366f3 into release/v0.14.0-alpha Mar 19, 2026
15 checks passed
@mmagician mmagician deleted the mmagician-default-genesis branch March 19, 2026 16:23
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.

Define the canonical genesis state

4 participants