Genesis¶
A launch carries two genesis hashes, uploaded at different phases:
- Initial genesis (
InitialGenesisSHA256) — the bare, pre-gentx genesis, uploaded inDRAFT. - Final genesis (
FinalGenesisSHA256) — the committee-assembled, post-gentx genesis, uploaded inWINDOW_CLOSED.
coordd never assembles genesis — a committee member builds it locally (gentool folds the approved allocation files
and the gentxs into a base genesis; or the chain binary's collect-gentxs adds the gentxs) and uploads it. coordd
only runs light well-formedness checks and anchors the hash; the committee is what validates the genesis it
publishes — by review (optionally backed by a rehearsal) plus the M-of-N PUBLISH_GENESIS
attestation.
Dual-mode upload¶
Both go through POST /api/v1/launch/{id}/genesis?type=initial|final, in one of two modes:
- Attestor mode (default,
application/json) — body{url, sha256[, genesis_time]}. coordd stores the URL + hash only (SSRF-checked), keeps no bytes, and serves reads as a 302 to the external URL. - Host mode (
application/octet-stream, gated byCOORD_GENESIS_HOST_MODE) — bytes stream to disk, capped bygenesis_max_bytes(413on exceed); reads stream the file.
(This is the same by-reference model allocation files use.)
Final-genesis checks¶
coordd runs a few mechanical guardrail checks on a final upload (no chain binary invoked): the bytes are well-formed
JSON, chain_id matches the record, genesis_time is set and in the future, and the genesis contains exactly the
approved validator set — in either assembly convention: the gentx form
(collect-gentxs: len(gen_txs) == len(approved), each approved consensus pubkey exactly once, no duplicates) or the
baked form (gentool: gen_txs is empty and the approved pubkeys appear exactly once each in staking.validators, no
extras). It then binds FinalGenesisInputSetHash (the approved-set fingerprint, re-checked at
PUBLISH_GENESIS so a genesis that no longer matches the set can't be finalized). These are guardrails, not genesis
validation: the genesis schema, balances, supply, and bonded pool are the committee's to vet (with gentool /
rehearsal) — the file is opaque to coordd.
Because attestor-mode can't read the file, genesis_time is a required request field for an attestor-mode final
upload (and must be in the future).
Verifying the genesis — reproduce, don't trust¶
Those checks are mechanical guardrails, and coordd never assembles the genesis itself — so the trust anchor is
independent reproduction by the committee, not the proposer's uploaded file. The approved inputs are deterministic
and pinned: the approved gentxs (GET /api/v1/launch/{id}/gentxs), the approved allocation files, and the chain record
are all fingerprinted by FinalGenesisInputSetHash. Combined with the retained initial genesis
(GET /api/v1/launch/{id}/genesis?type=initial) as the base, any committee member can rebuild the genesis locally (with
gentool, or the chain binary's collect-gentxs) and confirm their result's hash equals the proposer's
FinalGenesisSHA256. (The initial genesis is the reproduction base, not part of FinalGenesisInputSetHash — swapping
it is caught by that final-hash comparison, not the fingerprint.) The initial genesis stays downloadable via
?type=initial
even after the final is published — precisely so a signer can reproduce the final from its inputs at
PUBLISH_GENESIS review time; ?type=final fetches the published result, and omitting type returns the current
genesis (final once published, else initial). The M-of-N PUBLISH_GENESIS
signatures are that reproduction-backed attestation — each signer vouches for a hash they can regenerate from the
approved set, not one they merely downloaded.
The optional rehearsal service is the automated, enforceable form of this: rehearsald pulls the same approved
input set, rebuilds the genesis, boots an ephemeral chain, and posts a signed PASS/FAIL bound to the input-set
fingerprint — and the rehearsal gate can require a PASS before PUBLISH_GENESIS executes. (Validators, at
GENESIS_READY, download the file and verify its SHA256 to run their node — last-mile distribution against the
already-attested hash, not the trust anchor.)
Publishing¶
Uploading only records the hash. The WINDOW_CLOSED → GENESIS_READY transition happens when the
PUBLISH_GENESIS committee proposal executes (see Proposals & M-of-N).
Changing the genesis time¶
UPDATE_GENESIS_TIME updates the launch record's genesis_time and invalidates readiness confirmations. Note that
coordd does not rebuild the genesis file (it never assembles genesis) — producing a new genesis with a different
time is done via REVISE_GENESIS → re-upload. (The exact intended semantics of
UPDATE_GENESIS_TIME versus a re-upload are under review.)