diff --git a/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go b/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go index 105f995b..ff89c229 100644 --- a/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go +++ b/backend/mpc-system/services/account/adapters/input/http/co_managed_handler.go @@ -123,19 +123,10 @@ func (h *CoManagedHTTPHandler) CreateSession(c *gin.Context) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - // IMPORTANT: Convert user-friendly threshold to tss-lib format - // User says "3-of-5" meaning 3 signers needed - // tss-lib threshold t means t+1 signers needed - // So we store t-1: user's 3 becomes 2, tss-lib needs 2+1=3 signers - // This matches persistent-only behavior (see account.go:144) - // ROLLBACK: If this breaks, revert this change and the tss-party/main.go changes - tssThresholdT := req.ThresholdT - 1 - logger.Info("Creating co-managed keygen session", zap.String("wallet_name", req.WalletName), zap.Int("threshold_n", req.ThresholdN), - zap.Int("threshold_t_user", req.ThresholdT), - zap.Int("threshold_t_tss", tssThresholdT), + zap.Int("threshold_t", req.ThresholdT), zap.Int("persistent_count", persistentCount), zap.Int("external_count", externalCount), zap.String("initiator_party_id", req.InitiatorPartyID)) @@ -145,7 +136,7 @@ func (h *CoManagedHTTPHandler) CreateSession(c *gin.Context) { req.WalletName, inviteCode, int32(req.ThresholdN), - int32(tssThresholdT), + int32(req.ThresholdT), int32(persistentCount), int32(externalCount), 3600, // 1 hour expiry for session creation phase diff --git a/backend/mpc-system/services/service-party-app/tss-party/main.go b/backend/mpc-system/services/service-party-app/tss-party/main.go index a9f37a9d..287fb233 100644 --- a/backend/mpc-system/services/service-party-app/tss-party/main.go +++ b/backend/mpc-system/services/service-party-app/tss-party/main.go @@ -597,15 +597,15 @@ func executeSign( // Create peer context and parameters // For signing, the first parameter to NewParameters must be the number of parties // actually participating in the signing (len(sortedPartyIDs)), NOT the original keygen N. - // The threshold parameter must match what was used during keygen. + // The threshold parameter is the minimum signers minus 1 (tss-lib convention: t means t+1 required) // // For co-managed signing with 3-of-5: - // - thresholdN = 5 (original keygen parties) - NOT used here for party count - // - thresholdT = 3 (threshold from keygen, meaning 3+1=4 parties needed... but we have 3 signers) + // - thresholdN = 5 (original keygen parties) - NOT used here + // - thresholdT = 3 (signers needed) // - len(sortedPartyIDs) = 3 (actual signing participants) - // - threshold param = thresholdT (must match keygen threshold) + // - threshold param = thresholdT - 1 = 2 (tss-lib needs 2+1=3 signers) peerCtx := tss.NewPeerContext(sortedPartyIDs) - params := tss.NewParameters(tss.S256(), peerCtx, selfTSSID, len(sortedPartyIDs), thresholdT) + params := tss.NewParameters(tss.S256(), peerCtx, selfTSSID, len(sortedPartyIDs), thresholdT-1) // Create channels outCh := make(chan tss.Message, thresholdT*10)