Files
Hanzo AI 59f1220481 configs/genesis/mainnet: sync to state-repo canonical (zoo h=799 RLP unblock)
Today's bootstrap-chain CreateChainTx (#168, 2026-06-04) produced a
zoo mainnet chain with block-0 hash `0x88dd3a53…`, which orphans the
Zoo mainnet RLP archive (799 blocks, recorded parent hash
`0x7c548af4…`). admin_importChain returns "block 1 parent mismatch".

Root cause: bootstrap-chain consumed the cc7d3d7 form of zoo-mainnet/
genesis.json (969 bytes), which is a SUBSET of the empirical canonical.
The cc7d3d7 commit was labeled "RLP-matching pristine form" but
omitted the explicit block-0 header fields (parentHash, mixHash,
nonce, number, gasUsed, extraData, coinbase) and the
precompile-defer config fields (quasarTimestamp, fortunaTimestamp,
graniteTimestamp = 253399622400). luxd's defaults for these fields
produce a DIFFERENT block-0 hash than the empirical form.

Fix: sync this deployment-side genesis.json to the empirical canonical
at ~/work/lux/state/chains/zoo-mainnet/genesis.json (1449 bytes, sha256
f8482568e7a10e882c6bd0248549ad75257edec79a83f659f27e1a34e71b59fa).
Now bootstrap-chain will produce a chain with block-0 hash
0x7c548af47de27560779ccc67dda32a540944accc71dac3343da3b9cd18f14933
which matches the RLP archive's recorded parent.

Add LLM.md sibling at this path documenting:
- state-repo as source-of-truth (canonical) vs zoo/universe as
  deployment mirror
- the regression history (cc7d3d7 incomplete form vs empirical)
- the trade-off when re-firing CreateChainTx after the wrong-genesis
  chain has already committed (new chain ID required; aliases must
  re-sync)

This unblocks the zoo mainnet RLP import — a fresh CreateChainTx will
spawn a chain whose block-0 matches the RLP, and the script at
~/work/lux/universe/k8s/lux-mainnet/scripts/zoo-rlp-reimport.sh can
fire cleanly. The orphaned oxDk6jU7… chain stays in P-state but is
effectively unused; the chain-aliases map updates to the new ID.

Followup: testnet+devnet zoo genesis files and hanzo/pars/spc mainnet
genesis files may have the same regression. Audit + sync in a sibling
commit.
2026-06-05 09:45:30 -07:00

4.1 KiB

Zoo Mainnet — deployment genesis (canonical sync)

Source-of-truth

Authoritative provenance + empirical genesis hash live in lux/state:

  • Canonical genesis JSON: ~/work/lux/state/chains/zoo-mainnet/genesis.json
  • Provenance + hash + RLP details: ~/work/lux/state/chains/zoo-mainnet/LLM.md
  • RLP archive: ~/work/lux/state/rlp/zoo-mainnet/zoo-mainnet-200200.rlp (799 blocks, 1.3 MiB, sha256 0850841a368dd1f85ae09d40f0552aecb679225b58ce4524b2d0a3337c7afc98)
  • Empirical genesis hash: 0x7c548af47de27560779ccc67dda32a540944accc71dac3343da3b9cd18f14933

genesis.json in this directory is a byte-for-byte mirror of the state-repo canonical form. The sync target is the deployment artifact that bootstrap-chain (luxfi/genesis cmd) and the operator's tenantImports flow consume. Drift between this file and the state-repo source produces a different block-0 hash, which orphans every chain spawned from it from the RLP archive (no parent-hash match → admin_importChain returns "block 1 parent mismatch" and refuses to load).

Why this file exists separately from the source-of-truth

  • ~/work/lux/state/ is the empirical archive (immutable artifacts + documentation of historical chain state). It is the ground truth for what the historical Zoo mainnet was.
  • ~/work/zoo/universe/configs/genesis/ is the deployment artifact consumed by chain-bringup tools. It must mirror the state-repo canonical to spawn a chain whose block 0 matches the RLP archive.

This split is one half of the brand-isolation pattern landed in #109 (brand L1 genesis moved out of luxfi/genesis into per-brand universe repos). The state-repo continues to live at lux/state as the empirical oracle for what each historical chain WAS. The per-brand universe repo carries the deployment artifact that drives bringup of what each chain IS GOING TO BE.

Regression history (read this before editing)

The cc7d3d7 commit in luxfi/genesis was labeled "revert genesis.json to RLP-matching pristine form" but landed a SUBSET of the empirical form — missing the explicit block-0 header fields (parentHash, mixHash, nonce, number, gasUsed, extraData, coinbase) and the precompile-defer config fields (quasarTimestamp, fortunaTimestamp, graniteTimestamp all set to 253399622400 = far-future-deferred).

luxd's EVM applies defaults for missing fields when building the block 0 header, and the cc7d3d7 defaults produced hash 0x88dd3a539b0329d13be6dafd2c320e3753e00639f1156d8d66f4f8d044acff2c INSTEAD OF the empirical 0x7c548af4…. Today's bootstrap-chain (2026-06-04) used the cc7d3d7-form genesis from ~/work/lux/genesis/configs/zoo-mainnet/genesis.json (now MOVED.txt per #109), spawned oxDk6jU7W3JS3CyxCpzJ8mgytVwgHM8joWTPCoJZJo9yL9Cuf with the WRONG block-0 hash → the RLP cannot be loaded.

The fix is in this commit: deployment-side genesis.json is now byte- identical to the state-repo canonical (sha256 f8482568e7a10e882c6bd0248549ad75257edec79a83f659f27e1a34e71b59fa, 1449 bytes). Any future bootstrap-chain run will produce the canonical 0x7c548af4… block-0 hash and the RLP will load.

What to do if the bootstrap-chain CreateChainTx already fired

The previous CreateChainTx (with wrong genesis) is committed to P-state and cannot be reverted in-place. To restore the chain with the canonical genesis you have to fire ANOTHER CreateChainTx; this assigns a NEW blockchainID (different from both the historical Vqx99tRk… and today's oxDk6jU7…). The new chain accepts the RLP cleanly because its block 0 matches what the RLP archive expects.

Trade-off: each fresh CreateChainTx changes the chainAlias→blockchainID mapping that the gateway (KrakenD) and chain-aliases ConfigMap reference. Keep them in sync.

Layout note

There is also a ~/work/zoo/genesis/ directory (currently a stub with LICENSE + LLM.md only). It exists for future Zoo-specific genesis pkg work (e.g. zoo-fork-specific genesis tooling) — do NOT duplicate deployment artifacts into it. The split stays clean:

  • lux/state/chains/zoo-mainnet/ — empirical canonical
  • zoo/universe/configs/genesis/mainnet/ — deployment mirror
  • zoo/genesis/ — future tooling repo (currently empty)