mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-10-25 02:31:30 +00:00
luxd serves /v1 only — server/http/server.go pins baseURL="/v1" — so every /ext call in this repo was a silent no-op. The fleet collector's _rpc() returns None on non-200, so the lux.cloud dashboard rendered nodes_rpc_ok:0, version:null and every node rpc_reachable:false while the fleet was in fact running luxd/1.36.2 (mainnet), 1.36.24 (testnet), 1.36.25 (devnet). Fixing the path alone would not have helped: the collector addressed each validator by a hardcoded public LoadBalancer IP, and there are now zero LoadBalancer Services in lux-mainnet/testnet/devnet. Those IPs time out. So node addressing is no longer configured — it is derived from the cluster on every collection, and the one way to reach a validator is the lux-k8s API server's pod proxy, since luxd RPC is cluster-internal. That collapses the old MODE A / MODE B split into a single path: read the CR for the declared shape, the pods for phase/readiness/IP, then each pod's JSON-RPC through the proxy. One credential authenticates both. Deleting the endpoint ConfigMap and its 15 baked-in IPs removes the failure mode where infrastructure moves and a dashboard quietly reports zeros. Probes move to /v1/health/liveness, not /v1/health: a degraded-but-running validator answers /v1/health with 503, so probing it would restart nodes that are merely behind. Any fleet from charts/lux could never have gone Ready. LuxNode.external_ip becomes .ip — with no public per-pod endpoint, the honest value is the pod IP. Avalanche endpoints keep /ext; that is their API, not ours. Measured, with controls: pod-proxy POST /v1/info -> 200 on all 15 pods; /ext/health -> 404; /zzz/health -> 404; nonexistent pod -> 404. A test asserts every probe path is under /v1 and fails if /ext returns. Co-authored-by: Hanzo Dev <[email protected]>