fix(service): preserve invalidated slots in the initial-round DKG node list#91
Conversation
|
The core fix is sound: swapping Review iteration 2 · Commit 527faac · 2026-07-22T08:56:59Z |
|
The commit message says "Registrations stays VERIFIED-only for status-sensitive consumers," but in the diff |
…e list Build the initial-round kyber node list (SortedPubKeys) from the round's ALL-status registrations (GetAllRegisteredDKGRegistrations) instead of the VERIFIED/FINALIZED-only set. extractSortedPubKeys assigns kyber positions as a dense index after sorting by reg.Index, so dropping a member invalidated mid-dealing shifts every later node's index. A node first building its DistKeyGenerator after the invalidation would then get a shorter, shifted list diverging from peers who built earlier. This mirrors the resharing path (fetchLatestPubKeysAndCoeffs). network.Total is fixed at BeginDealing and never decremented, so the all-status set keeps a stable length equal to network.Total (validateRegistrations still enforces the count). The same registrations feed both SortedPubKeys and rc.Registrations; PID matching is status-insensitive (it keys off each registration's own DkgPubKey and on-chain Index), so the retained invalidated slots are harmless.
fb1505d to
527faac
Compare
Problem
The initial-round kyber node list was built from VERIFIED-only registrations.
extractSortedPubKeysassigns each kyber position as a dense index sorted byreg.Index, so dropping a member invalidated mid-dealing shifts every later node's index. A node that first builds itsDistKeyGeneratorafter an invalidation gets a shorter, shifted list that diverges from peers who built earlier — and fails thelen(regs) == network.Totalcheck, sincenetwork.Totalis fixed atBeginDealingand never decremented.Fix
Build (and validate) the node list from all registrations (any status) via
GetAllRegisteredDKGRegistrations, mirroring the resharing path. Invalidated members keep their slot, so the list has a stable length equal tonetwork.Totalregardless of when a node builds. PID matching (matchPIDFromRegistrations/CachePID) is status-insensitive — it keys off each registration's ownDkgPubKeyand on-chainIndex— so the retained slots are harmless.Tests
TestFetchRoundContext_PreservesInvalidatedSlotissue: none