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.
This commit is contained in:
Hanzo AI
2026-06-05 09:45:30 -07:00
parent d88c05fce0
commit 59f1220481
2 changed files with 108 additions and 15 deletions
+81
View File
@@ -0,0 +1,81 @@
# 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)
+27 -15
View File
@@ -2,40 +2,52 @@
"alloc": {
"0200000000000000000000000000000000000005": {
"balance": "0x0",
"nonce": "0x1",
"code": "0x01"
"code": "0x01",
"nonce": "0x1"
},
"9011E888251AB053B7bD1cdB598Db4f9DEd94714": {
"balance": "0x193e5939a08ce9dbd480000000"
}
},
"baseFeePerGas": "0x5d21dba00",
"coinbase": "0x0000000000000000000000000000000000000000",
"config": {
"berlinBlock": 0,
"byzantiumBlock": 0,
"chainId": 200200,
"constantinopleBlock": 0,
"durangoTimestamp": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"quasarTimestamp": 253399622400,
"evmTimestamp": 0,
"feeConfig": {
"baseFeeChangeDenominator": 36,
"blockGasCostStep": 200000,
"gasLimit": 12000000,
"maxBlockGasCost": 1000000,
"minBaseFee": 25000000000,
"minBlockGasCost": 0,
"targetBlockRate": 2,
"targetGas": 15000000
},
"fortunaTimestamp": 253399622400,
"graniteTimestamp": 253399622400,
"homesteadBlock": 0,
"istanbulBlock": 0,
"londonBlock": 0,
"muirGlacierBlock": 0,
"petersburgBlock": 0,
"evmTimestamp": 0,
"durangoTimestamp": 0,
"feeConfig": {
"gasLimit": 12000000,
"targetBlockRate": 2,
"minBaseFee": 25000000000,
"targetGas": 15000000,
"baseFeeChangeDenominator": 36,
"minBlockGasCost": 0,
"maxBlockGasCost": 1000000,
"blockGasCostStep": 200000
}
"terminalTotalDifficulty": 0
},
"difficulty": "0x0",
"extraData": "0x",
"gasLimit": "0xb71b00",
"gasUsed": "0x0",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x0",
"number": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x6727e9c3"
}
}