feat: add keygen_session_id to signing session flow
- Add keygen_session_id field to CreateSessionRequest and SessionInfo protobuf - Modify CreateSigningSessionAuto to accept and pass keygenSessionID - Update Account Handler to pass account's keygen_session_id when creating signing session - This enables parties to load the correct keyshare by session ID
This commit is contained in:
parent
7660868a38
commit
382386733d
|
|
@ -26,7 +26,9 @@
|
||||||
"Bash(copy /Y \"api\\proto\\session_coordinator.pb.go\" \"api\\grpc\\coordinator\\v1\"\" && copy /Y \"apiprotosession_coordinator_grpc.pb.go\" \"apigrpccoordinatorv1\"\")",
|
"Bash(copy /Y \"api\\proto\\session_coordinator.pb.go\" \"api\\grpc\\coordinator\\v1\"\" && copy /Y \"apiprotosession_coordinator_grpc.pb.go\" \"apigrpccoordinatorv1\"\")",
|
||||||
"Bash(timeout /t 10 /nobreak)",
|
"Bash(timeout /t 10 /nobreak)",
|
||||||
"Bash(bash scripts/deploy.sh:*)",
|
"Bash(bash scripts/deploy.sh:*)",
|
||||||
"Bash(go run:*)"
|
"Bash(go run:*)",
|
||||||
|
"Bash(timeout /t 5 /nobreak)",
|
||||||
|
"Bash(bash:*)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -30,6 +30,8 @@ message CreateSessionRequest {
|
||||||
PartyComposition party_composition = 7; // Optional: party composition requirements for auto-selection
|
PartyComposition party_composition = 7; // Optional: party composition requirements for auto-selection
|
||||||
// For sign sessions with delegate party: user must provide their encrypted share
|
// For sign sessions with delegate party: user must provide their encrypted share
|
||||||
DelegateUserShare delegate_user_share = 8;
|
DelegateUserShare delegate_user_share = 8;
|
||||||
|
// For sign sessions: which keygen session's shares to use
|
||||||
|
string keygen_session_id = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DelegateUserShare contains user's share for delegate party to use in signing
|
// DelegateUserShare contains user's share for delegate party to use in signing
|
||||||
|
|
@ -93,6 +95,8 @@ message SessionInfo {
|
||||||
int32 threshold_t = 4;
|
int32 threshold_t = 4;
|
||||||
bytes message_hash = 5;
|
bytes message_hash = 5;
|
||||||
string status = 6;
|
string status = 6;
|
||||||
|
// For sign sessions: which keygen session's shares to use
|
||||||
|
string keygen_session_id = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PartyInfo contains party information
|
// PartyInfo contains party information
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,395 @@
|
||||||
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// - protoc-gen-go-grpc v1.6.0
|
||||||
|
// - protoc v6.33.1
|
||||||
|
// source: api/proto/session_coordinator.proto
|
||||||
|
|
||||||
|
package coordinator
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
grpc "google.golang.org/grpc"
|
||||||
|
codes "google.golang.org/grpc/codes"
|
||||||
|
status "google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the grpc package it is being compiled against.
|
||||||
|
// Requires gRPC-Go v1.64.0 or later.
|
||||||
|
const _ = grpc.SupportPackageIsVersion9
|
||||||
|
|
||||||
|
const (
|
||||||
|
SessionCoordinator_CreateSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/CreateSession"
|
||||||
|
SessionCoordinator_JoinSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/JoinSession"
|
||||||
|
SessionCoordinator_GetSessionStatus_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/GetSessionStatus"
|
||||||
|
SessionCoordinator_MarkPartyReady_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/MarkPartyReady"
|
||||||
|
SessionCoordinator_StartSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/StartSession"
|
||||||
|
SessionCoordinator_ReportCompletion_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/ReportCompletion"
|
||||||
|
SessionCoordinator_CloseSession_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/CloseSession"
|
||||||
|
SessionCoordinator_SubmitDelegateShare_FullMethodName = "/mpc.coordinator.v1.SessionCoordinator/SubmitDelegateShare"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SessionCoordinatorClient is the client API for SessionCoordinator service.
|
||||||
|
//
|
||||||
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||||
|
//
|
||||||
|
// SessionCoordinator service manages MPC sessions
|
||||||
|
type SessionCoordinatorClient interface {
|
||||||
|
// Session management
|
||||||
|
CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error)
|
||||||
|
JoinSession(ctx context.Context, in *JoinSessionRequest, opts ...grpc.CallOption) (*JoinSessionResponse, error)
|
||||||
|
GetSessionStatus(ctx context.Context, in *GetSessionStatusRequest, opts ...grpc.CallOption) (*GetSessionStatusResponse, error)
|
||||||
|
MarkPartyReady(ctx context.Context, in *MarkPartyReadyRequest, opts ...grpc.CallOption) (*MarkPartyReadyResponse, error)
|
||||||
|
StartSession(ctx context.Context, in *StartSessionRequest, opts ...grpc.CallOption) (*StartSessionResponse, error)
|
||||||
|
ReportCompletion(ctx context.Context, in *ReportCompletionRequest, opts ...grpc.CallOption) (*ReportCompletionResponse, error)
|
||||||
|
CloseSession(ctx context.Context, in *CloseSessionRequest, opts ...grpc.CallOption) (*CloseSessionResponse, error)
|
||||||
|
// Delegate party share submission (delegate party submits user's share after keygen)
|
||||||
|
SubmitDelegateShare(ctx context.Context, in *SubmitDelegateShareRequest, opts ...grpc.CallOption) (*SubmitDelegateShareResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type sessionCoordinatorClient struct {
|
||||||
|
cc grpc.ClientConnInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSessionCoordinatorClient(cc grpc.ClientConnInterface) SessionCoordinatorClient {
|
||||||
|
return &sessionCoordinatorClient{cc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(CreateSessionResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_CreateSession_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) JoinSession(ctx context.Context, in *JoinSessionRequest, opts ...grpc.CallOption) (*JoinSessionResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(JoinSessionResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_JoinSession_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) GetSessionStatus(ctx context.Context, in *GetSessionStatusRequest, opts ...grpc.CallOption) (*GetSessionStatusResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(GetSessionStatusResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_GetSessionStatus_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) MarkPartyReady(ctx context.Context, in *MarkPartyReadyRequest, opts ...grpc.CallOption) (*MarkPartyReadyResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(MarkPartyReadyResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_MarkPartyReady_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) StartSession(ctx context.Context, in *StartSessionRequest, opts ...grpc.CallOption) (*StartSessionResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(StartSessionResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_StartSession_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) ReportCompletion(ctx context.Context, in *ReportCompletionRequest, opts ...grpc.CallOption) (*ReportCompletionResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(ReportCompletionResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_ReportCompletion_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) CloseSession(ctx context.Context, in *CloseSessionRequest, opts ...grpc.CallOption) (*CloseSessionResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(CloseSessionResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_CloseSession_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *sessionCoordinatorClient) SubmitDelegateShare(ctx context.Context, in *SubmitDelegateShareRequest, opts ...grpc.CallOption) (*SubmitDelegateShareResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(SubmitDelegateShareResponse)
|
||||||
|
err := c.cc.Invoke(ctx, SessionCoordinator_SubmitDelegateShare_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionCoordinatorServer is the server API for SessionCoordinator service.
|
||||||
|
// All implementations must embed UnimplementedSessionCoordinatorServer
|
||||||
|
// for forward compatibility.
|
||||||
|
//
|
||||||
|
// SessionCoordinator service manages MPC sessions
|
||||||
|
type SessionCoordinatorServer interface {
|
||||||
|
// Session management
|
||||||
|
CreateSession(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error)
|
||||||
|
JoinSession(context.Context, *JoinSessionRequest) (*JoinSessionResponse, error)
|
||||||
|
GetSessionStatus(context.Context, *GetSessionStatusRequest) (*GetSessionStatusResponse, error)
|
||||||
|
MarkPartyReady(context.Context, *MarkPartyReadyRequest) (*MarkPartyReadyResponse, error)
|
||||||
|
StartSession(context.Context, *StartSessionRequest) (*StartSessionResponse, error)
|
||||||
|
ReportCompletion(context.Context, *ReportCompletionRequest) (*ReportCompletionResponse, error)
|
||||||
|
CloseSession(context.Context, *CloseSessionRequest) (*CloseSessionResponse, error)
|
||||||
|
// Delegate party share submission (delegate party submits user's share after keygen)
|
||||||
|
SubmitDelegateShare(context.Context, *SubmitDelegateShareRequest) (*SubmitDelegateShareResponse, error)
|
||||||
|
mustEmbedUnimplementedSessionCoordinatorServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnimplementedSessionCoordinatorServer must be embedded to have
|
||||||
|
// forward compatible implementations.
|
||||||
|
//
|
||||||
|
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||||
|
// pointer dereference when methods are called.
|
||||||
|
type UnimplementedSessionCoordinatorServer struct{}
|
||||||
|
|
||||||
|
func (UnimplementedSessionCoordinatorServer) CreateSession(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method CreateSession not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) JoinSession(context.Context, *JoinSessionRequest) (*JoinSessionResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method JoinSession not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) GetSessionStatus(context.Context, *GetSessionStatusRequest) (*GetSessionStatusResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method GetSessionStatus not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) MarkPartyReady(context.Context, *MarkPartyReadyRequest) (*MarkPartyReadyResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method MarkPartyReady not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) StartSession(context.Context, *StartSessionRequest) (*StartSessionResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method StartSession not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) ReportCompletion(context.Context, *ReportCompletionRequest) (*ReportCompletionResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method ReportCompletion not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) CloseSession(context.Context, *CloseSessionRequest) (*CloseSessionResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method CloseSession not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) SubmitDelegateShare(context.Context, *SubmitDelegateShareRequest) (*SubmitDelegateShareResponse, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method SubmitDelegateShare not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) mustEmbedUnimplementedSessionCoordinatorServer() {}
|
||||||
|
func (UnimplementedSessionCoordinatorServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
|
// UnsafeSessionCoordinatorServer may be embedded to opt out of forward compatibility for this service.
|
||||||
|
// Use of this interface is not recommended, as added methods to SessionCoordinatorServer will
|
||||||
|
// result in compilation errors.
|
||||||
|
type UnsafeSessionCoordinatorServer interface {
|
||||||
|
mustEmbedUnimplementedSessionCoordinatorServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterSessionCoordinatorServer(s grpc.ServiceRegistrar, srv SessionCoordinatorServer) {
|
||||||
|
// If the following call panics, it indicates UnimplementedSessionCoordinatorServer was
|
||||||
|
// embedded by pointer and is nil. This will cause panics if an
|
||||||
|
// unimplemented method is ever invoked, so we test this at initialization
|
||||||
|
// time to prevent it from happening at runtime later due to I/O.
|
||||||
|
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||||
|
t.testEmbeddedByValue()
|
||||||
|
}
|
||||||
|
s.RegisterService(&SessionCoordinator_ServiceDesc, srv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_CreateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(CreateSessionRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).CreateSession(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_CreateSession_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).CreateSession(ctx, req.(*CreateSessionRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_JoinSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(JoinSessionRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).JoinSession(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_JoinSession_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).JoinSession(ctx, req.(*JoinSessionRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_GetSessionStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetSessionStatusRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).GetSessionStatus(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_GetSessionStatus_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).GetSessionStatus(ctx, req.(*GetSessionStatusRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_MarkPartyReady_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(MarkPartyReadyRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).MarkPartyReady(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_MarkPartyReady_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).MarkPartyReady(ctx, req.(*MarkPartyReadyRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_StartSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(StartSessionRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).StartSession(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_StartSession_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).StartSession(ctx, req.(*StartSessionRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_ReportCompletion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(ReportCompletionRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).ReportCompletion(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_ReportCompletion_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).ReportCompletion(ctx, req.(*ReportCompletionRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_CloseSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(CloseSessionRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).CloseSession(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_CloseSession_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).CloseSession(ctx, req.(*CloseSessionRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _SessionCoordinator_SubmitDelegateShare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(SubmitDelegateShareRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(SessionCoordinatorServer).SubmitDelegateShare(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: SessionCoordinator_SubmitDelegateShare_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(SessionCoordinatorServer).SubmitDelegateShare(ctx, req.(*SubmitDelegateShareRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionCoordinator_ServiceDesc is the grpc.ServiceDesc for SessionCoordinator service.
|
||||||
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
|
// and not to be introspected or modified (even as a copy)
|
||||||
|
var SessionCoordinator_ServiceDesc = grpc.ServiceDesc{
|
||||||
|
ServiceName: "mpc.coordinator.v1.SessionCoordinator",
|
||||||
|
HandlerType: (*SessionCoordinatorServer)(nil),
|
||||||
|
Methods: []grpc.MethodDesc{
|
||||||
|
{
|
||||||
|
MethodName: "CreateSession",
|
||||||
|
Handler: _SessionCoordinator_CreateSession_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "JoinSession",
|
||||||
|
Handler: _SessionCoordinator_JoinSession_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetSessionStatus",
|
||||||
|
Handler: _SessionCoordinator_GetSessionStatus_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "MarkPartyReady",
|
||||||
|
Handler: _SessionCoordinator_MarkPartyReady_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "StartSession",
|
||||||
|
Handler: _SessionCoordinator_StartSession_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "ReportCompletion",
|
||||||
|
Handler: _SessionCoordinator_ReportCompletion_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "CloseSession",
|
||||||
|
Handler: _SessionCoordinator_CloseSession_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "SubmitDelegateShare",
|
||||||
|
Handler: _SessionCoordinator_SubmitDelegateShare_Handler,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Streams: []grpc.StreamDesc{},
|
||||||
|
Metadata: "api/proto/session_coordinator.proto",
|
||||||
|
}
|
||||||
|
|
@ -824,6 +824,7 @@ func (h *AccountHTTPHandler) CreateSigningSession(c *gin.Context) {
|
||||||
messageHash,
|
messageHash,
|
||||||
600, // 10 minutes expiry
|
600, // 10 minutes expiry
|
||||||
delegateUserShare,
|
delegateUserShare,
|
||||||
|
accountOutput.Account.KeygenSessionID.String(),
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ func (c *SessionCoordinatorClient) CreateSigningSessionAuto(
|
||||||
messageHash []byte,
|
messageHash []byte,
|
||||||
expiresInSeconds int64,
|
expiresInSeconds int64,
|
||||||
delegateUserShare *DelegateUserShareInput,
|
delegateUserShare *DelegateUserShareInput,
|
||||||
|
keygenSessionID string,
|
||||||
) (*CreateSessionAutoResponse, error) {
|
) (*CreateSessionAutoResponse, error) {
|
||||||
// Convert party IDs to participant info (minimal info, coordinator will fill in details)
|
// Convert party IDs to participant info (minimal info, coordinator will fill in details)
|
||||||
pbParticipants := make([]*coordinatorpb.ParticipantInfo, len(partyIDs))
|
pbParticipants := make([]*coordinatorpb.ParticipantInfo, len(partyIDs))
|
||||||
|
|
@ -154,6 +155,7 @@ func (c *SessionCoordinatorClient) CreateSigningSessionAuto(
|
||||||
Participants: pbParticipants,
|
Participants: pbParticipants,
|
||||||
MessageHash: messageHash,
|
MessageHash: messageHash,
|
||||||
ExpiresInSeconds: expiresInSeconds,
|
ExpiresInSeconds: expiresInSeconds,
|
||||||
|
KeygenSessionId: keygenSessionID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add delegate user share if provided
|
// Add delegate user share if provided
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,13 @@ type MessageRouterClient interface {
|
||||||
|
|
||||||
// SessionInfo contains session information from coordinator
|
// SessionInfo contains session information from coordinator
|
||||||
type SessionInfo struct {
|
type SessionInfo struct {
|
||||||
SessionID uuid.UUID
|
SessionID uuid.UUID
|
||||||
SessionType string
|
SessionType string
|
||||||
ThresholdN int
|
ThresholdN int
|
||||||
ThresholdT int
|
ThresholdT int
|
||||||
MessageHash []byte
|
MessageHash []byte
|
||||||
Participants []ParticipantInfo
|
KeygenSessionID uuid.UUID // For signing sessions: which keygen session's share to use
|
||||||
|
Participants []ParticipantInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParticipantInfo contains participant information
|
// ParticipantInfo contains participant information
|
||||||
|
|
|
||||||
|
|
@ -96,14 +96,34 @@ func (uc *ParticipateSigningUseCase) Execute(
|
||||||
zap.String("session_id", input.SessionID.String()))
|
zap.String("session_id", input.SessionID.String()))
|
||||||
} else {
|
} else {
|
||||||
// Persistent party: load from database
|
// Persistent party: load from database
|
||||||
keyShares, err := uc.keyShareRepo.ListByParty(ctx, input.PartyID)
|
// If KeygenSessionID is provided, use it to load the specific share
|
||||||
if err != nil || len(keyShares) == 0 {
|
// Otherwise, use the most recent share (fallback for backward compatibility)
|
||||||
return nil, ErrKeyShareNotFound
|
if sessionInfo.KeygenSessionID != uuid.Nil {
|
||||||
|
// Load the specific share for this keygen session
|
||||||
|
keyShareForUpdate, err = uc.keyShareRepo.FindBySessionAndParty(ctx, sessionInfo.KeygenSessionID, input.PartyID)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to find keyshare for keygen session",
|
||||||
|
zap.String("party_id", input.PartyID),
|
||||||
|
zap.String("keygen_session_id", sessionInfo.KeygenSessionID.String()),
|
||||||
|
zap.Error(err))
|
||||||
|
return nil, ErrKeyShareNotFound
|
||||||
|
}
|
||||||
|
logger.Info("Using specific keyshare by keygen_session_id",
|
||||||
|
zap.String("party_id", input.PartyID),
|
||||||
|
zap.String("keygen_session_id", sessionInfo.KeygenSessionID.String()))
|
||||||
|
} else {
|
||||||
|
// Fallback: use the most recent key share
|
||||||
|
// TODO: This should be removed once all signing sessions provide keygen_session_id
|
||||||
|
keyShares, err := uc.keyShareRepo.ListByParty(ctx, input.PartyID)
|
||||||
|
if err != nil || len(keyShares) == 0 {
|
||||||
|
return nil, ErrKeyShareNotFound
|
||||||
|
}
|
||||||
|
keyShareForUpdate = keyShares[len(keyShares)-1]
|
||||||
|
logger.Warn("Using most recent keyshare (keygen_session_id not provided)",
|
||||||
|
zap.String("party_id", input.PartyID),
|
||||||
|
zap.String("fallback_session_id", keyShareForUpdate.SessionID.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the most recent key share (in production, would match by public key or session reference)
|
|
||||||
keyShareForUpdate = keyShares[len(keyShares)-1]
|
|
||||||
|
|
||||||
// Get original threshold_n from keygen
|
// Get original threshold_n from keygen
|
||||||
originalThresholdN = keyShareForUpdate.ThresholdN
|
originalThresholdN = keyShareForUpdate.ThresholdN
|
||||||
|
|
||||||
|
|
@ -115,6 +135,7 @@ func (uc *ParticipateSigningUseCase) Execute(
|
||||||
logger.Info("Using database share (persistent party)",
|
logger.Info("Using database share (persistent party)",
|
||||||
zap.String("party_id", input.PartyID),
|
zap.String("party_id", input.PartyID),
|
||||||
zap.String("session_id", input.SessionID.String()),
|
zap.String("session_id", input.SessionID.String()),
|
||||||
|
zap.String("keygen_session_id", keyShareForUpdate.SessionID.String()),
|
||||||
zap.Int("original_threshold_n", originalThresholdN),
|
zap.Int("original_threshold_n", originalThresholdN),
|
||||||
zap.Int("threshold_t", keyShareForUpdate.ThresholdT))
|
zap.Int("threshold_t", keyShareForUpdate.ThresholdT))
|
||||||
}
|
}
|
||||||
|
|
@ -276,19 +297,35 @@ func (h *signingMessageHandler) ReceiveMessages() <-chan *tss.ReceivedMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *signingMessageHandler) convertMessages(ctx context.Context, inChan <-chan *MPCMessage) {
|
func (h *signingMessageHandler) convertMessages(ctx context.Context, inChan <-chan *MPCMessage) {
|
||||||
|
logger.Debug("convertMessages started, waiting for messages",
|
||||||
|
zap.String("session_id", h.sessionID.String()),
|
||||||
|
zap.String("party_id", h.partyID))
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
logger.Debug("convertMessages context cancelled", zap.String("session_id", h.sessionID.String()))
|
||||||
close(h.msgChan)
|
close(h.msgChan)
|
||||||
return
|
return
|
||||||
case msg, ok := <-inChan:
|
case msg, ok := <-inChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
|
logger.Debug("convertMessages inChan closed", zap.String("session_id", h.sessionID.String()))
|
||||||
close(h.msgChan)
|
close(h.msgChan)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Debug("Received MPC message for conversion",
|
||||||
|
zap.String("session_id", h.sessionID.String()),
|
||||||
|
zap.String("from_party", msg.FromParty),
|
||||||
|
zap.Bool("is_broadcast", msg.IsBroadcast),
|
||||||
|
zap.Int("payload_size", len(msg.Payload)))
|
||||||
|
|
||||||
fromIndex, exists := h.partyIndexMap[msg.FromParty]
|
fromIndex, exists := h.partyIndexMap[msg.FromParty]
|
||||||
if !exists {
|
if !exists {
|
||||||
|
logger.Warn("Message from unknown party - dropping",
|
||||||
|
zap.String("session_id", h.sessionID.String()),
|
||||||
|
zap.String("from_party", msg.FromParty),
|
||||||
|
zap.Any("known_parties", h.partyIndexMap))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,8 +335,15 @@ func (h *signingMessageHandler) convertMessages(ctx context.Context, inChan <-ch
|
||||||
MsgBytes: msg.Payload,
|
MsgBytes: msg.Payload,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Debug("Converted message, sending to TSS",
|
||||||
|
zap.String("session_id", h.sessionID.String()),
|
||||||
|
zap.String("from_party", msg.FromParty),
|
||||||
|
zap.Int("from_index", fromIndex))
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case h.msgChan <- tssMsg:
|
case h.msgChan <- tssMsg:
|
||||||
|
logger.Debug("Message sent to TSS successfully",
|
||||||
|
zap.String("session_id", h.sessionID.String()))
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,13 @@ func main() {
|
||||||
|
|
||||||
fmt.Printf("Generated JWT token: %s\n\n", token)
|
fmt.Printf("Generated JWT token: %s\n\n", token)
|
||||||
|
|
||||||
// Create keygen session via account-service
|
// Create keygen session via account-service (without delegate)
|
||||||
|
// For true 2-of-3: threshold_t=1 means t+1=2 signers required out of 3 total
|
||||||
sessionData := map[string]interface{}{
|
sessionData := map[string]interface{}{
|
||||||
"threshold_n": 3,
|
"threshold_n": 3,
|
||||||
"threshold_t": 2,
|
"threshold_t": 1,
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
"require_delegate": true,
|
"require_delegate": false,
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonData, err := json.Marshal(sessionData)
|
jsonData, err := json.Marshal(sessionData)
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,9 @@ func main() {
|
||||||
fmt.Printf("Message Hash (SHA-256): %s\n\n", messageHashHex)
|
fmt.Printf("Message Hash (SHA-256): %s\n\n", messageHashHex)
|
||||||
|
|
||||||
// Create signing session via account-service
|
// Create signing session via account-service
|
||||||
|
// This account has threshold_t=1, so should only need 2 parties (t+1=2)
|
||||||
signingData := map[string]interface{}{
|
signingData := map[string]interface{}{
|
||||||
"username": "admin",
|
"username": "wallet-76e34337",
|
||||||
"message_hash": messageHashHex,
|
"message_hash": messageHashHex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue