lux-mainnet is five validators with anti-affinity across five hosts. The local cloud is two, and only one can run the node at all: ghcr.io/luxfi/node publishes a single amd64 manifest and spark is arm64. Five votes on one host is one vote wearing five hats, so this is the other thing — one validator, on evo. Five blockers cleared and recorded in the README, because each cost a cycle and none is guessable: the 256KB annotation limit that rejects a 949KB genesis, the image that sets Cmd and no Entrypoint, sybil protection being refused on a public network id, and a hostPath at /data shadowing the image's own plugin directory — which makes the C-chain opt out with "chain VM plugin not loaded". One open: the P-chain never finishes bootstrapping, so C is never created and there is no RPC. And a finding that settles the import question. The 218-block testnet RLP has block 0 = 0x1c5fe377; current testnet genesis produces 0xfc909f7e. The genesis repo records the change and calls it intentional — both networks were block-0 fresh, so nothing was owed to that history. It cannot be imported and is not meant to be. Only mainnet's cChainGenesis is locked to its blocks. Co-authored-by: Hanzo Dev <[email protected]>
lux-local — one validator, on the local cloud
Why this exists, and what it is not.
lux-mainnet is five validators with requiredDuringScheduling anti-affinity
across five hosts, because five independent votes need five failure domains.
The local cloud is two hosts, and only one of them can run the node at all:
ghcr.io/luxfi/node publishes a single amd64 manifest, and spark is arm64.
So the production topology does not fit here and pretending otherwise would put
five votes on one host, which is one vote wearing five hats.
This is the other thing: one validator, sybil protection off, serving the same chain the interfaces expect — 96369, with the DEX precompiles at the same activation the fleet uses. It is what makes both exchanges display something, and what a fixture can be captured from. It is not mainnet and holds none of mainnet's 1,082,780 blocks.
Where this got to
Running on evo, five blockers cleared, one open.
| ✓ | Only evo can run it. ghcr.io/luxfi/node ships one amd64 manifest; spark is arm64. |
| ✓ | kubectl apply refuses a 949KB genesis — it copies the manifest into a 256KB annotation. Server-side apply takes it. |
| ✓ | The image sets Cmd and no Entrypoint, so bare args replace the binary instead of following it. |
| ✓ | --sybil-protection-enabled=false is refused on a public network id. 1337 is not public. |
| ✓ | A hostPath at /data shadows the image's own /luxd/build/plugins, and the C-chain then opts out with "chain VM plugin not loaded". |
| ✗ | The P-chain never finishes bootstrapping: frontier poll skipped — no connected peers, forever. Without P, C is never created and there is no RPC. --bootstrap-ips=/--bootstrap-ids= are accepted and then ignored (deprecated), and --bootstrap-nodes= empty does not change it. The genesis names five stakers this node is not one of. |
Next: make this node one of the genesis stakers, or find the flag that lets a lone node declare the primary network bootstrapped.
The testnet RLP cannot be imported, and is not meant to be
state/rlp/lux-testnet/lux-testnet-96368.rlp is 218 blocks whose block 0 is
0x1c5fe37764b8bc146dc88bc1c2e0259cd8369b07a06439bcfa1782b5d4fb0995. Current
testnet genesis produces 0xfc909f7e…. The genesis repo records the change and
the reason: commits 2bf1ca3 and d3cbd78 activated Shanghai/Cancun/Prague at
genesis and raised the gas limit, and "both networks were block-0 fresh with no
committed historical state, so the hash update is intentional".
That history has no genesis to hang from any more, and the import refuses with
block 1 parent mismatch — correctly. Testnet runs fresh. Only mainnet's
cChainGenesis is locked, by its 1,082,780 blocks, which is why mainnet's RLP
would import and testnet's will not.