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:
- "go test -coverprofile dfssp_user.part -v dfss/dfssp/user"
- "go test -coverprofile dfssp_contract.part -v dfss/dfssp/contract"
- "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 dfssc_common.part -v dfss/dfssc/common"
- "go test -coverprofile dfssc_security.part -v dfss/dfssc/security"
......
......@@ -16,7 +16,9 @@ It has these top-level messages:
Empty
PostContractRequest
JoinSignatureRequest
UserConnected
ReadySignRequest
LaunchSignature
*/
package api
......@@ -155,6 +157,36 @@ func (m *JoinSignatureRequest) String() string { return proto.Compact
func (*JoinSignatureRequest) ProtoMessage() {}
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
type ReadySignRequest struct {
ContractUuid string `protobuf:"bytes,1,opt,name=contractUuid" json:"contractUuid,omitempty"`
......@@ -163,7 +195,26 @@ type ReadySignRequest struct {
func (m *ReadySignRequest) Reset() { *m = ReadySignRequest{} }
func (m *ReadySignRequest) String() string { return proto.CompactTextString(m) }
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() {
proto.RegisterType((*RegisterRequest)(nil), "api.RegisterRequest")
......@@ -173,7 +224,10 @@ func init() {
proto.RegisterType((*Empty)(nil), "api.Empty")
proto.RegisterType((*PostContractRequest)(nil), "api.PostContractRequest")
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((*LaunchSignature)(nil), "api.LaunchSignature")
proto.RegisterEnum("api.ErrorCode_Code", ErrorCode_Code_name, ErrorCode_Code_value)
}
......@@ -188,8 +242,8 @@ type PlatformClient interface {
Auth(ctx context.Context, in *AuthRequest, opts ...grpc.CallOption) (*RegisteredUser, error)
Unregister(ctx context.Context, in *Empty, 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)
ReadySign(ctx context.Context, in *ReadySignRequest, 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) (*LaunchSignature, error)
}
type platformClient struct {
......@@ -236,17 +290,40 @@ func (c *platformClient) PostContract(ctx context.Context, in *PostContractReque
return out, nil
}
func (c *platformClient) JoinSignature(ctx context.Context, in *JoinSignatureRequest, opts ...grpc.CallOption) (*ErrorCode, error) {
out := new(ErrorCode)
err := grpc.Invoke(ctx, "/api.Platform/JoinSignature", in, out, c.cc, opts...)
func (c *platformClient) JoinSignature(ctx context.Context, in *JoinSignatureRequest, opts ...grpc.CallOption) (Platform_JoinSignatureClient, error) {
stream, err := grpc.NewClientStream(ctx, &_Platform_serviceDesc.Streams[0], c.cc, "/api.Platform/JoinSignature", opts...)
if err != nil {
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) {
out := new(ErrorCode)
type Platform_JoinSignatureClient interface {
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...)
if err != nil {
return nil, err
......@@ -261,8 +338,8 @@ type PlatformServer interface {
Auth(context.Context, *AuthRequest) (*RegisteredUser, error)
Unregister(context.Context, *Empty) (*ErrorCode, error)
PostContract(context.Context, *PostContractRequest) (*ErrorCode, error)
JoinSignature(context.Context, *JoinSignatureRequest) (*ErrorCode, error)
ReadySign(context.Context, *ReadySignRequest) (*ErrorCode, error)
JoinSignature(*JoinSignatureRequest, Platform_JoinSignatureServer) error
ReadySign(context.Context, *ReadySignRequest) (*LaunchSignature, error)
}
func RegisterPlatformServer(s *grpc.Server, srv PlatformServer) {
......@@ -317,16 +394,25 @@ func _Platform_PostContract_Handler(srv interface{}, ctx context.Context, dec fu
return out, nil
}
func _Platform_JoinSignature_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(JoinSignatureRequest)
if err := dec(in); err != nil {
return nil, err
}
out, err := srv.(PlatformServer).JoinSignature(ctx, in)
if err != nil {
return nil, err
func _Platform_JoinSignature_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(JoinSignatureRequest)
if err := stream.RecvMsg(m); err != nil {
return 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) {
......@@ -361,49 +447,58 @@ var _Platform_serviceDesc = grpc.ServiceDesc{
MethodName: "PostContract",
Handler: _Platform_PostContract_Handler,
},
{
MethodName: "JoinSignature",
Handler: _Platform_JoinSignature_Handler,
},
{
MethodName: "ReadySign",
Handler: _Platform_ReadySign_Handler,
},
},
Streams: []grpc.StreamDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "JoinSignature",
Handler: _Platform_JoinSignature_Handler,
ServerStreams: true,
},
},
}
var fileDescriptor0 = []byte{
// 490 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x53, 0x5d, 0x8f, 0xd2, 0x40,
0x14, 0xdd, 0x42, 0x97, 0x8f, 0xbb, 0x2c, 0x36, 0x03, 0x9a, 0xca, 0x83, 0xd9, 0xcc, 0x8b, 0xc6,
0x07, 0x34, 0x68, 0x4c, 0x34, 0xbe, 0xd4, 0x4a, 0xd6, 0xf5, 0x81, 0x90, 0xe9, 0x56, 0x9f, 0x6b,
0xb9, 0x0b, 0x8d, 0xb4, 0x83, 0xd3, 0x41, 0xb3, 0x7f, 0xc6, 0x3f, 0xe4, 0x8f, 0xd2, 0xce, 0xb4,
0x43, 0xa8, 0x36, 0x26, 0xcb, 0x03, 0xcc, 0xb9, 0x1f, 0xe7, 0xde, 0x39, 0x67, 0x00, 0xb2, 0x66,
0x4b, 0x3f, 0x40, 0xf1, 0x3d, 0x89, 0x31, 0x9f, 0xee, 0x04, 0x97, 0x9c, 0xb4, 0xa3, 0x5d, 0x42,
0x3d, 0xb8, 0xc7, 0x70, 0x9d, 0xe4, 0x12, 0x05, 0xc3, 0x6f, 0x7b, 0xcc, 0x25, 0x19, 0xc3, 0x29,
0xa6, 0x51, 0xb2, 0x75, 0xad, 0x0b, 0xeb, 0x49, 0x9f, 0x95, 0x80, 0xb8, 0xd0, 0x15, 0x65, 0x81,
0xdb, 0xd2, 0x71, 0x03, 0xe9, 0x4f, 0x0b, 0xfa, 0x73, 0x21, 0xb8, 0xf0, 0xf9, 0x0a, 0xc9, 0x63,
0xb0, 0xe3, 0xe2, 0x57, 0x37, 0x0f, 0x67, 0xa3, 0x69, 0x31, 0x64, 0x7a, 0xc8, 0x4e, 0xd5, 0x17,
0xd3, 0x05, 0x8a, 0x30, 0xc5, 0x3c, 0x8f, 0xd6, 0x68, 0x08, 0x2b, 0x48, 0x17, 0x60, 0x6b, 0xaa,
0x33, 0xe8, 0x06, 0xa1, 0xef, 0xcf, 0x83, 0xc0, 0x39, 0x21, 0x00, 0x9d, 0xab, 0xc5, 0x27, 0x8f,
0x5d, 0x3a, 0x96, 0x4a, 0xbc, 0xf3, 0xde, 0x7b, 0xe1, 0xf5, 0x07, 0xa7, 0xa5, 0xc0, 0x67, 0x8f,
0x2d, 0xae, 0x16, 0x97, 0x4e, 0x9b, 0x8c, 0x54, 0xd5, 0xf5, 0x9c, 0x31, 0xe7, 0xb7, 0xf9, 0x58,
0xf4, 0x35, 0x9c, 0x79, 0x7b, 0xb9, 0xf9, 0xff, 0xfd, 0x8a, 0xa8, 0xe4, 0x5f, 0x31, 0xab, 0x96,
0x29, 0x01, 0x7d, 0x0e, 0x43, 0x23, 0x0f, 0xae, 0xc2, 0x1c, 0x05, 0x79, 0x04, 0x10, 0x6f, 0x13,
0xcc, 0xa4, 0x8f, 0x42, 0x56, 0x14, 0x47, 0x11, 0xda, 0x85, 0xd3, 0x79, 0xba, 0x93, 0xb7, 0xf4,
0x07, 0x8c, 0x96, 0x3c, 0x97, 0x3e, 0xcf, 0xa4, 0x88, 0x62, 0x69, 0xa6, 0x13, 0xb0, 0x37, 0x51,
0xbe, 0xd1, 0x9d, 0x03, 0xa6, 0xcf, 0x64, 0x02, 0xbd, 0x9b, 0x64, 0x8b, 0x59, 0x94, 0x1a, 0x2d,
0x0e, 0x98, 0x3c, 0x80, 0x4e, 0x9e, 0xac, 0x33, 0x14, 0x6e, 0xfb, 0xa2, 0x5d, 0x64, 0x2a, 0xa4,
0xe4, 0x8b, 0x79, 0x9a, 0x16, 0x63, 0x5d, 0xbb, 0x94, 0xaf, 0x82, 0x85, 0x7c, 0xe3, 0x8f, 0x3c,
0xc9, 0x82, 0xa2, 0x2e, 0x92, 0x7b, 0x81, 0x66, 0x32, 0x85, 0x41, 0x5c, 0x2d, 0x13, 0xee, 0x93,
0x55, 0xb5, 0x7b, 0x2d, 0xa6, 0xb6, 0xdb, 0x71, 0x51, 0x5a, 0x7c, 0xce, 0xf4, 0x99, 0xbe, 0x02,
0x87, 0x61, 0xb4, 0xba, 0x55, 0x84, 0x77, 0xe0, 0x9a, 0xfd, 0x6a, 0x41, 0x6f, 0xb9, 0x8d, 0xe4,
0x0d, 0x17, 0x29, 0x99, 0x41, 0xcf, 0x08, 0x49, 0xc6, 0xfa, 0x51, 0xfc, 0xf5, 0xec, 0x26, 0xc3,
0xfa, 0x53, 0xa1, 0x27, 0xe4, 0x19, 0xd8, 0xca, 0x37, 0xe2, 0xe8, 0xcc, 0x91, 0x85, 0x93, 0x51,
0x8d, 0xa1, 0x74, 0xa6, 0x68, 0x78, 0x0a, 0x10, 0x66, 0xc2, 0x8c, 0x81, 0x92, 0x50, 0x99, 0xd1,
0x40, 0xfe, 0x06, 0x06, 0xc7, 0xf6, 0x10, 0x57, 0x57, 0x34, 0x38, 0xd6, 0xd0, 0xfb, 0x16, 0xce,
0x6b, 0x0a, 0x93, 0x87, 0xba, 0xa4, 0x49, 0xf5, 0x86, 0xee, 0x97, 0xd0, 0x3f, 0xe8, 0x49, 0xee,
0x57, 0x37, 0xa9, 0xeb, 0xfb, 0x6f, 0xd7, 0x97, 0x8e, 0xfe, 0xd3, 0xbe, 0xf8, 0x13, 0x00, 0x00,
0xff, 0xff, 0x35, 0x7d, 0xdf, 0xdc, 0xca, 0x03, 0x00, 0x00,
// 605 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x54, 0x6f, 0x6f, 0xd2, 0x40,
0x18, 0xa7, 0xa5, 0x1b, 0xe3, 0xd9, 0x60, 0xcd, 0x31, 0x4d, 0xed, 0x0b, 0xb3, 0x5c, 0x4c, 0x34,
0xc6, 0xe0, 0x82, 0x89, 0x89, 0xbe, 0xeb, 0x2a, 0xd9, 0xa6, 0x86, 0x90, 0x63, 0x68, 0xe2, 0xbb,
0x5a, 0x6e, 0xd0, 0x8c, 0xb6, 0x78, 0x3d, 0x34, 0xbc, 0xf2, 0x9b, 0xf8, 0x4d, 0xfc, 0x1c, 0x7e,
0x1c, 0xbd, 0xbb, 0xf6, 0xa0, 0x65, 0xc4, 0x64, 0xbc, 0x80, 0xfe, 0x9e, 0xff, 0xcf, 0xef, 0xf9,
0x15, 0x40, 0x53, 0x32, 0xf4, 0x47, 0x94, 0x7d, 0x8f, 0x42, 0x9a, 0x75, 0x17, 0x2c, 0xe5, 0x29,
0xaa, 0x07, 0x8b, 0x08, 0x7b, 0x70, 0x4c, 0xe8, 0x34, 0xca, 0x38, 0x65, 0x84, 0x7e, 0x5b, 0xd2,
0x8c, 0xa3, 0x13, 0xd8, 0xa3, 0x71, 0x10, 0xcd, 0x1d, 0xe3, 0xd4, 0x78, 0xd6, 0x24, 0x39, 0x40,
0x0e, 0x34, 0x58, 0x1e, 0xe0, 0x98, 0xca, 0xae, 0x21, 0xfe, 0x65, 0x40, 0xb3, 0xcf, 0x58, 0xca,
0xfc, 0x74, 0x42, 0xd1, 0x53, 0xb0, 0x42, 0xf1, 0xab, 0x92, 0xdb, 0xbd, 0x4e, 0x57, 0x34, 0xe9,
0xae, 0xbd, 0x5d, 0xf9, 0x45, 0x54, 0x80, 0x2c, 0x18, 0xd3, 0x2c, 0x0b, 0xa6, 0x54, 0x17, 0x2c,
0x20, 0x1e, 0x80, 0xa5, 0x4a, 0x1d, 0x42, 0x63, 0x34, 0xf6, 0xfd, 0xfe, 0x68, 0x64, 0xd7, 0x10,
0xc0, 0xfe, 0xd5, 0xe0, 0x93, 0x47, 0x2e, 0x6c, 0x43, 0x3a, 0xce, 0xbd, 0x77, 0xde, 0xf8, 0xfa,
0xd2, 0x36, 0x25, 0xf8, 0xec, 0x91, 0xc1, 0xd5, 0xe0, 0xc2, 0xae, 0xa3, 0x8e, 0x8c, 0xba, 0xee,
0x13, 0x62, 0xff, 0xd5, 0x1f, 0x03, 0xbf, 0x81, 0x43, 0x6f, 0xc9, 0x67, 0xff, 0xdf, 0x4f, 0x58,
0x79, 0x7a, 0x4b, 0x93, 0x62, 0x98, 0x1c, 0xe0, 0x33, 0x68, 0x6b, 0x7a, 0xe8, 0x64, 0x9c, 0x51,
0x86, 0x1e, 0x03, 0x84, 0xf3, 0x88, 0x26, 0xdc, 0xa7, 0x8c, 0x17, 0x25, 0x4a, 0x16, 0xdc, 0x80,
0xbd, 0x7e, 0xbc, 0xe0, 0x2b, 0xfc, 0x03, 0x3a, 0xc3, 0x34, 0xe3, 0x7e, 0x9a, 0x70, 0x16, 0x84,
0x5c, 0x77, 0x47, 0x60, 0xcd, 0x82, 0x6c, 0xa6, 0x32, 0x8f, 0x88, 0x7a, 0x46, 0x2e, 0x1c, 0xdc,
0x44, 0x73, 0x9a, 0x04, 0xb1, 0xe6, 0x62, 0x8d, 0xd1, 0x43, 0xd8, 0xcf, 0xa2, 0x69, 0x42, 0x99,
0x53, 0x3f, 0xad, 0x0b, 0x4f, 0x81, 0x24, 0x7d, 0x61, 0x1a, 0xc7, 0xa2, 0xad, 0x63, 0xe5, 0xf4,
0x15, 0x50, 0xd0, 0x77, 0xf2, 0x3e, 0x8d, 0x92, 0x91, 0x88, 0x0b, 0xf8, 0x92, 0x51, 0xdd, 0x19,
0xc3, 0x51, 0x58, 0x0c, 0x33, 0x5e, 0x46, 0x93, 0x62, 0xf6, 0x8a, 0x4d, 0x4e, 0xb7, 0x48, 0x59,
0x7e, 0xe2, 0x16, 0x51, 0xcf, 0xf8, 0xb7, 0x01, 0x2d, 0xb9, 0xba, 0xd8, 0x24, 0xa1, 0x21, 0xa7,
0x13, 0xf4, 0x02, 0x9a, 0x54, 0x9f, 0x54, 0x95, 0x39, 0xec, 0xb5, 0xab, 0x87, 0x26, 0x9b, 0x80,
0x3b, 0x7d, 0xcd, 0xbb, 0x7d, 0xdd, 0x2f, 0x60, 0x29, 0x76, 0xc5, 0x56, 0x1f, 0xe8, 0xea, 0x72,
0x43, 0x50, 0xe3, 0x36, 0x87, 0x9b, 0xab, 0x99, 0xe5, 0xab, 0xb5, 0xc1, 0x8c, 0x16, 0x82, 0x19,
0x69, 0x12, 0x4f, 0xeb, 0xf9, 0xad, 0xd2, 0xfc, 0xaf, 0xc1, 0x26, 0x34, 0x98, 0xac, 0x24, 0x21,
0xf7, 0xe0, 0x02, 0xff, 0x84, 0xe3, 0x8f, 0xc1, 0x32, 0x09, 0x67, 0x6b, 0x26, 0xef, 0xb9, 0xf8,
0x13, 0x68, 0x65, 0x3a, 0xb5, 0xb4, 0x79, 0xd5, 0x28, 0x57, 0x2e, 0x76, 0x2c, 0x2e, 0xac, 0x61,
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 {
rpc Auth(AuthRequest) returns (RegisteredUser) {}
rpc Unregister(Empty) returns (ErrorCode) {}
rpc PostContract(PostContractRequest) returns (ErrorCode) {}
rpc JoinSignature(JoinSignatureRequest) returns (ErrorCode) {}
rpc ReadySign(ReadySignRequest) returns (ErrorCode) {}
rpc JoinSignature(JoinSignatureRequest) returns (stream UserConnected) {}
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
......@@ -70,7 +70,26 @@ message JoinSignatureRequest {
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
message ReadySignRequest {
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
// JoinSignature handler
//
// 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
return nil, nil
return nil
}
// ReadySign handler
//
// 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
return nil, nil
}
......
......@@ -52,15 +52,15 @@ func (s *mockServer) PostContract(ctx context.Context, in *api.PostContractReque
// JoinSignature handler
//
// 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
return nil, nil
return nil
}
// ReadySign handler
//
// 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) {
// TODO
return nil, nil
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment