Files
genesis/LLM.md
T
Hanzo AI 1fd6379752 genesis: regenerate all network configs
- mainnet: 100 accounts x 500M LUX, 5 stakers, P-lux1 HRP, real IPs
- testnet: 100 accounts x 500M LUX, 2 stakers, P-test1 HRP, networkID=2
- devnet: 100 accounts x 500M LUX, 3 stakers, P-dev1 HRP, networkID=3
- bootstrappers: real validator IPs
- fix mnemonic env priority: MNEMONIC > LUX_MNEMONIC > LIGHT_MNEMONIC
- remove stale .bak files
2026-04-04 11:22:32 -07:00

15 KiB

Genesis

Canonical genesis configurations for all Lux blockchain networks.

Networks

C-Chain (Primary Network)

Network Network ID Chain ID Genesis Hash Treasury
Mainnet 1 96369 0x3f4fa2a0b0ce089f52bf0ae9199c75ffdd76ecafc987794050cb0d286f1ec61e 2T LUX
Testnet 2 96368 0x1c5fe37764b8bc146dc88bc1c2e0259cd8369b07a06439bcfa1782b5d4fb0995 2T LUX
Devnet 3 96370 0x53fe8be293555d20de41847f96081f4e8beca1ee2c206999ffbf7c70e497cf43 2T LUX
Local 1337 1337 - 2T LUX

Subnet Chains

Chain Mainnet ID Testnet ID Devnet ID Treasury
Zoo 200200 200201 200202 2T ZOO
SPC 36911 36910 36912 1B SPC
Hanzo 36963 36962* 36964 1B AI
Pars 494949 494950 494951 2T PARS

*Note: Hanzo testnet was deployed with chain ID 36964 (devnet ID) due to a deployment error. The intended ID is 36962.

Deployed Genesis Hashes (All Chains)

Chain Mainnet Testnet Devnet
C-Chain 0x3f4fa2a...1ec61e 0x53fe8be...97cf43 0x53fe8be...97cf43
Zoo 0x7c548af...14933 0x0652fb2...d1979 0x0652fb2...d1979
SPC 0x4dc9fd5...cfac8 0x210fcc1...0b692 0x0652fb2...d1979
Hanzo 0x6cf786a...48e67 0x6cf786a...48e67 0x6cf786a...48e67
Pars 0xa32921a...b2f34 0xa32921a...b2f34 0xa32921a...b2f34

Genesis Treasury

All networks use the same production treasury address:

Address: 0x9011E888251AB053B7bD1cdB598Db4f9DEd94714
Balance: 2,000,000,000,000,000,000,000,000,000,000 wei (2T LUX)
Hex:     0x193e5939a08ce9dbd480000000

Directory Structure

configs/
├── mainnet/
│   ├── cchain.json         # C-Chain genesis (chain ID 96369)
│   ├── pchain.json         # P-Chain genesis (Platform)
│   ├── network.json        # Network ID, message, startTime
│   └── bootstrappers.json  # Bootstrap nodes
├── testnet/
│   ├── cchain.json         # C-Chain genesis (chain ID 96368)
│   └── genesis.json
├── devnet/
│   └── cchain.json
├── local/
│   ├── cchain.json
│   └── genesis.json
├── zoo-{mainnet,testnet,devnet}/
│   └── genesis.json        # Zoo (200200/200201/200202)
├── spc-{mainnet,testnet,devnet}/
│   └── genesis.json        # SPC (36911/36910/36912)
├── hanzo-{mainnet,testnet,devnet}/
│   └── genesis.json        # Hanzo (36963/36962/36964)
└── pars-{mainnet,testnet,devnet}/
    └── genesis.json        # Pars (494949/494950/494951)

C-Chain Configuration

Mainnet (96369)

{
  "chainId": 96369,
  "gasLimit": 12000000,
  "targetBlockRate": 2,
  "minBaseFee": 25000000000,
  "stateRoot": "0x2d1cedac263020c5c56ef962f6abe0da1f5217bdc6468f8c9258a0ea23699e80",
  "baseFeePerGas": "0x5d21dba00"
}

Network Parameters

Parameter Mainnet Testnet Devnet Local
Block Rate 2s 2s 1s 1s
Gas Limit 12M 12M 20M 15M
Min Base Fee 25 gwei 25 gwei 1 gwei 1 gwei
Chain ID 96369 96368 96370 1337

Warp Precompile (Required for Genesis Hash)

