fix(mpc-system): GetSessionStatus 返回实际的 threshold_n 和 threshold_t

问题:
- Message Router 的 GetSessionStatus 把 TotalParties 当作 ThresholdN 返回
- 导致 server-party 收到错误的 threshold_n=2 而不是 3
- TSS 协议无法正确启动(参与者数量验证失败)

修复:
- 在 session_coordinator.proto 添加 threshold_n 和 threshold_t 字段
- Session Coordinator 返回实际的 threshold 值
- Message Router 透传 threshold 值而不是参与者数量

Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-29 11:59:53 -08:00
parent 422d7007b1
commit 1b48c05aa7
4 changed files with 35 additions and 6 deletions

View File

@ -850,7 +850,11 @@ type GetSessionStatusResponse struct {
DelegateShare *DelegateShareInfo `protobuf:"bytes,8,opt,name=delegate_share,json=delegateShare,proto3" json:"delegate_share,omitempty"` DelegateShare *DelegateShareInfo `protobuf:"bytes,8,opt,name=delegate_share,json=delegateShare,proto3" json:"delegate_share,omitempty"`
// participants contains detailed participant information including party_index // participants contains detailed participant information including party_index
// Used by service-party-app for co_managed_keygen sessions // Used by service-party-app for co_managed_keygen sessions
Participants []*ParticipantStatus `protobuf:"bytes,9,rep,name=participants,proto3" json:"participants,omitempty"` Participants []*ParticipantStatus `protobuf:"bytes,9,rep,name=participants,proto3" json:"participants,omitempty"`
// threshold_n and threshold_t - actual threshold values from session config
// Used for co_managed_keygen sessions where total_parties may differ from threshold_n during joining
ThresholdN int32 `protobuf:"varint,10,opt,name=threshold_n,json=thresholdN,proto3" json:"threshold_n,omitempty"` // Total number of parties required (e.g., 3 in 2-of-3)
ThresholdT int32 `protobuf:"varint,11,opt,name=threshold_t,json=thresholdT,proto3" json:"threshold_t,omitempty"` // Minimum parties needed to sign (e.g., 2 in 2-of-3)
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
@ -948,6 +952,20 @@ func (x *GetSessionStatusResponse) GetParticipants() []*ParticipantStatus {
return nil return nil
} }
func (x *GetSessionStatusResponse) GetThresholdN() int32 {
if x != nil {
return x.ThresholdN
}
return 0
}
func (x *GetSessionStatusResponse) GetThresholdT() int32 {
if x != nil {
return x.ThresholdT
}
return 0
}
// ParticipantStatus contains participant status information // ParticipantStatus contains participant status information
type ParticipantStatus struct { type ParticipantStatus struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
@ -1718,7 +1736,7 @@ const file_session_coordinator_proto_rawDesc = "" +
"deviceInfo\"8\n" + "deviceInfo\"8\n" +
"\x17GetSessionStatusRequest\x12\x1d\n" + "\x17GetSessionStatusRequest\x12\x1d\n" +
"\n" + "\n" +
"session_id\x18\x01 \x01(\tR\tsessionId\"\xa0\x03\n" + "session_id\x18\x01 \x01(\tR\tsessionId\"\xe2\x03\n" +
"\x18GetSessionStatusResponse\x12\x16\n" + "\x18GetSessionStatusResponse\x12\x16\n" +
"\x06status\x18\x01 \x01(\tR\x06status\x12+\n" + "\x06status\x18\x01 \x01(\tR\x06status\x12+\n" +
"\x11completed_parties\x18\x02 \x01(\x05R\x10completedParties\x12#\n" + "\x11completed_parties\x18\x02 \x01(\x05R\x10completedParties\x12#\n" +
@ -1729,7 +1747,12 @@ const file_session_coordinator_proto_rawDesc = "" +
"\tsignature\x18\x06 \x01(\fR\tsignature\x12!\n" + "\tsignature\x18\x06 \x01(\fR\tsignature\x12!\n" +
"\fhas_delegate\x18\a \x01(\bR\vhasDelegate\x12L\n" + "\fhas_delegate\x18\a \x01(\bR\vhasDelegate\x12L\n" +
"\x0edelegate_share\x18\b \x01(\v2%.mpc.coordinator.v1.DelegateShareInfoR\rdelegateShare\x12I\n" + "\x0edelegate_share\x18\b \x01(\v2%.mpc.coordinator.v1.DelegateShareInfoR\rdelegateShare\x12I\n" +
"\fparticipants\x18\t \x03(\v2%.mpc.coordinator.v1.ParticipantStatusR\fparticipants\"g\n" + "\fparticipants\x18\t \x03(\v2%.mpc.coordinator.v1.ParticipantStatusR\fparticipants\x12\x1f\n" +
"\vthreshold_n\x18\n" +
" \x01(\x05R\n" +
"thresholdN\x12\x1f\n" +
"\vthreshold_t\x18\v \x01(\x05R\n" +
"thresholdT\"g\n" +
"\x11ParticipantStatus\x12\x19\n" + "\x11ParticipantStatus\x12\x19\n" +
"\bparty_id\x18\x01 \x01(\tR\apartyId\x12\x1f\n" + "\bparty_id\x18\x01 \x01(\tR\apartyId\x12\x1f\n" +
"\vparty_index\x18\x02 \x01(\x05R\n" + "\vparty_index\x18\x02 \x01(\x05R\n" +

View File

@ -135,6 +135,10 @@ message GetSessionStatusResponse {
// participants contains detailed participant information including party_index // participants contains detailed participant information including party_index
// Used by service-party-app for co_managed_keygen sessions // Used by service-party-app for co_managed_keygen sessions
repeated ParticipantStatus participants = 9; repeated ParticipantStatus participants = 9;
// threshold_n and threshold_t - actual threshold values from session config
// Used for co_managed_keygen sessions where total_parties may differ from threshold_n during joining
int32 threshold_n = 10; // Total number of parties required (e.g., 3 in 2-of-3)
int32 threshold_t = 11; // Minimum parties needed to sign (e.g., 2 in 2-of-3)
} }
// ParticipantStatus contains participant status information // ParticipantStatus contains participant status information

View File

@ -694,9 +694,9 @@ func (s *MessageRouterServer) GetSessionStatus(
return &pb.GetSessionStatusResponse{ return &pb.GetSessionStatusResponse{
SessionId: req.SessionId, SessionId: req.SessionId,
Status: coordResp.Status, Status: coordResp.Status,
ThresholdN: coordResp.TotalParties, // Use TotalParties as N ThresholdN: coordResp.ThresholdN, // Actual threshold N from session config
ThresholdT: coordResp.CompletedParties, // Return completed count in ThresholdT for info ThresholdT: coordResp.ThresholdT, // Actual threshold T from session config
Participants: participants, // Include participants for co_managed_keygen Participants: participants, // Include participants for co_managed_keygen
}, nil }, nil
} }

View File

@ -360,6 +360,8 @@ func (s *SessionCoordinatorServer) GetSessionStatus(
Signature: output.Signature, Signature: output.Signature,
HasDelegate: output.HasDelegate, // Only meaningful for keygen sessions HasDelegate: output.HasDelegate, // Only meaningful for keygen sessions
Participants: protoParticipants, // Include participant details with party_index Participants: protoParticipants, // Include participant details with party_index
ThresholdN: int32(output.ThresholdN),
ThresholdT: int32(output.ThresholdT),
} }
// Try to get delegate share from cache // Try to get delegate share from cache