Files
zeekayandHanzo Dev 30c1374991 A single-validator network for the local cloud, and what blocks it
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]>
2026-09-08 10:08:45 -07:00
..

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.