fix(session): distinguish keygen vs sign in CanStart() and AllPartiesReady()

- Keygen/co-keygen: must have exactly N participants joined
- Sign (co-sign/persistent): only check all registered participants joined

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-31 08:34:40 -08:00
parent d0c504dcf3
commit 1708a03aaf
1 changed files with 30 additions and 24 deletions

View File

@ -142,27 +142,27 @@ func (s *MPCSession) UpdateParticipantStatus(partyID value_objects.PartyID, stat
}
// CanStart checks if all participants have joined and the session can start
//
// BREAKING CHANGE WARNING (for co-sign feature, commit 99fa003b):
// Original code: len(s.Participants) == s.Threshold.N() && readyCount == s.Threshold.N()
// New code: Check all registered participants are joined (no T/N check)
// This change affects PERSISTENT SIGN flow because we now pass keygenThresholdN
// instead of len(parties) as threshold_n. With original code, sign sessions with
// T+1 participants would fail because T+1 != N.
// If issues arise with persistent sign, REVERT to original N-based check.
// Related files: session_coordinator.go, session_coordinator_client.go, account_handler.go
func (s *MPCSession) CanStart() bool {
// Session can start when all registered participants have joined
// The number of participants was determined at session creation time:
// - For keygen: N parties are registered
// - For sign: T or T+1 parties are registered (depending on the signing flow)
// We don't need to check against T or N here - just verify all registered parties have joined
// For keygen sessions (including co-managed keygen): must have exactly N participants
if s.SessionType.IsKeygen() {
if len(s.Participants) != s.Threshold.N() {
return false
}
readyCount := 0
for _, p := range s.Participants {
if p.IsJoined() || p.IsReady() {
readyCount++
}
}
return readyCount == s.Threshold.N()
}
// For sign sessions: check all registered participants have joined
// The number of participants was determined at session creation time (T or T+1)
if len(s.Participants) == 0 {
return false
}
for _, p := range s.Participants {
// All participants must be in joined or ready status
if !p.IsJoined() && !p.IsReady() {
return false
}
@ -272,15 +272,21 @@ func (s *MPCSession) MarkPartyReady(partyID string) error {
}
// AllPartiesReady checks if all participants are ready
//
// BREAKING CHANGE WARNING (for co-sign feature, commit 99fa003b):
// Original code: len(s.Participants) != s.Threshold.N() would return false
// New code: Check all registered participants are ready (no T/N check)
// This change affects PERSISTENT SIGN flow. See CanStart() for details.
// If issues arise with persistent sign, REVERT to original N-based check.
func (s *MPCSession) AllPartiesReady() bool {
// Check that all registered participants are ready or completed
// The participant count was determined at session creation time
// For keygen sessions: must have exactly N participants
if s.SessionType.IsKeygen() {
if len(s.Participants) != s.Threshold.N() {
return false
}
for _, p := range s.Participants {
if !p.IsReady() && !p.IsCompleted() {
return false
}
}
return true
}
// For sign sessions: check all registered participants are ready
if len(s.Participants) == 0 {
return false
}