mirror of
https://github.com/luxfi/mpc.git
synced 2026-09-24 00:26:24 +00:00
Survivor nodes in a t-of-n ensemble now report healthy so long as they still have enough ready peers (including self) to form a signing quorum for their configured threshold. Previously, ArePeersReady() was the gate and any single peer loss collapsed availability on the remaining nodes. Repro (Scientist, 2026-04-20): scale liquid-mpc-mpc-node StatefulSet from 3 → 2 replicas in the liquidity devnet; surviving pods returned HTTP 503 with log "Peers not ready expected=3 ready=2" even though 2 nodes are sufficient for the 2-of-3 (threshold=1) signing quorum. Fix: - pkg/transport/registry.go: add HasSigningQuorum(threshold) which returns true when readyCount >= threshold+1 (the CGGMP21/FROST signers-required count used everywhere in pkg/mpc/node.go). - pkg/mpc/registry.go: matching method on the legacy Consul-backed registry plus interface addition to PeerRegistry. - cmd/mpcd/main.go: /healthz handler switched to HasSigningQuorum(threshold) for the 200/503 gate. ArePeersReady() is still reported in the JSON body (as `ready`) for observability. `status` becomes "healthy" / "healthy-reduced" / "degraded" so operators can see the in-between state. - cmd/mpcd/main.go: ConsensusPeerRegistry wrapper delegates the new method to the underlying transport registry. Keygen sessions deliberately continue to require ArePeersReady() — a fresh wallet still needs every participant present. Only the /healthz gate is relaxed, which matches the availability story for signing. Tests: pkg/transport/registry_test.go covers - Test_HasSigningQuorum_3Node_2of3 (the Scientist repro — survivors still quorum-ok after one peer loss) - Test_HasSigningQuorum_5Node_3of5 (larger ensemble, f=2 tolerance) - Test_HasSigningQuorum_ArePeersReady_Decoupled (the two APIs do not gate each other) - Test_HasSigningQuorum_BoundaryCheck (pins arithmetic: required = threshold+1, not threshold) All 11 test cases pass; transport + mpc package suites clean.