mirror of
https://github.com/luxfi/genesis.git
synced 2026-07-27 05:54:08 +00:00
45008b7205a7f8dd2a0551555f9ba6c0a60cea08
* feat(genesis): bootstrap-l2 — durable replacement for /tmp script
Recreates the v1.27.x ConvertSubnetToL1 / CreateChain pipeline previously
maintained as /tmp/bootstrap-l2-v127. New tool at cmd/bootstrap-l2/:
- Reads MNEMONIC from env, derives BIP44 m/44'/9000'/0'/0/<idx>
- For each chain in --chains: IssueCreateNetworkTx → wallet re-sync →
IssueCreateChainTx (vmID nyGCobireNhxFB7iM5bxV74hAY6j9nQX6wizxfWomnMMtztkr)
→ IssueAddChainValidatorTx for every primary validator
- Probes info.isBootstrapped(chain=<bcID>) + eth_blockNumber>0 per chain;
if either misses the deadline the whole tool exits non-zero (no partial
state propagated to YAML/CMs)
- Emits a single JSON document {chains:[{name, subnetId, blockchainId,
evmChainId, firstBlockHex, bootstrappedAt}, ...]} for downstream
YAML/CM updates
- --print-addr-only mode to verify funding before spending
go.mod: bump luxfi/node v1.23.36 → v1.27.21 to match cluster runtime
(devnet runs luxd v1.27.21; pre-rename wallet codecs would produce txs the
nodes can't decode). Only existing genesis use of luxfi/node is the
address formatter — no behavior change for other cmds.
Designed for the four canonical Lux L2 EVMs (hanzo, zoo, pars, spc)
but the chain list is data-driven via --chains and --configs-dir.
* feat(genesis): bootstrap-l2 default VM ID → mgj786NP... (native subnet-evm)
Devnet luxd-0 /data/plugins contains exactly two subnet-evm plugin IDs
(mgj786NP7uDwBCcq6YwThhaN8FLyybkCa4zBWTQbNgmK6k9A6 and
ag3GReYPNuSR17rUP8acMdZipQBikdXNRKDyFszAysmy3vDXE), neither matching the
brand-namespaced alias nyGCobireNhxFB7iM5bxV74hAY6j9nQX6wizxfWomnMMtztkr
recorded in the 2026-05-27 chain-aliases ConfigMap annotation.
That alias required a runtime symlink (created post-startup, lost on PVC
remount) — the same fragile path that's been the historical source of
L2-EVM bootstrap failures. Mainnet's lux-mainnet/luxd-startup.yaml uses
mgj786NP... directly and `cp`'s it as the ag3GR... duplicate; we mirror
that pattern here so the plugin is *always* present without a startup
script writing into a PVC.
The chain-aliases CM annotation about nyGCobir... is now stale and will be
rewritten in the post-bootstrap update.
* feat(genesis): bootstrap-l2 — --existing-subnet-ids to resume after partial bootstrap
When CreateNetworkTx succeeds but the subsequent CreateChainTx fails (or
the tool gets killed mid-flight), the subnet still exists on-chain and
the fee was burned. Re-running the tool without --existing-subnet-ids
would burn another CreateNetwork fee.
Format: --existing-subnet-ids=hanzo:2PkWqv...,zoo:abc...
For each named chain, skip IssueCreateNetworkTx and pass the supplied
subnet ID straight into IssueCreateChainTx. Chains not in the map
continue to create a fresh subnet.
Also surfaces a real operational pattern: load-balanced services like
svc/luxd-headless can pin a kubectl port-forward to a lagging pod whose
state is behind the chain head; the tool must still complete by
re-using the subnet visible on the leader pod.
* feat(genesis): bootstrap-l2 — EVM heartbeat tx + decoupled bootstrap probe
Acceptance criterion 'eth_blockNumber > 0' on a fresh subnet-evm chain
requires injecting the first tx (subnet-evm only seals blocks when a tx
arrives). Adding two new flags:
--evm-heartbeat-key=<hex> LUX_PRIVATE_KEY hex (0x9011E888...).
Sends a 0-value self-tx after the chain
reports info.isBootstrapped=true; the first
tx rolls block 1.
--probe-bootstrap-only Skip the eth_blockNumber>0 wait. Used when
an out-of-band heartbeat (chain-heartbeat
CronJob) will roll block 1 later.
The probe is also split into waitBootstrap + probeChain so the heartbeat
fires after isBootstrapped but before eth_blockNumber checks (otherwise
eth_sendRawTransaction returns 'chain not bootstrapped').
Signing path: luxfi/crypto/secp256k1 → ecdsa.PrivateKey → geth/core/types
SignTx with EIP-155 signer scoped to each chain's evmChainID. EVM address
derivation goes through luxfi/crypto/secp256k1.PubkeyToAddress so we never
import an upstream go-ethereum crypto package.
* feat(genesis): bootstrap-l2 — preset chain ID (chain:subnetID:chainID) for resume
Extends --existing-subnet-ids parser to accept an optional third field
<chainID>. When present, both IssueCreateNetworkTx and IssueCreateChainTx
are skipped; the tool only waits for isBootstrapped, sends the heartbeat
(if --evm-heartbeat-key is set), and probes eth_blockNumber.
This is the post-partial-failure resume pattern: if hanzo's subnet+chain
were created successfully in a prior run but zoo onwards failed (or were
never attempted), pass
--existing-subnet-ids=hanzo:2PkWqv...:rHiiTB...,zoo:abc...
and the tool will skip the hanzo P-chain spend, treat hanzo as already
created, and continue with the next chain.
Also gates the AddChainValidatorTx and post-chain wallet re-sync on
presetChainID being unset, since both are unnecessary in resume mode.
* fix(genesis): canonical 0x prefix on all devnet alloc keys + fail-loud bootstrap-l2 (#72)
Two-part fix for the alloc-key shape that bootstrap-l2 consumes:
## 1. Genesis configs patched at source (4 files)
Every alloc key in:
- configs/hanzo-devnet/genesis.json
- configs/pars-devnet/genesis.json
- configs/spc-devnet/genesis.json
- configs/zoo-devnet/genesis.json
now matches the canonical /^0x[0-9a-fA-F]{40}$/ shape. The EVM
genesis loader rejects unprefixed keys; previously bootstrap-l2's
in-memory repair was masking the issue. Fixing at source makes the
configs self-describing and stops the "works for me but won't load
on a fresh node" failure mode.
## 2. bootstrap-l2 normalization is now fail-loud (cmd/bootstrap-l2/main.go)
Pre-flight repair upgrades from silent fix to:
- Normalize 0X → 0x (preserve body case for EIP-55 checksum signal)
- Add missing 0x prefix (repair, log count)
- Reject anything that doesn't match /^0x[0-9a-fA-F]{40}$/ AFTER
repair via log.Fatalf with up to 5 sample keys
Per the user's directive:
> "normalize alloc keys on load/write or fail loudly before chain
> creation. I prefer normalization plus a validation log, not
> silent mutation with no signal."
Log line now shows both healthy and repaired counts:
[devnet] hanzo: alloc keys ok=2 0x-repaired=0 (in-memory only, file unchanged)
A genuinely malformed key (non-hex, wrong length) aborts the entire
bootstrap before any CreateNetworkTx burns LUX:
[devnet] hanzo: 1 malformed alloc keys (require canonical
/^0x[0-9a-fA-F]{40}$/); sample: ["0xZZZ..."]
## 3. Single source of truth: normalizeAllocKey() helper
New pure function returns `(canonical, repaired, valid)`. Every
consumer (the in-memory repair, future validation tooling, any
on-disk rewriter) routes through this one function. Routes:
- body-case PRESERVED (EIP-55 checksum)
- prefix-case NORMALIZED (`0X` → `0x`)
- shape-validated (length 40, hex only)
- idempotent
## Tests
9 new tests in cmd/bootstrap-l2/main_test.go:
- already-canonical roundtrip
- missing-prefix repair flag
- 0X-prefix normalization
- body-case preservation (EIP-55 invariant)
- short body rejection (39/38/empty)
- long body rejection (41)
- non-hex rejection (g, _, space)
- empty string rejection
- idempotency under repeated normalize calls
All pass. Build clean.
Lux Network Genesis Configurations
This repository contains the canonical genesis configurations for all Lux networks.
Directory Structure
genesis/
├── mainnet/ # LUX Mainnet (Chain ID: 96369)
│ ├── cchain.json # C-Chain genesis (EVM compatible)
│ ├── pchain.json # P-Chain genesis (ProtocolVM)
│ ├── xchain.json # X-Chain genesis (Exchange chain)
│ ├── network.json # Network configuration
│ └── genesis.json # Full network genesis
├── testnet/ # LUX Testnet (Chain ID: 96368)
│ ├── cchain.json # C-Chain genesis (EVM compatible)
│ └── genesis.json # Full testnet genesis
├── devnet/ # LUX Devnet (Chain ID: 96370) - Fast iteration network
│ └── cchain.json # C-Chain genesis (EVM compatible)
├── local/ # Local development network (Chain ID: 1337)
│ ├── cchain.json # C-Chain genesis (EVM compatible)
│ └── genesis.json # Local network genesis
├── bootstrappers.json # Network bootstrapper nodes
└── checkpoints.json # Network checkpoints
Mainnet C-Chain Genesis
The mainnet C-Chain was initialized with a single genesis allocation:
| Address | Balance |
|---|---|
0x9011e888251ab053b7bd1cdb598db4f9ded94714 |
2,000,000,000,000,000,000,000,000,000,000 wei (2T LUX) |
Key Parameters
- Chain ID: 96369
- Gas Limit: 30,000,000 (0x1C9C380)
- Min Base Fee: 25 gwei
- Block Rate: 2 seconds
Network IDs
| Network | Chain ID | Network ID | Purpose |
|---|---|---|---|
| LUX Mainnet | 96369 | 96369 | Production network |
| LUX Testnet | 96368 | 96368 | Public test network |
| LUX Devnet | 96370 | 96370 | Fast iteration dev network |
| Local | 1337 | 1337 | Local development |
Network Configurations
Mainnet (96369)
- Block Rate: 2 seconds
- Gas Limit: 30M
- Min Base Fee: 25 gwei
- Genesis Account:
0x9011...with 2T LUX
Testnet (96368)
- Block Rate: 2 seconds
- Gas Limit: 12M
- Min Base Fee: 25 gwei
- Genesis Account:
0x9011...with 2T LUX (same as mainnet)
Devnet (96370)
- Block Rate: 1 second (faster)
- Gas Limit: 20M
- Min Base Fee: 1 gwei (cheaper)
- Genesis Account:
0x9011...with 2T LUX - All upgrades enabled at genesis (Shanghai, Cancun, etc.)
Local (1337)
- Block Rate: 1 second
- Gas Limit: 15M
- Min Base Fee: 1 gwei
- Genesis Account:
0x9011...with 2T LUX - All upgrades enabled at genesis
Usage
These genesis files are used by:
luxdnode for network initializationcorethfor C-Chain configuration- Block explorers for genesis block verification
- Migration tools for state reconstruction
RPC Endpoints
- Mainnet:
http://localhost:9630/ext/bc/C/rpc - Testnet:
http://localhost:9630/ext/bc/C/rpc(testnet node) - Devnet:
http://localhost:9630/ext/bc/C/rpc(devnet node)
Genesis Account
All networks use the same production genesis account:
| Account | Balance | Networks |
|---|---|---|
0x9011e888251ab053b7bd1cdb598db4f9ded94714 |
2T LUX | All networks |
State Data & RLP Exports
Blockchain state exports and RLP-encoded blocks are maintained in a separate repository:
Repository: github.com/luxfi/state
Available Data
| Network | Chain ID | Blocks | RLP Location |
|---|---|---|---|
| Lux Mainnet | 96369 | 1,082,780 | rlp/lux-mainnet/lux-mainnet-96369.rlp |
| Lux Testnet | 96368 | 219 | rlp/lux-testnet/lux-testnet-96368.rlp |
| Zoo Mainnet | 200200 | 799 | rlp/zoo-mainnet/zoo-mainnet-200200.rlp |
| Zoo Testnet | 200201 | 85 | rlp/zoo-testnet/zoo-testnet-200201.rlp |
Import Workflow
# Clone repos
git clone https://github.com/luxfi/genesis
git clone https://github.com/luxfi/state
# Initialize with genesis
geth init --datadir /path/to/db genesis/mainnet/cchain.json
# Import blocks from state repo
geth import --datadir /path/to/db state/rlp/lux-mainnet/lux-mainnet-96369.rlp
Source Data
The state repo also contains:
pebbledb/- Original SubnetEVM PebbleDB databasesdocs/- State verification and recovery documentationpkg/- Go tools for archaeology, bridge, and scanning
Description
Lux Network genesis for Mainnet, Testnet, Devnet, Local/Custom.
20 MiB
Languages
Go
96.6%
Python
3%
Makefile
0.4%