Both mainnet and testnet C-Chain genesis MUST include the warp precompile:

{
  "alloc": {
    "0200000000000000000000000000000000000005": {
      "balance": "0x0",
      "nonce": "0x1",
      "code": "0x01"
    },
    "0x9011E888251AB053B7bD1cdB598Db4f9DEd94714": {
      "balance": "0x193e5939a08ce9dbd480000000"
    }
  }
}

This produces the canonical state root: 0x2d1cedac263020c5c56ef962f6abe0da1f5217bdc6468f8c9258a0ea23699e80

Upgrade Timestamps

C-Chain protocol upgrades activated Dec 25, 2024 @ 4:20pm UTC (timestamp 1735143600):

{
  "subnetEVMTimestamp": 0,
  "durangoTimestamp": 0,
  "etnaTimestamp": 1735143600,
  "fortunaTimestamp": 1735143600,
  "graniteTimestamp": 1735143600
}

Genesis Package (pkg/genesis/)

Core Types

// Config - Top-level genesis configuration
type Config struct {
    NetworkID                  uint32
    Allocations                []Allocation
    StartTime                  uint64
    InitialStakeDuration       uint64
    InitialStakeDurationOffset uint64
    InitialStakedFunds         []ids.ShortID
    InitialStakers             []Staker
    CChainGenesis              string
    Message                    string
}

// Staker - Initial validator
type Staker struct {
    NodeID        ids.NodeID
    RewardAddress ids.ShortID
    DelegationFee uint32
    Signer        *ProofOfPossession
    Weight        uint64
    StartTime     uint64
    EndTime       uint64
}

// Allocation - Genesis allocation
type Allocation struct {
    ETHAddr        ids.ShortID
    LUXAddr        ids.ShortID
    InitialAmount  uint64
    UnlockSchedule []LockedAmount
}

Bech32 Address Format

Addresses use chain prefix + bech32 encoding:

Format: {chain}-{hrp}1{data}{checksum}
Example: P-lux1ck0t9h5u7jvvzhx29n99guqjsfkpzt67wgx7wg

Chain Prefixes:
- P-lux1...  (P-Chain/Platform)
- X-lux1...  (X-Chain/Exchange)
- C-0x...    (C-Chain/EVM hex)

Important: The bech32 checksum is computed using only the HRP ("lux"), not the chain prefix ("P-lux").

CLI Tools

genesis (cmd/genesis/)

Generate genesis configurations:

# Generate from mnemonic
MNEMONIC="test test..." ./genesis -network-id 96369 -validators 5 -output genesis.json

# From existing keys
./genesis -network mainnet -keys-dir ~/.lux/keys -output genesis.json

extract-genesis (cmd/extract-genesis/)

Extract genesis from existing chain data:

./extract-genesis -chaindata /path/to/chaindata -output cchain.json

State Repository Integration

Historical blockchain state is maintained separately in luxfi/state.

Available State Data

Network Blocks RLP Size Location
Lux Mainnet 1,082,780 1.2 GB rlp/lux-mainnet/lux-mainnet-96369.rlp
Lux Testnet 218 695 KB rlp/lux-testnet/lux-testnet-96368.rlp
Zoo Mainnet 799 1.3 MB rlp/zoo-mainnet/zoo-mainnet-200200.rlp
Zoo Testnet 84 156 KB rlp/zoo-testnet/zoo-testnet-200201.rlp
SPC Mainnet 11 7.8 KB rlp/spc-mainnet/spc-mainnet-36911.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 /tmp/lux genesis/configs/mainnet/cchain.json

# Import blocks
geth import --datadir /tmp/lux state/rlp/lux-mainnet/lux-mainnet-96369.rlp

SubnetEVM Header Formats

State repo RLP uses SubnetEVM header encoding:

Fields Format Usage
16 Genesis block No optional fields
17-19 Post-genesis ExtDataHash, ExtDataGasUsed, BlockGasCost

Coreth field order (positions 15+):

15: ExtDataHash    (common.Hash - value type, required)
16: BaseFee        (*big.Int)
17: ExtDataGasUsed (*big.Int)
18: BlockGasCost   (*big.Int)

Mainnet Validators

