From 8885e188716c2a0d4808da820d2a650d25cfbb34 Mon Sep 17 00:00:00 2001 From: j75689 Date: Fri, 7 Jul 2023 06:50:37 +0800 Subject: [PATCH 1/7] feat: add bls signature verification --- api/cosmos/staking/v1beta1/tx.pulsar.go | 567 +++++++++++++++--------- client/keys/root.go | 2 + client/keys/root_test.go | 2 +- client/keys/sign.go | 106 +++++ crypto/keyring/record.go | 5 + crypto/keys/eth/ethsecp256k1/pubkey.go | 6 +- proto/cosmos/staking/v1beta1/tx.proto | 4 +- simapp/simd/cmd/testnet.go | 5 +- tests/e2e/genutil/suite.go | 5 + testutil/network/network.go | 6 +- testutil/sims/address_helpers.go | 14 + types/address.go | 5 +- x/genutil/client/cli/gentx.go | 10 +- x/genutil/gentx_test.go | 7 +- x/genutil/types/genesis_state_test.go | 14 +- x/gov/abci_test.go | 5 +- x/slashing/abci_test.go | 6 +- x/slashing/app_test.go | 5 +- x/staking/app_test.go | 7 +- x/staking/client/cli/flags.go | 2 + x/staking/client/cli/tx.go | 6 +- x/staking/keeper/msg_server.go | 50 ++- x/staking/simulation/operations.go | 7 +- x/staking/testutil/helpers.go | 21 +- x/staking/types/data_test.go | 12 +- x/staking/types/errors.go | 1 + x/staking/types/msg.go | 20 +- x/staking/types/msg_test.go | 35 +- x/staking/types/tx.pb.go | 239 ++++++---- 29 files changed, 839 insertions(+), 335 deletions(-) create mode 100644 client/keys/sign.go diff --git a/api/cosmos/staking/v1beta1/tx.pulsar.go b/api/cosmos/staking/v1beta1/tx.pulsar.go index aa057b8d9f..923013335f 100644 --- a/api/cosmos/staking/v1beta1/tx.pulsar.go +++ b/api/cosmos/staking/v1beta1/tx.pulsar.go @@ -32,6 +32,7 @@ var ( fd_MsgCreateValidator_relayer_address protoreflect.FieldDescriptor fd_MsgCreateValidator_challenger_address protoreflect.FieldDescriptor fd_MsgCreateValidator_bls_key protoreflect.FieldDescriptor + fd_MsgCreateValidator_bls_proof protoreflect.FieldDescriptor ) func init() { @@ -48,6 +49,7 @@ func init() { fd_MsgCreateValidator_relayer_address = md_MsgCreateValidator.Fields().ByName("relayer_address") fd_MsgCreateValidator_challenger_address = md_MsgCreateValidator.Fields().ByName("challenger_address") fd_MsgCreateValidator_bls_key = md_MsgCreateValidator.Fields().ByName("bls_key") + fd_MsgCreateValidator_bls_proof = md_MsgCreateValidator.Fields().ByName("bls_proof") } var _ protoreflect.Message = (*fastReflection_MsgCreateValidator)(nil) @@ -181,6 +183,12 @@ func (x *fastReflection_MsgCreateValidator) Range(f func(protoreflect.FieldDescr return } } + if x.BlsProof != "" { + value := protoreflect.ValueOfString(x.BlsProof) + if !f(fd_MsgCreateValidator_bls_proof, value) { + return + } + } } // Has reports whether a field is populated. @@ -218,6 +226,8 @@ func (x *fastReflection_MsgCreateValidator) Has(fd protoreflect.FieldDescriptor) return x.ChallengerAddress != "" case "cosmos.staking.v1beta1.MsgCreateValidator.bls_key": return x.BlsKey != "" + case "cosmos.staking.v1beta1.MsgCreateValidator.bls_proof": + return x.BlsProof != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgCreateValidator")) @@ -256,6 +266,8 @@ func (x *fastReflection_MsgCreateValidator) Clear(fd protoreflect.FieldDescripto x.ChallengerAddress = "" case "cosmos.staking.v1beta1.MsgCreateValidator.bls_key": x.BlsKey = "" + case "cosmos.staking.v1beta1.MsgCreateValidator.bls_proof": + x.BlsProof = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgCreateValidator")) @@ -305,6 +317,9 @@ func (x *fastReflection_MsgCreateValidator) Get(descriptor protoreflect.FieldDes case "cosmos.staking.v1beta1.MsgCreateValidator.bls_key": value := x.BlsKey return protoreflect.ValueOfString(value) + case "cosmos.staking.v1beta1.MsgCreateValidator.bls_proof": + value := x.BlsProof + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgCreateValidator")) @@ -347,6 +362,8 @@ func (x *fastReflection_MsgCreateValidator) Set(fd protoreflect.FieldDescriptor, x.ChallengerAddress = value.Interface().(string) case "cosmos.staking.v1beta1.MsgCreateValidator.bls_key": x.BlsKey = value.Interface().(string) + case "cosmos.staking.v1beta1.MsgCreateValidator.bls_proof": + x.BlsProof = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgCreateValidator")) @@ -401,6 +418,8 @@ func (x *fastReflection_MsgCreateValidator) Mutable(fd protoreflect.FieldDescrip panic(fmt.Errorf("field challenger_address of message cosmos.staking.v1beta1.MsgCreateValidator is not mutable")) case "cosmos.staking.v1beta1.MsgCreateValidator.bls_key": panic(fmt.Errorf("field bls_key of message cosmos.staking.v1beta1.MsgCreateValidator is not mutable")) + case "cosmos.staking.v1beta1.MsgCreateValidator.bls_proof": + panic(fmt.Errorf("field bls_proof of message cosmos.staking.v1beta1.MsgCreateValidator is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgCreateValidator")) @@ -440,6 +459,8 @@ func (x *fastReflection_MsgCreateValidator) NewField(fd protoreflect.FieldDescri return protoreflect.ValueOfString("") case "cosmos.staking.v1beta1.MsgCreateValidator.bls_key": return protoreflect.ValueOfString("") + case "cosmos.staking.v1beta1.MsgCreateValidator.bls_proof": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgCreateValidator")) @@ -553,6 +574,10 @@ func (x *fastReflection_MsgCreateValidator) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + l = len(x.BlsProof) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -582,6 +607,13 @@ func (x *fastReflection_MsgCreateValidator) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.BlsProof) > 0 { + i -= len(x.BlsProof) + copy(dAtA[i:], x.BlsProof) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.BlsProof))) + i-- + dAtA[i] = 0x62 + } if len(x.BlsKey) > 0 { i -= len(x.BlsKey) copy(dAtA[i:], x.BlsKey) @@ -1104,6 +1136,38 @@ func (x *fastReflection_MsgCreateValidator) ProtoMethods() *protoiface.Methods { } x.BlsKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 12: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field BlsProof", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + 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.BlsProof = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -1504,6 +1568,7 @@ var ( fd_MsgEditValidator_relayer_address protoreflect.FieldDescriptor fd_MsgEditValidator_challenger_address protoreflect.FieldDescriptor fd_MsgEditValidator_bls_key protoreflect.FieldDescriptor + fd_MsgEditValidator_bls_proof protoreflect.FieldDescriptor ) func init() { @@ -1516,6 +1581,7 @@ func init() { fd_MsgEditValidator_relayer_address = md_MsgEditValidator.Fields().ByName("relayer_address") fd_MsgEditValidator_challenger_address = md_MsgEditValidator.Fields().ByName("challenger_address") fd_MsgEditValidator_bls_key = md_MsgEditValidator.Fields().ByName("bls_key") + fd_MsgEditValidator_bls_proof = md_MsgEditValidator.Fields().ByName("bls_proof") } var _ protoreflect.Message = (*fastReflection_MsgEditValidator)(nil) @@ -1625,6 +1691,12 @@ func (x *fastReflection_MsgEditValidator) Range(f func(protoreflect.FieldDescrip return } } + if x.BlsProof != "" { + value := protoreflect.ValueOfString(x.BlsProof) + if !f(fd_MsgEditValidator_bls_proof, value) { + return + } + } } // Has reports whether a field is populated. @@ -1654,6 +1726,8 @@ func (x *fastReflection_MsgEditValidator) Has(fd protoreflect.FieldDescriptor) b return x.ChallengerAddress != "" case "cosmos.staking.v1beta1.MsgEditValidator.bls_key": return x.BlsKey != "" + case "cosmos.staking.v1beta1.MsgEditValidator.bls_proof": + return x.BlsProof != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgEditValidator")) @@ -1684,6 +1758,8 @@ func (x *fastReflection_MsgEditValidator) Clear(fd protoreflect.FieldDescriptor) x.ChallengerAddress = "" case "cosmos.staking.v1beta1.MsgEditValidator.bls_key": x.BlsKey = "" + case "cosmos.staking.v1beta1.MsgEditValidator.bls_proof": + x.BlsProof = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgEditValidator")) @@ -1721,6 +1797,9 @@ func (x *fastReflection_MsgEditValidator) Get(descriptor protoreflect.FieldDescr case "cosmos.staking.v1beta1.MsgEditValidator.bls_key": value := x.BlsKey return protoreflect.ValueOfString(value) + case "cosmos.staking.v1beta1.MsgEditValidator.bls_proof": + value := x.BlsProof + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgEditValidator")) @@ -1755,6 +1834,8 @@ func (x *fastReflection_MsgEditValidator) Set(fd protoreflect.FieldDescriptor, v x.ChallengerAddress = value.Interface().(string) case "cosmos.staking.v1beta1.MsgEditValidator.bls_key": x.BlsKey = value.Interface().(string) + case "cosmos.staking.v1beta1.MsgEditValidator.bls_proof": + x.BlsProof = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgEditValidator")) @@ -1792,6 +1873,8 @@ func (x *fastReflection_MsgEditValidator) Mutable(fd protoreflect.FieldDescripto panic(fmt.Errorf("field challenger_address of message cosmos.staking.v1beta1.MsgEditValidator is not mutable")) case "cosmos.staking.v1beta1.MsgEditValidator.bls_key": panic(fmt.Errorf("field bls_key of message cosmos.staking.v1beta1.MsgEditValidator is not mutable")) + case "cosmos.staking.v1beta1.MsgEditValidator.bls_proof": + panic(fmt.Errorf("field bls_proof of message cosmos.staking.v1beta1.MsgEditValidator is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgEditValidator")) @@ -1820,6 +1903,8 @@ func (x *fastReflection_MsgEditValidator) NewField(fd protoreflect.FieldDescript return protoreflect.ValueOfString("") case "cosmos.staking.v1beta1.MsgEditValidator.bls_key": return protoreflect.ValueOfString("") + case "cosmos.staking.v1beta1.MsgEditValidator.bls_proof": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.MsgEditValidator")) @@ -1917,6 +2002,10 @@ func (x *fastReflection_MsgEditValidator) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + l = len(x.BlsProof) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -1946,6 +2035,13 @@ func (x *fastReflection_MsgEditValidator) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.BlsProof) > 0 { + i -= len(x.BlsProof) + copy(dAtA[i:], x.BlsProof) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.BlsProof))) + i-- + dAtA[i] = 0x42 + } if len(x.BlsKey) > 0 { i -= len(x.BlsKey) copy(dAtA[i:], x.BlsKey) @@ -2279,6 +2375,38 @@ func (x *fastReflection_MsgEditValidator) ProtoMethods() *protoiface.Methods { } x.BlsKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field BlsProof", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + 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.BlsProof = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -7501,6 +7629,7 @@ type MsgCreateValidator struct { RelayerAddress string `protobuf:"bytes,9,opt,name=relayer_address,json=relayerAddress,proto3" json:"relayer_address,omitempty"` ChallengerAddress string `protobuf:"bytes,10,opt,name=challenger_address,json=challengerAddress,proto3" json:"challenger_address,omitempty"` BlsKey string `protobuf:"bytes,11,opt,name=bls_key,json=blsKey,proto3" json:"bls_key,omitempty"` + BlsProof string `protobuf:"bytes,12,opt,name=bls_proof,json=blsProof,proto3" json:"bls_proof,omitempty"` } func (x *MsgCreateValidator) Reset() { @@ -7600,6 +7729,13 @@ func (x *MsgCreateValidator) GetBlsKey() string { return "" } +func (x *MsgCreateValidator) GetBlsProof() string { + if x != nil { + return x.BlsProof + } + return "" +} + // MsgCreateValidatorResponse defines the Msg/CreateValidator response type. type MsgCreateValidatorResponse struct { state protoimpl.MessageState @@ -7644,6 +7780,7 @@ type MsgEditValidator struct { RelayerAddress string `protobuf:"bytes,5,opt,name=relayer_address,json=relayerAddress,proto3" json:"relayer_address,omitempty"` ChallengerAddress string `protobuf:"bytes,6,opt,name=challenger_address,json=challengerAddress,proto3" json:"challenger_address,omitempty"` BlsKey string `protobuf:"bytes,7,opt,name=bls_key,json=blsKey,proto3" json:"bls_key,omitempty"` // The BLS pubkey for the authorized relayer/challenger + BlsProof string `protobuf:"bytes,8,opt,name=bls_proof,json=blsProof,proto3" json:"bls_proof,omitempty"` } func (x *MsgEditValidator) Reset() { @@ -7715,6 +7852,13 @@ func (x *MsgEditValidator) GetBlsKey() string { return "" } +func (x *MsgEditValidator) GetBlsProof() string { + if x != nil { + return x.BlsProof + } + return "" +} + // MsgEditValidatorResponse defines the Msg/EditValidator response type. type MsgEditValidatorResponse struct { state protoimpl.MessageState @@ -8201,7 +8345,7 @@ var file_cosmos_staking_v1beta1_tx_proto_rawDesc = []byte{ 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, - 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa0, 0x06, 0x0a, 0x12, 0x4d, 0x73, 0x67, + 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbd, 0x06, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x50, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, @@ -8250,227 +8394,230 @@ var file_cosmos_staking_v1beta1_tx_proto_rawDesc = []byte{ 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x11, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x6c, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x62, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x3a, 0x11, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, - 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x22, 0x1c, 0x0a, 0x1a, 0x4d, - 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdd, 0x04, 0x0a, 0x10, 0x4d, 0x73, - 0x67, 0x45, 0x64, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x50, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, - 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, - 0xb0, 0x2a, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x45, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, - 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x61, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x38, 0xda, 0xde, 0x1f, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, - 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x13, 0x6d, 0x69, - 0x6e, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xda, 0xde, 0x1f, 0x26, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x52, 0x11, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, - 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0e, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x47, 0x0a, 0x12, 0x63, 0x68, 0x61, 0x6c, 0x6c, - 0x65, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x11, 0x63, - 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x17, 0x0a, 0x07, 0x62, 0x6c, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x62, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x3a, 0x3e, 0x88, 0xa0, 0x1f, 0x00, 0xe8, - 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x1b, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x45, 0x64, 0x69, 0x74, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x1a, 0x0a, 0x18, 0x4d, 0x73, 0x67, - 0x45, 0x64, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x94, 0x02, 0x0a, 0x0b, 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x45, 0x0a, 0x11, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, - 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, - 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x3a, 0x39, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x11, - 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x16, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, - 0x2f, 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x22, 0x15, 0x0a, 0x13, - 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xf7, 0x02, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x42, 0x65, 0x67, 0x69, 0x6e, - 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, - 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, - 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x4c, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, - 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x62, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6c, 0x73, 0x5f, + 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x6c, 0x73, + 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x3a, 0x11, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, + 0xe7, 0xb0, 0x2a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x22, 0x1c, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfa, 0x04, 0x0a, 0x10, 0x4d, 0x73, 0x67, 0x45, 0x64, + 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x50, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, + 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, + 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x61, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xda, + 0xde, 0x1f, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x12, 0x68, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x73, + 0x65, 0x6c, 0x66, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xda, 0xde, 0x1f, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, + 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x11, + 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x41, 0x0a, 0x0f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0e, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x47, 0x0a, 0x12, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x4c, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, 0x74, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, - 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x11, 0x63, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, + 0x07, 0x62, 0x6c, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x62, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6c, 0x73, 0x5f, 0x70, 0x72, + 0x6f, 0x6f, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x6c, 0x73, 0x50, 0x72, + 0x6f, 0x6f, 0x66, 0x3a, 0x3e, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, + 0x2a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, + 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x45, 0x64, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x22, 0x1a, 0x0a, 0x18, 0x4d, 0x73, 0x67, 0x45, 0x64, 0x69, 0x74, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x94, 0x02, 0x0a, 0x0b, 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, + 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, - 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x40, 0x88, 0xa0, 0x1f, + 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x39, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x1d, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x42, 0x65, - 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x22, 0x70, 0x0a, - 0x1a, 0x4d, 0x73, 0x67, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x63, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, - 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, - 0x98, 0x02, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x65, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, - 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x3c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, - 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x3b, 0x88, - 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, - 0x2a, 0x18, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, - 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x22, 0x6b, 0x0a, 0x15, 0x4d, 0x73, - 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, - 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xdf, 0x02, 0x0a, 0x1c, 0x4d, 0x73, 0x67, 0x43, - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, - 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x45, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, + 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x16, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x44, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf7, 0x02, + 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, + 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4c, 0x0a, 0x15, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, - 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x4a, 0x88, - 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, - 0x2a, 0x27, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, - 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x26, 0x0a, 0x24, 0x4d, 0x73, 0x67, - 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xc5, 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, + 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4c, 0x0a, 0x15, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x41, 0x0a, - 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x09, 0xc8, - 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x3a, 0x37, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x8a, 0xe7, 0xb0, 0x2a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, - 0x78, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x9d, 0x06, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x71, 0x0a, 0x0f, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, - 0x2a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x32, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x6b, 0x0a, 0x0d, 0x45, 0x64, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, - 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x64, 0x69, - 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x73, + 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, + 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x40, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, + 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x22, 0x70, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x42, 0x65, + 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, + 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x98, 0x02, 0x0a, 0x0d, 0x4d, 0x73, + 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, + 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x3b, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, + 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x18, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x22, 0x6b, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, + 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, + 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, + 0x65, 0x22, 0xdf, 0x02, 0x0a, 0x1c, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, + 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, + 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x3c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, + 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, + 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x4a, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, + 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x27, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x26, 0x0a, 0x24, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc5, 0x01, 0x0a, 0x0f, + 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, + 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x37, 0x82, 0xe7, 0xb0, 0x2a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x24, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, 0x2f, 0x73, 0x74, 0x61, 0x6b, + 0x69, 0x6e, 0x67, 0x2f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x9d, + 0x06, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x71, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x0d, 0x45, 0x64, 0x69, + 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x64, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x08, - 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x1a, 0x2b, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x0f, 0x42, 0x65, - 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, - 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, + 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, + 0x67, 0x45, 0x64, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x08, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x65, 0x12, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x44, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4d, 0x73, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x0f, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, + 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0a, 0x55, 0x6e, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x25, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x1a, 0x2d, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x19, + 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, - 0x0a, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x25, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x1a, 0x2d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, - 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, - 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x19, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x34, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, + 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, + 0x3c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x3c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, - 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, - 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x2f, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, - 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xd7, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x53, 0x58, 0xaa, 0x02, 0x16, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, - 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, - 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, - 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, + 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x27, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xd7, + 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, + 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, + 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x3b, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0xa2, 0x02, 0x03, 0x43, 0x53, 0x58, 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, + 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, + 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x5c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, + 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/client/keys/root.go b/client/keys/root.go index 6faf2f462c..f3c1ce7823 100644 --- a/client/keys/root.go +++ b/client/keys/root.go @@ -49,6 +49,8 @@ The pass backend requires GnuPG: https://gnupg.org/ RenameKeyCommand(), ParseKeyStringCommand(), MigrateCommand(), + SignMsgKeysCmd(), + VerifySignatureCmd(), ) cmd.PersistentFlags().String(flags.FlagHome, defaultNodeHome, "The application home directory") diff --git a/client/keys/root_test.go b/client/keys/root_test.go index 20b3f1a234..648c3f666a 100644 --- a/client/keys/root_test.go +++ b/client/keys/root_test.go @@ -11,5 +11,5 @@ func TestCommands(t *testing.T) { assert.Assert(t, rootCommands != nil) // Commands are registered - assert.Equal(t, 11, len(rootCommands.Commands())) + assert.Equal(t, 13, len(rootCommands.Commands())) } diff --git a/client/keys/sign.go b/client/keys/sign.go new file mode 100644 index 0000000000..96b2edfcfa --- /dev/null +++ b/client/keys/sign.go @@ -0,0 +1,106 @@ +package keys + +import ( + "encoding/hex" + "errors" + + "github.com/cometbft/cometbft/crypto/tmhash" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" +) + +// SignMsgKeysCmd returns the Cobra Command for signing messages with the private key of a given name. +func SignMsgKeysCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "sign [message]", + Short: "Sign message", + Long: "Return a signature from their associated name and address private key.", + RunE: runSignMsgCmd, + } + + cmd.Flags().String(flags.FlagFrom, "", "Name or address of private key with which to sign") + return cmd +} + +func runSignMsgCmd(cmd *cobra.Command, args []string) error { + if len(args) != 1 { + return errors.New("invalid number of arguments") + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + _, name, _, err := client.GetFromFields(clientCtx, clientCtx.Keyring, clientCtx.From) + if err != nil { + return err + } + + msg, err := hex.DecodeString(args[0]) + if err != nil { + return err + } + sig, _, err := clientCtx.Keyring.Sign(name, tmhash.Sum(msg)) + if err != nil { + return err + } + + cmd.Println(hex.EncodeToString(sig)) + return nil +} + +// VerifySignatureCmd returns the Cobra Command for verifying signatures with a given public key and message. +func VerifySignatureCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "verify [message] [signature]", + Short: "Verify signature", + Long: "Verify signature with public key and message", + RunE: runVerifySignatureCmd, + } + + cmd.Flags().String(flags.FlagFrom, "", "Name or address of private key with which to sign") + return cmd +} + +func runVerifySignatureCmd(cmd *cobra.Command, args []string) error { + if len(args) != 2 { + return errors.New("invalid number of arguments") + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + _, name, _, err := client.GetFromFields(clientCtx, clientCtx.Keyring, clientCtx.From) + if err != nil { + return err + } + record, err := clientCtx.Keyring.Key(name) + if err != nil { + return err + } + + priv, err := record.ExtractPrivKey() + if err != nil { + return nil + } + + msg, err := hex.DecodeString(args[0]) + if err != nil { + return nil + } + signature, err := hex.DecodeString(args[1]) + if err != nil { + return nil + } + if priv.PubKey().VerifySignature(tmhash.Sum(msg), signature) { + cmd.Println("Signature verify successfully") + } else { + cmd.Println("Signature verify failed") + } + return nil +} diff --git a/crypto/keyring/record.go b/crypto/keyring/record.go index 1b1885648e..d3ce1bf792 100644 --- a/crypto/keyring/record.go +++ b/crypto/keyring/record.go @@ -109,6 +109,11 @@ func (k *Record) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { return nil } +// ExtractPrivKey returns the priv key +func (k *Record) ExtractPrivKey() (cryptotypes.PrivKey, error) { + return extractPrivKeyFromRecord(k) +} + func extractPrivKeyFromRecord(k *Record) (cryptotypes.PrivKey, error) { rl := k.GetLocal() if rl == nil { diff --git a/crypto/keys/eth/ethsecp256k1/pubkey.go b/crypto/keys/eth/ethsecp256k1/pubkey.go index e98b004df7..3b3f4a5034 100644 --- a/crypto/keys/eth/ethsecp256k1/pubkey.go +++ b/crypto/keys/eth/ethsecp256k1/pubkey.go @@ -93,6 +93,10 @@ func (pubKey *PubKey) VerifySignature(msg, sig []byte) bool { sig = sig[:len(sig)-1] } + if len(msg) != crypto.DigestLength { + msg = crypto.Keccak256Hash(msg).Bytes() + } + // the signature needs to be in [R || S] format when provided to VerifySignature - return crypto.VerifySignature(pubKey.Key, crypto.Keccak256Hash(msg).Bytes(), sig) + return crypto.VerifySignature(pubKey.Key, msg, sig) } diff --git a/proto/cosmos/staking/v1beta1/tx.proto b/proto/cosmos/staking/v1beta1/tx.proto index c56b37df93..1c2997de17 100644 --- a/proto/cosmos/staking/v1beta1/tx.proto +++ b/proto/cosmos/staking/v1beta1/tx.proto @@ -71,6 +71,7 @@ message MsgCreateValidator { string relayer_address = 9 [(cosmos_proto.scalar) = "cosmos.AddressString"]; string challenger_address = 10 [(cosmos_proto.scalar) = "cosmos.AddressString"]; string bls_key = 11; + string bls_proof = 12; } // MsgCreateValidatorResponse defines the Msg/CreateValidator response type. @@ -98,7 +99,8 @@ message MsgEditValidator { string relayer_address = 5 [(cosmos_proto.scalar) = "cosmos.AddressString"]; string challenger_address = 6 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - string bls_key = 7; // The BLS pubkey for the authorized relayer/challenger + string bls_key = 7; // The BLS pubkey for the authorized relayer/challenger + string bls_proof = 8; } // MsgEditValidatorResponse defines the Msg/EditValidator response type. diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index 945f3617db..f65bc0b83c 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -12,6 +12,7 @@ import ( "path/filepath" tmconfig "github.com/cometbft/cometbft/config" + "github.com/cometbft/cometbft/crypto/tmhash" "github.com/cometbft/cometbft/types" tmtime "github.com/cometbft/cometbft/types/time" "github.com/prysmaticlabs/prysm/crypto/bls" @@ -302,6 +303,8 @@ func initTestnetFiles( valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction) blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) createValMsg, err := stakingtypes.NewMsgCreateValidator( sdk.AccAddress(addr), valPubKeys[i], @@ -309,7 +312,7 @@ func initTestnetFiles( stakingtypes.NewDescription(nodeDirName, "", "", "", ""), stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()), sdk.OneInt(), - addr, addr, addr, addr, blsPk, + addr, addr, addr, addr, blsPk, blsProof, ) if err != nil { return err diff --git a/tests/e2e/genutil/suite.go b/tests/e2e/genutil/suite.go index e95df9fb9e..0985b4bdf3 100644 --- a/tests/e2e/genutil/suite.go +++ b/tests/e2e/genutil/suite.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" + "github.com/cometbft/cometbft/crypto/tmhash" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/suite" @@ -53,6 +54,8 @@ func (s *E2ETestSuite) TestGenTxCmd() { amount := sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(12)) blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) tests := []struct { name string @@ -83,6 +86,7 @@ func (s *E2ETestSuite) TestGenTxCmd() { val.Address.String(), val.Address.String(), blsPk, + blsProof, }, expError: false, }, @@ -97,6 +101,7 @@ func (s *E2ETestSuite) TestGenTxCmd() { val.Address.String(), val.Address.String(), blsPk, + blsProof, }, expError: true, }, diff --git a/testutil/network/network.go b/testutil/network/network.go index 6c69aa1fc5..4d55734db1 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -17,6 +17,7 @@ import ( "time" dbm "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/crypto/tmhash" "github.com/cometbft/cometbft/node" tmclient "github.com/cometbft/cometbft/rpc/client" "github.com/prysmaticlabs/prysm/crypto/bls" @@ -498,7 +499,8 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) { return nil, err } blsPubKey := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) - + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) createValMsg, err := stakingtypes.NewMsgCreateValidator( addr, valPubKeys[i], @@ -506,7 +508,7 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) { stakingtypes.NewDescription(nodeDirName, "", "", "", ""), stakingtypes.NewCommissionRates(commission, math.LegacyOneDec(), math.LegacyOneDec()), math.OneInt(), - addr, addr, addr, addr, blsPubKey, + addr, addr, addr, addr, blsPubKey, blsProof, ) if err != nil { return nil, err diff --git a/testutil/sims/address_helpers.go b/testutil/sims/address_helpers.go index 742bcfca72..9aa0dc93b3 100644 --- a/testutil/sims/address_helpers.go +++ b/testutil/sims/address_helpers.go @@ -8,6 +8,7 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/errors" @@ -144,6 +145,19 @@ func CreateTestPubKeys(numPubKeys int) []cryptotypes.PubKey { return publicKeys } +// CreateTestAccounts returns number of PubKey, PrivKey +func CreateTestAccounts(num int) ([]cryptotypes.PubKey, []cryptotypes.PrivKey) { + var publicKeys = make([]cryptotypes.PubKey, 0, num) + var privateKeys = make([]cryptotypes.PrivKey, 0, num) + for i := 0; i < num; i++ { + privKey, _ := ethsecp256k1.GenPrivKey() + publicKeys = append(publicKeys, privKey.PubKey()) + privateKeys = append(privateKeys, privKey) + } + + return publicKeys, privateKeys +} + // NewPubKeyFromHex returns a PubKey from a hex string. func NewPubKeyFromHex(pk string) (res cryptotypes.PubKey) { pkBytes, err := hex.DecodeString(pk) diff --git a/types/address.go b/types/address.go index ab38985771..d84586798e 100644 --- a/types/address.go +++ b/types/address.go @@ -77,8 +77,9 @@ const ( EthAddressLength = 20 // BLSPubKeyLength defines a valid BLS Public key length - BLSPubKeyLength = 48 - BLSEmptyPubKey = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dead" + BLSPubKeyLength = 48 + BLSSignatureLength = 96 + BLSEmptyPubKey = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dead" ) // cache variables diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index 6816ce5bc6..82b4d04879 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -33,9 +33,9 @@ func GenTxCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig, genBalI fsCreateValidator, defaultsDesc := cli.CreateValidatorMsgFlagSet(ipDefault) cmd := &cobra.Command{ - Use: "gentx [key_name] [amount] [validator] [relayer] [challenger] [blskey]", + Use: "gentx [key_name] [amount] [validator] [relayer] [challenger] [blskey] [blsProof]", Short: "Generate a genesis tx carrying a self delegation", - Args: cobra.ExactArgs(6), + Args: cobra.ExactArgs(7), Long: fmt.Sprintf(`Generate a genesis transaction that creates a validator with a self-delegation, that is signed by the key in the Keyring referenced by a given name. A node ID and Bech32 consensus pubkey may optionally be provided. If they are omitted, they will be retrieved from the priv_validator.json @@ -47,6 +47,7 @@ $ %s gentx my-key-name 1000000stake \ 0x6D967dc83b625603c963713eABd5B43A281E595e \ 0xcdd393723f1Af81faa3F3c87B51dAB72B6c68154 \ ac1e598ae0ccbeeaafa31bc6faefa85c2ae3138699cac79169cd718f1a38445201454ec092a86f200e08a15266bdc6e9 \ + b68b819c2d431bd8ea800326bbcd91bbbbec5404b8f456b23c87de368c7f48507e7be120f32354ebf3df38c2b5808cebd4c07254f0b4626007c6d46fc05b260901 \ --home=/path/to/home/dir --keyring-backend=os --chain-id=greenfield_9000-1 \ --moniker="myvalidator" \ --commission-max-change-rate=0.01 \ @@ -172,12 +173,17 @@ $ %s gentx my-key-name 1000000stake \ if len(blsPk) != 2*sdk.BLSPubKeyLength { return fmt.Errorf("invalid bls pubkey") } + blsProof := args[6] + if len(blsProof) != 2*sdk.BLSSignatureLength { + return fmt.Errorf("invalid bls proof, len: %d", len(blsProof)) + } createValCfg.Validator = validator createValCfg.Delegator = addr createValCfg.Relayer = relayer createValCfg.Challenger = challenger createValCfg.BlsKey = blsPk + createValCfg.BLSProof = blsProof // create a 'create-validator' message txBldr, msg, err := cli.BuildCreateValidatorMsg(clientCtx, createValCfg, txFactory, true) diff --git a/x/genutil/gentx_test.go b/x/genutil/gentx_test.go index c34bb174e5..aa62c1deb2 100644 --- a/x/genutil/gentx_test.go +++ b/x/genutil/gentx_test.go @@ -19,6 +19,7 @@ import ( moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/tmhash" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltestutil "github.com/cosmos/cosmos-sdk/x/genutil/testutil" @@ -67,17 +68,19 @@ func (suite *GenTxTestSuite) SetupTest() { one := math.OneInt() blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) suite.msg1, err = stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk1.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), - sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk) + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk, blsProof) suite.NoError(err) suite.msg2, err = stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk2.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), - sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk1.Address()), blsPk) + sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk1.Address()), blsPk, blsProof) suite.NoError(err) } diff --git a/x/genutil/types/genesis_state_test.go b/x/genutil/types/genesis_state_test.go index 927fc3e5c0..55a5f09731 100644 --- a/x/genutil/types/genesis_state_test.go +++ b/x/genutil/types/genesis_state_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "testing" + "github.com/cometbft/cometbft/crypto/tmhash" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -43,20 +44,24 @@ func TestValidateGenesisMultipleMessages(t *testing.T) { blsSecretKey1, _ := bls.RandKey() blsPk1 := hex.EncodeToString(blsSecretKey1.PublicKey().Marshal()) + blsProofBuf := blsSecretKey1.Sign(tmhash.Sum(blsSecretKey1.PublicKey().Marshal())) + blsProof1 := hex.EncodeToString(blsProofBuf.Marshal()) msg1, err := stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk1.Address()), pk1, sdk.NewInt64Coin(sdk.DefaultBondDenom, 50), desc, comm, sdk.OneInt(), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), - sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1) + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1, blsProof1) require.NoError(t, err) blsSecretKey2, _ := bls.RandKey() blsPk2 := hex.EncodeToString(blsSecretKey2.PublicKey().Marshal()) + blsProofBuf = blsSecretKey2.Sign(tmhash.Sum(blsSecretKey2.PublicKey().Marshal())) + blsProof2 := hex.EncodeToString(blsProofBuf.Marshal()) msg2, err := stakingtypes.NewMsgCreateValidator( sdk.AccAddress(pk2.Address()), pk2, sdk.NewInt64Coin(sdk.DefaultBondDenom, 50), desc, comm, sdk.OneInt(), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), - sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2) + sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2, blsProof2) require.NoError(t, err) txConfig := moduletestutil.MakeTestEncodingConfig(staking.AppModuleBasic{}, genutil.AppModuleBasic{}).TxConfig @@ -74,10 +79,11 @@ func TestValidateGenesisBadMessage(t *testing.T) { desc := stakingtypes.NewDescription("testname", "", "", "", "") blsSecretKey1, _ := bls.RandKey() blsPk1 := hex.EncodeToString(blsSecretKey1.PublicKey().Marshal()) - + blsProofBuf := blsSecretKey1.Sign(tmhash.Sum(blsSecretKey1.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) msg1 := stakingtypes.NewMsgEditValidator( sdk.AccAddress(pk1.Address()), desc, nil, nil, - sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1, + sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1, blsProof, ) txConfig := moduletestutil.MakeTestEncodingConfig(staking.AppModuleBasic{}, genutil.AppModuleBasic{}).TxConfig diff --git a/x/gov/abci_test.go b/x/gov/abci_test.go index d6f8d7ad0a..2bbd9a22dc 100644 --- a/x/gov/abci_test.go +++ b/x/gov/abci_test.go @@ -6,6 +6,7 @@ import ( "time" abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/tmhash" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/require" @@ -393,11 +394,13 @@ func createValidators(t *testing.T, stakingMsgSvr stakingtypes.MsgServer, ctx sd valTokens := sdk.TokensFromConsensusPower(powerAmt[i], sdk.DefaultPowerReduction) blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) valCreateMsg, err := stakingtypes.NewMsgCreateValidator( addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens), TestDescription, TestCommissionRates, sdk.OneInt(), addrs[i], addrs[i], - addrs[i], addrs[i], blsPk) + addrs[i], addrs[i], blsPk, blsProof) require.NoError(t, err) res, err := stakingMsgSvr.CreateValidator(sdk.WrapSDKContext(ctx), valCreateMsg) require.NoError(t, err) diff --git a/x/slashing/abci_test.go b/x/slashing/abci_test.go index 36ed0ba9c0..62785223e4 100644 --- a/x/slashing/abci_test.go +++ b/x/slashing/abci_test.go @@ -38,14 +38,14 @@ func TestBeginBlocker(t *testing.T) { ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - pks := simtestutil.CreateTestPubKeys(1) + pks, pvs := simtestutil.CreateTestAccounts(1) simtestutil.AddTestAddrsFromPubKeys(bankKeeper, stakingKeeper, ctx, pks, stakingKeeper.TokensFromConsensusPower(ctx, 200)) - addr, pk := sdk.AccAddress(pks[0].Address()), pks[0] + addr, pk, pv := sdk.AccAddress(pks[0].Address()), pks[0], pvs[0] tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper) // bond the validator power := int64(100) - amt := tstaking.CreateValidatorWithValPower(addr, pk, power, true) + amt := tstaking.CreateValidatorWithValPower(addr, pk, pv, power, true) staking.EndBlocker(ctx, stakingKeeper) require.Equal( t, bankKeeper.GetAllBalances(ctx, addr), diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index a0598d8c69..45ce627d0e 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -6,6 +6,7 @@ import ( "testing" abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/tmhash" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/require" @@ -79,11 +80,13 @@ func TestSlashingMsgs(t *testing.T) { commission := stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) createValidatorMsg, err := stakingtypes.NewMsgCreateValidator( addr1, valKey.PubKey(), bondCoin, description, commission, sdk.OneInt(), - addr1, addr1, addr1, addr1, blsPk, + addr1, addr1, addr1, addr1, blsPk, blsProof, ) require.NoError(t, err) diff --git a/x/staking/app_test.go b/x/staking/app_test.go index d34a36a320..aa540cdb7d 100644 --- a/x/staking/app_test.go +++ b/x/staking/app_test.go @@ -12,6 +12,7 @@ import ( "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/tmhash" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" @@ -70,10 +71,12 @@ func TestStakingMsgs(t *testing.T) { description := types.NewDescription("foo_moniker", "", "", "", "") blsSecretKey, _ := bls.RandKey() blsPubKey := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof1 := hex.EncodeToString(blsProofBuf.Marshal()) createValidatorMsg, err := types.NewMsgCreateValidator( addr1, valKey.PubKey(), bondCoin, description, commissionRates, sdk.OneInt(), - addr1, addr1, addr1, addr1, blsPubKey, + addr1, addr1, addr1, addr1, blsPubKey, blsProof1, ) require.NoError(t, err) @@ -99,7 +102,7 @@ func TestStakingMsgs(t *testing.T) { description = types.NewDescription("bar_moniker", "", "", "", "") editValidatorMsg := types.NewMsgEditValidator( addr1, description, nil, nil, - sdk.AccAddress(""), sdk.AccAddress(""), "", + sdk.AccAddress(""), sdk.AccAddress(""), "", "", ) header = tmproto.Header{ChainID: sdktestutil.DefaultChainId, Height: app.LastBlockHeight() + 1} _, _, err = simtestutil.SignCheckDeliver(t, txConfig, app.BaseApp, header, []sdk.Msg{editValidatorMsg}, sdktestutil.DefaultChainId, []uint64{0}, []uint64{1}, true, true, []cryptotypes.PrivKey{priv1}) diff --git a/x/staking/client/cli/flags.go b/x/staking/client/cli/flags.go index 2560a36f73..0217910bfb 100644 --- a/x/staking/client/cli/flags.go +++ b/x/staking/client/cli/flags.go @@ -36,6 +36,7 @@ const ( FlagAddressRelayer = "addr-relayer" FlagAddressChallenger = "addr-challenger" FlagBlsKey = "bls-key" + FlagBlsProof = "bls-proof" ) // common flagsets to add to various functions @@ -96,6 +97,7 @@ func FlagSetRelayerAddress() *flag.FlagSet { func FlagSetBlsKey() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) fs.String(FlagBlsKey, "", "The bls pubkey of the validator") + fs.String(FlagBlsProof, "", "The bls proof of the validator") return fs } diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 88cdf328c6..d8cacbf4e0 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -232,10 +232,11 @@ func NewEditValidatorCmd() *cobra.Command { } blsPk, _ := cmd.Flags().GetString(FlagBlsKey) + blsProof, _ := cmd.Flags().GetString(FlagBlsProof) msg := types.NewMsgEditValidator( valAddr, description, newRate, newMinSelfDelegation, - relayer, challenger, blsPk, + relayer, challenger, blsPk, blsProof, ) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) @@ -497,6 +498,7 @@ type TxCreateValidatorConfig struct { Relayer sdk.AccAddress Challenger sdk.AccAddress BlsKey string + BLSProof string } func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, chainID string, valPubKey cryptotypes.PubKey) (TxCreateValidatorConfig, error) { @@ -636,7 +638,7 @@ func BuildCreateValidatorMsg(clientCtx client.Context, config TxCreateValidatorC msg, err := types.NewMsgCreateValidator( config.Validator, config.PubKey, amount, description, commissionRates, minSelfDelegation, - from, config.Delegator, config.Relayer, config.Challenger, config.BlsKey) + from, config.Delegator, config.Relayer, config.Challenger, config.BlsKey, config.BLSProof) if err != nil { return txBldr, msg, err } diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index 009170a0b3..8393ff5f84 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -7,12 +7,15 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/cometbft/cometbft/crypto/tmhash" + "github.com/prysmaticlabs/prysm/crypto/bls" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -106,6 +109,19 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa return nil, types.ErrValidatorBlsKeyExists } + // check to see if the bls proof is signed from operator + blsProof, err := hex.DecodeString(msg.BlsProof) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) + } + ok, err = k.CheckBlsProof(ctx, blsPk, blsProof, valAddr) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) + } + if !ok { + return nil, types.ErrValidatorInvalidBlsProof + } + bondDenom := k.BondDenom(ctx) if msg.Value.Denom != bondDenom { return nil, sdkerrors.Wrapf( @@ -289,11 +305,23 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida } // replace bls pubkey - if len(msg.BlsKey) != 0 { + if len(msg.BlsKey) != 0 && len(msg.BlsProof) != 0 { blsPk, err := hex.DecodeString(msg.BlsKey) if err != nil || len(blsPk) != sdk.BLSPubKeyLength { return nil, types.ErrValidatorInvalidBlsKey } + // check to see if the bls proof is signed from operator + blsProof, err := hex.DecodeString(msg.BlsProof) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) + } + ok, err := k.CheckBlsProof(ctx, blsPk, blsProof, validator.GetOperator()) + if err != nil { + return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) + } + if !ok { + return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, "signature verification failed") + } if tmpValidator, found := k.GetValidatorByBlsKey(ctx, blsPk); found { if tmpValidator.OperatorAddress != validator.OperatorAddress { return nil, types.ErrValidatorBlsKeyExists @@ -628,3 +656,23 @@ func (ms msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdatePara return &types.MsgUpdateParamsResponse{}, nil } + +// CheckBlsProof checks the BLS signature of the validator +func (ms msgServer) CheckBlsProof(goCtx context.Context, blsPk, sig []byte, valAddr sdk.Address) (bool, error) { + if len(sig) != sdk.BLSSignatureLength { + return false, sdkerrors.Wrapf(sdkerrors.ErrorInvalidSigner, "signature length (actual: %d) doesn't match typical BLS signature 96 bytes", len(sig)) + } + + blsPubKey, err := bls.PublicKeyFromBytes(blsPk) + if err != nil { + return false, sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "BLS public key is invalid") + } + + signature, err := bls.SignatureFromBytes(sig) + if err != nil { + return false, sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "BLS signature key is invalid") + } + + sigHash := tmhash.Sum(blsPk) + return signature.Verify(blsPubKey, sigHash), nil +} diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go index 2f3138dbbb..8475e72391 100644 --- a/x/staking/simulation/operations.go +++ b/x/staking/simulation/operations.go @@ -5,6 +5,7 @@ import ( "fmt" "math/rand" + "github.com/cometbft/cometbft/crypto/tmhash" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/cosmos/cosmos-sdk/baseapp" @@ -161,11 +162,13 @@ func SimulateMsgCreateValidator(ak types.AccountKeeper, bk types.BankKeeper, k * blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) msg, err := types.NewMsgCreateValidator( address, simAccount.ConsKey.PubKey(), selfDelegation, description, commission, sdk.OneInt(), - address, address, address, address, blsPk, + address, address, address, address, blsPk, blsProof, ) if err != nil { return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to create CreateValidator message"), nil, err @@ -226,7 +229,7 @@ func SimulateMsgEditValidator(ak types.AccountKeeper, bk types.BankKeeper, k *ke simtypes.RandStringOfLength(r, 10), ) - msg := types.NewMsgEditValidator(address, description, &newCommissionRate, nil, address, address, "") + msg := types.NewMsgEditValidator(address, description, &newCommissionRate, nil, address, address, "", "") txCtx := simulation.OperationInput{ R: r, diff --git a/x/staking/testutil/helpers.go b/x/staking/testutil/helpers.go index 2292ea107f..aedd44d59f 100644 --- a/x/staking/testutil/helpers.go +++ b/x/staking/testutil/helpers.go @@ -7,6 +7,7 @@ import ( "time" "cosmossdk.io/math" + "github.com/cometbft/cometbft/crypto/tmhash" "github.com/prysmaticlabs/prysm/crypto/bls" "github.com/stretchr/testify/require" @@ -36,29 +37,31 @@ func NewHelper(t *testing.T, ctx sdk.Context, k *keeper.Keeper) *Helper { } // CreateValidator calls staking module `MsgServer/CreateValidator` to create a new validator -func (sh *Helper) CreateValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, stakeAmount math.Int, ok bool) { +func (sh *Helper) CreateValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, stakeAmount math.Int, ok bool) { coin := sdk.NewCoin(sh.Denom, stakeAmount) - sh.createValidator(addr, pk, coin, ok) + sh.createValidator(addr, pk, pv, coin, ok) } // CreateValidatorWithValPower calls staking module `MsgServer/CreateValidator` to create a new validator with zero // commission -func (sh *Helper) CreateValidatorWithValPower(addr sdk.AccAddress, pk cryptotypes.PubKey, valPower int64, ok bool) math.Int { +func (sh *Helper) CreateValidatorWithValPower(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, valPower int64, ok bool) math.Int { amount := sh.k.TokensFromConsensusPower(sh.Ctx, valPower) coin := sdk.NewCoin(sh.Denom, amount) - sh.createValidator(addr, pk, coin, ok) + sh.createValidator(addr, pk, pv, coin, ok) return amount } // CreateValidatorMsg returns a message used to create validator in this service. -func (sh *Helper) CreateValidatorMsg(addr sdk.AccAddress, pk cryptotypes.PubKey, stakeAmount math.Int) *stakingtypes.MsgCreateValidator { +func (sh *Helper) CreateValidatorMsg(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, stakeAmount math.Int) *stakingtypes.MsgCreateValidator { coin := sdk.NewCoin(sh.Denom, stakeAmount) blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) msg, err := stakingtypes.NewMsgCreateValidator( addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt(), - addr, addr, addr, addr, blsPk, + addr, addr, addr, addr, blsPk, blsProof, ) require.NoError(sh.t, err) return msg @@ -69,13 +72,15 @@ func (sh *Helper) CreateValidatorWithMsg(ctx context.Context, msg *stakingtypes. return sh.msgSrvr.CreateValidator(ctx, msg) } -func (sh *Helper) createValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, coin sdk.Coin, ok bool) { +func (sh *Helper) createValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, coin sdk.Coin, ok bool) { blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) msg, err := stakingtypes.NewMsgCreateValidator( addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt(), - addr, addr, addr, addr, blsPk, + addr, addr, addr, addr, blsPk, blsProof, ) require.NoError(sh.t, err) res, err := sh.msgSrvr.CreateValidator(sh.Ctx.WithBlockHeight(0), msg) diff --git a/x/staking/types/data_test.go b/x/staking/types/data_test.go index 15ca7c3c98..b050c6df6f 100644 --- a/x/staking/types/data_test.go +++ b/x/staking/types/data_test.go @@ -4,16 +4,20 @@ import ( "fmt" codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + + "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" ) var ( - pk1 = ed25519.GenPrivKey().PubKey() + pv1, _ = ethsecp256k1.GenPrivKey() + pv2, _ = ethsecp256k1.GenPrivKey() + pv3, _ = ethsecp256k1.GenPrivKey() + pk1 = pv1.PubKey() pk1Any *codectypes.Any - pk2 = ed25519.GenPrivKey().PubKey() - pk3 = ed25519.GenPrivKey().PubKey() + pk2 = pv2.PubKey() + pk3 = pv3.PubKey() addr1, _ = sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixAccAddr, pk1.Address().Bytes()) addr2, _ = sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixAccAddr, pk2.Address().Bytes()) addr3, _ = sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixAccAddr, pk3.Address().Bytes()) diff --git a/x/staking/types/errors.go b/x/staking/types/errors.go index 3599eecc2d..c021ba77af 100644 --- a/x/staking/types/errors.go +++ b/x/staking/types/errors.go @@ -58,4 +58,5 @@ var ( ErrRedelegationNotAllowed = errors.Register(ModuleName, 48, "redelegation is not allowed") ErrInvalidSigner = errors.Register(ModuleName, 49, "invalid signer") ErrInvalidMinSelfDelegation = errors.Register(ModuleName, 50, "invalid minimum self delegation, must no less than the chain level minimum self delegation") + ErrValidatorInvalidBlsProof = errors.Register(ModuleName, 51, "validator bls proof is invalid") ) diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index 3ded029ffe..b1103d7558 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -36,7 +36,7 @@ var ( func NewMsgCreateValidator( valAddr sdk.AccAddress, pubKey cryptotypes.PubKey, //nolint:interfacer selfDelegation sdk.Coin, description Description, commission CommissionRates, minSelfDelegation math.Int, - from, selfDelAddr, relayerAddr, challengerAddr sdk.AccAddress, blsKey string, + from, selfDelAddr, relayerAddr, challengerAddr sdk.AccAddress, blsKey, blsProof string, ) (*MsgCreateValidator, error) { var pkAny *codectypes.Any if pubKey != nil { @@ -57,6 +57,7 @@ func NewMsgCreateValidator( RelayerAddress: relayerAddr.String(), ChallengerAddress: challengerAddr.String(), BlsKey: blsKey, + BlsProof: blsProof, }, nil } @@ -113,6 +114,10 @@ func (msg MsgCreateValidator) ValidateBasic() error { return ErrValidatorInvalidBlsKey } + if len(msg.BlsProof) != 2*sdk.BLSSignatureLength { + return ErrValidatorInvalidBlsProof.Wrapf("proof length is invalid %d", len(msg.BlsProof)) + } + if msg.Description == (Description{}) { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } @@ -150,7 +155,7 @@ func (msg MsgCreateValidator) UnpackInterfaces(unpacker codectypes.AnyUnpacker) //nolint:interfacer func NewMsgEditValidator( valAddr sdk.AccAddress, description Description, newRate *sdk.Dec, newMinSelfDelegation *math.Int, - newRelayerAddr, newChallengerAddr sdk.AccAddress, newBlsKey string, + newRelayerAddr, newChallengerAddr sdk.AccAddress, newBlsKey, newBlsProof string, ) *MsgEditValidator { return &MsgEditValidator{ Description: description, @@ -160,6 +165,7 @@ func NewMsgEditValidator( RelayerAddress: newRelayerAddr.String(), ChallengerAddress: newChallengerAddr.String(), BlsKey: newBlsKey, + BlsProof: newBlsProof, } } @@ -201,6 +207,16 @@ func (msg MsgEditValidator) ValidateBasic() error { } } + if len(msg.BlsKey) != 0 && len(msg.BlsProof) != 0 { + if len(msg.BlsKey) != 2*sdk.BLSPubKeyLength { + return ErrValidatorInvalidBlsKey + } + length := len(msg.BlsProof) + if length != 2*sdk.BLSSignatureLength { + return ErrValidatorInvalidBlsProof.Wrapf("proof length is invalid %d", len(msg.BlsProof)) + } + } + if msg.Description == (Description{}) { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } diff --git a/x/staking/types/msg_test.go b/x/staking/types/msg_test.go index ca148772f4..f3334d7f9f 100644 --- a/x/staking/types/msg_test.go +++ b/x/staking/types/msg_test.go @@ -6,6 +6,7 @@ import ( "time" "cosmossdk.io/math" + "github.com/cometbft/cometbft/crypto/tmhash" "github.com/prysmaticlabs/prysm/crypto/bls" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -16,7 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -40,18 +41,20 @@ func TestMsgDecode(t *testing.T) { var pkUnmarshaled cryptotypes.PubKey err = cdc.UnmarshalInterface(pk1bz, &pkUnmarshaled) require.NoError(t, err) - require.True(t, pk1.Equals(pkUnmarshaled.(*ed25519.PubKey))) + require.True(t, pk1.Equals(pkUnmarshaled.(*ethsecp256k1.PubKey))) // now let's try to serialize the whole message blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof := hex.EncodeToString(blsProofBuf.Marshal()) commission1 := types.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) msg, err := types.NewMsgCreateValidator( valAddr1, pk1, coinPos, types.Description{}, commission1, sdk.OneInt(), valAddr1, valAddr1, - valAddr1, valAddr1, blsPk, + valAddr1, valAddr1, blsPk, blsProof, ) require.NoError(t, err) msgSerialized, err := cdc.MarshalInterface(msg) @@ -92,15 +95,24 @@ func TestMsgCreateValidator(t *testing.T) { {"delegation less than min self delegation", "a", "b", "c", "d", "e", commission1, coinPos.Amount.Add(math.OneInt()), valAddr1, pk1, coinPos, false}, } - blsSecretKey, _ := bls.RandKey() - blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) for _, tc := range tests { description := types.NewDescription(tc.moniker, tc.identity, tc.website, tc.securityContact, tc.details) + var ( + blsPk string + blsProof string + ) + if !tc.validatorAddr.Equals(emptyAddr) { + blsSecretKey, _ := bls.RandKey() + blsPk = hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof = hex.EncodeToString(blsProofBuf.Marshal()) + } + msg, err := types.NewMsgCreateValidator( tc.validatorAddr, tc.pubkey, tc.bond, description, tc.CommissionRates, tc.minSelfDelegation, tc.validatorAddr, tc.validatorAddr, - tc.validatorAddr, tc.validatorAddr, blsPk, + tc.validatorAddr, tc.validatorAddr, blsPk, blsProof, ) require.NoError(t, err) if tc.expectPass { @@ -130,12 +142,19 @@ func TestMsgEditValidator(t *testing.T) { description := types.NewDescription(tc.moniker, tc.identity, tc.website, tc.securityContact, tc.details) newRate := math.LegacyZeroDec() + var ( + blsPk string + blsProof string + ) + blsSecretKey, _ := bls.RandKey() - blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsPk = hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) + blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) + blsProof = hex.EncodeToString(blsProofBuf.Marshal()) msg := types.NewMsgEditValidator( tc.validatorAddr, description, &newRate, &tc.minSelfDelegation, - tc.validatorAddr, tc.validatorAddr, blsPk) + tc.validatorAddr, tc.validatorAddr, blsPk, blsProof) if tc.expectPass { require.Nil(t, msg.ValidateBasic(), "test: %v", tc.name) } else { diff --git a/x/staking/types/tx.pb.go b/x/staking/types/tx.pb.go index 742cdc07b6..7f7039d63e 100644 --- a/x/staking/types/tx.pb.go +++ b/x/staking/types/tx.pb.go @@ -51,6 +51,7 @@ type MsgCreateValidator struct { RelayerAddress string `protobuf:"bytes,9,opt,name=relayer_address,json=relayerAddress,proto3" json:"relayer_address,omitempty"` ChallengerAddress string `protobuf:"bytes,10,opt,name=challenger_address,json=challengerAddress,proto3" json:"challenger_address,omitempty"` BlsKey string `protobuf:"bytes,11,opt,name=bls_key,json=blsKey,proto3" json:"bls_key,omitempty"` + BlsProof string `protobuf:"bytes,12,opt,name=bls_proof,json=blsProof,proto3" json:"bls_proof,omitempty"` } func (m *MsgCreateValidator) Reset() { *m = MsgCreateValidator{} } @@ -136,6 +137,7 @@ type MsgEditValidator struct { RelayerAddress string `protobuf:"bytes,5,opt,name=relayer_address,json=relayerAddress,proto3" json:"relayer_address,omitempty"` ChallengerAddress string `protobuf:"bytes,6,opt,name=challenger_address,json=challengerAddress,proto3" json:"challenger_address,omitempty"` BlsKey string `protobuf:"bytes,7,opt,name=bls_key,json=blsKey,proto3" json:"bls_key,omitempty"` + BlsProof string `protobuf:"bytes,8,opt,name=bls_proof,json=blsProof,proto3" json:"bls_proof,omitempty"` } func (m *MsgEditValidator) Reset() { *m = MsgEditValidator{} } @@ -662,81 +664,82 @@ func init() { func init() { proto.RegisterFile("cosmos/staking/v1beta1/tx.proto", fileDescriptor_0926ef28816b35ab) } var fileDescriptor_0926ef28816b35ab = []byte{ - // 1172 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0xcd, 0x6f, 0x1b, 0x45, - 0x14, 0xf7, 0x3a, 0x89, 0xd3, 0x4c, 0x48, 0xdc, 0x6c, 0x92, 0xc6, 0x59, 0x8a, 0x5d, 0xb9, 0xa1, - 0x89, 0x42, 0xb3, 0xa6, 0x01, 0xf1, 0x11, 0x22, 0x44, 0xdc, 0xb4, 0x50, 0x4a, 0xa4, 0x68, 0x43, - 0x39, 0x20, 0x24, 0x6b, 0x76, 0x77, 0xb2, 0x5e, 0x79, 0x77, 0x67, 0xbb, 0x33, 0x8e, 0xea, 0x1b, - 0xe2, 0x84, 0xb8, 0xd0, 0x03, 0x07, 0x2e, 0x48, 0x39, 0x72, 0xcc, 0xa1, 0xff, 0x02, 0x52, 0xc5, - 0xa9, 0xea, 0x09, 0x21, 0xd1, 0xa2, 0xe4, 0x10, 0xfe, 0x03, 0xae, 0x68, 0x76, 0x67, 0xbf, 0xfc, - 0x9d, 0x92, 0x1e, 0xe0, 0x12, 0x3b, 0x33, 0xbf, 0xf7, 0x9b, 0xf7, 0x7e, 0xef, 0xbd, 0x99, 0x67, - 0x50, 0xd2, 0x30, 0xb1, 0x31, 0xa9, 0x10, 0x0a, 0x1b, 0xa6, 0x63, 0x54, 0x0e, 0x6e, 0xa8, 0x88, - 0xc2, 0x1b, 0x15, 0xfa, 0x40, 0x76, 0x3d, 0x4c, 0xb1, 0x78, 0x29, 0x00, 0xc8, 0x1c, 0x20, 0x73, - 0x80, 0xb4, 0x68, 0x60, 0x6c, 0x58, 0xa8, 0xe2, 0xa3, 0xd4, 0xe6, 0x7e, 0x05, 0x3a, 0xad, 0xc0, - 0x44, 0x2a, 0xb5, 0x6f, 0x51, 0xd3, 0x46, 0x84, 0x42, 0xdb, 0xe5, 0x80, 0x39, 0x03, 0x1b, 0xd8, - 0xff, 0x5a, 0x61, 0xdf, 0xf8, 0xea, 0x62, 0x70, 0x52, 0x2d, 0xd8, 0xe0, 0xc7, 0x06, 0x5b, 0x45, - 0xee, 0xa5, 0x0a, 0x09, 0x8a, 0x5c, 0xd4, 0xb0, 0xe9, 0xf0, 0xfd, 0xa5, 0x1e, 0x51, 0x84, 0x4e, - 0x07, 0xa8, 0x05, 0x8e, 0xb2, 0x09, 0x43, 0xb0, 0x0f, 0xbe, 0x31, 0x03, 0x6d, 0xd3, 0xc1, 0x15, - 0xff, 0x6f, 0xb0, 0x54, 0x3e, 0xcc, 0x01, 0x71, 0x87, 0x18, 0x37, 0x3d, 0x04, 0x29, 0xfa, 0x02, - 0x5a, 0xa6, 0x0e, 0x29, 0xf6, 0xc4, 0x5d, 0x30, 0xa9, 0x23, 0xa2, 0x79, 0xa6, 0x4b, 0x4d, 0xec, - 0x14, 0x84, 0x2b, 0xc2, 0xca, 0xe4, 0xfa, 0x55, 0xb9, 0xbb, 0x46, 0xf2, 0x76, 0x0c, 0xad, 0x4e, - 0x3c, 0x7e, 0x56, 0xca, 0xfc, 0x7c, 0x7a, 0xb4, 0x2a, 0x28, 0x49, 0x0a, 0x51, 0x01, 0x40, 0xc3, - 0xb6, 0x6d, 0x12, 0xc2, 0x08, 0xb3, 0x3e, 0xe1, 0x72, 0x2f, 0xc2, 0x9b, 0x11, 0x52, 0x81, 0x14, - 0x91, 0x24, 0x69, 0x82, 0x45, 0xb4, 0xc0, 0xac, 0x6d, 0x3a, 0x35, 0x82, 0xac, 0xfd, 0x9a, 0x8e, - 0x2c, 0x64, 0x40, 0xdf, 0xdb, 0x91, 0x2b, 0xc2, 0xca, 0x44, 0x75, 0x93, 0xd9, 0xfc, 0xfe, 0xac, - 0x74, 0xcd, 0x30, 0x69, 0xbd, 0xa9, 0xca, 0x1a, 0xb6, 0xb9, 0xd8, 0xfc, 0x63, 0x8d, 0xe8, 0x8d, - 0x0a, 0x6d, 0xb9, 0x88, 0xc8, 0x77, 0x1c, 0xfa, 0xf4, 0xd1, 0x1a, 0xe0, 0xde, 0xdc, 0x71, 0xa8, - 0x32, 0x63, 0x9b, 0xce, 0x1e, 0xb2, 0xf6, 0xb7, 0x23, 0x5a, 0xf1, 0x16, 0x98, 0xe1, 0x87, 0x60, - 0xaf, 0x06, 0x75, 0xdd, 0x43, 0x84, 0x14, 0x46, 0xfd, 0xb3, 0x0a, 0x4f, 0x1f, 0xad, 0xcd, 0x71, - 0xeb, 0xad, 0x60, 0x67, 0x8f, 0x7a, 0xa6, 0x63, 0x28, 0x17, 0x23, 0x13, 0xbe, 0xce, 0x68, 0x0e, - 0x42, 0x9d, 0x23, 0x9a, 0xb1, 0x41, 0x34, 0x91, 0x49, 0x48, 0x73, 0x1b, 0xe4, 0xdc, 0xa6, 0xda, - 0x40, 0xad, 0x42, 0xce, 0xd7, 0x72, 0x4e, 0x0e, 0xaa, 0x51, 0x0e, 0xab, 0x51, 0xde, 0x72, 0x5a, - 0xd5, 0xc2, 0xaf, 0x31, 0xa3, 0xe6, 0xb5, 0x5c, 0x8a, 0xe5, 0xdd, 0xa6, 0x7a, 0x17, 0xb5, 0x14, - 0x6e, 0x2d, 0x6e, 0x80, 0xb1, 0x03, 0x68, 0x35, 0x51, 0x61, 0xdc, 0xa7, 0x59, 0x0c, 0x53, 0xc2, - 0x4a, 0x30, 0x91, 0x0f, 0x33, 0x95, 0xd9, 0xc0, 0x44, 0xbc, 0x0e, 0x46, 0xf7, 0x3d, 0x6c, 0x17, - 0x2e, 0x0c, 0xf0, 0xde, 0x47, 0x89, 0x5b, 0x20, 0xef, 0x21, 0x0b, 0xb6, 0x50, 0x1c, 0xf6, 0xc4, - 0x00, 0xc3, 0x69, 0x6e, 0x10, 0x06, 0xfd, 0x31, 0x10, 0xb5, 0x3a, 0xb4, 0x2c, 0xe4, 0x18, 0x09, - 0x16, 0x30, 0x80, 0x65, 0x26, 0xb6, 0x09, 0x89, 0x16, 0xc0, 0xb8, 0x6a, 0x91, 0x1a, 0x93, 0x6f, - 0x92, 0x59, 0x2b, 0x39, 0xd5, 0x22, 0x77, 0x51, 0x6b, 0x63, 0xe6, 0xdb, 0xc3, 0x52, 0xe6, 0xaf, - 0xc3, 0x52, 0xe6, 0x9b, 0xd3, 0xa3, 0x55, 0xdf, 0xef, 0xf2, 0x65, 0x20, 0x75, 0x76, 0x88, 0x82, - 0x88, 0x8b, 0x1d, 0x82, 0xca, 0x7f, 0x8c, 0x82, 0x8b, 0x3b, 0xc4, 0xb8, 0xa5, 0x9b, 0xf4, 0x65, - 0xb6, 0x4f, 0xd7, 0xaa, 0xc9, 0x9e, 0xb9, 0x6a, 0x20, 0xc8, 0xc7, 0xfd, 0x53, 0xf3, 0x20, 0x45, - 0xbc, 0x5b, 0xde, 0x1b, 0xb2, 0x53, 0xb6, 0x91, 0x96, 0xe8, 0x94, 0x6d, 0xa4, 0x29, 0xd3, 0x5a, - 0xaa, 0x59, 0xc5, 0x7a, 0xf7, 0xa6, 0x1c, 0x3d, 0xd3, 0x31, 0x43, 0x35, 0x64, 0x97, 0x82, 0x1a, - 0x3b, 0x97, 0x82, 0xca, 0xfd, 0xab, 0x82, 0x1a, 0x4f, 0x15, 0xd4, 0x87, 0xc9, 0x82, 0xea, 0xcc, - 0xe1, 0x77, 0xa7, 0x47, 0xab, 0xaf, 0x26, 0xc2, 0x6f, 0x2f, 0xa5, 0xb2, 0x04, 0x0a, 0xed, 0x6b, - 0x51, 0xed, 0xfd, 0x90, 0x05, 0x93, 0x3b, 0xc4, 0xe0, 0x92, 0xa0, 0xee, 0x37, 0x94, 0x70, 0x3e, - 0x37, 0xd4, 0xd9, 0x6b, 0x6d, 0x13, 0xe4, 0xa0, 0x8d, 0x9b, 0x0e, 0xf5, 0x4b, 0x6c, 0xd8, 0xab, - 0x85, 0xdb, 0x6c, 0xbc, 0x9f, 0xd2, 0xad, 0x23, 0x2c, 0xa6, 0xdb, 0xa5, 0xb4, 0x6e, 0xa1, 0x0c, - 0xe5, 0x79, 0x30, 0x9b, 0xf8, 0x37, 0x52, 0xeb, 0xef, 0xac, 0xff, 0xd4, 0x55, 0x91, 0x61, 0x3a, - 0x0a, 0xd2, 0xcf, 0x59, 0xb4, 0xcf, 0xc0, 0x7c, 0x2c, 0x1a, 0xf1, 0xb4, 0xa1, 0x85, 0x9b, 0x8d, - 0xcc, 0xf6, 0x3c, 0xad, 0x2b, 0x9b, 0x4e, 0x68, 0xc4, 0x36, 0x32, 0x34, 0xdb, 0x36, 0xa1, 0x9d, - 0x99, 0x18, 0x7d, 0x81, 0x4c, 0x7c, 0x34, 0x38, 0x13, 0xaf, 0xa5, 0x33, 0xd1, 0x26, 0x71, 0xd9, - 0xf5, 0x6f, 0xd0, 0xb6, 0xd5, 0x30, 0x2f, 0xa2, 0xe2, 0xdf, 0x49, 0xae, 0x85, 0x58, 0x53, 0xd7, - 0xd8, 0x0c, 0xc5, 0x2f, 0x4c, 0xa9, 0xe3, 0x49, 0xfb, 0x3c, 0x1c, 0xb0, 0xaa, 0x53, 0xcc, 0xcf, - 0x87, 0xcf, 0x4b, 0x42, 0xe0, 0xeb, 0x74, 0xcc, 0xc0, 0x30, 0xe5, 0x1f, 0xb3, 0x60, 0x6a, 0x87, - 0x18, 0xf7, 0x1c, 0xfd, 0xff, 0xd8, 0x1b, 0x1f, 0x0c, 0xce, 0x48, 0x21, 0x9d, 0x91, 0x58, 0x88, - 0x72, 0x03, 0xcc, 0xa7, 0x16, 0x5e, 0x6a, 0x1e, 0x9e, 0x67, 0xc1, 0x65, 0xf6, 0x78, 0x42, 0x47, - 0x43, 0xd6, 0x3d, 0x47, 0xc5, 0x8e, 0x6e, 0x3a, 0xc6, 0xa0, 0xa1, 0xea, 0xbf, 0x99, 0x16, 0x71, - 0x19, 0xe4, 0x35, 0x36, 0x25, 0x30, 0xf9, 0xea, 0xc8, 0x34, 0xea, 0x41, 0xbf, 0x8d, 0x28, 0xd3, - 0xe1, 0xf2, 0x27, 0xfe, 0xea, 0xc6, 0xa7, 0x83, 0xf3, 0xb7, 0x9c, 0xce, 0x5f, 0x4f, 0x01, 0xcb, - 0xd7, 0xc0, 0x52, 0xbf, 0xfd, 0xe8, 0xf6, 0xfb, 0x45, 0x00, 0x79, 0x96, 0x77, 0x57, 0x87, 0x14, - 0xed, 0x42, 0x0f, 0xda, 0x44, 0x7c, 0x07, 0x4c, 0xc0, 0x26, 0xad, 0x63, 0xcf, 0xa4, 0xad, 0x81, - 0xa2, 0xc7, 0x50, 0x71, 0x0b, 0xe4, 0x5c, 0x9f, 0x81, 0xcf, 0xf1, 0xc5, 0x5e, 0x93, 0x4d, 0x70, - 0x4e, 0x4a, 0xab, 0xc0, 0x70, 0xe3, 0x5d, 0x16, 0x7a, 0x4c, 0xc9, 0x42, 0x5e, 0x4a, 0x84, 0xfc, - 0x20, 0xfa, 0x89, 0xd3, 0xe6, 0x73, 0x79, 0x11, 0x2c, 0xb4, 0x2d, 0x85, 0x21, 0xae, 0xff, 0x94, - 0x03, 0x23, 0x3b, 0xc4, 0x10, 0xef, 0x83, 0x7c, 0xfb, 0xef, 0x99, 0xd5, 0x5e, 0x1e, 0x76, 0x4e, - 0x76, 0xd2, 0xfa, 0xf0, 0xd8, 0xa8, 0x77, 0x1a, 0x60, 0x2a, 0x3d, 0x01, 0xae, 0xf4, 0x21, 0x49, - 0x21, 0xa5, 0x37, 0x87, 0x45, 0x46, 0x87, 0x7d, 0x05, 0x2e, 0x44, 0x4f, 0xfe, 0xd5, 0x3e, 0xd6, - 0x21, 0x48, 0x7a, 0x63, 0x08, 0x50, 0xc4, 0x7e, 0x1f, 0xe4, 0xdb, 0x9f, 0xc8, 0x7e, 0xea, 0xb5, - 0x61, 0xfb, 0xaa, 0xd7, 0xeb, 0x05, 0x50, 0x01, 0x48, 0xdc, 0xd4, 0xaf, 0xf7, 0x61, 0x88, 0x61, - 0xd2, 0xda, 0x50, 0xb0, 0xe8, 0x8c, 0xef, 0x05, 0xb0, 0xd8, 0xfb, 0x1a, 0x7a, 0xbb, 0x5f, 0xce, - 0x7b, 0x59, 0x49, 0x9b, 0x2f, 0x62, 0x15, 0x79, 0x54, 0x07, 0xaf, 0xa4, 0xba, 0x71, 0xb9, 0x5f, - 0x40, 0x09, 0xa0, 0x54, 0x19, 0x12, 0x18, 0x9e, 0x24, 0x8d, 0x7d, 0xcd, 0x7a, 0xaf, 0x7a, 0xfb, - 0xf1, 0x71, 0x51, 0x78, 0x72, 0x5c, 0x14, 0xfe, 0x3c, 0x2e, 0x0a, 0x0f, 0x4f, 0x8a, 0x99, 0x27, - 0x27, 0xc5, 0xcc, 0x6f, 0x27, 0xc5, 0xcc, 0x97, 0xd7, 0xfb, 0x8e, 0xe4, 0x71, 0x33, 0xfa, 0xc3, - 0xb9, 0x9a, 0xf3, 0xdf, 0x81, 0xb7, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x4a, 0x20, 0x62, 0x55, - 0x54, 0x11, 0x00, 0x00, + // 1197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x57, 0xcd, 0x6f, 0xdc, 0x44, + 0x14, 0xdf, 0xdd, 0x24, 0x9b, 0x64, 0xd2, 0x64, 0x1b, 0x27, 0x69, 0x36, 0x6e, 0xd9, 0xad, 0xb6, + 0xa1, 0x89, 0x42, 0xe3, 0xa5, 0x01, 0xf1, 0x11, 0x22, 0x44, 0xb6, 0x69, 0xa1, 0x94, 0x48, 0x91, + 0x43, 0x39, 0x20, 0xa4, 0xd5, 0xd8, 0x9e, 0x78, 0xad, 0xd8, 0x1e, 0xd7, 0x33, 0x1b, 0x75, 0x6f, + 0x88, 0x13, 0xe2, 0x42, 0x0f, 0x1c, 0xb8, 0x20, 0xf5, 0xc8, 0x31, 0x87, 0x5e, 0x39, 0x22, 0x55, + 0x9c, 0xaa, 0x9e, 0x10, 0x87, 0x16, 0x25, 0x87, 0xf0, 0x1f, 0x20, 0x71, 0x42, 0x63, 0x8f, 0x3f, + 0xf7, 0x33, 0x25, 0x3d, 0xd0, 0xcb, 0xae, 0x3d, 0xf3, 0x7b, 0xbf, 0x79, 0xef, 0xf7, 0xde, 0x9b, + 0x19, 0x83, 0xb2, 0x8a, 0x89, 0x85, 0x49, 0x95, 0x50, 0xb8, 0x6f, 0xd8, 0x7a, 0xf5, 0xe0, 0xba, + 0x82, 0x28, 0xbc, 0x5e, 0xa5, 0xf7, 0x25, 0xc7, 0xc5, 0x14, 0x0b, 0x17, 0x7c, 0x80, 0xc4, 0x01, + 0x12, 0x07, 0x88, 0x0b, 0x3a, 0xc6, 0xba, 0x89, 0xaa, 0x1e, 0x4a, 0x69, 0xee, 0x55, 0xa1, 0xdd, + 0xf2, 0x4d, 0xc4, 0x72, 0x7a, 0x8a, 0x1a, 0x16, 0x22, 0x14, 0x5a, 0x0e, 0x07, 0xcc, 0xea, 0x58, + 0xc7, 0xde, 0x63, 0x95, 0x3d, 0xf1, 0xd1, 0x05, 0x7f, 0xa5, 0xba, 0x3f, 0xc1, 0x97, 0xf5, 0xa7, + 0x4a, 0xdc, 0x4b, 0x05, 0x12, 0x14, 0xba, 0xa8, 0x62, 0xc3, 0xe6, 0xf3, 0x8b, 0x5d, 0xa2, 0x08, + 0x9c, 0xf6, 0x51, 0xf3, 0x1c, 0x65, 0x11, 0x86, 0x60, 0x7f, 0x7c, 0x62, 0x1a, 0x5a, 0x86, 0x8d, + 0xab, 0xde, 0xaf, 0x3f, 0x54, 0xf9, 0x25, 0x0f, 0x84, 0x6d, 0xa2, 0xdf, 0x70, 0x11, 0xa4, 0xe8, + 0x0b, 0x68, 0x1a, 0x1a, 0xa4, 0xd8, 0x15, 0x76, 0xc0, 0x84, 0x86, 0x88, 0xea, 0x1a, 0x0e, 0x35, + 0xb0, 0x5d, 0xcc, 0x5e, 0xce, 0x2e, 0x4f, 0xac, 0x5d, 0x91, 0x3a, 0x6b, 0x24, 0x6d, 0x45, 0xd0, + 0xda, 0xf8, 0xe3, 0x67, 0xe5, 0xcc, 0xcf, 0x27, 0x87, 0x2b, 0x59, 0x39, 0x4e, 0x21, 0xc8, 0x00, + 0xa8, 0xd8, 0xb2, 0x0c, 0x42, 0x18, 0x61, 0xce, 0x23, 0x5c, 0xea, 0x46, 0x78, 0x23, 0x44, 0xca, + 0x90, 0x22, 0x12, 0x27, 0x8d, 0xb1, 0x08, 0x26, 0x98, 0xb1, 0x0c, 0xbb, 0x4e, 0x90, 0xb9, 0x57, + 0xd7, 0x90, 0x89, 0x74, 0xe8, 0x79, 0x3b, 0x74, 0x39, 0xbb, 0x3c, 0x5e, 0xdb, 0x60, 0x36, 0x7f, + 0x3c, 0x2b, 0x5f, 0xd5, 0x0d, 0xda, 0x68, 0x2a, 0x92, 0x8a, 0x2d, 0x2e, 0x36, 0xff, 0x5b, 0x25, + 0xda, 0x7e, 0x95, 0xb6, 0x1c, 0x44, 0xa4, 0xdb, 0x36, 0x7d, 0xfa, 0x68, 0x15, 0x70, 0x6f, 0x6e, + 0xdb, 0x54, 0x9e, 0xb6, 0x0c, 0x7b, 0x17, 0x99, 0x7b, 0x5b, 0x21, 0xad, 0x70, 0x13, 0x4c, 0xf3, + 0x45, 0xb0, 0x5b, 0x87, 0x9a, 0xe6, 0x22, 0x42, 0x8a, 0xc3, 0xde, 0x5a, 0xc5, 0xa7, 0x8f, 0x56, + 0x67, 0xb9, 0xf5, 0xa6, 0x3f, 0xb3, 0x4b, 0x5d, 0xc3, 0xd6, 0xe5, 0xf3, 0xa1, 0x09, 0x1f, 0x67, + 0x34, 0x07, 0x81, 0xce, 0x21, 0xcd, 0x48, 0x3f, 0x9a, 0xd0, 0x24, 0xa0, 0xb9, 0x05, 0xf2, 0x4e, + 0x53, 0xd9, 0x47, 0xad, 0x62, 0xde, 0xd3, 0x72, 0x56, 0xf2, 0xab, 0x51, 0x0a, 0xaa, 0x51, 0xda, + 0xb4, 0x5b, 0xb5, 0xe2, 0x6f, 0x11, 0xa3, 0xea, 0xb6, 0x1c, 0x8a, 0xa5, 0x9d, 0xa6, 0x72, 0x07, + 0xb5, 0x64, 0x6e, 0x2d, 0xac, 0x83, 0x91, 0x03, 0x68, 0x36, 0x51, 0x71, 0xd4, 0xa3, 0x59, 0x08, + 0x52, 0xc2, 0x4a, 0x30, 0x96, 0x0f, 0x23, 0x91, 0x59, 0xdf, 0x44, 0xb8, 0x06, 0x86, 0xf7, 0x5c, + 0x6c, 0x15, 0xc7, 0xfa, 0x78, 0xef, 0xa1, 0x84, 0x4d, 0x50, 0x70, 0x91, 0x09, 0x5b, 0x28, 0x0a, + 0x7b, 0xbc, 0x8f, 0xe1, 0x14, 0x37, 0x08, 0x82, 0xfe, 0x18, 0x08, 0x6a, 0x03, 0x9a, 0x26, 0xb2, + 0xf5, 0x18, 0x0b, 0xe8, 0xc3, 0x32, 0x1d, 0xd9, 0x04, 0x44, 0xf3, 0x60, 0x54, 0x31, 0x49, 0x9d, + 0xc9, 0x37, 0xc1, 0xac, 0xe5, 0xbc, 0x62, 0x92, 0x3b, 0xa8, 0x25, 0x5c, 0x04, 0xe3, 0x6c, 0xc2, + 0x71, 0x31, 0xde, 0x2b, 0x9e, 0xf3, 0xa6, 0xc6, 0x14, 0x93, 0xec, 0xb0, 0xf7, 0xf5, 0xe9, 0x6f, + 0x1f, 0x96, 0x33, 0x7f, 0x3d, 0x2c, 0x67, 0xbe, 0x39, 0x39, 0x5c, 0xf1, 0x82, 0xaa, 0x5c, 0x02, + 0x62, 0x7b, 0xfb, 0xc8, 0x88, 0x38, 0xd8, 0x26, 0xa8, 0xf2, 0xcf, 0x30, 0x38, 0xbf, 0x4d, 0xf4, + 0x9b, 0x9a, 0x41, 0x5f, 0x66, 0x6f, 0x75, 0x2c, 0xa9, 0xdc, 0xa9, 0x4b, 0x0a, 0x82, 0x42, 0xd4, + 0x5c, 0x75, 0x17, 0x52, 0xc4, 0x5b, 0xe9, 0xbd, 0x01, 0xdb, 0x68, 0x0b, 0xa9, 0xb1, 0x36, 0xda, + 0x42, 0xaa, 0x3c, 0xa5, 0x26, 0x3a, 0x59, 0x68, 0x74, 0xee, 0xd8, 0xe1, 0x53, 0x2d, 0x33, 0x50, + 0xb7, 0x76, 0xa8, 0xb6, 0x91, 0x33, 0xa9, 0xb6, 0xfc, 0x7f, 0xaa, 0xb6, 0xd1, 0xee, 0xd5, 0x36, + 0x96, 0xaa, 0xb6, 0x0f, 0xe3, 0xd5, 0xd6, 0x9e, 0xe0, 0xef, 0x4e, 0x0e, 0x57, 0x2e, 0xc6, 0xb4, + 0x49, 0xd7, 0x59, 0x45, 0x04, 0xc5, 0xf4, 0x58, 0x58, 0x98, 0x3f, 0xe4, 0xc0, 0xc4, 0x36, 0xd1, + 0xb9, 0x5e, 0xa8, 0xf3, 0xde, 0x96, 0x3d, 0x9b, 0xbd, 0xed, 0xf4, 0x85, 0xb8, 0x01, 0xf2, 0xd0, + 0xc2, 0x4d, 0x9b, 0x7a, 0xf5, 0x37, 0xe8, 0xa6, 0xc4, 0x6d, 0xd6, 0xdf, 0x4f, 0xe8, 0xd6, 0x16, + 0x16, 0xd3, 0xed, 0x42, 0x52, 0xb7, 0x40, 0x86, 0xca, 0x1c, 0x98, 0x89, 0xbd, 0x86, 0x6a, 0xfd, + 0x9d, 0xf3, 0x0e, 0xc9, 0x1a, 0xd2, 0x0d, 0x5b, 0x46, 0xda, 0x19, 0x8b, 0xf6, 0x19, 0x98, 0x8b, + 0x44, 0x23, 0xae, 0x3a, 0xb0, 0x70, 0x33, 0xa1, 0xd9, 0xae, 0xab, 0x76, 0x64, 0xd3, 0x08, 0x0d, + 0xd9, 0x86, 0x06, 0x66, 0xdb, 0x22, 0xb4, 0x3d, 0x13, 0xc3, 0x2f, 0x90, 0x89, 0x8f, 0xfa, 0x67, + 0xe2, 0xb5, 0x64, 0x26, 0x52, 0x12, 0x57, 0x1c, 0x6f, 0x7b, 0x4d, 0x8d, 0x06, 0x79, 0x11, 0x64, + 0x6f, 0xc3, 0x72, 0x4c, 0xc4, 0x3a, 0xbe, 0xce, 0x6e, 0x5f, 0x7c, 0x37, 0x15, 0xdb, 0x0e, 0xc3, + 0xcf, 0x83, 0xab, 0x59, 0x6d, 0x92, 0xf9, 0xf9, 0xe0, 0x79, 0x39, 0xeb, 0xfb, 0x3a, 0x15, 0x31, + 0x30, 0x4c, 0xe5, 0xc7, 0x1c, 0x98, 0xdc, 0x26, 0xfa, 0x5d, 0x5b, 0x7b, 0x15, 0x7b, 0xe3, 0x83, + 0xfe, 0x19, 0x29, 0x26, 0x33, 0x12, 0x09, 0x51, 0xd9, 0x07, 0x73, 0x89, 0x81, 0x97, 0x9a, 0x87, + 0xe7, 0x39, 0x70, 0x89, 0x9d, 0xac, 0xd0, 0x56, 0x91, 0x79, 0xd7, 0x56, 0xb0, 0xad, 0x19, 0xb6, + 0xde, 0xef, 0x3a, 0xf6, 0xff, 0x4c, 0x8b, 0xb0, 0x04, 0x0a, 0x2a, 0xbb, 0x42, 0x30, 0xf9, 0x1a, + 0xc8, 0xd0, 0x1b, 0x7e, 0xbf, 0x0d, 0xc9, 0x53, 0xc1, 0xf0, 0x27, 0xde, 0xe8, 0xfa, 0xa7, 0xfd, + 0xf3, 0xb7, 0x94, 0xcc, 0x5f, 0x57, 0x01, 0x2b, 0x57, 0xc1, 0x62, 0xaf, 0xf9, 0x70, 0xf7, 0xfb, + 0x35, 0x0b, 0x0a, 0x2c, 0xef, 0x8e, 0x06, 0x29, 0xda, 0x81, 0x2e, 0xb4, 0x88, 0xf0, 0x0e, 0x18, + 0x87, 0x4d, 0xda, 0xc0, 0xae, 0x41, 0x5b, 0x7d, 0x45, 0x8f, 0xa0, 0xc2, 0x26, 0xc8, 0x3b, 0x1e, + 0x03, 0xff, 0x02, 0x28, 0x75, 0xbb, 0xf6, 0xf8, 0xeb, 0x24, 0xb4, 0xf2, 0x0d, 0xd7, 0xdf, 0x65, + 0xa1, 0x47, 0x94, 0x2c, 0xe4, 0xc5, 0x58, 0xc8, 0xf7, 0xc3, 0x8f, 0xa3, 0x94, 0xcf, 0x95, 0x05, + 0x30, 0x9f, 0x1a, 0x0a, 0x42, 0x5c, 0xfb, 0x29, 0x0f, 0x86, 0xb6, 0x89, 0x2e, 0xdc, 0x03, 0x85, + 0xf4, 0x97, 0xd0, 0x4a, 0x37, 0x0f, 0xdb, 0xaf, 0x7d, 0xe2, 0xda, 0xe0, 0xd8, 0xb0, 0x77, 0xf6, + 0xc1, 0x64, 0xf2, 0x7a, 0xb8, 0xdc, 0x83, 0x24, 0x81, 0x14, 0xdf, 0x1c, 0x14, 0x19, 0x2e, 0xf6, + 0x15, 0x18, 0x0b, 0x8f, 0xfc, 0x2b, 0x3d, 0xac, 0x03, 0x90, 0xf8, 0xc6, 0x00, 0xa0, 0x90, 0xfd, + 0x1e, 0x28, 0xa4, 0x8f, 0xc8, 0x5e, 0xea, 0xa5, 0xb0, 0x3d, 0xd5, 0xeb, 0x76, 0x02, 0x28, 0x00, + 0xc4, 0x76, 0xea, 0xd7, 0x7b, 0x30, 0x44, 0x30, 0x71, 0x75, 0x20, 0x58, 0xb8, 0xc6, 0xf7, 0x59, + 0xb0, 0xd0, 0x7d, 0x1b, 0x7a, 0xbb, 0x57, 0xce, 0xbb, 0x59, 0x89, 0x1b, 0x2f, 0x62, 0x15, 0x7a, + 0xd4, 0x00, 0xe7, 0x12, 0xdd, 0xb8, 0xd4, 0x2b, 0xa0, 0x18, 0x50, 0xac, 0x0e, 0x08, 0x0c, 0x56, + 0x12, 0x47, 0xbe, 0x66, 0xbd, 0x57, 0xbb, 0xf5, 0xf8, 0xa8, 0x94, 0x7d, 0x72, 0x54, 0xca, 0xfe, + 0x79, 0x54, 0xca, 0x3e, 0x38, 0x2e, 0x65, 0x9e, 0x1c, 0x97, 0x32, 0xbf, 0x1f, 0x97, 0x32, 0x5f, + 0x5e, 0xeb, 0x79, 0x5f, 0x8f, 0x9a, 0xd1, 0xbb, 0xb9, 0x2b, 0x79, 0xef, 0x1c, 0x78, 0xeb, 0xdf, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x31, 0x9c, 0x3c, 0x78, 0x8e, 0x11, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1085,6 +1088,13 @@ func (m *MsgCreateValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.BlsProof) > 0 { + i -= len(m.BlsProof) + copy(dAtA[i:], m.BlsProof) + i = encodeVarintTx(dAtA, i, uint64(len(m.BlsProof))) + i-- + dAtA[i] = 0x62 + } if len(m.BlsKey) > 0 { i -= len(m.BlsKey) copy(dAtA[i:], m.BlsKey) @@ -1225,6 +1235,13 @@ func (m *MsgEditValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.BlsProof) > 0 { + i -= len(m.BlsProof) + copy(dAtA[i:], m.BlsProof) + i = encodeVarintTx(dAtA, i, uint64(len(m.BlsProof))) + i-- + dAtA[i] = 0x42 + } if len(m.BlsKey) > 0 { i -= len(m.BlsKey) copy(dAtA[i:], m.BlsKey) @@ -1737,6 +1754,10 @@ func (m *MsgCreateValidator) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.BlsProof) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -1781,6 +1802,10 @@ func (m *MsgEditValidator) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.BlsProof) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -2336,6 +2361,38 @@ func (m *MsgCreateValidator) Unmarshal(dAtA []byte) error { } m.BlsKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlsProof", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlsProof = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2669,6 +2726,38 @@ func (m *MsgEditValidator) Unmarshal(dAtA []byte) error { } m.BlsKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlsProof", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlsProof = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) From 9380a65608ac58a693ea93e9b95699f83df875ad Mon Sep 17 00:00:00 2001 From: j75689 Date: Fri, 7 Jul 2023 12:48:44 +0800 Subject: [PATCH 2/7] chore: fix testcase --- testutil/sims/address_helpers.go | 14 -------------- x/slashing/abci_test.go | 6 +++--- x/staking/testutil/helpers.go | 11 ++++++----- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/testutil/sims/address_helpers.go b/testutil/sims/address_helpers.go index 9aa0dc93b3..742bcfca72 100644 --- a/testutil/sims/address_helpers.go +++ b/testutil/sims/address_helpers.go @@ -8,7 +8,6 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/errors" @@ -145,19 +144,6 @@ func CreateTestPubKeys(numPubKeys int) []cryptotypes.PubKey { return publicKeys } -// CreateTestAccounts returns number of PubKey, PrivKey -func CreateTestAccounts(num int) ([]cryptotypes.PubKey, []cryptotypes.PrivKey) { - var publicKeys = make([]cryptotypes.PubKey, 0, num) - var privateKeys = make([]cryptotypes.PrivKey, 0, num) - for i := 0; i < num; i++ { - privKey, _ := ethsecp256k1.GenPrivKey() - publicKeys = append(publicKeys, privKey.PubKey()) - privateKeys = append(privateKeys, privKey) - } - - return publicKeys, privateKeys -} - // NewPubKeyFromHex returns a PubKey from a hex string. func NewPubKeyFromHex(pk string) (res cryptotypes.PubKey) { pkBytes, err := hex.DecodeString(pk) diff --git a/x/slashing/abci_test.go b/x/slashing/abci_test.go index 62785223e4..36ed0ba9c0 100644 --- a/x/slashing/abci_test.go +++ b/x/slashing/abci_test.go @@ -38,14 +38,14 @@ func TestBeginBlocker(t *testing.T) { ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - pks, pvs := simtestutil.CreateTestAccounts(1) + pks := simtestutil.CreateTestPubKeys(1) simtestutil.AddTestAddrsFromPubKeys(bankKeeper, stakingKeeper, ctx, pks, stakingKeeper.TokensFromConsensusPower(ctx, 200)) - addr, pk, pv := sdk.AccAddress(pks[0].Address()), pks[0], pvs[0] + addr, pk := sdk.AccAddress(pks[0].Address()), pks[0] tstaking := stakingtestutil.NewHelper(t, ctx, stakingKeeper) // bond the validator power := int64(100) - amt := tstaking.CreateValidatorWithValPower(addr, pk, pv, power, true) + amt := tstaking.CreateValidatorWithValPower(addr, pk, power, true) staking.EndBlocker(ctx, stakingKeeper) require.Equal( t, bankKeeper.GetAllBalances(ctx, addr), diff --git a/x/staking/testutil/helpers.go b/x/staking/testutil/helpers.go index aedd44d59f..51cd002d1a 100644 --- a/x/staking/testutil/helpers.go +++ b/x/staking/testutil/helpers.go @@ -39,20 +39,20 @@ func NewHelper(t *testing.T, ctx sdk.Context, k *keeper.Keeper) *Helper { // CreateValidator calls staking module `MsgServer/CreateValidator` to create a new validator func (sh *Helper) CreateValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, stakeAmount math.Int, ok bool) { coin := sdk.NewCoin(sh.Denom, stakeAmount) - sh.createValidator(addr, pk, pv, coin, ok) + sh.createValidator(addr, pk, coin, ok) } // CreateValidatorWithValPower calls staking module `MsgServer/CreateValidator` to create a new validator with zero // commission -func (sh *Helper) CreateValidatorWithValPower(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, valPower int64, ok bool) math.Int { +func (sh *Helper) CreateValidatorWithValPower(addr sdk.AccAddress, pk cryptotypes.PubKey, valPower int64, ok bool) math.Int { amount := sh.k.TokensFromConsensusPower(sh.Ctx, valPower) coin := sdk.NewCoin(sh.Denom, amount) - sh.createValidator(addr, pk, pv, coin, ok) + sh.createValidator(addr, pk, coin, ok) return amount } // CreateValidatorMsg returns a message used to create validator in this service. -func (sh *Helper) CreateValidatorMsg(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, stakeAmount math.Int) *stakingtypes.MsgCreateValidator { +func (sh *Helper) CreateValidatorMsg(addr sdk.AccAddress, pk cryptotypes.PubKey, stakeAmount math.Int) *stakingtypes.MsgCreateValidator { coin := sdk.NewCoin(sh.Denom, stakeAmount) blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) @@ -72,11 +72,12 @@ func (sh *Helper) CreateValidatorWithMsg(ctx context.Context, msg *stakingtypes. return sh.msgSrvr.CreateValidator(ctx, msg) } -func (sh *Helper) createValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, coin sdk.Coin, ok bool) { +func (sh *Helper) createValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, coin sdk.Coin, ok bool) { blsSecretKey, _ := bls.RandKey() blsPk := hex.EncodeToString(blsSecretKey.PublicKey().Marshal()) blsProofBuf := blsSecretKey.Sign(tmhash.Sum(blsSecretKey.PublicKey().Marshal())) blsProof := hex.EncodeToString(blsProofBuf.Marshal()) + msg, err := stakingtypes.NewMsgCreateValidator( addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt(), From 2d03e3a7d2e1dc19b042355b23193b75d9590dcc Mon Sep 17 00:00:00 2001 From: j75689 Date: Fri, 7 Jul 2023 12:59:43 +0800 Subject: [PATCH 3/7] choer: fix testcase --- x/staking/types/data_test.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/x/staking/types/data_test.go b/x/staking/types/data_test.go index b050c6df6f..15ca7c3c98 100644 --- a/x/staking/types/data_test.go +++ b/x/staking/types/data_test.go @@ -4,20 +4,16 @@ import ( "fmt" codectypes "github.com/cosmos/cosmos-sdk/codec/types" - - "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" ) var ( - pv1, _ = ethsecp256k1.GenPrivKey() - pv2, _ = ethsecp256k1.GenPrivKey() - pv3, _ = ethsecp256k1.GenPrivKey() - pk1 = pv1.PubKey() + pk1 = ed25519.GenPrivKey().PubKey() pk1Any *codectypes.Any - pk2 = pv2.PubKey() - pk3 = pv3.PubKey() + pk2 = ed25519.GenPrivKey().PubKey() + pk3 = ed25519.GenPrivKey().PubKey() addr1, _ = sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixAccAddr, pk1.Address().Bytes()) addr2, _ = sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixAccAddr, pk2.Address().Bytes()) addr3, _ = sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixAccAddr, pk3.Address().Bytes()) From f35a783541166f26757ba505ad47c38a814de8cc Mon Sep 17 00:00:00 2001 From: j75689 Date: Fri, 7 Jul 2023 13:14:02 +0800 Subject: [PATCH 4/7] chore: fix testcase --- tests/integration/genutil/gentx_test.go | 9 +++++++-- x/staking/testutil/helpers.go | 2 +- x/staking/types/msg_test.go | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/integration/genutil/gentx_test.go b/tests/integration/genutil/gentx_test.go index 9a1c4811d1..61cf7dcebe 100644 --- a/tests/integration/genutil/gentx_test.go +++ b/tests/integration/genutil/gentx_test.go @@ -9,6 +9,7 @@ import ( "time" "cosmossdk.io/math" + "github.com/cometbft/cometbft/crypto/tmhash" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" @@ -86,17 +87,21 @@ func (suite *GenTxTestSuite) SetupTest() { amount := sdk.NewInt64Coin(sdk.DefaultBondDenom, 50) one := math.OneInt() blsSecretKey1, _ := bls.RandKey() + blsProofBuf := blsSecretKey1.Sign(tmhash.Sum(blsSecretKey1.PublicKey().Marshal())) + blsProof1 := hex.EncodeToString(blsProofBuf.Marshal()) blsPk1 := hex.EncodeToString(blsSecretKey1.PublicKey().Marshal()) suite.msg1, err = stakingtypes.NewMsgCreateValidator( - sdk.AccAddress(pk1.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1) + sdk.AccAddress(pk1.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), sdk.AccAddress(pk1.Address()), blsPk1, blsProof1) suite.NoError(err) blsSecretKey2, _ := bls.RandKey() blsPk2 := hex.EncodeToString(blsSecretKey2.PublicKey().Marshal()) + blsProofBuf = blsSecretKey2.Sign(tmhash.Sum(blsSecretKey2.PublicKey().Marshal())) + blsProof2 := hex.EncodeToString(blsProofBuf.Marshal()) suite.msg2, err = stakingtypes.NewMsgCreateValidator( - sdk.AccAddress(pk2.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2) + sdk.AccAddress(pk2.Address()), pk1, amount, desc, comm, one, sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), sdk.AccAddress(pk2.Address()), blsPk2, blsProof2) suite.NoError(err) } diff --git a/x/staking/testutil/helpers.go b/x/staking/testutil/helpers.go index 51cd002d1a..b0b2861968 100644 --- a/x/staking/testutil/helpers.go +++ b/x/staking/testutil/helpers.go @@ -37,7 +37,7 @@ func NewHelper(t *testing.T, ctx sdk.Context, k *keeper.Keeper) *Helper { } // CreateValidator calls staking module `MsgServer/CreateValidator` to create a new validator -func (sh *Helper) CreateValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, pv cryptotypes.PrivKey, stakeAmount math.Int, ok bool) { +func (sh *Helper) CreateValidator(addr sdk.AccAddress, pk cryptotypes.PubKey, stakeAmount math.Int, ok bool) { coin := sdk.NewCoin(sh.Denom, stakeAmount) sh.createValidator(addr, pk, coin, ok) } diff --git a/x/staking/types/msg_test.go b/x/staking/types/msg_test.go index f3334d7f9f..521c0cf935 100644 --- a/x/staking/types/msg_test.go +++ b/x/staking/types/msg_test.go @@ -17,7 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -41,7 +41,7 @@ func TestMsgDecode(t *testing.T) { var pkUnmarshaled cryptotypes.PubKey err = cdc.UnmarshalInterface(pk1bz, &pkUnmarshaled) require.NoError(t, err) - require.True(t, pk1.Equals(pkUnmarshaled.(*ethsecp256k1.PubKey))) + require.True(t, pk1.Equals(pkUnmarshaled.(*ed25519.PubKey))) // now let's try to serialize the whole message blsSecretKey, _ := bls.RandKey() From f29ef1cc1f0d9e058bde0a24ffa06da37da692b7 Mon Sep 17 00:00:00 2001 From: j75689 Date: Fri, 7 Jul 2023 13:35:56 +0800 Subject: [PATCH 5/7] chore: fix e2e test --- tests/e2e/genutil/suite.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e/genutil/suite.go b/tests/e2e/genutil/suite.go index 0985b4bdf3..5a4d2458bd 100644 --- a/tests/e2e/genutil/suite.go +++ b/tests/e2e/genutil/suite.go @@ -116,6 +116,7 @@ func (s *E2ETestSuite) TestGenTxCmd() { val.Address.String(), val.Address.String(), blsPk, + blsProof, }, expError: false, }, From fa67a3f42745953bc1d3c95521032b369c9412e0 Mon Sep 17 00:00:00 2001 From: j75689 Date: Fri, 7 Jul 2023 20:37:33 +0800 Subject: [PATCH 6/7] chore: fix comments --- client/keys/sign.go | 15 +++++++++++++-- x/staking/keeper/msg_server.go | 24 +++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/client/keys/sign.go b/client/keys/sign.go index 96b2edfcfa..cdc6f6575e 100644 --- a/client/keys/sign.go +++ b/client/keys/sign.go @@ -16,8 +16,19 @@ func SignMsgKeysCmd() *cobra.Command { cmd := &cobra.Command{ Use: "sign [message]", Short: "Sign message", - Long: "Return a signature from their associated name and address private key.", - RunE: runSignMsgCmd, + Long: `Return a signature from their associated name and address private key. +!!!NOTE!!! +This is not a secure way to sign messages. +This command is allowed to sign any message from your private key. +Please *DO NOT* use this command unless you know what you are doing. + +Example For Signing BLS PoP Message: + $ gnfd keys add bls --keyring-backend test --algo eth_bls + $ BLS=$(./build/bin/gnfd keys show bls --keyring-backend test --output json | jq -r .pubkey_hex) + $ gnfd keys sign $BLS --from bls + +`, + RunE: runSignMsgCmd, } cmd.Flags().String(flags.FlagFrom, "", "Name or address of private key with which to sign") diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index 8393ff5f84..4e7d90550e 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -114,13 +114,10 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa if err != nil { return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) } - ok, err = k.CheckBlsProof(ctx, blsPk, blsProof, valAddr) + err = k.CheckBlsProof(blsPk, blsProof) if err != nil { return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) } - if !ok { - return nil, types.ErrValidatorInvalidBlsProof - } bondDenom := k.BondDenom(ctx) if msg.Value.Denom != bondDenom { @@ -315,13 +312,11 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida if err != nil { return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) } - ok, err := k.CheckBlsProof(ctx, blsPk, blsProof, validator.GetOperator()) + err = k.CheckBlsProof(blsPk, blsProof) if err != nil { return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, err.Error()) } - if !ok { - return nil, sdkerrors.Wrap(types.ErrValidatorInvalidBlsProof, "signature verification failed") - } + if tmpValidator, found := k.GetValidatorByBlsKey(ctx, blsPk); found { if tmpValidator.OperatorAddress != validator.OperatorAddress { return nil, types.ErrValidatorBlsKeyExists @@ -658,21 +653,24 @@ func (ms msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdatePara } // CheckBlsProof checks the BLS signature of the validator -func (ms msgServer) CheckBlsProof(goCtx context.Context, blsPk, sig []byte, valAddr sdk.Address) (bool, error) { +func (ms msgServer) CheckBlsProof(blsPk, sig []byte) error { if len(sig) != sdk.BLSSignatureLength { - return false, sdkerrors.Wrapf(sdkerrors.ErrorInvalidSigner, "signature length (actual: %d) doesn't match typical BLS signature 96 bytes", len(sig)) + return sdkerrors.Wrapf(sdkerrors.ErrorInvalidSigner, "signature length (actual: %d) doesn't match typical BLS signature 96 bytes", len(sig)) } blsPubKey, err := bls.PublicKeyFromBytes(blsPk) if err != nil { - return false, sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "BLS public key is invalid") + return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "BLS public key is invalid") } signature, err := bls.SignatureFromBytes(sig) if err != nil { - return false, sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "BLS signature key is invalid") + return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "BLS signature key is invalid") } sigHash := tmhash.Sum(blsPk) - return signature.Verify(blsPubKey, sigHash), nil + if !signature.Verify(blsPubKey, sigHash) { + return sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, "BLS signature verification is failed") + } + return nil } From c32d1f6f7fd0a14d6886f3723341da441ea2c940 Mon Sep 17 00:00:00 2001 From: j75689 Date: Fri, 7 Jul 2023 20:44:55 +0800 Subject: [PATCH 7/7] chore: revert ethsepc256k1 changes --- crypto/keys/eth/ethsecp256k1/pubkey.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crypto/keys/eth/ethsecp256k1/pubkey.go b/crypto/keys/eth/ethsecp256k1/pubkey.go index 3b3f4a5034..e98b004df7 100644 --- a/crypto/keys/eth/ethsecp256k1/pubkey.go +++ b/crypto/keys/eth/ethsecp256k1/pubkey.go @@ -93,10 +93,6 @@ func (pubKey *PubKey) VerifySignature(msg, sig []byte) bool { sig = sig[:len(sig)-1] } - if len(msg) != crypto.DigestLength { - msg = crypto.Keccak256Hash(msg).Bytes() - } - // the signature needs to be in [R || S] format when provided to VerifySignature - return crypto.VerifySignature(pubKey.Key, msg, sig) + return crypto.VerifySignature(pubKey.Key, crypto.Keccak256Hash(msg).Bytes(), sig) }