[wip] integrate DKG and DSS
This commit is contained in:
parent
fa9a7dfbad
commit
01204261b7
@ -426,7 +426,7 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods {
|
||||
var (
|
||||
md_Participant protoreflect.MessageDescriptor
|
||||
fd_Participant_cosmos_address protoreflect.FieldDescriptor
|
||||
fd_Participant_nitro_address protoreflect.FieldDescriptor
|
||||
fd_Participant_public_key protoreflect.FieldDescriptor
|
||||
fd_Participant_role protoreflect.FieldDescriptor
|
||||
fd_Participant_kyc_id protoreflect.FieldDescriptor
|
||||
)
|
||||
@ -435,7 +435,7 @@ func init() {
|
||||
file_cerc_onboarding_v1_onboarding_proto_init()
|
||||
md_Participant = File_cerc_onboarding_v1_onboarding_proto.Messages().ByName("Participant")
|
||||
fd_Participant_cosmos_address = md_Participant.Fields().ByName("cosmos_address")
|
||||
fd_Participant_nitro_address = md_Participant.Fields().ByName("nitro_address")
|
||||
fd_Participant_public_key = md_Participant.Fields().ByName("public_key")
|
||||
fd_Participant_role = md_Participant.Fields().ByName("role")
|
||||
fd_Participant_kyc_id = md_Participant.Fields().ByName("kyc_id")
|
||||
}
|
||||
@ -511,9 +511,9 @@ func (x *fastReflection_Participant) Range(f func(protoreflect.FieldDescriptor,
|
||||
return
|
||||
}
|
||||
}
|
||||
if x.NitroAddress != "" {
|
||||
value := protoreflect.ValueOfString(x.NitroAddress)
|
||||
if !f(fd_Participant_nitro_address, value) {
|
||||
if len(x.PublicKey) != 0 {
|
||||
value := protoreflect.ValueOfBytes(x.PublicKey)
|
||||
if !f(fd_Participant_public_key, value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -546,8 +546,8 @@ func (x *fastReflection_Participant) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
switch fd.FullName() {
|
||||
case "cerc.onboarding.v1.Participant.cosmos_address":
|
||||
return x.CosmosAddress != ""
|
||||
case "cerc.onboarding.v1.Participant.nitro_address":
|
||||
return x.NitroAddress != ""
|
||||
case "cerc.onboarding.v1.Participant.public_key":
|
||||
return len(x.PublicKey) != 0
|
||||
case "cerc.onboarding.v1.Participant.role":
|
||||
return x.Role != ""
|
||||
case "cerc.onboarding.v1.Participant.kyc_id":
|
||||
@ -570,8 +570,8 @@ func (x *fastReflection_Participant) Clear(fd protoreflect.FieldDescriptor) {
|
||||
switch fd.FullName() {
|
||||
case "cerc.onboarding.v1.Participant.cosmos_address":
|
||||
x.CosmosAddress = ""
|
||||
case "cerc.onboarding.v1.Participant.nitro_address":
|
||||
x.NitroAddress = ""
|
||||
case "cerc.onboarding.v1.Participant.public_key":
|
||||
x.PublicKey = nil
|
||||
case "cerc.onboarding.v1.Participant.role":
|
||||
x.Role = ""
|
||||
case "cerc.onboarding.v1.Participant.kyc_id":
|
||||
@ -595,9 +595,9 @@ func (x *fastReflection_Participant) Get(descriptor protoreflect.FieldDescriptor
|
||||
case "cerc.onboarding.v1.Participant.cosmos_address":
|
||||
value := x.CosmosAddress
|
||||
return protoreflect.ValueOfString(value)
|
||||
case "cerc.onboarding.v1.Participant.nitro_address":
|
||||
value := x.NitroAddress
|
||||
return protoreflect.ValueOfString(value)
|
||||
case "cerc.onboarding.v1.Participant.public_key":
|
||||
value := x.PublicKey
|
||||
return protoreflect.ValueOfBytes(value)
|
||||
case "cerc.onboarding.v1.Participant.role":
|
||||
value := x.Role
|
||||
return protoreflect.ValueOfString(value)
|
||||
@ -626,8 +626,8 @@ func (x *fastReflection_Participant) Set(fd protoreflect.FieldDescriptor, value
|
||||
switch fd.FullName() {
|
||||
case "cerc.onboarding.v1.Participant.cosmos_address":
|
||||
x.CosmosAddress = value.Interface().(string)
|
||||
case "cerc.onboarding.v1.Participant.nitro_address":
|
||||
x.NitroAddress = value.Interface().(string)
|
||||
case "cerc.onboarding.v1.Participant.public_key":
|
||||
x.PublicKey = value.Bytes()
|
||||
case "cerc.onboarding.v1.Participant.role":
|
||||
x.Role = value.Interface().(string)
|
||||
case "cerc.onboarding.v1.Participant.kyc_id":
|
||||
@ -654,8 +654,8 @@ func (x *fastReflection_Participant) Mutable(fd protoreflect.FieldDescriptor) pr
|
||||
switch fd.FullName() {
|
||||
case "cerc.onboarding.v1.Participant.cosmos_address":
|
||||
panic(fmt.Errorf("field cosmos_address of message cerc.onboarding.v1.Participant is not mutable"))
|
||||
case "cerc.onboarding.v1.Participant.nitro_address":
|
||||
panic(fmt.Errorf("field nitro_address of message cerc.onboarding.v1.Participant is not mutable"))
|
||||
case "cerc.onboarding.v1.Participant.public_key":
|
||||
panic(fmt.Errorf("field public_key of message cerc.onboarding.v1.Participant is not mutable"))
|
||||
case "cerc.onboarding.v1.Participant.role":
|
||||
panic(fmt.Errorf("field role of message cerc.onboarding.v1.Participant is not mutable"))
|
||||
case "cerc.onboarding.v1.Participant.kyc_id":
|
||||
@ -675,8 +675,8 @@ func (x *fastReflection_Participant) NewField(fd protoreflect.FieldDescriptor) p
|
||||
switch fd.FullName() {
|
||||
case "cerc.onboarding.v1.Participant.cosmos_address":
|
||||
return protoreflect.ValueOfString("")
|
||||
case "cerc.onboarding.v1.Participant.nitro_address":
|
||||
return protoreflect.ValueOfString("")
|
||||
case "cerc.onboarding.v1.Participant.public_key":
|
||||
return protoreflect.ValueOfBytes(nil)
|
||||
case "cerc.onboarding.v1.Participant.role":
|
||||
return protoreflect.ValueOfString("")
|
||||
case "cerc.onboarding.v1.Participant.kyc_id":
|
||||
@ -754,7 +754,7 @@ func (x *fastReflection_Participant) ProtoMethods() *protoiface.Methods {
|
||||
if l > 0 {
|
||||
n += 1 + l + runtime.Sov(uint64(l))
|
||||
}
|
||||
l = len(x.NitroAddress)
|
||||
l = len(x.PublicKey)
|
||||
if l > 0 {
|
||||
n += 1 + l + runtime.Sov(uint64(l))
|
||||
}
|
||||
@ -809,10 +809,10 @@ func (x *fastReflection_Participant) ProtoMethods() *protoiface.Methods {
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if len(x.NitroAddress) > 0 {
|
||||
i -= len(x.NitroAddress)
|
||||
copy(dAtA[i:], x.NitroAddress)
|
||||
i = runtime.EncodeVarint(dAtA, i, uint64(len(x.NitroAddress)))
|
||||
if len(x.PublicKey) > 0 {
|
||||
i -= len(x.PublicKey)
|
||||
copy(dAtA[i:], x.PublicKey)
|
||||
i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PublicKey)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
@ -906,9 +906,9 @@ func (x *fastReflection_Participant) ProtoMethods() *protoiface.Methods {
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field NitroAddress", wireType)
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow
|
||||
@ -918,23 +918,25 @@ func (x *fastReflection_Participant) ProtoMethods() *protoiface.Methods {
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
if byteLen < 0 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
|
||||
}
|
||||
x.NitroAddress = string(dAtA[iNdEx:postIndex])
|
||||
x.PublicKey = append(x.PublicKey[:0], dAtA[iNdEx:postIndex]...)
|
||||
if x.PublicKey == nil {
|
||||
x.PublicKey = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
@ -1577,8 +1579,8 @@ type Participant struct {
|
||||
|
||||
// participant's cosmos (laconic) address
|
||||
CosmosAddress string `protobuf:"bytes,1,opt,name=cosmos_address,json=cosmosAddress,proto3" json:"cosmos_address,omitempty"`
|
||||
// participant's Nitro address
|
||||
NitroAddress string `protobuf:"bytes,2,opt,name=nitro_address,json=nitroAddress,proto3" json:"nitro_address,omitempty"`
|
||||
// full public key used to derive participant's Nitro address
|
||||
PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
// participant's role (participant | validator)
|
||||
Role string `protobuf:"bytes,3,opt,name=role,proto3" json:"role,omitempty"`
|
||||
// participant's KYC receipt ID
|
||||
@ -1612,11 +1614,11 @@ func (x *Participant) GetCosmosAddress() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Participant) GetNitroAddress() string {
|
||||
func (x *Participant) GetPublicKey() []byte {
|
||||
if x != nil {
|
||||
return x.NitroAddress
|
||||
return x.PublicKey
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Participant) GetRole() string {
|
||||
@ -1692,46 +1694,43 @@ var file_cerc_onboarding_v1_onboarding_proto_rawDesc = []byte{
|
||||
0x6c, 0x65, 0x64, 0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6f, 0x6e, 0x62, 0x6f, 0x61,
|
||||
0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x52, 0x11,
|
||||
0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
|
||||
0x64, 0x22, 0xa2, 0x02, 0x0a, 0x0b, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e,
|
||||
0x64, 0x22, 0xed, 0x01, 0x0a, 0x0b, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e,
|
||||
0x74, 0x12, 0x56, 0x0a, 0x0e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xf2, 0xde, 0x1f, 0x2b, 0x6a,
|
||||
0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
|
||||
0x73, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52, 0x0d, 0x63, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x52, 0x0a, 0x0d, 0x6e, 0x69, 0x74,
|
||||
0x72, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x42, 0x2d, 0xf2, 0xde, 0x1f, 0x29, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x6e, 0x69, 0x74, 0x72,
|
||||
0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a,
|
||||
0x22, 0x6e, 0x69, 0x74, 0x72, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52,
|
||||
0x0c, 0x6e, 0x69, 0x74, 0x72, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2f, 0x0a,
|
||||
0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1b, 0xf2, 0xde, 0x1f,
|
||||
0x17, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x20, 0x79, 0x61, 0x6d,
|
||||
0x6c, 0x3a, 0x22, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x36,
|
||||
0x0a, 0x06, 0x6b, 0x79, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1f,
|
||||
0xf2, 0xde, 0x1f, 0x1b, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x6b, 0x79, 0x63, 0x5f, 0x69, 0x64,
|
||||
0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6b, 0x79, 0x63, 0x5f, 0x69, 0x64, 0x22, 0x52,
|
||||
0x05, 0x6b, 0x79, 0x63, 0x49, 0x64, 0x22, 0x76, 0x0a, 0x0a, 0x45, 0x74, 0x68, 0x50, 0x61, 0x79,
|
||||
0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xf2, 0xde, 0x1f, 0x1d, 0x6a, 0x73, 0x6f, 0x6e, 0x3a,
|
||||
0x22, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22,
|
||||
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
|
||||
0x73, 0x12, 0x2b, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19,
|
||||
0xf2, 0xde, 0x1f, 0x15, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x6d, 0x73, 0x67, 0x22, 0x20, 0x79,
|
||||
0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x73, 0x67, 0x22, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x42, 0xd4,
|
||||
0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x65, 0x72, 0x63, 0x2e, 0x6f, 0x6e, 0x62, 0x6f,
|
||||
0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0f, 0x4f, 0x6e, 0x62, 0x6f, 0x61,
|
||||
0x72, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x69,
|
||||
0x74, 0x2e, 0x76, 0x64, 0x62, 0x2e, 0x74, 0x6f, 0x2f, 0x63, 0x65, 0x72, 0x63, 0x2d, 0x69, 0x6f,
|
||||
0x2f, 0x6c, 0x61, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x65,
|
||||
0x72, 0x63, 0x2f, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31,
|
||||
0x3b, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03,
|
||||
0x43, 0x4f, 0x58, 0xaa, 0x02, 0x12, 0x43, 0x65, 0x72, 0x63, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61,
|
||||
0x72, 0x64, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x43, 0x65, 0x72, 0x63, 0x5c,
|
||||
0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e,
|
||||
0x43, 0x65, 0x72, 0x63, 0x5c, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5c,
|
||||
0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
|
||||
0x14, 0x43, 0x65, 0x72, 0x63, 0x3a, 0x3a, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e,
|
||||
0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6f, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1b, 0xf2, 0xde, 0x1f, 0x17, 0x6a, 0x73, 0x6f, 0x6e,
|
||||
0x3a, 0x22, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x72, 0x6f,
|
||||
0x6c, 0x65, 0x22, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x36, 0x0a, 0x06, 0x6b, 0x79, 0x63,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1f, 0xf2, 0xde, 0x1f, 0x1b, 0x6a,
|
||||
0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x6b, 0x79, 0x63, 0x5f, 0x69, 0x64, 0x22, 0x20, 0x79, 0x61, 0x6d,
|
||||
0x6c, 0x3a, 0x22, 0x6b, 0x79, 0x63, 0x5f, 0x69, 0x64, 0x22, 0x52, 0x05, 0x6b, 0x79, 0x63, 0x49,
|
||||
0x64, 0x22, 0x76, 0x0a, 0x0a, 0x45, 0x74, 0x68, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12,
|
||||
0x3b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x42, 0x21, 0xf2, 0xde, 0x1f, 0x1d, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x61, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x61, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x22, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x03,
|
||||
0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xf2, 0xde, 0x1f, 0x15, 0x6a,
|
||||
0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x6d, 0x73, 0x67, 0x22, 0x20, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22,
|
||||
0x6d, 0x73, 0x67, 0x22, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x42, 0xd4, 0x01, 0x0a, 0x16, 0x63, 0x6f,
|
||||
0x6d, 0x2e, 0x63, 0x65, 0x72, 0x63, 0x2e, 0x6f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e,
|
||||
0x67, 0x2e, 0x76, 0x31, 0x42, 0x0f, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x2e, 0x76, 0x64, 0x62,
|
||||
0x2e, 0x74, 0x6f, 0x2f, 0x63, 0x65, 0x72, 0x63, 0x2d, 0x69, 0x6f, 0x2f, 0x6c, 0x61, 0x63, 0x6f,
|
||||
0x6e, 0x69, 0x63, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x65, 0x72, 0x63, 0x2f, 0x6f, 0x6e,
|
||||
0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x6e, 0x62, 0x6f,
|
||||
0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x4f, 0x58, 0xaa, 0x02,
|
||||
0x12, 0x43, 0x65, 0x72, 0x63, 0x2e, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67,
|
||||
0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x43, 0x65, 0x72, 0x63, 0x5c, 0x4f, 0x6e, 0x62, 0x6f, 0x61,
|
||||
0x72, 0x64, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x43, 0x65, 0x72, 0x63, 0x5c,
|
||||
0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50,
|
||||
0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x43, 0x65, 0x72, 0x63,
|
||||
0x3a, 0x3a, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
32
app/app.go
32
app/app.go
@ -19,9 +19,11 @@ import (
|
||||
govkeeper "cosmossdk.io/x/gov/keeper"
|
||||
slashingkeeper "cosmossdk.io/x/slashing/keeper"
|
||||
stakingkeeper "cosmossdk.io/x/staking/keeper"
|
||||
"git.vdb.to/cerc-io/laconicd/server/distsig"
|
||||
"git.vdb.to/cerc-io/laconicd/utils"
|
||||
auctionkeeper "git.vdb.to/cerc-io/laconicd/x/auction/keeper"
|
||||
bondkeeper "git.vdb.to/cerc-io/laconicd/x/bond/keeper"
|
||||
nitrokeeper "git.vdb.to/cerc-io/laconicd/x/nitrobank/keeper"
|
||||
onboardingkeeper "git.vdb.to/cerc-io/laconicd/x/onboarding/keeper"
|
||||
registrykeeper "git.vdb.to/cerc-io/laconicd/x/registry/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
@ -30,12 +32,10 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/std"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
|
||||
_ "cosmossdk.io/api/cosmos/tx/config/v1" // import for side-effects
|
||||
_ "cosmossdk.io/x/accounts" // import for side-effects
|
||||
_ "cosmossdk.io/x/bank" // import for side-effects
|
||||
|
||||
// _ "cosmossdk.io/x/bank/v2" // import for side-effects
|
||||
_ "cosmossdk.io/api/cosmos/tx/config/v1" // import for side-effects
|
||||
_ "cosmossdk.io/runtime/v2/services" // import for side-effects
|
||||
_ "cosmossdk.io/x/accounts" // import for side-effects
|
||||
_ "cosmossdk.io/x/bank" // import for side-effects
|
||||
_ "cosmossdk.io/x/consensus" // import for side-effects
|
||||
_ "cosmossdk.io/x/distribution" // import for side-effects
|
||||
_ "cosmossdk.io/x/gov" // import for side-effects
|
||||
@ -56,7 +56,7 @@ var (
|
||||
//go:embed app.yaml
|
||||
AppConfigYAML []byte
|
||||
|
||||
_ = basedepinject.ProvideAccount // TODO
|
||||
_ = basedepinject.ProvideAccount // TODO: build consensus controlled module accounts
|
||||
)
|
||||
|
||||
type (
|
||||
@ -75,7 +75,9 @@ type LaconicApp[T Tx] struct {
|
||||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
store store.RootStore
|
||||
|
||||
// keepers
|
||||
distsigManager *distsig.Manager
|
||||
|
||||
// basic keepers
|
||||
AccountKeeper authkeeper.AccountKeeper
|
||||
BankKeeper bankkeeper.Keeper
|
||||
StakingKeeper *stakingkeeper.Keeper
|
||||
@ -89,6 +91,7 @@ type LaconicApp[T Tx] struct {
|
||||
BondKeeper *bondkeeper.Keeper
|
||||
RegistryKeeper registrykeeper.Keeper
|
||||
OnboardingKeeper *onboardingkeeper.Keeper
|
||||
NitroKeeper *nitrokeeper.Keeper
|
||||
}
|
||||
|
||||
// AppConfig returns the default app config.
|
||||
@ -107,6 +110,7 @@ func AppConfig() depinject.Config {
|
||||
codec.ProvideProtoCodec,
|
||||
codec.ProvideLegacyAmino, // note: needed by ProvideAppBuilder (runtime/v2)
|
||||
ProvideRootStoreConfig,
|
||||
distsig.ProvideManager,
|
||||
|
||||
// // inject desired account types:
|
||||
// basedepinject.ProvideAccount,
|
||||
@ -142,6 +146,7 @@ func NewLaconicApp[T Tx](
|
||||
// &app.legacyAmino,
|
||||
&app.txConfig,
|
||||
&app.interfaceRegistry,
|
||||
&app.distsigManager,
|
||||
&app.StakingKeeper,
|
||||
&app.AccountKeeper,
|
||||
&app.BankKeeper,
|
||||
@ -162,8 +167,6 @@ func NewLaconicApp[T Tx](
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// // TODO: db config correct?
|
||||
// // TODO: store tracer injection?
|
||||
app.App, err = appBuilder.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -174,9 +177,10 @@ func NewLaconicApp[T Tx](
|
||||
return nil, fmt.Errorf("store builder did not return a db")
|
||||
}
|
||||
|
||||
// TODO: review streaming services
|
||||
|
||||
// Note: upgrade handlers are registered here in simapp
|
||||
// TODO: db config correct?
|
||||
// TODO: store metrics, tracer?
|
||||
// TODO: streaming services?
|
||||
// TODO: upgrade handlers?
|
||||
|
||||
if err = app.LoadLatest(); err != nil {
|
||||
return nil, err
|
||||
@ -197,6 +201,10 @@ func (app *LaconicApp[T]) AppCodec() codec.Codec {
|
||||
return app.appCodec
|
||||
}
|
||||
|
||||
func (app *LaconicApp[T]) DistSigManager() *distsig.Manager {
|
||||
return app.distsigManager
|
||||
}
|
||||
|
||||
func ProvideRootStoreConfig(config runtime.GlobalConfig) (*root.Config, error) {
|
||||
return serverstore.UnmarshalConfig(config)
|
||||
}
|
||||
|
107
app/app_abci.go
Normal file
107
app/app_abci.go
Normal file
@ -0,0 +1,107 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/gob"
|
||||
|
||||
"cosmossdk.io/core/store"
|
||||
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/server/distsig"
|
||||
"git.vdb.to/cerc-io/laconicd/x/onboarding"
|
||||
)
|
||||
|
||||
func (app *LaconicApp[T]) ExtendVote(
|
||||
ctx context.Context, _ store.ReaderMap, req *abci.ExtendVoteRequest,
|
||||
) (*abci.ExtendVoteResponse, error) {
|
||||
dsm := app.DistSigManager()
|
||||
ourEthAddress := dsm.LongtermEthAddress()
|
||||
us, err := app.OnboardingKeeper.GetParticipantByNitroAddress(ctx, ourEthAddress.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if us == nil { // if we are not a participant, we don't need to do anything
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// // If any OnboardParticipant tx (or any tx that changes validator set) has been processed,
|
||||
// // begin DKG for the new participants. The extension will contain our DKG deals.
|
||||
// newParticipants := false
|
||||
// for _, tx := range req.Txs {
|
||||
// var opMsg onboarding.MsgOnboardParticipant
|
||||
// if err := opMsg.Unmarshal(tx); err != nil {
|
||||
// // we've already processed the tx, so we don't need to look at the message; we know the
|
||||
// // participant set has changed and we need to run DKG.
|
||||
// newParticipants = true
|
||||
// }
|
||||
// }
|
||||
// // TODO: check if responses are processed, generate commits
|
||||
// if !newParticipants {
|
||||
// return nil, nil
|
||||
// }
|
||||
|
||||
// Get public keys of participants
|
||||
var pubkeys []distsig.Point
|
||||
if err := app.OnboardingKeeper.Participants.Walk(ctx, nil, func(_ string, p onboarding.Participant) (bool, error) {
|
||||
var pubkey distsig.Point
|
||||
if err := pubkey.UnmarshalBinary(p.PublicKey); err != nil {
|
||||
return false, err
|
||||
}
|
||||
pubkeys = append(pubkeys, pubkey)
|
||||
return false, nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !dsm.NeedDKG(pubkeys) {
|
||||
app.Logger().Debug("No change in DSS participants")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if err = dsm.StartDKG(req.Height, pubkeys); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
enc := gob.NewEncoder(buf)
|
||||
if err := enc.Encode(dsm.FlushDKGMessages()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var extension []byte
|
||||
if len(buf.Bytes()) != 0 {
|
||||
extension = buf.Bytes()
|
||||
}
|
||||
return &abci.ExtendVoteResponse{
|
||||
VoteExtension: extension,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (app *LaconicApp[T]) VerifyVoteExtension(
|
||||
ctx context.Context, _ store.ReaderMap, req *abci.VerifyVoteExtensionRequest,
|
||||
) (*abci.VerifyVoteExtensionResponse, error) {
|
||||
dec := gob.NewDecoder(bytes.NewReader(req.VoteExtension))
|
||||
var messages distsig.DkgMessages
|
||||
if err := dec.Decode(&messages); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// // This method must be deterministic, so just check that there is a deal for each participant
|
||||
// numParticipants := 0
|
||||
// app.OnboardingKeeper.Participants.Walk(ctx, nil, func(string, onboarding.Participant) (bool, error) {
|
||||
// numParticipants++
|
||||
// return false, nil
|
||||
// })
|
||||
// if len(deals) != numParticipants {
|
||||
// return &abci.VerifyVoteExtensionResponse{
|
||||
// Status: abci.VERIFY_VOTE_EXTENSION_STATUS_REJECT,
|
||||
// }, nil
|
||||
// }
|
||||
|
||||
err := app.DistSigManager().ProcessDKGMessages(&messages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// This method must be deterministic, so just accept whatever for now (TODO: actually verify)
|
||||
return &abci.VerifyVoteExtensionResponse{
|
||||
Status: abci.VERIFY_VOTE_EXTENSION_STATUS_ACCEPT,
|
||||
}, nil
|
||||
}
|
@ -26,15 +26,14 @@ import (
|
||||
"cosmossdk.io/store/v2/db"
|
||||
banktypes "cosmossdk.io/x/bank/types"
|
||||
|
||||
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdktestutil "github.com/cosmos/cosmos-sdk/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/mock"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
modtestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/testutil"
|
||||
)
|
||||
|
||||
func NewTestApp(t *testing.T) (*LaconicApp[Tx], context.Context) {
|
||||
@ -47,10 +46,8 @@ func NewTestApp(t *testing.T) (*LaconicApp[Tx], context.Context) {
|
||||
vp.Set(serverv2.FlagHome, t.TempDir())
|
||||
|
||||
// set up long-term distsig key
|
||||
codecOpts := codectestutil.NewCodecOptionsWithCodecs(utils.NewAddressCodec(), utils.NewValAddressCodec())
|
||||
encCfg := modtestutil.MakeTestEncodingConfig(codecOpts)
|
||||
kr := keyring.NewInMemory(encCfg.Codec)
|
||||
accounts := testutil.CreateKeyringAccounts(t, kr, 1)
|
||||
kr := testutil.NewKeyring()
|
||||
accounts := sdktestutil.CreateKeyringAccounts(t, kr, 1)
|
||||
vp.Set(distsig.FlagLongtermKey, accounts[0].Name)
|
||||
|
||||
app, err := NewLaconicApp[Tx](depinject.Configs(
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"cosmossdk.io/server/v2/cometbft"
|
||||
serverstore "cosmossdk.io/server/v2/store"
|
||||
confixcmd "cosmossdk.io/tools/confix/cmd"
|
||||
|
||||
// "cosmossdk.io/x/accounts"
|
||||
|
||||
// "cosmossdk.io/x/accounts"
|
||||
@ -35,7 +36,8 @@ import (
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/app"
|
||||
"git.vdb.to/cerc-io/laconicd/gql"
|
||||
"git.vdb.to/cerc-io/laconicd/nitro"
|
||||
"git.vdb.to/cerc-io/laconicd/server/distsig"
|
||||
"git.vdb.to/cerc-io/laconicd/server/nitro"
|
||||
// "git.vdb.to/cerc-io/laconicd/x/nitrobank"
|
||||
)
|
||||
|
||||
@ -43,11 +45,11 @@ import (
|
||||
// an alternative design could fetch these even later from the command context
|
||||
type CommandDependencies[T app.Tx] struct {
|
||||
GlobalConfig coreserver.ConfigMap
|
||||
TxConfig client.TxConfig
|
||||
ModuleManager *runtimev2.MM[T]
|
||||
LaconicApp *app.LaconicApp[T]
|
||||
ConsensusServer *cometbft.CometBFTServer[T]
|
||||
ClientContext client.Context
|
||||
DistSigManager *distsig.Manager
|
||||
}
|
||||
|
||||
func InitRootCmd[T app.Tx](
|
||||
@ -90,8 +92,9 @@ func InitRootCmd[T app.Tx](
|
||||
&serverstore.Server[T]{},
|
||||
&telemetry.Server[T]{},
|
||||
&rest.Server[T]{},
|
||||
&nitro.Server{},
|
||||
&gql.Server{},
|
||||
&nitro.Server{},
|
||||
&distsig.Manager{},
|
||||
)
|
||||
}
|
||||
|
||||
@ -116,13 +119,13 @@ func InitRootCmd[T app.Tx](
|
||||
app.App.AppManager,
|
||||
cometbft.AppCodecs[T]{
|
||||
AppCodec: app.AppCodec(),
|
||||
TxCodec: &client.DefaultTxDecoder[T]{TxConfig: deps.TxConfig},
|
||||
TxCodec: &client.DefaultTxDecoder[T]{TxConfig: deps.ClientContext.TxConfig},
|
||||
LegacyAmino: deps.ClientContext.LegacyAmino,
|
||||
ConsensusAddressCodec: deps.ClientContext.ConsensusAddressCodec,
|
||||
},
|
||||
app.App.QueryHandlers(),
|
||||
app.App.SchemaDecoderResolver(),
|
||||
initCometOptions[T](),
|
||||
initCometOptions[T](app),
|
||||
deps.GlobalConfig,
|
||||
)
|
||||
if err != nil {
|
||||
@ -151,14 +154,11 @@ func InitRootCmd[T app.Tx](
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// nitrobank := deps.ModuleManager.Modules()[nitrobank.ModuleName].(nitrobank.AppModule)
|
||||
// accounts := deps.ModuleManager.Modules()[accounts.ModuleName]
|
||||
nitroServer, err := nitro.NewServer(logger, deps.GlobalConfig, deps.ClientContext)
|
||||
gqlServer, err := gql.New(logger, deps.GlobalConfig, deps.ClientContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gqlServer, err := gql.New(logger, deps.GlobalConfig, deps.ClientContext)
|
||||
nitroServer, err := nitro.NewServer(logger, deps.GlobalConfig, deps.ClientContext.Keyring)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -175,8 +175,9 @@ func InitRootCmd[T app.Tx](
|
||||
storeComponent,
|
||||
telemetryServer,
|
||||
restServer,
|
||||
nitroServer,
|
||||
gqlServer,
|
||||
nitroServer,
|
||||
deps.DistSigManager,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -5,11 +5,12 @@ import (
|
||||
|
||||
cmtcfg "github.com/cometbft/cometbft/config"
|
||||
|
||||
"cosmossdk.io/core/transaction"
|
||||
serverv2 "cosmossdk.io/server/v2"
|
||||
"cosmossdk.io/server/v2/cometbft"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"cosmossdk.io/core/transaction"
|
||||
"git.vdb.to/cerc-io/laconicd/app"
|
||||
)
|
||||
|
||||
// initAppConfig helps to override default client config template and configs.
|
||||
@ -49,12 +50,19 @@ func initCometConfig() cometbft.CfgOption {
|
||||
cfg.Consensus.TimeoutCommit = 3 * time.Second
|
||||
// overwrite default pprof listen address
|
||||
cfg.RPC.PprofListenAddress = "localhost:6060"
|
||||
// use previous db backend
|
||||
cfg.DBBackend = "goleveldb"
|
||||
|
||||
return cometbft.OverwriteDefaultConfigTomlConfig(cfg)
|
||||
}
|
||||
|
||||
func initCometOptions[T transaction.Tx]() cometbft.ServerOptions[T] {
|
||||
func initCometOptions[T transaction.Tx](laconic *app.LaconicApp[T]) cometbft.ServerOptions[T] {
|
||||
serverOptions := cometbft.DefaultServerOptions[T]()
|
||||
// Implement custom handlers (e.g. for Vote Extensions)
|
||||
// serverOptions.PrepareProposalHandler = CustomPrepareProposal[T]()
|
||||
// serverOptions.ProcessProposalHandler = CustomProcessProposalHandler[T]()
|
||||
serverOptions.ExtendVoteHandler = laconic.ExtendVote
|
||||
serverOptions.VerifyVoteExtensionHandler = laconic.VerifyVoteExtension
|
||||
|
||||
// overwrite app mempool, using max-txs option
|
||||
// serverOptions.Mempool = func(cfg map[string]any) mempool.Mempool[T] {
|
||||
@ -63,7 +71,6 @@ func initCometOptions[T transaction.Tx]() cometbft.ServerOptions[T] {
|
||||
// sdkmempool.SenderNonceMaxTxOpt(maxTxs),
|
||||
// )
|
||||
// }
|
||||
|
||||
// return mempool.NoOpMempool[T]{}
|
||||
// }
|
||||
|
||||
|
@ -6,13 +6,14 @@ import (
|
||||
"cosmossdk.io/core/address"
|
||||
runtime "cosmossdk.io/runtime/v2"
|
||||
serverv2 "cosmossdk.io/server/v2"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/server/nitro"
|
||||
)
|
||||
|
||||
func ProvideClientContext(
|
||||
@ -63,3 +64,7 @@ func ProvideClientContext(
|
||||
func ProvideKeyring(clientCtx client.Context) keyring.Keyring {
|
||||
return clientCtx.Keyring
|
||||
}
|
||||
|
||||
func ProvideNitroService(configMap runtime.GlobalConfig) (nitro.Service, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node"
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/app"
|
||||
"git.vdb.to/cerc-io/laconicd/server/distsig"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -74,14 +75,21 @@ func NewRootCmd[T app.Tx](
|
||||
moduleManager *runtime.MM[T]
|
||||
clientCtx client.Context
|
||||
laconic *app.LaconicApp[T]
|
||||
dsManager *distsig.Manager
|
||||
depinjectConfig = depinject.Configs(
|
||||
depinject.Supply(logger, runtime.GlobalConfig(configMap)),
|
||||
depinject.Provide(ProvideClientContext),
|
||||
depinject.Provide(
|
||||
ProvideClientContext,
|
||||
ProvideKeyring,
|
||||
),
|
||||
)
|
||||
)
|
||||
if serverv2.IsAppRequired(subCommand) {
|
||||
// server construction
|
||||
laconic, err = app.NewLaconicApp[T](depinjectConfig, &autoCliOpts, &moduleManager, &clientCtx)
|
||||
laconic, err = app.NewLaconicApp[T](
|
||||
depinjectConfig,
|
||||
&autoCliOpts, &moduleManager, &clientCtx, &dsManager,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -92,18 +100,18 @@ func NewRootCmd[T app.Tx](
|
||||
app.AppConfig(),
|
||||
depinjectConfig,
|
||||
),
|
||||
&autoCliOpts, &moduleManager, &clientCtx,
|
||||
&autoCliOpts, &moduleManager, &clientCtx, &dsManager,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
commandDeps := CommandDependencies[T]{
|
||||
GlobalConfig: configMap,
|
||||
TxConfig: clientCtx.TxConfig,
|
||||
ModuleManager: moduleManager,
|
||||
LaconicApp: laconic,
|
||||
ClientContext: clientCtx,
|
||||
GlobalConfig: configMap,
|
||||
ModuleManager: moduleManager,
|
||||
LaconicApp: laconic,
|
||||
ClientContext: clientCtx,
|
||||
DistSigManager: dsManager,
|
||||
}
|
||||
rootCommand = &cobra.Command{
|
||||
Use: "laconicd",
|
||||
|
16
go.mod
16
go.mod
@ -26,6 +26,7 @@ require (
|
||||
cosmossdk.io/store v1.10.0-rc.1
|
||||
cosmossdk.io/store/v2 v2.0.0-beta.1
|
||||
cosmossdk.io/tools/confix v0.1.0
|
||||
git.vdb.to/cerc-io/chainsig v0.1.0
|
||||
github.com/99designs/gqlgen v0.17.22
|
||||
github.com/cometbft/cometbft v1.0.0
|
||||
github.com/cosmos/cosmos-proto v1.0.0-beta.5
|
||||
@ -40,6 +41,7 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/ipfs/go-cid v0.4.1
|
||||
github.com/ipld/go-ipld-prime v0.21.0
|
||||
github.com/lmittmann/tint v1.0.2
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
@ -48,6 +50,7 @@ require (
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
github.com/tidwall/sjson v1.2.5
|
||||
github.com/vektah/gqlparser/v2 v2.5.11
|
||||
go.dedis.ch/kyber/v3 v3.1.0
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1
|
||||
google.golang.org/grpc v1.68.1
|
||||
@ -67,7 +70,7 @@ require (
|
||||
cosmossdk.io/x/protocolpool v1.0.0-alpha.4
|
||||
cosmossdk.io/x/slashing v0.0.0-20241007000829-38662ecb209f
|
||||
cosmossdk.io/x/staking v1.0.0-alpha.4
|
||||
github.com/lmittmann/tint v1.0.2
|
||||
github.com/cometbft/cometbft/api v1.0.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -112,7 +115,6 @@ require (
|
||||
github.com/cockroachdb/redact v1.1.5 // indirect
|
||||
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
||||
github.com/cometbft/cometbft-db v1.0.1 // indirect
|
||||
github.com/cometbft/cometbft/api v1.0.0 // indirect
|
||||
github.com/consensys/bavard v0.1.13 // indirect
|
||||
github.com/consensys/gnark-crypto v0.12.1 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
@ -321,6 +323,8 @@ require (
|
||||
github.com/zondax/ledger-go v0.14.3 // indirect
|
||||
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
|
||||
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
|
||||
go.dedis.ch/fixbuf v1.0.3 // indirect
|
||||
go.dedis.ch/protobuf v1.0.11 // indirect
|
||||
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
@ -354,8 +358,11 @@ require (
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
// github.com/statechannels/go-nitro v0.1.2 => github.com/cerc-io/go-nitro v0.1.3-ts-port-0.1.10
|
||||
replace github.com/statechannels/go-nitro => ../mod/go-nitro
|
||||
replace (
|
||||
git.vdb.to/cerc-io/chainsig => ../mod/chainsig
|
||||
// github.com/statechannels/go-nitro v0.1.2 => github.com/cerc-io/go-nitro v0.1.3-ts-port-0.1.10
|
||||
github.com/statechannels/go-nitro => ../mod/go-nitro
|
||||
)
|
||||
|
||||
// replace (
|
||||
// cosmossdk.io/core v0.7.6 => github.com/roysc/cosmos-sdk/core v0.0.0-20241001191620-a3729c1ad6ba
|
||||
@ -410,6 +417,7 @@ replace (
|
||||
replace (
|
||||
github.com/cometbft/cometbft => ../mod/cometbft
|
||||
github.com/cosmos/cosmos-sdk => ../mod/cosmos-sdk
|
||||
go.dedis.ch/kyber/v3 => ../mod/kyber
|
||||
)
|
||||
|
||||
// replace google.golang.org/protobuf => /Users/roy/clone/protobuf-go
|
||||
|
6
go.sum
6
go.sum
@ -935,6 +935,10 @@ gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRyS
|
||||
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=
|
||||
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
|
||||
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I=
|
||||
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
|
||||
go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw=
|
||||
go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo=
|
||||
go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4=
|
||||
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 h1:qxen9oVGzDdIRP6ejyAJc760RwW4SnVDiTYTzwnXuxo=
|
||||
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5/go.mod h1:eW0HG9/oHQhvRCvb1/pIXW4cOvtDqeQK+XSi3TnwaXY=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
@ -974,6 +978,7 @@ golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -1064,6 +1069,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/gql/schema"
|
||||
"git.vdb.to/cerc-io/laconicd/utils"
|
||||
auctiontypes "git.vdb.to/cerc-io/laconicd/x/auction"
|
||||
bondtypes "git.vdb.to/cerc-io/laconicd/x/bond"
|
||||
onboardingTypes "git.vdb.to/cerc-io/laconicd/x/onboarding"
|
||||
@ -407,9 +408,13 @@ func (q queryResolver) GetParticipants(ctx context.Context) ([]*schema.Participa
|
||||
|
||||
participants := make([]*schema.Participant, len(participantResp.GetParticipants()))
|
||||
for i, p := range participantResp.Participants {
|
||||
nitroAddress, err := utils.EthAddressFromPubKey(p.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
participants[i] = &schema.Participant{
|
||||
CosmosAddress: p.CosmosAddress,
|
||||
NitroAddress: p.NitroAddress,
|
||||
NitroAddress: nitroAddress.String(),
|
||||
Role: p.Role,
|
||||
KycID: p.KycId,
|
||||
}
|
||||
@ -426,9 +431,13 @@ func (q queryResolver) GetParticipantByAddress(ctx context.Context, address stri
|
||||
}
|
||||
|
||||
p := participantResp.Participant
|
||||
nitroAddress, err := utils.EthAddressFromPubKey(p.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
participant := &schema.Participant{
|
||||
CosmosAddress: p.CosmosAddress,
|
||||
NitroAddress: p.NitroAddress,
|
||||
NitroAddress: nitroAddress.String(),
|
||||
Role: p.Role,
|
||||
KycID: p.KycId,
|
||||
}
|
||||
@ -451,7 +460,7 @@ func (q queryResolver) GetParticipantByNitroAddress(ctx context.Context, nitroAd
|
||||
p := participantResp.Participant
|
||||
participant := &schema.Participant{
|
||||
CosmosAddress: p.CosmosAddress,
|
||||
NitroAddress: p.NitroAddress,
|
||||
NitroAddress: nitroAddress,
|
||||
Role: p.Role,
|
||||
KycID: p.KycId,
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ message MsgOpenChannel {
|
||||
message MsgOpenChannelResponse {}
|
||||
|
||||
service Msg {
|
||||
option (cosmos.msg.v1.service) = true;
|
||||
|
||||
rpc ProposeChannel(MsgProposeChannel) returns (MsgProposeChannelResponse) {
|
||||
option (google.api.http).post = "/cerc/nitrobank/v1/propose_channel";
|
||||
}
|
||||
|
@ -21,10 +21,8 @@ message Participant {
|
||||
[ (gogoproto.moretags) =
|
||||
"json:\"cosmos_address\" yaml:\"cosmos_address\"" ];
|
||||
|
||||
// participant's Nitro address
|
||||
string nitro_address = 2
|
||||
[ (gogoproto.moretags) =
|
||||
"json:\"nitro_address\" yaml:\"nitro_address\"" ];
|
||||
// full public key used to derive participant's Nitro address
|
||||
bytes public_key = 2;
|
||||
|
||||
// participant's role (participant | validator)
|
||||
string role = 3 [ (gogoproto.moretags) = "json:\"role\" yaml:\"role\"" ];
|
||||
|
13
server/distsig/config.go
Normal file
13
server/distsig/config.go
Normal file
@ -0,0 +1,13 @@
|
||||
package distsig
|
||||
|
||||
type Config struct {
|
||||
LongtermKey string `mapstructure:"longterm-key" toml:"longterm-key" comment:"The long-term key used in distributed signatures"`
|
||||
// TODO: set this in genesis
|
||||
ThresholdRatio float64 `mapstructure:"threshold-ratio" toml:"threshold-ratio" comment:"The ratio of signers required to sign a message"`
|
||||
}
|
||||
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
ThresholdRatio: 4. / 7,
|
||||
}
|
||||
}
|
175
server/distsig/distsig_test.go
Normal file
175
server/distsig/distsig_test.go
Normal file
@ -0,0 +1,175 @@
|
||||
package distsig
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
"git.vdb.to/cerc-io/chainsig/ethschnorr"
|
||||
sdktestutil "github.com/cosmos/cosmos-sdk/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/testutil"
|
||||
)
|
||||
|
||||
func NewTestManager(t *testing.T) (*Manager, Point) {
|
||||
logger := log.NewTestLogger(t)
|
||||
kr := testutil.NewKeyring()
|
||||
accounts := sdktestutil.CreateKeyringAccounts(t, kr, 1)
|
||||
cfg := DefaultConfig()
|
||||
cfg.LongtermKey = accounts[0].Name
|
||||
|
||||
dsm, err := New(logger, cfg, kr)
|
||||
require.NoError(t, err)
|
||||
|
||||
longterm, err := kr.Key(cfg.LongtermKey)
|
||||
require.NoError(t, err)
|
||||
longtermPoint, err := KeyRecordToPoint(longterm)
|
||||
require.NoError(t, err)
|
||||
|
||||
return dsm, longtermPoint
|
||||
}
|
||||
|
||||
type round struct {
|
||||
name string
|
||||
verify func(*Manager) error
|
||||
tweak func([]PeerMessages)
|
||||
}
|
||||
|
||||
var (
|
||||
dkgRounds = []round{
|
||||
{
|
||||
name: "deal",
|
||||
},
|
||||
{
|
||||
name: "response",
|
||||
verify: func(m *Manager) error {
|
||||
if !m.currentDkg().Certified() {
|
||||
return errors.New("not certified")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "commit",
|
||||
verify: func(m *Manager) error {
|
||||
if !m.currentDkg().Finished() {
|
||||
return errors.New("run not finished")
|
||||
}
|
||||
if m.currentDkg().share == nil {
|
||||
return errors.New("dist key share is absent")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
dssRounds = []round{
|
||||
{
|
||||
name: "sign",
|
||||
verify: func(m *Manager) error {
|
||||
dss := m.sigs[m.completeSigs[0]]
|
||||
if dss.sig == nil {
|
||||
return errors.New("signature is nil")
|
||||
}
|
||||
dkg, err := m.getDkg(dss.dkgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ethschnorr.Verify(dkg.share.Public(), dss.Message(), dss.sig)
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func runRound(t *testing.T, r round, members []*Manager) {
|
||||
buf := make([]PeerMessages, len(members))
|
||||
for i := range members {
|
||||
buf[i] = members[i].FlushMessages()
|
||||
}
|
||||
if r.tweak != nil {
|
||||
r.tweak(buf)
|
||||
}
|
||||
for i := range members {
|
||||
for j := range members {
|
||||
if i == j {
|
||||
continue
|
||||
}
|
||||
require.NoError(t, members[i].ProcessMessages(&buf[j]),
|
||||
"round=%s, i=%d, j=%d", r.name, i, j)
|
||||
}
|
||||
}
|
||||
if r.verify != nil {
|
||||
for i, m := range members {
|
||||
require.NoError(t, r.verify(m), "round=%s, i=%d", r.name, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDkgBasic(t *testing.T) {
|
||||
numMembers := 2
|
||||
blockHeight := int64(1)
|
||||
|
||||
members := make([]*Manager, numMembers)
|
||||
pubkeys := make([]Point, numMembers)
|
||||
for i := range members {
|
||||
members[i], pubkeys[i] = NewTestManager(t)
|
||||
}
|
||||
t.Logf("DKG with %d members", numMembers)
|
||||
|
||||
for i, m := range members {
|
||||
require.NoError(t, m.StartDKG(blockHeight, pubkeys), "i=%d", i)
|
||||
}
|
||||
for _, r := range dkgRounds {
|
||||
runRound(t, r, members)
|
||||
}
|
||||
|
||||
require.False(t, members[0].NeedDKG(pubkeys))
|
||||
require.Error(t, members[0].StartDKG(blockHeight, pubkeys))
|
||||
|
||||
// add participants and refresh DKG
|
||||
for len(members) < 7 {
|
||||
blockHeight++
|
||||
|
||||
m, pub := NewTestManager(t)
|
||||
members = append(members, m)
|
||||
pubkeys = append(pubkeys, pub)
|
||||
t.Logf("DKG with %d members", len(members))
|
||||
|
||||
for i, m := range members {
|
||||
require.True(t, m.NeedDKG(pubkeys), "i=%d", i)
|
||||
require.NoError(t, m.StartDKG(blockHeight, pubkeys), "i=%d", i)
|
||||
}
|
||||
for _, r := range dkgRounds {
|
||||
runRound(t, r, members)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureBasic(t *testing.T) {
|
||||
numMembers := 7
|
||||
|
||||
members := make([]*Manager, numMembers)
|
||||
pubkeys := make([]Point, numMembers)
|
||||
for i := range members {
|
||||
members[i], pubkeys[i] = NewTestManager(t)
|
||||
}
|
||||
|
||||
for _, m := range members {
|
||||
require.NoError(t, m.StartDKG(1, pubkeys))
|
||||
}
|
||||
for _, r := range dkgRounds {
|
||||
runRound(t, r, members)
|
||||
}
|
||||
|
||||
msg := big.NewInt(42)
|
||||
for _, m := range members {
|
||||
require.NoError(t, m.StartSignature(m.currentDkgID, msg))
|
||||
}
|
||||
runRound(t, dssRounds[0], members)
|
||||
|
||||
require.Error(t, members[0].StartSignature(0, msg))
|
||||
|
||||
require.NoError(t, members[0].StartDKG(2, pubkeys[:3]))
|
||||
require.Error(t, members[0].StartSignature(2, msg))
|
||||
}
|
224
server/distsig/keygen.go
Normal file
224
server/distsig/keygen.go
Normal file
@ -0,0 +1,224 @@
|
||||
package distsig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
dkg "go.dedis.ch/kyber/v3/share/dkg/rabin"
|
||||
)
|
||||
|
||||
// DkgMessages collects local DKG messages that are pending broadcast.
|
||||
type DkgMessages struct {
|
||||
runID DkgRunID
|
||||
messages []dkgMessage
|
||||
}
|
||||
|
||||
// DKG steps (actions) that are executed by the DKG protocol
|
||||
type dkgStep int
|
||||
|
||||
const (
|
||||
dkg_deal dkgStep = iota
|
||||
dkg_certify
|
||||
dkg_commit
|
||||
dkg_finish
|
||||
dkg_done
|
||||
)
|
||||
|
||||
type dkgRun struct {
|
||||
*dkg.DistKeyGenerator
|
||||
// runID RunID
|
||||
msgBuffer []dkgMessage
|
||||
step dkgStep
|
||||
share *dkg.DistKeyShare
|
||||
}
|
||||
|
||||
type dkgMessage interface {
|
||||
send(*dkgRun) (dkgMessage, error)
|
||||
from() uint32
|
||||
target() uint32
|
||||
}
|
||||
|
||||
// prepareMessages produces DKG state transitions that don't rely on peer inputs, i.e. the deal or
|
||||
// commit steps. This is called during ExtendVote by all validators.
|
||||
func (d *dkgRun) prepareMessages() error {
|
||||
out, err := d.handleMessage(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if out != nil {
|
||||
d.msgBuffer = append(d.msgBuffer, out...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dkgRun) flushMessages() []dkgMessage {
|
||||
buf := d.msgBuffer
|
||||
d.msgBuffer = nil
|
||||
return buf
|
||||
}
|
||||
|
||||
// processMessages processes incoming DKG messages and produces outgoing messages. This is called
|
||||
// during VerifyVoteExtension by all validators (TODO: verify).
|
||||
func (d *dkgRun) processMessages(in []dkgMessage) error {
|
||||
for _, msg := range in {
|
||||
out, err := d.handleMessage(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if out != nil {
|
||||
d.msgBuffer = append(d.msgBuffer, out...)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dkgRun) handleMessage(in dkgMessage) ([]dkgMessage, error) {
|
||||
// fmt.Printf("[%d, %7s] handle: %T", d.index, d.step, in)
|
||||
// if in != nil {
|
||||
// fmt.Printf(" (from %d to %+v)", in.from(), in.target())
|
||||
// }
|
||||
// fmt.Println()
|
||||
|
||||
// nil input means we try to execute a step requiring no peer input
|
||||
if in == nil {
|
||||
var out []dkgMessage
|
||||
switch d.step {
|
||||
case dkg_deal:
|
||||
deals, err := d.Deals()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for index, deal := range deals {
|
||||
out = append(out, msgDeal{index: uint32(index), msg: deal})
|
||||
}
|
||||
case dkg_commit:
|
||||
sc, err := d.SecretCommits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = []dkgMessage{msgSecretCommits{msg: sc}}
|
||||
case dkg_done:
|
||||
dks, err := d.DistKeyShare()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.share = dks
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected stage: %v", d.step)
|
||||
}
|
||||
d.step = nextStep(d.step)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
var out []dkgMessage
|
||||
if msg, err := in.send(d); err != nil {
|
||||
return nil, err
|
||||
} else if msg != nil {
|
||||
out = []dkgMessage{msg}
|
||||
}
|
||||
if (d.step == dkg_certify && d.Certified()) ||
|
||||
(d.step == dkg_finish && d.Finished()) {
|
||||
d.step = nextStep(d.step)
|
||||
msgs, err := d.handleMessage(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, msgs...)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func nextStep(step dkgStep) dkgStep {
|
||||
if step == dkg_done {
|
||||
return dkg_done
|
||||
}
|
||||
return step + 1
|
||||
}
|
||||
|
||||
type (
|
||||
msgDeal struct {
|
||||
msg *dkg.Deal
|
||||
index uint32 // recipient index
|
||||
}
|
||||
msgResponse struct{ msg *dkg.Response }
|
||||
msgJustification struct{ msg *dkg.Justification }
|
||||
msgSecretCommits struct{ msg *dkg.SecretCommits }
|
||||
msgComplaintCommits struct{ msg *dkg.ComplaintCommits }
|
||||
msgReconstructCommits struct{ msg *dkg.ReconstructCommits }
|
||||
)
|
||||
|
||||
func (m msgDeal) send(d *dkgRun) (dkgMessage, error) {
|
||||
if m.index != uint32(d.Index()) {
|
||||
return nil, nil
|
||||
}
|
||||
out, err := d.ProcessDeal(m.msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return msgResponse{out}, nil
|
||||
}
|
||||
|
||||
func (m msgResponse) send(d *dkgRun) (dkgMessage, error) {
|
||||
if out, err := d.ProcessResponse(m.msg); err != nil {
|
||||
return nil, err
|
||||
} else if out != nil {
|
||||
return msgJustification{out}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m msgJustification) send(d *dkgRun) (dkgMessage, error) {
|
||||
return nil, d.ProcessJustification(m.msg)
|
||||
}
|
||||
|
||||
func (m msgSecretCommits) send(d *dkgRun) (dkgMessage, error) {
|
||||
if out, err := d.ProcessSecretCommits(m.msg); err != nil {
|
||||
return nil, err
|
||||
} else if out != nil {
|
||||
return msgComplaintCommits{out}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m msgComplaintCommits) send(d *dkgRun) (dkgMessage, error) {
|
||||
out, err := d.ProcessComplaintCommits(m.msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return msgReconstructCommits{out}, nil
|
||||
}
|
||||
|
||||
func (m msgReconstructCommits) send(d *dkgRun) (dkgMessage, error) {
|
||||
return nil, d.ProcessReconstructCommits(m.msg)
|
||||
}
|
||||
|
||||
func (d dkgStep) String() string {
|
||||
switch d {
|
||||
case dkg_deal:
|
||||
return "deal"
|
||||
case dkg_certify:
|
||||
return "certify"
|
||||
case dkg_commit:
|
||||
return "commit"
|
||||
case dkg_finish:
|
||||
return "finish"
|
||||
case dkg_done:
|
||||
return "done"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// for debugging
|
||||
func (m msgDeal) from() uint32 { return m.msg.Index }
|
||||
func (m msgResponse) from() uint32 { return m.msg.Response.Index }
|
||||
func (m msgJustification) from() uint32 { return m.msg.Justification.Index }
|
||||
func (m msgSecretCommits) from() uint32 { return m.msg.Index }
|
||||
func (m msgComplaintCommits) from() uint32 { return m.msg.Index }
|
||||
func (m msgReconstructCommits) from() uint32 { return m.msg.Index }
|
||||
|
||||
func (m msgDeal) target() uint32 { return m.index }
|
||||
func (m msgResponse) target() uint32 { return m.msg.Index }
|
||||
func (m msgJustification) target() uint32 { return m.msg.Index }
|
||||
func (m msgSecretCommits) target() uint32 { return 0 }
|
||||
func (m msgComplaintCommits) target() uint32 { return m.msg.DealerIndex }
|
||||
func (m msgReconstructCommits) target() uint32 { return m.msg.DealerIndex }
|
280
server/distsig/manager.go
Normal file
280
server/distsig/manager.go
Normal file
@ -0,0 +1,280 @@
|
||||
package distsig
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
dkg "go.dedis.ch/kyber/v3/share/dkg/rabin"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
"cosmossdk.io/runtime/v2"
|
||||
serverv2 "cosmossdk.io/server/v2"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
|
||||
clientdss "git.vdb.to/cerc-io/chainsig/ethdss"
|
||||
"git.vdb.to/cerc-io/chainsig/ethschnorr"
|
||||
"git.vdb.to/cerc-io/laconicd/utils"
|
||||
)
|
||||
|
||||
type (
|
||||
DealMap = map[int]*dkg.Deal
|
||||
|
||||
DkgRunID int64
|
||||
SigRunID string
|
||||
)
|
||||
|
||||
const (
|
||||
componentName = "distsig"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
config *Config
|
||||
logger log.Logger
|
||||
longterm Scalar
|
||||
longtermPubKey cryptotypes.PubKey
|
||||
|
||||
dkgs map[DkgRunID]*dkgRun
|
||||
currentDkgID DkgRunID // zero indicates no current run
|
||||
|
||||
sigs map[SigRunID]*sigRun
|
||||
completeSigs []SigRunID
|
||||
}
|
||||
|
||||
type PeerMessages struct {
|
||||
dkg *DkgMessages
|
||||
dss []SigMessages
|
||||
}
|
||||
|
||||
func New(logger log.Logger, cfg *Config, kr keyring.Keyring) (*Manager, error) {
|
||||
longtermPrivKey, err := utils.ExtractPrivateKey(kr, cfg.LongtermKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract longterm key: %w", err)
|
||||
}
|
||||
m := &Manager{
|
||||
longterm: suite.Scalar().SetBytes(longtermPrivKey.Bytes()),
|
||||
longtermPubKey: longtermPrivKey.PubKey(),
|
||||
config: cfg,
|
||||
dkgs: make(map[DkgRunID]*dkgRun),
|
||||
sigs: make(map[SigRunID]*sigRun),
|
||||
}
|
||||
m.logger = logger.With(log.ModuleKey, m.Name())
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *Manager) getDkg(runid DkgRunID) (*dkgRun, error) {
|
||||
if runid == 0 {
|
||||
// runid = m.currentDkg
|
||||
return nil, fmt.Errorf("invalid run ID")
|
||||
}
|
||||
if run, ok := m.dkgs[runid]; ok {
|
||||
return run, nil
|
||||
}
|
||||
return nil, fmt.Errorf("DKG not initialized for run: %v", runid)
|
||||
}
|
||||
|
||||
func (m *Manager) currentDkg() *dkgRun {
|
||||
run, err := m.getDkg(m.currentDkgID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return run
|
||||
}
|
||||
|
||||
func (m *Manager) LongtermPublicKey() cryptotypes.PubKey {
|
||||
return m.longtermPubKey
|
||||
}
|
||||
|
||||
func (m *Manager) LongtermEthAddress() common.Address {
|
||||
pubkey, err := SuitePublicKeyFromBytes(m.LongtermPublicKey().Bytes())
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to parse longterm pubkey: %w", err))
|
||||
}
|
||||
return pubkey.Address()
|
||||
}
|
||||
|
||||
func thresholdForRatio(m int, tr float64) int {
|
||||
return int(math.Ceil(float64(m) * tr))
|
||||
}
|
||||
|
||||
func (m *Manager) initDKG(members []Point) (*dkgRun, error) {
|
||||
t := thresholdForRatio(len(members), m.config.ThresholdRatio)
|
||||
keygen, err := dkg.NewDistKeyGenerator(suite.(dkg.Suite), m.longterm, members, t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dkgRun{DistKeyGenerator: keygen}, nil
|
||||
}
|
||||
|
||||
// NeedDKG returns true if DKG needs to be run for the given participants.
|
||||
func (m *Manager) NeedDKG(pubkeys []Point) bool {
|
||||
return m.currentDkgID == 0 || !equalPoints(m.currentDkg().Participants(), pubkeys)
|
||||
}
|
||||
|
||||
// StartDKG begins a new DKG run including the given participants.
|
||||
func (m *Manager) StartDKG(block int64, pubkeys []Point) error {
|
||||
// TODO: generate runid from block height and hash of pubkeys?
|
||||
runid := DkgRunID(block)
|
||||
if _, ok := m.dkgs[runid]; ok {
|
||||
return fmt.Errorf("DKG run %v already exists", runid)
|
||||
}
|
||||
if len(pubkeys) < 2 {
|
||||
m.currentDkgID = 0
|
||||
m.logger.Debug("Too few participants for distributed signature")
|
||||
return nil
|
||||
}
|
||||
run, err := m.initDKG(pubkeys)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.dkgs[runid] = run
|
||||
m.currentDkgID = runid
|
||||
return run.prepareMessages()
|
||||
}
|
||||
|
||||
func (m *Manager) initDSS(dkgid DkgRunID, msg *big.Int) (*sigRun, error) {
|
||||
run, err := m.getDkg(dkgid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !run.Finished() {
|
||||
return nil, fmt.Errorf("DKG run has not finished: %v", dkgid)
|
||||
}
|
||||
random, err := run.DistKeyShare()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dss, err := clientdss.NewDSS(clientdss.DSSArgs{
|
||||
Secret: m.longterm,
|
||||
Participants: run.Participants(),
|
||||
Long: run.share,
|
||||
Random: random,
|
||||
Msg: msg,
|
||||
T: run.Threshold(),
|
||||
// Qualified: run.QUAL(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sigRun{DSS: dss, dkgID: dkgid}, nil
|
||||
}
|
||||
|
||||
// StartSignature begins a DSS run for the given message and DKG state.
|
||||
func (m *Manager) StartSignature(msg *big.Int) error {
|
||||
if m.currentDkgID == 0 {
|
||||
return fmt.Errorf("no distributed key prepared")
|
||||
}
|
||||
run, err := m.initDSS(m.currentDkgID, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sigid := run.SigRunID()
|
||||
m.sigs[sigid] = run
|
||||
return run.prepareMessages()
|
||||
}
|
||||
|
||||
func (m *Manager) CompletedSignatures() map[SigRunID]ethschnorr.Signature {
|
||||
var ret map[SigRunID]ethschnorr.Signature
|
||||
for _, id := range m.completeSigs {
|
||||
run, ok := m.sigs[id]
|
||||
if !ok {
|
||||
panic(fmt.Errorf("DSS run not found: %v", id))
|
||||
}
|
||||
if run.sig == nil {
|
||||
panic(fmt.Errorf("DSS signature not completed: %v", id))
|
||||
}
|
||||
// Deterministically pick a participant responsible for submitting the signature
|
||||
session := new(big.Int).SetBytes(run.SessionID()[:8])
|
||||
submitterIdx := session.Uint64() % uint64(len(run.Participants()))
|
||||
if run.Index() == int(submitterIdx) {
|
||||
ret[id] = run.sig
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// FlushMessages flushes the message buffers for any active DKG and DSS runs.
|
||||
func (m *Manager) FlushMessages() PeerMessages {
|
||||
var ret PeerMessages
|
||||
if buf := m.currentDkg().flushMessages(); len(buf) != 0 {
|
||||
ret.dkg = &DkgMessages{runID: m.currentDkgID, messages: buf}
|
||||
}
|
||||
for id, run := range m.sigs {
|
||||
if buf := run.flushMessages(); buf != nil {
|
||||
ret.dss = append(ret.dss, SigMessages{id, buf})
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ProcessMessages processes DKG and DSS peer messages.
|
||||
func (m *Manager) ProcessMessages(dm *PeerMessages) error {
|
||||
if dkg := dm.dkg; dkg != nil {
|
||||
run, err := m.getDkg(dkg.runID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := run.processMessages(dkg.messages); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, dss := range dm.dss {
|
||||
run, ok := m.sigs[dss.runID]
|
||||
if !ok {
|
||||
return fmt.Errorf("DSS not initialized for run: %v", dss.runID)
|
||||
}
|
||||
if err := run.processMessage(dss.messages); err != nil {
|
||||
return err
|
||||
}
|
||||
if run.sig != nil {
|
||||
m.completeSigs = append(m.completeSigs, dss.runID)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func equalPoints(a, b []Point) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, p := range a {
|
||||
if !p.Equal(b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (*Manager) Name() string { return componentName }
|
||||
func (*Manager) Start(context.Context) error { return nil }
|
||||
func (*Manager) Stop(context.Context) error { return nil }
|
||||
|
||||
func (m *Manager) Config() any {
|
||||
if m.config == nil {
|
||||
return DefaultConfig()
|
||||
}
|
||||
return m.config
|
||||
}
|
||||
|
||||
func (pm PeerMessages) Empty() bool {
|
||||
return pm.dkg == nil && len(pm.dss) == 0
|
||||
}
|
||||
|
||||
func UnmarshalConfig(cfg map[string]any) (*Config, error) {
|
||||
config := DefaultConfig()
|
||||
if err := serverv2.UnmarshalSubConfig(cfg, componentName, config); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal %T: %w", config, err)
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func ProvideManager(logger log.Logger, globalConfig runtime.GlobalConfig, kr keyring.Keyring) (*Manager, error) {
|
||||
config, err := UnmarshalConfig(globalConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return New(logger, config, kr)
|
||||
}
|
61
server/distsig/signature.go
Normal file
61
server/distsig/signature.go
Normal file
@ -0,0 +1,61 @@
|
||||
package distsig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
clientdss "git.vdb.to/cerc-io/chainsig/ethdss"
|
||||
"git.vdb.to/cerc-io/chainsig/ethschnorr"
|
||||
)
|
||||
|
||||
type SigMessages struct {
|
||||
runID SigRunID
|
||||
messages sigMessage
|
||||
}
|
||||
|
||||
type sigStep int
|
||||
|
||||
const (
|
||||
sig_partial sigStep = iota
|
||||
sig_complete
|
||||
)
|
||||
|
||||
type sigRun struct {
|
||||
*clientdss.DSS
|
||||
msgBuffer sigMessage
|
||||
|
||||
dkgID DkgRunID
|
||||
step sigStep
|
||||
|
||||
sig ethschnorr.Signature
|
||||
}
|
||||
|
||||
type sigMessage = *clientdss.PartialSig
|
||||
|
||||
func (d *sigRun) SigRunID() SigRunID {
|
||||
return SigRunID(fmt.Sprintf("%020d-%x", d.dkgID, d.SessionID()[:10]))
|
||||
}
|
||||
|
||||
func (d *sigRun) prepareMessages() error {
|
||||
var err error
|
||||
d.msgBuffer, err = d.PartialSig()
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *sigRun) flushMessages() sigMessage {
|
||||
buf := d.msgBuffer
|
||||
d.msgBuffer = nil
|
||||
return buf
|
||||
}
|
||||
|
||||
func (d *sigRun) processMessage(in sigMessage) error {
|
||||
err := d.ProcessPartialSig(in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// return d.EnoughPartialSig(), nil
|
||||
if d.EnoughPartialSig() {
|
||||
d.sig, err = d.Signature()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
37
server/distsig/suite.go
Normal file
37
server/distsig/suite.go
Normal file
@ -0,0 +1,37 @@
|
||||
package distsig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.vdb.to/cerc-io/chainsig/secp256k1"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"go.dedis.ch/kyber/v3"
|
||||
"go.dedis.ch/kyber/v3/suites"
|
||||
)
|
||||
|
||||
type (
|
||||
Scalar = kyber.Scalar
|
||||
Point = kyber.Point
|
||||
|
||||
PublicKey = secp256k1.PublicKey
|
||||
)
|
||||
|
||||
var (
|
||||
suite suites.Suite = secp256k1.NewBlakeKeccackSecp256k1()
|
||||
|
||||
// Note: the compressed encoding of pubkeys used by the SDK and our library are the same.
|
||||
// See gitlab.com/yawning/secp256k1-voi/secec
|
||||
SuitePublicKeyFromBytes = secp256k1.NewPublicKeyFromBytes
|
||||
)
|
||||
|
||||
func KeyRecordToPoint(longterm *keyring.Record) (kyber.Point, error) {
|
||||
pubkey, err := longterm.GetPubKey()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to access public key: %w", err)
|
||||
}
|
||||
suitePubkey, err := SuitePublicKeyFromBytes(pubkey.Bytes())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode public key: %w", err)
|
||||
}
|
||||
return suitePubkey.Point()
|
||||
}
|
26
server/distsig/utils.go
Normal file
26
server/distsig/utils.go
Normal file
@ -0,0 +1,26 @@
|
||||
package distsig
|
||||
|
||||
import "encoding/hex"
|
||||
|
||||
type BlockHash [32]byte
|
||||
|
||||
func (bh BlockHash) String() string {
|
||||
return hex.EncodeToString(bh[:])
|
||||
}
|
||||
|
||||
func (bh BlockHash) Bytes() []byte {
|
||||
return bh[:]
|
||||
}
|
||||
|
||||
func (bh BlockHash) Equal(other BlockHash) bool {
|
||||
return bh == other
|
||||
}
|
||||
|
||||
func BlockHashFromBytes(b []byte) BlockHash {
|
||||
if len(b) != 32 {
|
||||
panic("invalid block hash length")
|
||||
}
|
||||
var bh BlockHash
|
||||
copy(bh[:], b)
|
||||
return bh
|
||||
}
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/statechannels/go-nitro/crypto"
|
||||
"github.com/statechannels/go-nitro/node"
|
||||
"github.com/statechannels/go-nitro/node/engine"
|
||||
"github.com/statechannels/go-nitro/node/engine/chainservice"
|
||||
@ -57,7 +58,8 @@ type Server struct {
|
||||
// path to Nitro store directory
|
||||
storeDir string
|
||||
|
||||
ScAddr nitrotypes.PartyAddress
|
||||
// EthAddress common.Address
|
||||
StateChannelAddress nitrotypes.PartyAddress
|
||||
}
|
||||
|
||||
func NewServer(logger log.Logger, cfg server.ConfigMap, kr keyring.Keyring) (*Server, error) {
|
||||
@ -69,7 +71,7 @@ func NewServer(logger log.Logger, cfg server.ConfigMap, kr keyring.Keyring) (*Se
|
||||
|
||||
s.config = s.Config().(*Config)
|
||||
if len(cfg) > 0 {
|
||||
if err := serverv2.UnmarshalSubConfig(cfg, s.Name(), &s.config); err != nil {
|
||||
if err := serverv2.UnmarshalSubConfig(cfg, s.Name(), s.config); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
|
||||
}
|
||||
}
|
||||
@ -91,7 +93,7 @@ func (s *Server) init(kr keyring.Keyring) error {
|
||||
// Sign(message) only passes once validator's signature is prepared
|
||||
|
||||
storeOpts := store.StoreOpts{
|
||||
PkBytes: sckey,
|
||||
PkBytes: sckey.Bytes(),
|
||||
UseDurableStore: true,
|
||||
DurableStoreFolder: s.storeDir,
|
||||
}
|
||||
@ -100,7 +102,7 @@ func (s *Server) init(kr keyring.Keyring) error {
|
||||
bootPeers = strings.Split(c.BootPeers, ",")
|
||||
}
|
||||
messageOpts := p2pms.MessageOpts{
|
||||
PkBytes: sckey,
|
||||
PkBytes: sckey.Bytes(),
|
||||
TcpPort: c.MsgPort,
|
||||
WsMsgPort: c.WsMsgPort,
|
||||
BootPeers: bootPeers,
|
||||
@ -111,11 +113,13 @@ func (s *Server) init(kr keyring.Keyring) error {
|
||||
ChainUrl: c.EthUrl,
|
||||
ChainStartBlockNum: c.EthStartBlock,
|
||||
ChainAuthToken: c.EthAuthToken,
|
||||
ChainPk: hex.EncodeToString(ethkey),
|
||||
NaAddress: common.HexToAddress(c.EthNaAddress),
|
||||
VpaAddress: common.HexToAddress(c.EthVpaAddress),
|
||||
CaAddress: common.HexToAddress(c.EthCaAddress),
|
||||
// TODO delegation to distsig
|
||||
// ChainPk: hex.EncodeToString(ethkey),
|
||||
NaAddress: common.HexToAddress(c.EthNaAddress),
|
||||
VpaAddress: common.HexToAddress(c.EthVpaAddress),
|
||||
CaAddress: common.HexToAddress(c.EthCaAddress),
|
||||
}
|
||||
// Inject SDK logger into slog, which Nitro uses
|
||||
loggerImpl, ok := s.logger.Impl().(*slog.Logger)
|
||||
if !ok {
|
||||
return errors.New("logger does not have slog implementation")
|
||||
@ -127,7 +131,8 @@ func (s *Server) init(kr keyring.Keyring) error {
|
||||
return err
|
||||
}
|
||||
s.Node = node
|
||||
s.ScAddr = *store.GetAddress()
|
||||
// s.EthAddress = crypto.GetAddressFromSecretKeyBytes(ethkey)
|
||||
s.StateChannelAddress = *store.GetAddress()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
)
|
||||
|
||||
// Service represents a service which triggers Nitro state channel actions
|
||||
// TODO
|
||||
type Service interface {
|
||||
// CreatePaymentChannel creates a new virtual payment channel with the specified intermediaries,
|
||||
// counterparty, ChallengeDuration, and outcome
|
||||
|
15
testutil/keyring.go
Normal file
15
testutil/keyring.go
Normal file
@ -0,0 +1,15 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
modtestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||
|
||||
"git.vdb.to/cerc-io/laconicd/utils"
|
||||
)
|
||||
|
||||
func NewKeyring() keyring.Keyring {
|
||||
codecOpts := codectestutil.NewCodecOptionsWithCodecs(utils.NewAddressCodec(), utils.NewValAddressCodec())
|
||||
encCfg := modtestutil.MakeTestEncodingConfig(codecOpts)
|
||||
return keyring.NewInMemory(encCfg.Codec)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package nitro
|
||||
package utils
|
||||
|
||||
import (
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
@ -19,14 +19,10 @@ func extractPrivKeyFromLocal(rl *keyring.Record_Local) (cryptotypes.PrivKey, err
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
func extractPrivKeyBytes(kr keyring.Keyring, uid string) ([]byte, error) {
|
||||
func ExtractPrivateKey(kr keyring.Keyring, uid string) (cryptotypes.PrivKey, error) {
|
||||
ethkr, err := kr.Key(uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ethkey, err := extractPrivKeyFromLocal(ethkr.GetLocal())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ethkey.Bytes(), nil
|
||||
return extractPrivKeyFromLocal(ethkr.GetLocal())
|
||||
}
|
@ -2,17 +2,33 @@ package utils
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
|
||||
"github.com/statechannels/go-nitro/crypto"
|
||||
)
|
||||
|
||||
func DecodeEthereumAddress(message []byte, sig string) (string, error) {
|
||||
func DecodeEthereumAddress(message []byte, sig string) (common.Address, error) {
|
||||
if len(sig) > 2 && sig[:2] == "0x" {
|
||||
sig = sig[2:]
|
||||
}
|
||||
|
||||
signature := crypto.SplitSignature(common.Hex2Bytes(sig))
|
||||
ethereumAddress, err := crypto.RecoverEthereumMessageSigner(message, signature)
|
||||
|
||||
return ethereumAddress.String(), err
|
||||
return crypto.RecoverEthMessageSignerAddress(message, signature)
|
||||
}
|
||||
|
||||
func DecodeEthereumPubKey(message []byte, sig string) ([]byte, error) {
|
||||
if len(sig) > 2 && sig[:2] == "0x" {
|
||||
sig = sig[2:]
|
||||
}
|
||||
|
||||
signature := crypto.SplitSignature(common.Hex2Bytes(sig))
|
||||
return crypto.RecoverEthMessageSignerPubKey(message, signature)
|
||||
}
|
||||
|
||||
func EthAddressFromPubKey(pubkey []byte) (common.Address, error) {
|
||||
ecdsaPubKey, err := ethcrypto.UnmarshalPubkey(pubkey)
|
||||
if err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
return ethcrypto.PubkeyToAddress(*ecdsaPubKey), nil
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
appmodule "cosmossdk.io/core/appmodule/v2"
|
||||
banktypes "cosmossdk.io/x/bank/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
|
@ -86,24 +86,27 @@ func (k Keeper) OnboardParticipant(
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Invalid format for payload")
|
||||
}
|
||||
|
||||
// Decode eth address from signature which should be the nitro address of the participant
|
||||
nitroAddress, err := utils.DecodeEthereumAddress(message, msg.EthSignature)
|
||||
// Decode eth pubkey from signature. The derived address should be the nitro address of the participant
|
||||
nitroPubKey, err := utils.DecodeEthereumPubKey(message, msg.EthSignature)
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Failed to decode Ethereum address")
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Failed to decode Ethereum public key")
|
||||
}
|
||||
nitroAddress, err := utils.EthAddressFromPubKey(nitroPubKey)
|
||||
if err != nil {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Failed to derive Ethereum address from public key")
|
||||
}
|
||||
|
||||
if nitroAddress != msg.EthPayload.Address {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Recovered ethereum address does not match the address set in payload")
|
||||
if nitroAddress.String() != msg.EthPayload.Address {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Recovered Ethereum address does not match the address set in payload")
|
||||
}
|
||||
|
||||
// TODO: redundant
|
||||
cosmosAddr, err := k.addressCodec.BytesToString(signerAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
participant := &onboarding.Participant{
|
||||
CosmosAddress: cosmosAddr,
|
||||
NitroAddress: nitroAddress,
|
||||
PublicKey: nitroPubKey,
|
||||
Role: msg.Role,
|
||||
KycId: msg.KycId,
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ func (m *Params) GetOnboardingEnabled() bool {
|
||||
type Participant struct {
|
||||
// participant's cosmos (laconic) address
|
||||
CosmosAddress string `protobuf:"bytes,1,opt,name=cosmos_address,json=cosmosAddress,proto3" json:"cosmos_address,omitempty" json:"cosmos_address" yaml:"cosmos_address"`
|
||||
// participant's Nitro address
|
||||
NitroAddress string `protobuf:"bytes,2,opt,name=nitro_address,json=nitroAddress,proto3" json:"nitro_address,omitempty" json:"nitro_address" yaml:"nitro_address"`
|
||||
// full public key used to derive participant's Nitro address
|
||||
PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
// participant's role (participant | validator)
|
||||
Role string `protobuf:"bytes,3,opt,name=role,proto3" json:"role,omitempty" json:"role" yaml:"role"`
|
||||
// participant's KYC receipt ID
|
||||
@ -121,11 +121,11 @@ func (m *Participant) GetCosmosAddress() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Participant) GetNitroAddress() string {
|
||||
func (m *Participant) GetPublicKey() []byte {
|
||||
if m != nil {
|
||||
return m.NitroAddress
|
||||
return m.PublicKey
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Participant) GetRole() string {
|
||||
@ -206,32 +206,32 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_59afed779274eaf0 = []byte{
|
||||
// 399 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xc1, 0xce, 0xd2, 0x40,
|
||||
0x14, 0x85, 0xe9, 0x0f, 0xa2, 0x8e, 0x62, 0xe2, 0x44, 0x23, 0x4a, 0xec, 0x60, 0xdd, 0x60, 0x08,
|
||||
0x9d, 0x10, 0x12, 0x4d, 0x74, 0x65, 0x13, 0x16, 0xee, 0x48, 0x17, 0x2e, 0xdc, 0x90, 0xe9, 0x4c,
|
||||
0xad, 0x23, 0x6d, 0x87, 0xcc, 0x34, 0x8d, 0x7d, 0x0b, 0x9f, 0xc1, 0xa7, 0x71, 0xc9, 0xd2, 0x55,
|
||||
0x63, 0xe0, 0x0d, 0xfa, 0x04, 0xa6, 0x33, 0x14, 0x28, 0xfe, 0xbb, 0x7b, 0xcf, 0x3d, 0xe7, 0xbb,
|
||||
0xd3, 0xe6, 0x82, 0xd7, 0x34, 0x94, 0x14, 0x8b, 0x34, 0x10, 0x44, 0x32, 0x9e, 0x46, 0x38, 0x9f,
|
||||
0x5f, 0x74, 0xee, 0x56, 0x8a, 0x4c, 0x40, 0x58, 0x9b, 0xdc, 0x0b, 0x39, 0x9f, 0xbf, 0x78, 0x12,
|
||||
0x89, 0x48, 0xe8, 0x31, 0xae, 0x2b, 0xe3, 0x74, 0xb6, 0xa0, 0xbf, 0x22, 0x92, 0x24, 0x0a, 0x7e,
|
||||
0x05, 0xf0, 0x1c, 0x58, 0x87, 0x29, 0x09, 0xe2, 0x90, 0x0d, 0xad, 0xb1, 0x35, 0xb9, 0xe7, 0xbd,
|
||||
0xab, 0x4a, 0xb4, 0xf8, 0xae, 0x44, 0xfa, 0xde, 0xf9, 0xdf, 0xe3, 0x8c, 0x0b, 0x92, 0xc4, 0xb7,
|
||||
0x4e, 0xfc, 0xc7, 0x67, 0x71, 0x79, 0xd4, 0x7e, 0xdd, 0x80, 0x07, 0x2b, 0x22, 0x33, 0x4e, 0xf9,
|
||||
0x96, 0xa4, 0x19, 0xfc, 0x0c, 0x1e, 0x51, 0xa1, 0x12, 0xa1, 0xd6, 0x84, 0x31, 0x19, 0x2a, 0xa5,
|
||||
0x77, 0xde, 0xf7, 0x70, 0x55, 0xa2, 0xa9, 0xd9, 0xd9, 0x9e, 0x37, 0xfb, 0xae, 0x54, 0x7f, 0x60,
|
||||
0x84, 0x8f, 0xa6, 0x87, 0x3e, 0x18, 0xa4, 0x3c, 0x93, 0xe2, 0x84, 0xbd, 0xd1, 0xd8, 0x59, 0x55,
|
||||
0xa2, 0x37, 0x06, 0xdb, 0x1a, 0x37, 0xd4, 0xb6, 0xe8, 0x3f, 0xd4, 0x7d, 0xc3, 0xc4, 0xa0, 0x27,
|
||||
0x45, 0x1c, 0x0e, 0xbb, 0x1a, 0x35, 0xaa, 0x4a, 0xf4, 0xcc, 0xa0, 0x6a, 0xb5, 0x21, 0xe8, 0xda,
|
||||
0xd7, 0x46, 0xf8, 0x16, 0xf4, 0x37, 0x05, 0x5d, 0x73, 0x36, 0xec, 0xe9, 0x08, 0xaa, 0x4a, 0x34,
|
||||
0x32, 0x11, 0xa3, 0x37, 0xa1, 0x63, 0xe7, 0xdf, 0xd9, 0x14, 0xf4, 0x13, 0x73, 0x72, 0x00, 0x96,
|
||||
0xd9, 0xb7, 0x15, 0x29, 0x62, 0x41, 0x18, 0xfc, 0x00, 0xee, 0xb6, 0xff, 0xcd, 0xab, 0xaa, 0x44,
|
||||
0x2f, 0x0d, 0xe6, 0xea, 0xf9, 0xa7, 0x87, 0x37, 0x09, 0x38, 0x05, 0xdd, 0x44, 0x45, 0xc7, 0xaf,
|
||||
0x7f, 0x5e, 0x95, 0xe8, 0xa9, 0x09, 0x26, 0x2a, 0x6a, 0x42, 0x75, 0xe9, 0xd7, 0x2e, 0xcf, 0xfb,
|
||||
0xbd, 0xb7, 0xad, 0xdd, 0xde, 0xb6, 0xfe, 0xee, 0x6d, 0xeb, 0xe7, 0xc1, 0xee, 0xec, 0x0e, 0x76,
|
||||
0xe7, 0xcf, 0xc1, 0xee, 0x7c, 0x99, 0x44, 0x3c, 0x73, 0x73, 0x16, 0xb8, 0x99, 0xc0, 0xf5, 0x75,
|
||||
0xcd, 0xb8, 0xc0, 0x31, 0xa1, 0x22, 0xe5, 0x94, 0xe1, 0x1f, 0x17, 0x27, 0x18, 0xf4, 0xf5, 0x65,
|
||||
0x2d, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x87, 0xe5, 0xd5, 0x6b, 0xaa, 0x02, 0x00, 0x00,
|
||||
// 397 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x3f, 0x8b, 0xdb, 0x30,
|
||||
0x18, 0xc6, 0xe3, 0x26, 0x4d, 0x1b, 0xf5, 0x0f, 0x54, 0xb4, 0xd4, 0x6d, 0x88, 0x9d, 0xba, 0x4b,
|
||||
0x20, 0xd4, 0x22, 0x04, 0x5a, 0x68, 0xa7, 0x1a, 0x32, 0x94, 0x2e, 0xc1, 0x43, 0x87, 0x2e, 0x46,
|
||||
0x96, 0x5c, 0x57, 0x17, 0xdb, 0x32, 0x96, 0xcf, 0x9c, 0xbf, 0xc5, 0x7d, 0xac, 0x1b, 0x33, 0xde,
|
||||
0x64, 0x8e, 0x64, 0xbe, 0xc5, 0x9f, 0xe0, 0xb0, 0x14, 0x5f, 0xfe, 0xdc, 0x6d, 0x7a, 0x7f, 0xef,
|
||||
0xf3, 0xe8, 0xe1, 0x81, 0x17, 0x7c, 0x26, 0x41, 0x46, 0x10, 0x4f, 0x7c, 0x8e, 0x33, 0xca, 0x92,
|
||||
0x10, 0x15, 0xb3, 0x83, 0xc9, 0x4e, 0x33, 0x9e, 0x73, 0x08, 0x1b, 0x91, 0x7d, 0x80, 0x8b, 0xd9,
|
||||
0xc7, 0xb7, 0x21, 0x0f, 0xb9, 0x5c, 0xa3, 0xe6, 0xa5, 0x94, 0x56, 0x0a, 0xfa, 0x4b, 0x9c, 0xe1,
|
||||
0x58, 0xc0, 0x7f, 0x00, 0xee, 0x0d, 0x5e, 0x90, 0x60, 0x3f, 0x0a, 0xa8, 0xae, 0x8d, 0xb5, 0xc9,
|
||||
0x73, 0xe7, 0x5b, 0x5d, 0x99, 0xf3, 0x33, 0xc1, 0x93, 0xef, 0xd6, 0x43, 0x8d, 0x35, 0x2e, 0x71,
|
||||
0x1c, 0x3d, 0xba, 0x71, 0xdf, 0xec, 0xe1, 0x62, 0xc7, 0x6e, 0x35, 0xf0, 0x62, 0x89, 0xb3, 0x9c,
|
||||
0x11, 0x96, 0xe2, 0x24, 0x87, 0x7f, 0xc0, 0x6b, 0xc2, 0x45, 0xcc, 0x85, 0x87, 0x29, 0xcd, 0x02,
|
||||
0x21, 0x64, 0xe6, 0xc0, 0x41, 0x75, 0x65, 0x4e, 0x55, 0xe6, 0xf1, 0xbe, 0xcd, 0x3b, 0xa1, 0xee,
|
||||
0x2b, 0x05, 0x7e, 0xaa, 0x19, 0x8e, 0x00, 0x48, 0xcf, 0xfd, 0x88, 0x11, 0x6f, 0x15, 0x94, 0xfa,
|
||||
0x93, 0xb1, 0x36, 0x79, 0xe9, 0x0e, 0x14, 0xf9, 0x1d, 0x94, 0x10, 0x81, 0x5e, 0xc6, 0xa3, 0x40,
|
||||
0xef, 0xca, 0xb0, 0x61, 0x5d, 0x99, 0xef, 0x55, 0x58, 0x43, 0xdb, 0x08, 0xf9, 0x76, 0xa5, 0x10,
|
||||
0x7e, 0x05, 0xfd, 0x55, 0x49, 0x3c, 0x46, 0xf5, 0x9e, 0xb4, 0x98, 0x75, 0x65, 0x0e, 0x95, 0x45,
|
||||
0xf1, 0xd6, 0xb4, 0x9b, 0xdc, 0xa7, 0xab, 0x92, 0xfc, 0xa2, 0x56, 0x01, 0xc0, 0x22, 0xff, 0xbf,
|
||||
0xc4, 0x65, 0xc4, 0x31, 0x85, 0x3f, 0xc0, 0xb3, 0xe3, 0x9a, 0x9f, 0xea, 0xca, 0x1c, 0xa9, 0x6f,
|
||||
0x4e, 0xfa, 0xdd, 0x17, 0x6b, 0x1d, 0x70, 0x0a, 0xba, 0xb1, 0x08, 0x65, 0x97, 0x81, 0xf3, 0xa1,
|
||||
0xae, 0xcc, 0x77, 0xca, 0x18, 0x8b, 0xb0, 0x35, 0x35, 0x4f, 0xb7, 0x51, 0x39, 0xce, 0xd5, 0xc6,
|
||||
0xd0, 0xd6, 0x1b, 0x43, 0xbb, 0xd9, 0x18, 0xda, 0xe5, 0xd6, 0xe8, 0xac, 0xb7, 0x46, 0xe7, 0x7a,
|
||||
0x6b, 0x74, 0xfe, 0x4e, 0x42, 0x96, 0xdb, 0x05, 0xf5, 0xed, 0x9c, 0xa3, 0xe6, 0x50, 0xbe, 0x30,
|
||||
0x8e, 0x22, 0x4c, 0x78, 0xc2, 0x08, 0x45, 0x17, 0x07, 0xd7, 0xe4, 0xf7, 0xe5, 0x91, 0xcc, 0xef,
|
||||
0x02, 0x00, 0x00, 0xff, 0xff, 0xdb, 0xbd, 0x79, 0xd2, 0x75, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Params) Marshal() (dAtA []byte, err error) {
|
||||
@ -301,10 +301,10 @@ func (m *Participant) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if len(m.NitroAddress) > 0 {
|
||||
i -= len(m.NitroAddress)
|
||||
copy(dAtA[i:], m.NitroAddress)
|
||||
i = encodeVarintOnboarding(dAtA, i, uint64(len(m.NitroAddress)))
|
||||
if len(m.PublicKey) > 0 {
|
||||
i -= len(m.PublicKey)
|
||||
copy(dAtA[i:], m.PublicKey)
|
||||
i = encodeVarintOnboarding(dAtA, i, uint64(len(m.PublicKey)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
@ -388,7 +388,7 @@ func (m *Participant) Size() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + sovOnboarding(uint64(l))
|
||||
}
|
||||
l = len(m.NitroAddress)
|
||||
l = len(m.PublicKey)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovOnboarding(uint64(l))
|
||||
}
|
||||
@ -559,9 +559,9 @@ func (m *Participant) Unmarshal(dAtA []byte) error {
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field NitroAddress", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowOnboarding
|
||||
@ -571,23 +571,25 @@ func (m *Participant) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthOnboarding
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthOnboarding
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.NitroAddress = string(dAtA[iNdEx:postIndex])
|
||||
m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.PublicKey == nil {
|
||||
m.PublicKey = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
|
Loading…
Reference in New Issue
Block a user