Node NodeID P-Chain Address
1 NodeID-FrtEjhat6RUqjEWCJgYZKqBaxY2Woyy5G P-lux1ck0t9h5u7jvvzhx29n99guqjsfkpzt67wgx7wg
2 NodeID-9hq49qGVZN7M7tXxdpF3AqptQGdmPCFnQ P-lux1dclruwcn9ug8u0jjk3ukh676jr3lsy4er9m3l5
3 NodeID-8osEnSC4LQFdG1LMit12CBsE6BfKGHNAw P-lux1qdv9zns0gpfesw0h28jqp2up6h77du2damqf88
4 NodeID-MrdgTgPuddyo7anomKr4akMcoKzVKcgbG P-lux1jjs4nx7ul4d6pnsjtpv2khzu8p4yctegvass46
5 NodeID-Mgd5yHs4pe6qRjkBcW5Y7oqHA51j4afcC P-lux1970ngvf6s6rsndrkvjzr6lfvf2tdl30529c435

Token Decimals

// P-Chain/X-Chain: 6 decimals (microLUX as base unit)
const (
    MicroLux uint64 = 1            // 0.000001 LUX
    MilliLux uint64 = 1_000        // 0.001 LUX
    Lux      uint64 = 1_000_000    // 1 LUX
)

// C-Chain: 18 decimals (wei, standard EVM)
// 1 LUX = 10^18 wei on C-Chain

Verification

Genesis Hash Check

# Verify mainnet C-Chain genesis
geth init --datadir /tmp/verify configs/mainnet/cchain.json 2>&1 | grep "genesis hash"
# Expected: 0x3f4fa2a0b0ce089f52bf0ae9199c75ffdd76ecafc987794050cb0d286f1ec61e

# Verify state root
cat configs/mainnet/cchain.json | jq -r '.stateRoot'
# Expected: 0x2d1cedac263020c5c56ef962f6abe0da1f5217bdc6468f8c9258a0ea23699e80

Network ID Verification

cat configs/mainnet/network.json | jq '.networkID'
# Expected: 96369

cat configs/testnet/network.json | jq '.networkID'  
# Expected: 96368

Fortuna Timestamp Fix (2025-12-25)

Problem

Block import failed with gas limit mismatch when importing Zoo chain blocks:

invalid gas limit: have 12000000, want 10000000

Root Cause

Zoo genesis files had fortunaTimestamp: 0 which activates Fortuna from block 0. Fortuna uses dynamic gas limits via state.MaxCapacity() returning 10M, but original blocks had 12M gas limit (Cortina rules).

Solution

Set far-future timestamps for Fortuna, Etna, and Granite upgrades:

{
  "etnaTimestamp": 253399622400,
  "fortunaTimestamp": 253399622400,
  "graniteTimestamp": 253399622400
}

Files Updated

  • configs/zoo-mainnet/genesis.json
  • configs/zoo-testnet/genesis.json

Verified Block Counts (2025-12-28)

Network Chain ID Blocks Genesis Hash
Lux Mainnet 96369 1,082,780 0x3f4fa2a0b0ce089f52bf0ae9199c75ffdd76ecafc987794050cb0d286f1ec61e
Lux Testnet 96368 218 0x1c5fe37764b8bc146dc88bc1c2e0259cd8369b07a06439bcfa1782b5d4fb0995
Zoo Mainnet 200200 799 0x7c548af47de27560779ccc67dda32a540944accc71dac3343da3b9cd18f14933
Zoo Testnet 200201 84 0x0652fb2fde1460544a5893e5eba5095ff566861cbc87fcb1c73be2b81d6d1979
SPC Mainnet 36911 11 0x4dc9fd5cf4ee64609f140ba0aa50f320cadf0ae8b59a29415979bc05b17cfac8

Canonical Genesis Checksums (SHA256)

IMPORTANT: All genesis files are sorted alphabetically by key for determinism. These checksums are the canonical reference - if they don't match, the file has been modified.

File SHA256
mainnet/cchain.json 968e9f3cd19a9b88ca157db3894622272ded02f0f184b5386493ff55897001be
testnet/cchain.json ba211e1bbbd7807c2224d240628facb2dfb6c2d6cde2e274eb881a57609ed038
zoo-mainnet/genesis.json 14c01e8bb5ac13144a3730c695847d53506647efbaada3f3240a16e7b10684f7
zoo-testnet/genesis.json 74357b85e6968ca70d8907b2e940e5e234fd6b288749865d91ab69a6083e6dae
zoo-devnet/genesis.json dd604fee5c78f7367b314a9a7d7ee1d5f8c42839165164262368afc7dd91fc5e
spc-mainnet/genesis.json 9c01115559556fc245d4993b193889370bd99edd22a7fa1e9e3d7ddafbb63535
spc-testnet/genesis.json af12bb81dd9abce26b7a311f00fa2ac7f5adfb996e698b9f473252199f747b2c
spc-devnet/genesis.json 317d54ac7846b0f174964552b4949d858072f6ffbc37f6c10092e01d595ce46f
hanzo-mainnet/genesis.json adae3c441b34db937dbcd961450bff5bcabd388a5479fe9ba7380ef61f083637
hanzo-testnet/genesis.json a2d00685bf7f414815dc3579552e19045183428c520f4f5b23a6726cf4002c32
hanzo-devnet/genesis.json 1c489d29c08857696909f029a1b2cda554e059e86c630ae64f35a5243f4bd25c
pars-mainnet/genesis.json ca35306a73f4cbfeccc8018b71596b122f698a23f3c038993a2ad34ca315e539
pars-testnet/genesis.json 9d7ff05187bb2570d2a1af8ccfa41a99dfaf8b56558decf127209ac6d5faec85
pars-devnet/genesis.json 3fc55f6be7b46dd6955ab2ec95186a4aa7da13991650909cb5f9ecbaa51b06c7

Verify Checksum

cd ~/work/lux/genesis/configs
shasum -a 256 zoo-mainnet/genesis.json
# Should output: 241fd0209253e7a5a04c55c7a6f4f0ba864a83dd9840c4969d5a1b5b5f6c3366

Re-sort if Modified

# If file was modified, re-sort it:
jq -S '.' genesis.json > genesis.sorted.json && mv genesis.sorted.json genesis.json

Genesis Hash Fix (2025-12-28)

Problem

Mainnet genesis hash was computing as 0xc3069db32ef986d8e287458e44066eb04205648e602dc2fede561c424a6516de instead of the expected 0x3f4fa2a0b0ce089f52bf0ae9199c75ffdd76ecafc987794050cb0d286f1ec61e from historical RLP blocks.

Root Cause

The warpConfig.blockTimestamp was set to 0, which caused ApplyPrecompileActivations() in coreth to add the warp precompile to genesis state BEFORE the alloc was applied. When warp wasn't in alloc, this changed the state trie and produced a different genesis hash.

Key insight from coreth/core/genesis.go:271:

// ApplyPrecompileActivations runs FIRST (line 271)
ApplyPrecompileActivations(g.Config, nil, blockContext, statedb)

// Then alloc is applied (lines 276-283)
for addr, account := range g.Alloc {
    // This overwrites precompile if in alloc, leaves it if not
}

Solution

The original mainnet genesis was created with warp precompile IN the alloc section:

{
  "alloc": {
    "0200000000000000000000000000000000000005": {
      "balance": "0x0",
      "nonce": "0x1", 
      "code": "0x01"
    }
  },
  "warpConfig": {
    "blockTimestamp": 1730446786,
    "quorumNumerator": 67,
    "requirePrimaryNetworkSigners": false
  }
}

The warpConfig.blockTimestamp equals the genesis timestamp (0x672485c2 = 1730446786), meaning warp is activated at genesis. Having warp in both alloc AND warpConfig ensures consistent state.

Files Restored

  • configs/mainnet/cchain.json - Restored from git with warp in alloc
  • configs/mainnet/genesis.json - Updated cChainGenesis to match

Verification

# Start mainnet
netrunner start --networks mainnet

# Verify genesis hash
curl -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x0",false],"id":1}' \
  http://127.0.0.1:9630/ext/bc/C/rpc | jq '.result.hash'
# Expected: "0x3f4fa2a0b0ce089f52bf0ae9199c75ffdd76ecafc987794050cb0d286f1ec61e"

# Verify warp precompile in state
curl -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","method":"eth_getCode","params":["0x0200000000000000000000000000000000000005","0x0"],"id":1}' \
  http://127.0.0.1:9630/ext/bc/C/rpc | jq '.result'
# Expected: "0x01"

Known Issues

Documentation Discrepancies

  1. Network IDs: Some older docs reference Network ID 1/2 instead of 96369/96368
  2. File paths: Docs may reference chain.rlp.gz but actual files are {network}-{chainid}.rlp
  3. Block counts: Documentation may be outdated - verify against actual RLP files

State Repo Sync

The state repo should be periodically updated with:

  • Latest block exports
  • Updated metadata.json files
  • Corrected documentation

Last Updated: 2025-12-28 - Genesis hashes verified against RLP