Commit 438c6a5f authored by Loïck Bonniot's avatar Loïck Bonniot

[p] Add common package and update gRPC api

- common package now contains a waitingGroup, a useful struct to deal
  with synchronization
- updated version of gRPC api should be more efficient for signature
  initialization (untested)
parent 5966dad3
...@@ -31,6 +31,7 @@ Unit tests: ...@@ -31,6 +31,7 @@ Unit tests:
- "go test -coverprofile dfssp_user.part -v dfss/dfssp/user" - "go test -coverprofile dfssp_user.part -v dfss/dfssp/user"
- "go test -coverprofile dfssp_contract.part -v dfss/dfssp/contract" - "go test -coverprofile dfssp_contract.part -v dfss/dfssp/contract"
- "go test -coverprofile dfssp_templates.part -v dfss/dfssp/templates" - "go test -coverprofile dfssp_templates.part -v dfss/dfssp/templates"
- "go test -coverprofile dfssp_common.part -v dfss/dfssp/common"
- "go test -coverprofile dfssd.part -v dfss/dfssd" - "go test -coverprofile dfssd.part -v dfss/dfssd"
- "go test -coverprofile dfssc_common.part -v dfss/dfssc/common" - "go test -coverprofile dfssc_common.part -v dfss/dfssc/common"
- "go test -coverprofile dfssc_security.part -v dfss/dfssc/security" - "go test -coverprofile dfssc_security.part -v dfss/dfssc/security"
......
...@@ -16,7 +16,9 @@ It has these top-level messages: ...@@ -16,7 +16,9 @@ It has these top-level messages:
Empty Empty
PostContractRequest PostContractRequest
JoinSignatureRequest JoinSignatureRequest
UserConnected
ReadySignRequest ReadySignRequest
LaunchSignature
*/ */
package api package api
...@@ -155,6 +157,36 @@ func (m *JoinSignatureRequest) String() string { return proto.Compact ...@@ -155,6 +157,36 @@ func (m *JoinSignatureRequest) String() string { return proto.Compact
func (*JoinSignatureRequest) ProtoMessage() {} func (*JoinSignatureRequest) ProtoMessage() {}
func (*JoinSignatureRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } func (*JoinSignatureRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
// UserConnected is emitted by the platform to the client to announce a new client connection
type UserConnected struct {
ErrorCode *ErrorCode `protobuf:"bytes,1,opt,name=errorCode" json:"errorCode,omitempty"`
ContractUuid string `protobuf:"bytes,2,opt,name=contractUuid" json:"contractUuid,omitempty"`
}
func (m *UserConnected) Reset() { *m = UserConnected{} }
func (m *UserConnected) String() string { return proto.CompactTextString(m) }
func (*UserConnected) ProtoMessage() {}
func (*UserConnected) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *UserConnected) GetErrorCode() *ErrorCode {
if m != nil {
return m.ErrorCode
}
return nil
}
type UserConnected_User struct {
KeyHash []byte `protobuf:"bytes,1,opt,name=KeyHash,proto3" json:"KeyHash,omitempty"`
Email string `protobuf:"bytes,2,opt,name=email" json:"email,omitempty"`
Ip string `protobuf:"bytes,3,opt,name=ip" json:"ip,omitempty"`
Port uint32 `protobuf:"varint,4,opt,name=port" json:"port,omitempty"`
}
func (m *UserConnected_User) Reset() { *m = UserConnected_User{} }
func (m *UserConnected_User) String() string { return proto.CompactTextString(m) }
func (*UserConnected_User) ProtoMessage() {}
func (*UserConnected_User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7, 0} }
// ReadySignRequest contains the contract unique identitier that is ready to be signed // ReadySignRequest contains the contract unique identitier that is ready to be signed
type ReadySignRequest struct { type ReadySignRequest struct {
ContractUuid string `protobuf:"bytes,1,opt,name=contractUuid" json:"contractUuid,omitempty"` ContractUuid string `protobuf:"bytes,1,opt,name=contractUuid" json:"contractUuid,omitempty"`
...@@ -163,7 +195,26 @@ type ReadySignRequest struct { ...@@ -163,7 +195,26 @@ type ReadySignRequest struct {
func (m *ReadySignRequest) Reset() { *m = ReadySignRequest{} } func (m *ReadySignRequest) Reset() { *m = ReadySignRequest{} }
func (m *ReadySignRequest) String() string { return proto.CompactTextString(m) } func (m *ReadySignRequest) String() string { return proto.CompactTextString(m) }
func (*ReadySignRequest) ProtoMessage() {} func (*ReadySignRequest) ProtoMessage() {}
func (*ReadySignRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (*ReadySignRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
// LaunchSignature is emitted by the platform when every signers are ready
type LaunchSignature struct {
ErrorCode *ErrorCode `protobuf:"bytes,1,opt,name=errorCode" json:"errorCode,omitempty"`
SignatureUuid string `protobuf:"bytes,2,opt,name=signatureUuid" json:"signatureUuid,omitempty"`
KeyHash []string `protobuf:"bytes,3,rep,name=keyHash" json:"keyHash,omitempty"`
}
func (m *LaunchSignature) Reset() { *m = LaunchSignature{} }
func (m *LaunchSignature) String() string { return proto.CompactTextString(m) }
func (*LaunchSignature) ProtoMessage() {}
func (*LaunchSignature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (m *LaunchSignature) GetErrorCode() *ErrorCode {
if m != nil {
return m.ErrorCode
}
return nil
}
func init() { func init() {
proto.RegisterType((*RegisterRequest)(nil), "api.RegisterRequest") proto.RegisterType((*RegisterRequest)(nil), "api.RegisterRequest")
...@@ -173,7 +224,10 @@ func init() { ...@@ -173,7 +224,10 @@ func init() {
proto.RegisterType((*Empty)(nil), "api.Empty") proto.RegisterType((*Empty)(nil), "api.Empty")
proto.RegisterType((*PostContractRequest)(nil), "api.PostContractRequest") proto.RegisterType((*PostContractRequest)(nil), "api.PostContractRequest")
proto.RegisterType((*JoinSignatureRequest)(nil), "api.JoinSignatureRequest") proto.RegisterType((*JoinSignatureRequest)(nil), "api.JoinSignatureRequest")
proto.RegisterType((*UserConnected)(nil), "api.UserConnected")
proto.RegisterType((*UserConnected_User)(nil), "api.UserConnected.User")
proto.RegisterType((*ReadySignRequest)(nil), "api.ReadySignRequest") proto.RegisterType((*ReadySignRequest)(nil), "api.ReadySignRequest")
proto.RegisterType((*LaunchSignature)(nil), "api.LaunchSignature")
proto.RegisterEnum("api.ErrorCode_Code", ErrorCode_Code_name, ErrorCode_Code_value) proto.RegisterEnum("api.ErrorCode_Code", ErrorCode_Code_name, ErrorCode_Code_value)
} }
...@@ -188,8 +242,8 @@ type PlatformClient interface { ...@@ -188,8 +242,8 @@ type PlatformClient interface {
Auth(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*RegisteredUser, error) Auth(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*RegisteredUser, error)
Unregister(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ErrorCode, error) Unregister(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ErrorCode, error)
PostContract(ctx context.Context, in *PostContractRequest, opts ...grpc.CallOption) (*ErrorCode, error) PostContract(ctx context.Context, in *PostContractRequest, opts ...grpc.CallOption) (*ErrorCode, error)
JoinSignature(ctx context.Context, in *JoinSignatureRequest, opts ...grpc.CallOption) (*ErrorCode, error) JoinSignature(ctx context.Context, in *JoinSignatureRequest, opts ...grpc.CallOption) (Platform_JoinSignatureClient, error)
ReadySign(ctx context.Context, in *ReadySignRequest, opts ...grpc.CallOption) (*ErrorCode, error) ReadySign(ctx context.Context, in *ReadySignRequest, opts ...grpc.CallOption) (*LaunchSignature, error)
} }
type platformClient struct { type platformClient struct {
...@@ -236,17 +290,40 @@ func (c *platformClient) PostContract(ctx context.Context, in *PostContractReque ...@@ -236,17 +290,40 @@ func (c *platformClient) PostContract(ctx context.Context, in *PostContractReque
return out, nil return out, nil
} }
func (c *platformClient) JoinSignature(ctx context.Context, in *JoinSignatureRequest, opts ...grpc.CallOption) (*ErrorCode, error) { func (c *platformClient) JoinSignature(ctx context.Context, in *JoinSignatureRequest, opts ...grpc.CallOption) (Platform_JoinSignatureClient, error) {
out := new(ErrorCode) stream, err := grpc.NewClientStream(ctx, &_Platform_serviceDesc.Streams[0], c.cc, "/api.Platform/JoinSignature", opts...)
err := grpc.Invoke(ctx, "/api.Platform/JoinSignature", in, out, c.cc, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil x := &platformJoinSignatureClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
} }
func (c *platformClient) ReadySign(ctx context.Context, in *ReadySignRequest, opts ...grpc.CallOption) (*ErrorCode, error) { type Platform_JoinSignatureClient interface {
out := new(ErrorCode) Recv() (*UserConnected, error)
grpc.ClientStream
}
type platformJoinSignatureClient struct {
grpc.ClientStream
}
func (x *platformJoinSignatureClient) Recv() (*UserConnected, error) {
m := new(UserConnected)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *platformClient) ReadySign(ctx context.Context, in *ReadySignRequest, opts ...grpc.CallOption) (*LaunchSignature, error) {
out := new(LaunchSignature)
err := grpc.Invoke(ctx, "/api.Platform/ReadySign", in, out, c.cc, opts...) err := grpc.Invoke(ctx, "/api.Platform/ReadySign", in, out, c.cc, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -261,8 +338,8 @@ type PlatformServer interface { ...@@ -261,8 +338,8 @@ type PlatformServer interface {
Auth(context.Context, *AuthRequest) (*RegisteredUser, error) Auth(context.Context, *AuthRequest) (*RegisteredUser, error)
Unregister(context.Context, *Empty) (*ErrorCode, error) Unregister(context.Context, *Empty) (*ErrorCode, error)
PostContract(context.Context, *PostContractRequest) (*ErrorCode, error) PostContract(context.Context, *PostContractRequest) (*ErrorCode, error)
JoinSignature(context.Context, *JoinSignatureRequest) (*ErrorCode, error) JoinSignature(*JoinSignatureRequest, Platform_JoinSignatureServer) error
ReadySign(context.Context, *ReadySignRequest) (*ErrorCode, error) ReadySign(context.Context, *ReadySignRequest) (*LaunchSignature, error)
} }
func RegisterPlatformServer(s *grpc.Server, srv PlatformServer) { func RegisterPlatformServer(s *grpc.Server, srv PlatformServer) {
...@@ -317,16 +394,25 @@ func _Platform_PostContract_Handler(srv interface{}, ctx context.Context, dec fu ...@@ -317,16 +394,25 @@ func _Platform_PostContract_Handler(srv interface{}, ctx context.Context, dec fu
return out, nil return out, nil
} }
func _Platform_JoinSignature_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { func _Platform_JoinSignature_Handler(srv interface{}, stream grpc.ServerStream) error {
in := new(JoinSignatureRequest) m := new(JoinSignatureRequest)
if err := dec(in); err != nil { if err := stream.RecvMsg(m); err != nil {
return nil, err return err
}
out, err := srv.(PlatformServer).JoinSignature(ctx, in)
if err != nil {
return nil, err
} }
return out, nil return srv.(PlatformServer).JoinSignature(m, &platformJoinSignatureServer{stream})
}
type Platform_JoinSignatureServer interface {
Send(*UserConnected) error
grpc.ServerStream
}
type platformJoinSignatureServer struct {
grpc.ServerStream
}
func (x *platformJoinSignatureServer) Send(m *UserConnected) error {
return x.ServerStream.SendMsg(m)
} }
func _Platform_ReadySign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { func _Platform_ReadySign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
...@@ -361,49 +447,58 @@ var _Platform_serviceDesc = grpc.ServiceDesc{ ...@@ -361,49 +447,58 @@ var _Platform_serviceDesc = grpc.ServiceDesc{
MethodName: "PostContract", MethodName: "PostContract",
Handler: _Platform_PostContract_Handler, Handler: _Platform_PostContract_Handler,
}, },
{
MethodName: "JoinSignature",
Handler: _Platform_JoinSignature_Handler,
},
{ {
MethodName: "ReadySign", MethodName: "ReadySign",
Handler: _Platform_ReadySign_Handler, Handler: _Platform_ReadySign_Handler,
}, },
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{
{
StreamName: "JoinSignature",
Handler: _Platform_JoinSignature_Handler,
ServerStreams: true,
},
},
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 490 bytes of a gzipped FileDescriptorProto // 605 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x53, 0x5d, 0x8f, 0xd2, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x54, 0x6f, 0x6f, 0xd2, 0x40,
0x14, 0xdd, 0x42, 0x97, 0x8f, 0xbb, 0x2c, 0x36, 0x03, 0x9a, 0xca, 0x83, 0xd9, 0xcc, 0x8b, 0xc6, 0x18, 0xa7, 0xa5, 0x1b, 0xe3, 0xd9, 0x60, 0xcd, 0x31, 0x4d, 0xed, 0x0b, 0xb3, 0x5c, 0x4c, 0x34,
0x07, 0x34, 0x68, 0x4c, 0x34, 0xbe, 0xd4, 0x4a, 0xd6, 0xf5, 0x81, 0x90, 0xe9, 0x56, 0x9f, 0x6b, 0xc6, 0xe0, 0x82, 0x89, 0x89, 0xbe, 0xeb, 0x2a, 0xd9, 0xa6, 0x86, 0x90, 0x63, 0x68, 0xe2, 0xbb,
0xb9, 0x0b, 0x8d, 0xb4, 0x83, 0xd3, 0x41, 0xb3, 0x7f, 0xc6, 0x3f, 0xe4, 0x8f, 0xd2, 0xce, 0xb4, 0x5a, 0x6e, 0xd0, 0x8c, 0xb6, 0x78, 0x3d, 0x34, 0xbc, 0xf2, 0x9b, 0xf8, 0x4d, 0xfc, 0x1c, 0x7e,
0x43, 0xa8, 0x36, 0x26, 0xcb, 0x03, 0xcc, 0xb9, 0x1f, 0xe7, 0xde, 0x39, 0x67, 0x00, 0xb2, 0x66, 0x1c, 0xbd, 0xbb, 0xf6, 0xa0, 0x65, 0xc4, 0x64, 0xbc, 0x80, 0xfe, 0x9e, 0xff, 0xcf, 0xef, 0xf9,
0x4b, 0x3f, 0x40, 0xf1, 0x3d, 0x89, 0x31, 0x9f, 0xee, 0x04, 0x97, 0x9c, 0xb4, 0xa3, 0x5d, 0x42, 0x15, 0x40, 0x53, 0x32, 0xf4, 0x47, 0x94, 0x7d, 0x8f, 0x42, 0x9a, 0x75, 0x17, 0x2c, 0xe5, 0x29,
0x3d, 0xb8, 0xc7, 0x70, 0x9d, 0xe4, 0x12, 0x05, 0xc3, 0x6f, 0x7b, 0xcc, 0x25, 0x19, 0xc3, 0x29, 0xaa, 0x07, 0x8b, 0x08, 0x7b, 0x70, 0x4c, 0xe8, 0x34, 0xca, 0x38, 0x65, 0x84, 0x7e, 0x5b, 0xd2,
0xa6, 0x51, 0xb2, 0x75, 0xad, 0x0b, 0xeb, 0x49, 0x9f, 0x95, 0x80, 0xb8, 0xd0, 0x15, 0x65, 0x81, 0x8c, 0xa3, 0x13, 0xd8, 0xa3, 0x71, 0x10, 0xcd, 0x1d, 0xe3, 0xd4, 0x78, 0xd6, 0x24, 0x39, 0x40,
0xdb, 0xd2, 0x71, 0x03, 0xe9, 0x4f, 0x0b, 0xfa, 0x73, 0x21, 0xb8, 0xf0, 0xf9, 0x0a, 0xc9, 0x63, 0x0e, 0x34, 0x58, 0x1e, 0xe0, 0x98, 0xca, 0xae, 0x21, 0xfe, 0x65, 0x40, 0xb3, 0xcf, 0x58, 0xca,
0xb0, 0xe3, 0xe2, 0x57, 0x37, 0x0f, 0x67, 0xa3, 0x69, 0x31, 0x64, 0x7a, 0xc8, 0x4e, 0xd5, 0x17, 0xfc, 0x74, 0x42, 0xd1, 0x53, 0xb0, 0x42, 0xf1, 0xab, 0x92, 0xdb, 0xbd, 0x4e, 0x57, 0x34, 0xe9,
0xd3, 0x05, 0x8a, 0x30, 0xc5, 0x3c, 0x8f, 0xd6, 0x68, 0x08, 0x2b, 0x48, 0x17, 0x60, 0x6b, 0xaa, 0xae, 0xbd, 0x5d, 0xf9, 0x45, 0x54, 0x80, 0x2c, 0x18, 0xd3, 0x2c, 0x0b, 0xa6, 0x54, 0x17, 0x2c,
0x33, 0xe8, 0x06, 0xa1, 0xef, 0xcf, 0x83, 0xc0, 0x39, 0x21, 0x00, 0x9d, 0xab, 0xc5, 0x27, 0x8f, 0x20, 0x1e, 0x80, 0xa5, 0x4a, 0x1d, 0x42, 0x63, 0x34, 0xf6, 0xfd, 0xfe, 0x68, 0x64, 0xd7, 0x10,
0x5d, 0x3a, 0x96, 0x4a, 0xbc, 0xf3, 0xde, 0x7b, 0xe1, 0xf5, 0x07, 0xa7, 0xa5, 0xc0, 0x67, 0x8f, 0xc0, 0xfe, 0xd5, 0xe0, 0x93, 0x47, 0x2e, 0x6c, 0x43, 0x3a, 0xce, 0xbd, 0x77, 0xde, 0xf8, 0xfa,
0x2d, 0xae, 0x16, 0x97, 0x4e, 0x9b, 0x8c, 0x54, 0xd5, 0xf5, 0x9c, 0x31, 0xe7, 0xb7, 0xf9, 0x58, 0xd2, 0x36, 0x25, 0xf8, 0xec, 0x91, 0xc1, 0xd5, 0xe0, 0xc2, 0xae, 0xa3, 0x8e, 0x8c, 0xba, 0xee,
0xf4, 0x35, 0x9c, 0x79, 0x7b, 0xb9, 0xf9, 0xff, 0xfd, 0x8a, 0xa8, 0xe4, 0x5f, 0x31, 0xab, 0x96, 0x13, 0x62, 0xff, 0xd5, 0x1f, 0x03, 0xbf, 0x81, 0x43, 0x6f, 0xc9, 0x67, 0xff, 0xdf, 0x4f, 0x58,
0x29, 0x01, 0x7d, 0x0e, 0x43, 0x23, 0x0f, 0xae, 0xc2, 0x1c, 0x05, 0x79, 0x04, 0x10, 0x6f, 0x13, 0x79, 0x7a, 0x4b, 0x93, 0x62, 0x98, 0x1c, 0xe0, 0x33, 0x68, 0x6b, 0x7a, 0xe8, 0x64, 0x9c, 0x51,
0xcc, 0xa4, 0x8f, 0x42, 0x56, 0x14, 0x47, 0x11, 0xda, 0x85, 0xd3, 0x79, 0xba, 0x93, 0xb7, 0xf4, 0x86, 0x1e, 0x03, 0x84, 0xf3, 0x88, 0x26, 0xdc, 0xa7, 0x8c, 0x17, 0x25, 0x4a, 0x16, 0xdc, 0x80,
0x07, 0x8c, 0x96, 0x3c, 0x97, 0x3e, 0xcf, 0xa4, 0x88, 0x62, 0x69, 0xa6, 0x13, 0xb0, 0x37, 0x51, 0xbd, 0x7e, 0xbc, 0xe0, 0x2b, 0xfc, 0x03, 0x3a, 0xc3, 0x34, 0xe3, 0x7e, 0x9a, 0x70, 0x16, 0x84,
0xbe, 0xd1, 0x9d, 0x03, 0xa6, 0xcf, 0x64, 0x02, 0xbd, 0x9b, 0x64, 0x8b, 0x59, 0x94, 0x1a, 0x2d, 0x5c, 0x77, 0x47, 0x60, 0xcd, 0x82, 0x6c, 0xa6, 0x32, 0x8f, 0x88, 0x7a, 0x46, 0x2e, 0x1c, 0xdc,
0x0e, 0x98, 0x3c, 0x80, 0x4e, 0x9e, 0xac, 0x33, 0x14, 0x6e, 0xfb, 0xa2, 0x5d, 0x64, 0x2a, 0xa4, 0x44, 0x73, 0x9a, 0x04, 0xb1, 0xe6, 0x62, 0x8d, 0xd1, 0x43, 0xd8, 0xcf, 0xa2, 0x69, 0x42, 0x99,
0xe4, 0x8b, 0x79, 0x9a, 0x16, 0x63, 0x5d, 0xbb, 0x94, 0xaf, 0x82, 0x85, 0x7c, 0xe3, 0x8f, 0x3c, 0x53, 0x3f, 0xad, 0x0b, 0x4f, 0x81, 0x24, 0x7d, 0x61, 0x1a, 0xc7, 0xa2, 0xad, 0x63, 0xe5, 0xf4,
0xc9, 0x82, 0xa2, 0x2e, 0x92, 0x7b, 0x81, 0x66, 0x32, 0x85, 0x41, 0x5c, 0x2d, 0x13, 0xee, 0x93, 0x15, 0x50, 0xd0, 0x77, 0xf2, 0x3e, 0x8d, 0x92, 0x91, 0x88, 0x0b, 0xf8, 0x92, 0x51, 0xdd, 0x19,
0x55, 0xb5, 0x7b, 0x2d, 0xa6, 0xb6, 0xdb, 0x71, 0x51, 0x5a, 0x7c, 0xce, 0xf4, 0x99, 0xbe, 0x02, 0xc3, 0x51, 0x58, 0x0c, 0x33, 0x5e, 0x46, 0x93, 0x62, 0xf6, 0x8a, 0x4d, 0x4e, 0xb7, 0x48, 0x59,
0x87, 0x61, 0xb4, 0xba, 0x55, 0x84, 0x77, 0xe0, 0x9a, 0xfd, 0x6a, 0x41, 0x6f, 0xb9, 0x8d, 0xe4, 0x7e, 0xe2, 0x16, 0x51, 0xcf, 0xf8, 0xb7, 0x01, 0x2d, 0xb9, 0xba, 0xd8, 0x24, 0xa1, 0x21, 0xa7,
0x0d, 0x17, 0x29, 0x99, 0x41, 0xcf, 0x08, 0x49, 0xc6, 0xfa, 0x51, 0xfc, 0xf5, 0xec, 0x26, 0xc3, 0x13, 0xf4, 0x02, 0x9a, 0x54, 0x9f, 0x54, 0x95, 0x39, 0xec, 0xb5, 0xab, 0x87, 0x26, 0x9b, 0x80,
0xfa, 0x53, 0xa1, 0x27, 0xe4, 0x19, 0xd8, 0xca, 0x37, 0xe2, 0xe8, 0xcc, 0x91, 0x85, 0x93, 0x51, 0x3b, 0x7d, 0xcd, 0xbb, 0x7d, 0xdd, 0x2f, 0x60, 0x29, 0x76, 0xc5, 0x56, 0x1f, 0xe8, 0xea, 0x72,
0x8d, 0xa1, 0x74, 0xa6, 0x68, 0x78, 0x0a, 0x10, 0x66, 0xc2, 0x8c, 0x81, 0x92, 0x50, 0x99, 0xd1, 0x43, 0x50, 0xe3, 0x36, 0x87, 0x9b, 0xab, 0x99, 0xe5, 0xab, 0xb5, 0xc1, 0x8c, 0x16, 0x82, 0x19,
0x40, 0xfe, 0x06, 0x06, 0xc7, 0xf6, 0x10, 0x57, 0x57, 0x34, 0x38, 0xd6, 0xd0, 0xfb, 0x16, 0xce, 0x69, 0x12, 0x4f, 0xeb, 0xf9, 0xad, 0xd2, 0xfc, 0xaf, 0xc1, 0x26, 0x34, 0x98, 0xac, 0x24, 0x21,
0x6b, 0x0a, 0x93, 0x87, 0xba, 0xa4, 0x49, 0xf5, 0x86, 0xee, 0x97, 0xd0, 0x3f, 0xe8, 0x49, 0xee, 0xf7, 0xe0, 0x02, 0xff, 0x84, 0xe3, 0x8f, 0xc1, 0x32, 0x09, 0x67, 0x6b, 0x26, 0xef, 0xb9, 0xf8,
0x57, 0x37, 0xa9, 0xeb, 0xfb, 0x6f, 0xd7, 0x97, 0x8e, 0xfe, 0xd3, 0xbe, 0xf8, 0x13, 0x00, 0x00, 0x13, 0x68, 0x65, 0x3a, 0xb5, 0xb4, 0x79, 0xd5, 0x28, 0x57, 0x2e, 0x76, 0x2c, 0x2e, 0xac, 0x61,
0xff, 0xff, 0x35, 0x7d, 0xdf, 0xdc, 0xca, 0x03, 0x00, 0x00, 0xef, 0x8f, 0x09, 0x07, 0xc3, 0x79, 0xc0, 0x6f, 0x52, 0x16, 0xa3, 0x1e, 0x1c, 0x68, 0x25, 0xa2,
0x13, 0xd5, 0x73, 0xeb, 0xbd, 0x75, 0xb7, 0x26, 0xc1, 0x35, 0xf4, 0x12, 0x2c, 0x29, 0x7c, 0x64,
0x2b, 0x4f, 0xe9, 0x1d, 0x70, 0x3b, 0x95, 0x0a, 0xb9, 0xb4, 0x45, 0xc2, 0x73, 0x80, 0x71, 0xc2,
0x74, 0x1b, 0xc8, 0x0b, 0x4a, 0x35, 0xef, 0x28, 0xfe, 0x16, 0x8e, 0xca, 0xfa, 0x46, 0x8e, 0x8a,
0xd8, 0x21, 0xf9, 0x1d, 0xb9, 0xe7, 0xd0, 0xaa, 0x48, 0x14, 0x3d, 0x52, 0x21, 0xbb, 0x64, 0xeb,
0x22, 0xe5, 0xaa, 0x08, 0x10, 0xd7, 0xce, 0x0c, 0xd1, 0xbf, 0xb9, 0x3e, 0x2b, 0x7a, 0x50, 0xec,
0x53, 0x3d, 0xb3, 0x9b, 0x13, 0xb5, 0x75, 0x45, 0x5c, 0xfb, 0xba, 0xaf, 0xfe, 0x01, 0x5f, 0xfd,
0x0b, 0x00, 0x00, 0xff, 0xff, 0x91, 0x07, 0xf4, 0xa6, 0x17, 0x05, 0x00, 0x00,
} }
...@@ -7,8 +7,8 @@ service Platform { ...@@ -7,8 +7,8 @@ service Platform {
rpc Auth(AuthRequest) returns (RegisteredUser) {} rpc Auth(AuthRequest) returns (RegisteredUser) {}
rpc Unregister(Empty) returns (ErrorCode) {} rpc Unregister(Empty) returns (ErrorCode) {}
rpc PostContract(PostContractRequest) returns (ErrorCode) {} rpc PostContract(PostContractRequest) returns (ErrorCode) {}
rpc JoinSignature(JoinSignatureRequest) returns (ErrorCode) {} rpc JoinSignature(JoinSignatureRequest) returns (stream UserConnected) {}
rpc ReadySign(ReadySignRequest) returns (ErrorCode) {} rpc ReadySign(ReadySignRequest) returns (LaunchSignature) {} // Warning, LaunchSignature can be emitted with a very high delay
} }
// RegisterRequest message contains the client's email adress and his // RegisterRequest message contains the client's email adress and his
...@@ -70,7 +70,26 @@ message JoinSignatureRequest { ...@@ -70,7 +70,26 @@ message JoinSignatureRequest {
uint32 port = 2; uint32 port = 2;
} }
// UserConnected is emitted by the platform to the client to announce a new client connection
message UserConnected {
ErrorCode errorCode = 1;
string contractUuid = 2;
message User {
bytes KeyHash = 1;
string email = 2;
string ip = 3;
uint32 port = 4;
}
}
// ReadySignRequest contains the contract unique identitier that is ready to be signed // ReadySignRequest contains the contract unique identitier that is ready to be signed
message ReadySignRequest { message ReadySignRequest {
string contractUuid = 1; string contractUuid = 1;
} }
// LaunchSignature is emitted by the platform when every signers are ready
message LaunchSignature {
ErrorCode errorCode = 1;
string signatureUuid = 2;
repeated string keyHash = 3;
}
package common
import (
"container/list"
"sync"
)
type waitingGroup struct {
channels *list.List
oldMessages []interface{}
mutex sync.Mutex
}
// WaitingGroupMap is a synchronisation tool for goroutines.
// It enables several goroutines to wait for other goroutines in a specific "room".
//
// After joining a room, a goroutine can broadcast or wait for events.
// To avoid memory leaks, always call Unjoin when leaving a goroutine.
//
// See group_test.go for some examples.
type WaitingGroupMap struct {
data map[string]*waitingGroup
mutex sync.Mutex
}
// NewWaitingGroupMap returns a ready to use WaitingGroupMap.
func NewWaitingGroupMap() *WaitingGroupMap {
return &WaitingGroupMap{
data: make(map[string]*waitingGroup),
}
}
// Join permits the current goroutine to join a room.
// It returns the listenning channel and a slice containing messages already sent by other members of the room.
// The room is automatically created if unknown.
func (g *WaitingGroupMap) Join(room string) (listen chan interface{}, oldMessages []interface{}) {
// Check if the current waiting group knows this room
g.mutex.Lock()
_, present := g.data[room]
if !present {
g.data[room] = &waitingGroup{
channels: list.New(),
oldMessages: make([]interface{}, 0),
}
}
g.mutex.Unlock()
g.data[room].mutex.Lock()
listen = make(chan interface{}, 100)
g.data[room].channels.PushBack(listen)
oldMessages = g.data[room].oldMessages
g.data[room].mutex.Unlock()
return
}
// Unjoin remove the given chan from the current room, freeing memory if needed.
// If there is nobody remaining in the room, it is destroyed by calling Close.
func (g *WaitingGroupMap) Unjoin(room string, i chan interface{}) {
g.data[room].mutex.Lock()
for e := g.data[room].channels.Front(); e != nil; e = e.Next() {
if e.Value == i {
g.data[room].channels.Remove(e) // Remove element from list
break
}
}
if g.data[room].channels.Len() == 0 {
g.Close(room)
return
}
g.data[room].mutex.Unlock()
}
// Broadcast emits a message to every member of the room, including the sender.
func (g *WaitingGroupMap) Broadcast(room string, value interface{}) {
g.data[room].mutex.Lock()
g.data[room].oldMessages = append(g.data[room].oldMessages, value)
g.data[room].mutex.Unlock()
for e := g.data[room].channels.Front(); e != nil; e = e.Next() {
e.Value.(chan interface{}) <- value
}
}
// Close removes the room from the current WaitingGroupMap, closing all opened channels,
// and clearing oldMessages.
func (g *WaitingGroupMap) Close(room string) {
for e := g.data[room].channels.Front(); e != nil; e = e.Next() {
close(e.Value.(chan interface{}))
}
delete(g.data, room)
}
// CloseAll clears every available room in the current WaitingGroupMap.
func (g *WaitingGroupMap) CloseAll() {
for k := range g.data {
g.Close(k)
}
}
package common
import (
"sync"
"testing"
"time"
)
func TestWaitingGroup(t *testing.T) {
nb := 60
w := NewWaitingGroupMap()
waitGroup := &sync.WaitGroup{} // test only
waitGroup.Add(nb)
// Spawn nb emitters waiting for (nb-1) other emitters
for i := 0; i < nb; i++ {
go func(i int) {
// Add some virtual latency
time.Sleep(time.Duration(i) * time.Millisecond)
// Join the waitingGroupMap
myChan, nbs := w.Join("A")
w.Broadcast("A", i)
// Wait for other msg
for m := range myChan {
nbs = append(nbs, m)
if len(nbs) == nb {
break
}
}
// Free the waitingGroupMap
w.Unjoin("A", myChan)
waitGroup.Done()
}(i)
}
waitGroup.Wait() // test only, wait for test to fully happen
}
func TestCloseWaitingGroup(t *testing.T) {
w := NewWaitingGroupMap()
waitGroup := &sync.WaitGroup{} // test only
waitGroup.Add(1)
go func() {
myChan, _ := w.Join("A")
for _ = range myChan {
t.Fatal("Should not be here")
}
// No need to call Unjoin here: if we do, we will try to unjoin a unknown room
waitGroup.Done()
}()
time.Sleep(10 * time.Millisecond)
w.CloseAll()
waitGroup.Wait()
}
...@@ -60,15 +60,15 @@ func (s *platformServer) PostContract(ctx context.Context, in *api.PostContractR ...@@ -60,15 +60,15 @@ func (s *platformServer) PostContract(ctx context.Context, in *api.PostContractR
// JoinSignature handler // JoinSignature handler
// //
// Handle incoming JoinSignatureRequest messages // Handle incoming JoinSignatureRequest messages
func (s *platformServer) JoinSignature(ctx context.Context, in *api.JoinSignatureRequest) (*api.ErrorCode, error) { func (s *platformServer) JoinSignature(in *api.JoinSignatureRequest, stream api.Platform_JoinSignatureServer) error {
// TODO // TODO
return nil, nil return nil
} }
// ReadySign handler // ReadySign handler
// //
// Handle incoming ReadySignRequest messages // Handle incoming ReadySignRequest messages
func (s *platformServer) ReadySign(ctx context.Context, in *api.ReadySignRequest) (*api.ErrorCode, error) { func (s *platformServer) ReadySign(ctx context.Context, in *api.ReadySignRequest) (*api.LaunchSignature, error) {
// TODO // TODO
return nil, nil return nil, nil
} }
......
...@@ -52,15 +52,15 @@ func (s *mockServer) PostContract(ctx context.Context, in *api.PostContractReque ...@@ -52,15 +52,15 @@ func (s *mockServer) PostContract(ctx context.Context, in *api.PostContractReque
// JoinSignature handler // JoinSignature handler
// //
// Handle incoming JoinSignatureRequest messages // Handle incoming JoinSignatureRequest messages
func (s *mockServer) JoinSignature(ctx context.Context, in *api.JoinSignatureRequest) (*api.ErrorCode, error) { func (s *mockServer) JoinSignature(in *api.JoinSignatureRequest, stream api.Platform_JoinSignatureServer) error {
// TODO // TODO
return nil, nil return nil
} }
// ReadySign handler // ReadySign handler
// //
// Handle incoming ReadySignRequest messages // Handle incoming ReadySignRequest messages
func (s *mockServer) ReadySign(ctx context.Context, in *api.ReadySignRequest) (*api.ErrorCode, error) { func (s *mockServer) ReadySign(ctx context.Context, in *api.ReadySignRequest) (*api.LaunchSignature, error) {