diff --git a/cmd/validator/accounts/exit_test.go b/cmd/validator/accounts/exit_test.go index 587f811afb..c0b04e0cd6 100644 --- a/cmd/validator/accounts/exit_test.go +++ b/cmd/validator/accounts/exit_test.go @@ -134,7 +134,6 @@ func TestExitAccountsCli_OK_AllPublicKeys(t *testing.T) { mockNodeClient.EXPECT(). GetGenesis(gomock.Any(), gomock.Any()). - Times(2). Return(ðpb.Genesis{GenesisTime: genesisTime}, nil) mockValidatorClient.EXPECT(). diff --git a/proto/eth/service/key_management.pb.go b/proto/eth/service/key_management.pb.go index 57f86d0902..ea332d5c3a 100755 --- a/proto/eth/service/key_management.pb.go +++ b/proto/eth/service/key_management.pb.go @@ -13,6 +13,8 @@ import ( _ "github.com/golang/protobuf/protoc-gen-go/descriptor" empty "github.com/golang/protobuf/ptypes/empty" + github_com_prysmaticlabs_prysm_v4_consensus_types_primitives "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" + _ "github.com/prysmaticlabs/prysm/v4/proto/eth/ext" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -1242,6 +1244,108 @@ func (x *DeleteGasLimitRequest) GetPubkey() []byte { return nil } +type SetVoluntaryExitRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pubkey []byte `protobuf:"bytes,1,opt,name=pubkey,proto3" json:"pubkey,omitempty" ssz-size:"48"` + Epoch github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Epoch `protobuf:"varint,2,opt,name=epoch,proto3" json:"epoch,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.Epoch"` +} + +func (x *SetVoluntaryExitRequest) Reset() { + *x = SetVoluntaryExitRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_eth_service_key_management_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetVoluntaryExitRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetVoluntaryExitRequest) ProtoMessage() {} + +func (x *SetVoluntaryExitRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_eth_service_key_management_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetVoluntaryExitRequest.ProtoReflect.Descriptor instead. +func (*SetVoluntaryExitRequest) Descriptor() ([]byte, []int) { + return file_proto_eth_service_key_management_proto_rawDescGZIP(), []int{20} +} + +func (x *SetVoluntaryExitRequest) GetPubkey() []byte { + if x != nil { + return x.Pubkey + } + return nil +} + +func (x *SetVoluntaryExitRequest) GetEpoch() github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Epoch { + if x != nil { + return x.Epoch + } + return github_com_prysmaticlabs_prysm_v4_consensus_types_primitives.Epoch(0) +} + +type SetVoluntaryExitResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data *SetVoluntaryExitResponse_SignedVoluntaryExit `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *SetVoluntaryExitResponse) Reset() { + *x = SetVoluntaryExitResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_eth_service_key_management_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetVoluntaryExitResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetVoluntaryExitResponse) ProtoMessage() {} + +func (x *SetVoluntaryExitResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_eth_service_key_management_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetVoluntaryExitResponse.ProtoReflect.Descriptor instead. +func (*SetVoluntaryExitResponse) Descriptor() ([]byte, []int) { + return file_proto_eth_service_key_management_proto_rawDescGZIP(), []int{21} +} + +func (x *SetVoluntaryExitResponse) GetData() *SetVoluntaryExitResponse_SignedVoluntaryExit { + if x != nil { + return x.Data + } + return nil +} + type ListKeystoresResponse_Keystore struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1254,7 +1358,7 @@ type ListKeystoresResponse_Keystore struct { func (x *ListKeystoresResponse_Keystore) Reset() { *x = ListKeystoresResponse_Keystore{} if protoimpl.UnsafeEnabled { - mi := &file_proto_eth_service_key_management_proto_msgTypes[20] + mi := &file_proto_eth_service_key_management_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1267,7 +1371,7 @@ func (x *ListKeystoresResponse_Keystore) String() string { func (*ListKeystoresResponse_Keystore) ProtoMessage() {} func (x *ListKeystoresResponse_Keystore) ProtoReflect() protoreflect.Message { - mi := &file_proto_eth_service_key_management_proto_msgTypes[20] + mi := &file_proto_eth_service_key_management_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1310,7 +1414,7 @@ type ListRemoteKeysResponse_Keystore struct { func (x *ListRemoteKeysResponse_Keystore) Reset() { *x = ListRemoteKeysResponse_Keystore{} if protoimpl.UnsafeEnabled { - mi := &file_proto_eth_service_key_management_proto_msgTypes[21] + mi := &file_proto_eth_service_key_management_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1323,7 +1427,7 @@ func (x *ListRemoteKeysResponse_Keystore) String() string { func (*ListRemoteKeysResponse_Keystore) ProtoMessage() {} func (x *ListRemoteKeysResponse_Keystore) ProtoReflect() protoreflect.Message { - mi := &file_proto_eth_service_key_management_proto_msgTypes[21] + mi := &file_proto_eth_service_key_management_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1372,7 +1476,7 @@ type ImportRemoteKeysRequest_Keystore struct { func (x *ImportRemoteKeysRequest_Keystore) Reset() { *x = ImportRemoteKeysRequest_Keystore{} if protoimpl.UnsafeEnabled { - mi := &file_proto_eth_service_key_management_proto_msgTypes[22] + mi := &file_proto_eth_service_key_management_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1385,7 +1489,7 @@ func (x *ImportRemoteKeysRequest_Keystore) String() string { func (*ImportRemoteKeysRequest_Keystore) ProtoMessage() {} func (x *ImportRemoteKeysRequest_Keystore) ProtoReflect() protoreflect.Message { - mi := &file_proto_eth_service_key_management_proto_msgTypes[22] + mi := &file_proto_eth_service_key_management_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1427,7 +1531,7 @@ type GetFeeRecipientByPubkeyResponse_FeeRecipient struct { func (x *GetFeeRecipientByPubkeyResponse_FeeRecipient) Reset() { *x = GetFeeRecipientByPubkeyResponse_FeeRecipient{} if protoimpl.UnsafeEnabled { - mi := &file_proto_eth_service_key_management_proto_msgTypes[23] + mi := &file_proto_eth_service_key_management_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1440,7 +1544,7 @@ func (x *GetFeeRecipientByPubkeyResponse_FeeRecipient) String() string { func (*GetFeeRecipientByPubkeyResponse_FeeRecipient) ProtoMessage() {} func (x *GetFeeRecipientByPubkeyResponse_FeeRecipient) ProtoReflect() protoreflect.Message { - mi := &file_proto_eth_service_key_management_proto_msgTypes[23] + mi := &file_proto_eth_service_key_management_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1482,7 +1586,7 @@ type GetGasLimitResponse_GasLimit struct { func (x *GetGasLimitResponse_GasLimit) Reset() { *x = GetGasLimitResponse_GasLimit{} if protoimpl.UnsafeEnabled { - mi := &file_proto_eth_service_key_management_proto_msgTypes[24] + mi := &file_proto_eth_service_key_management_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1495,7 +1599,7 @@ func (x *GetGasLimitResponse_GasLimit) String() string { func (*GetGasLimitResponse_GasLimit) ProtoMessage() {} func (x *GetGasLimitResponse_GasLimit) ProtoReflect() protoreflect.Message { - mi := &file_proto_eth_service_key_management_proto_msgTypes[24] + mi := &file_proto_eth_service_key_management_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1525,6 +1629,116 @@ func (x *GetGasLimitResponse_GasLimit) GetGasLimit() uint64 { return 0 } +type SetVoluntaryExitResponse_SignedVoluntaryExit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit) Reset() { + *x = SetVoluntaryExitResponse_SignedVoluntaryExit{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_eth_service_key_management_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetVoluntaryExitResponse_SignedVoluntaryExit) ProtoMessage() {} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit) ProtoReflect() protoreflect.Message { + mi := &file_proto_eth_service_key_management_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetVoluntaryExitResponse_SignedVoluntaryExit.ProtoReflect.Descriptor instead. +func (*SetVoluntaryExitResponse_SignedVoluntaryExit) Descriptor() ([]byte, []int) { + return file_proto_eth_service_key_management_proto_rawDescGZIP(), []int{21, 0} +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit) GetMessage() *SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit { + if x != nil { + return x.Message + } + return nil +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +type SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Epoch uint64 `protobuf:"varint,1,opt,name=epoch,proto3" json:"epoch,omitempty"` + ValidatorIndex uint64 `protobuf:"varint,2,opt,name=validator_index,json=validatorIndex,proto3" json:"validator_index,omitempty"` +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit) Reset() { + *x = SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_eth_service_key_management_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit) ProtoMessage() {} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit) ProtoReflect() protoreflect.Message { + mi := &file_proto_eth_service_key_management_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit.ProtoReflect.Descriptor instead. +func (*SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit) Descriptor() ([]byte, []int) { + return file_proto_eth_service_key_management_proto_rawDescGZIP(), []int{21, 0, 0} +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit) GetEpoch() uint64 { + if x != nil { + return x.Epoch + } + return 0 +} + +func (x *SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit) GetValidatorIndex() uint64 { + if x != nil { + return x.ValidatorIndex + } + return 0 +} + var File_proto_eth_service_key_management_proto protoreflect.FileDescriptor var file_proto_eth_service_key_management_proto_rawDesc = []byte{ @@ -1537,292 +1751,347 @@ var file_proto_eth_service_key_management_proto_rawDesc = []byte{ 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x01, 0x0a, 0x15, - 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, - 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, - 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, - 0x60, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, - 0x6e, 0x67, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x65, 0x72, 0x69, - 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, - 0x68, 0x22, 0x85, 0x01, 0x0a, 0x16, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, - 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x73, 0x6c, 0x61, 0x73, - 0x68, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x50, - 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5b, 0x0a, 0x17, 0x49, 0x6d, 0x70, - 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, - 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x48, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x60, 0x0a, 0x08, + 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x50, + 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x22, 0x85, + 0x01, 0x0a, 0x16, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x12, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5b, 0x0a, 0x17, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x40, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4b, + 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x32, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x13, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x12, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb1, 0x01, 0x0a, 0x16, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x32, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x07, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x17, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, - 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x13, 0x73, 0x6c, 0x61, 0x73, 0x68, - 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x72, - 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb1, 0x01, 0x0a, 0x16, 0x49, 0x6d, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, - 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x45, 0x10, - 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x22, 0xbe, 0x01, 0x0a, - 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, - 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, + 0x12, 0x4b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0d, 0x0a, 0x09, 0x44, 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x09, + 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x22, 0xbe, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3f, 0x0a, 0x06, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, - 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, - 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0xb5, 0x01, - 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, - 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x1a, 0x50, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x61, - 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, - 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x22, 0xa8, 0x01, 0x0a, 0x17, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x57, 0x0a, 0x0b, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, - 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, - 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x0a, - 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0x34, 0x0a, 0x08, 0x4b, 0x65, - 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, - 0x22, 0x5e, 0x0a, 0x18, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74, 0x68, - 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x22, 0x33, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x75, - 0x62, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x5d, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x74, 0x75, 0x73, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3f, 0x0a, 0x06, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x01, 0x12, + 0x0e, 0x0a, 0x0a, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, + 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0xb5, 0x01, 0x0a, 0x16, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x41, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x22, 0xc2, 0x01, 0x0a, 0x18, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x4d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x65, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x1a, 0x50, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, + 0x62, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, + 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, + 0x6c, 0x79, 0x22, 0xa8, 0x01, 0x0a, 0x17, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, + 0x0a, 0x0b, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0x34, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x5e, 0x0a, + 0x18, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x33, 0x0a, + 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x75, 0x62, 0x6b, + 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x75, 0x62, 0x6b, 0x65, + 0x79, 0x73, 0x22, 0x5d, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, + 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x22, 0xc2, 0x01, 0x0a, 0x18, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4d, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, + 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3d, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, + 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, + 0x44, 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0xb2, 0x01, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, + 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x3d, 0x0a, 0x06, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, - 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, - 0x0d, 0x0a, 0x09, 0x44, 0x55, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x09, - 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0xb2, 0x01, 0x0a, 0x17, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, - 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2f, 0x0a, - 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, - 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0x27, - 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0xc1, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x46, - 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, - 0x6b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x65, 0x74, 0x68, 0x65, - 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, - 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x1a, 0x46, 0x0a, 0x0c, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, - 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65, - 0x74, 0x68, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x65, 0x74, 0x68, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x58, 0x0a, 0x1e, 0x53, - 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, - 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, - 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x74, 0x68, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x65, 0x74, 0x68, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x47, 0x61, 0x73, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3f, 0x0a, 0x08, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, - 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, - 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x49, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x47, 0x61, 0x73, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2f, 0x0a, 0x06, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, + 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0x27, 0x0a, 0x0d, 0x50, + 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, - 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, - 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x73, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, + 0x62, 0x6b, 0x65, 0x79, 0x22, 0xc1, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, + 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, + 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x65, + 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, + 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x65, + 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x1a, 0x46, 0x0a, 0x0c, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x74, 0x68, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x65, 0x74, + 0x68, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x58, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x46, + 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, + 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, - 0x65, 0x79, 0x32, 0x96, 0x0e, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x78, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2b, 0x2e, - 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, - 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x95, - 0x01, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, - 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, - 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x69, 0x6e, 0x74, + 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x74, 0x68, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x65, 0x74, 0x68, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x47, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x1a, 0x3f, 0x0a, 0x08, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, + 0x6d, 0x69, 0x74, 0x22, 0x49, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, + 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x2f, + 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, + 0x97, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, + 0x45, 0x78, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x06, 0x70, + 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, + 0x02, 0x34, 0x38, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x5c, 0x0a, 0x05, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, + 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, + 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, + 0x63, 0x68, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x22, 0xfe, 0x03, 0x0a, 0x18, 0x53, 0x65, + 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x56, + 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x6f, 0x6c, 0x75, 0x6e, + 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x89, + 0x03, 0x0a, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, + 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x12, 0x6a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x50, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, + 0x65, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x6f, + 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x2e, 0x56, 0x6f, 0x6c, 0x75, + 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x1a, 0xe7, 0x01, 0x0a, 0x0d, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, + 0x69, 0x74, 0x12, 0x5c, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, + 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, + 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, + 0x12, 0x78, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, + 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, + 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x32, 0xc9, 0x0f, 0x0a, 0x0d, 0x4b, + 0x65, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x78, 0x0a, 0x0d, + 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6b, 0x65, 0x79, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x65, 0x74, 0x68, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, + 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, - 0x01, 0x2a, 0x2a, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, - 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x7b, - 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, - 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, - 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x10, - 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, - 0x12, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x2d, 0x2e, 0x65, - 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x2a, 0x1b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x6b, - 0x65, 0x79, 0x73, 0x12, 0xb0, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x65, 0x52, - 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, - 0x12, 0x23, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, - 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, - 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, - 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x32, 0x12, 0x30, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, - 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x72, 0x65, 0x63, - 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0xa4, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x46, 0x65, - 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, - 0x65, 0x79, 0x12, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, - 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x46, 0x65, 0x65, - 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, + 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x95, + 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, + 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x2a, 0x1a, 0x2f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x6b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x7b, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, 0x01, 0x2a, 0x22, 0x30, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, - 0x2f, 0x66, 0x65, 0x65, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x96, 0x01, - 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, - 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x23, 0x2e, 0x65, - 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x35, 0x3a, 0x01, 0x2a, 0x2a, 0x30, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, - 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x72, 0x65, 0x63, - 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x94, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x47, 0x61, - 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x23, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, - 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x75, - 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, + 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x6b, + 0x65, 0x79, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x49, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, + 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, + 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x6b, 0x65, 0x79, 0x73, 0x12, + 0x99, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x12, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x2a, 0x1b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, - 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, - 0x65, 0x79, 0x7d, 0x2f, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x89, 0x01, - 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x28, 0x2e, + 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x6b, 0x65, 0x79, 0x73, 0x12, 0xb0, 0x01, 0x0a, 0x18, + 0x4c, 0x69, 0x73, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, + 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x23, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, - 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x8f, 0x01, 0x0a, 0x0e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2b, 0x2e, 0x65, - 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x2a, 0x2d, 0x2f, 0x69, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, + 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x12, 0x30, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, - 0x7d, 0x2f, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x9a, 0x01, 0x0a, 0x18, - 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x19, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, - 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, - 0x74, 0x68, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xaa, 0x02, 0x14, 0x45, 0x74, 0x68, - 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0xca, 0x02, 0x14, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, - 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0xa4, + 0x01, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x34, 0x2e, 0x65, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x53, 0x65, 0x74, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, + 0x74, 0x42, 0x79, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, + 0x3a, 0x01, 0x2a, 0x22, 0x30, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, + 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, + 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x72, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x96, 0x01, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x50, 0x75, + 0x62, 0x6b, 0x65, 0x79, 0x12, 0x23, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, 0x01, 0x2a, 0x2a, 0x30, 0x2f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, + 0x7d, 0x2f, 0x66, 0x65, 0x65, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x94, + 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x23, + 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, + 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, 0x67, 0x61, 0x73, 0x5f, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x89, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x47, 0x61, 0x73, + 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x74, + 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, + 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, + 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x12, 0x8f, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x73, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x32, 0x3a, 0x01, 0x2a, 0x2a, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, + 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x2f, 0x7b, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x12, 0xb0, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6e, + 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x12, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x53, 0x65, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, + 0x65, 0x74, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x3a, + 0x01, 0x2a, 0x22, 0x32, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x65, 0x74, + 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x7d, 0x2f, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, + 0x79, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x42, 0x9a, 0x01, 0x0a, 0x18, 0x6f, 0x72, 0x67, 0x2e, 0x65, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x42, 0x19, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, + 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, + 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0xaa, 0x02, 0x14, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xca, 0x02, 0x14, 0x45, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1838,82 +2107,90 @@ func file_proto_eth_service_key_management_proto_rawDescGZIP() []byte { } var file_proto_eth_service_key_management_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_proto_eth_service_key_management_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_proto_eth_service_key_management_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_proto_eth_service_key_management_proto_goTypes = []interface{}{ - (ImportedKeystoreStatus_Status)(0), // 0: ethereum.eth.service.ImportedKeystoreStatus.Status - (DeletedKeystoreStatus_Status)(0), // 1: ethereum.eth.service.DeletedKeystoreStatus.Status - (ImportedRemoteKeysStatus_Status)(0), // 2: ethereum.eth.service.ImportedRemoteKeysStatus.Status - (DeletedRemoteKeysStatus_Status)(0), // 3: ethereum.eth.service.DeletedRemoteKeysStatus.Status - (*ListKeystoresResponse)(nil), // 4: ethereum.eth.service.ListKeystoresResponse - (*ImportKeystoresRequest)(nil), // 5: ethereum.eth.service.ImportKeystoresRequest - (*ImportKeystoresResponse)(nil), // 6: ethereum.eth.service.ImportKeystoresResponse - (*DeleteKeystoresRequest)(nil), // 7: ethereum.eth.service.DeleteKeystoresRequest - (*DeleteKeystoresResponse)(nil), // 8: ethereum.eth.service.DeleteKeystoresResponse - (*ImportedKeystoreStatus)(nil), // 9: ethereum.eth.service.ImportedKeystoreStatus - (*DeletedKeystoreStatus)(nil), // 10: ethereum.eth.service.DeletedKeystoreStatus - (*ListRemoteKeysResponse)(nil), // 11: ethereum.eth.service.ListRemoteKeysResponse - (*ImportRemoteKeysRequest)(nil), // 12: ethereum.eth.service.ImportRemoteKeysRequest - (*ImportRemoteKeysResponse)(nil), // 13: ethereum.eth.service.ImportRemoteKeysResponse - (*DeleteRemoteKeysRequest)(nil), // 14: ethereum.eth.service.DeleteRemoteKeysRequest - (*DeleteRemoteKeysResponse)(nil), // 15: ethereum.eth.service.DeleteRemoteKeysResponse - (*ImportedRemoteKeysStatus)(nil), // 16: ethereum.eth.service.ImportedRemoteKeysStatus - (*DeletedRemoteKeysStatus)(nil), // 17: ethereum.eth.service.DeletedRemoteKeysStatus - (*PubkeyRequest)(nil), // 18: ethereum.eth.service.PubkeyRequest - (*GetFeeRecipientByPubkeyResponse)(nil), // 19: ethereum.eth.service.GetFeeRecipientByPubkeyResponse - (*SetFeeRecipientByPubkeyRequest)(nil), // 20: ethereum.eth.service.SetFeeRecipientByPubkeyRequest - (*GetGasLimitResponse)(nil), // 21: ethereum.eth.service.GetGasLimitResponse - (*SetGasLimitRequest)(nil), // 22: ethereum.eth.service.SetGasLimitRequest - (*DeleteGasLimitRequest)(nil), // 23: ethereum.eth.service.DeleteGasLimitRequest - (*ListKeystoresResponse_Keystore)(nil), // 24: ethereum.eth.service.ListKeystoresResponse.Keystore - (*ListRemoteKeysResponse_Keystore)(nil), // 25: ethereum.eth.service.ListRemoteKeysResponse.Keystore - (*ImportRemoteKeysRequest_Keystore)(nil), // 26: ethereum.eth.service.ImportRemoteKeysRequest.Keystore - (*GetFeeRecipientByPubkeyResponse_FeeRecipient)(nil), // 27: ethereum.eth.service.GetFeeRecipientByPubkeyResponse.FeeRecipient - (*GetGasLimitResponse_GasLimit)(nil), // 28: ethereum.eth.service.GetGasLimitResponse.GasLimit - (*empty.Empty)(nil), // 29: google.protobuf.Empty + (ImportedKeystoreStatus_Status)(0), // 0: ethereum.eth.service.ImportedKeystoreStatus.Status + (DeletedKeystoreStatus_Status)(0), // 1: ethereum.eth.service.DeletedKeystoreStatus.Status + (ImportedRemoteKeysStatus_Status)(0), // 2: ethereum.eth.service.ImportedRemoteKeysStatus.Status + (DeletedRemoteKeysStatus_Status)(0), // 3: ethereum.eth.service.DeletedRemoteKeysStatus.Status + (*ListKeystoresResponse)(nil), // 4: ethereum.eth.service.ListKeystoresResponse + (*ImportKeystoresRequest)(nil), // 5: ethereum.eth.service.ImportKeystoresRequest + (*ImportKeystoresResponse)(nil), // 6: ethereum.eth.service.ImportKeystoresResponse + (*DeleteKeystoresRequest)(nil), // 7: ethereum.eth.service.DeleteKeystoresRequest + (*DeleteKeystoresResponse)(nil), // 8: ethereum.eth.service.DeleteKeystoresResponse + (*ImportedKeystoreStatus)(nil), // 9: ethereum.eth.service.ImportedKeystoreStatus + (*DeletedKeystoreStatus)(nil), // 10: ethereum.eth.service.DeletedKeystoreStatus + (*ListRemoteKeysResponse)(nil), // 11: ethereum.eth.service.ListRemoteKeysResponse + (*ImportRemoteKeysRequest)(nil), // 12: ethereum.eth.service.ImportRemoteKeysRequest + (*ImportRemoteKeysResponse)(nil), // 13: ethereum.eth.service.ImportRemoteKeysResponse + (*DeleteRemoteKeysRequest)(nil), // 14: ethereum.eth.service.DeleteRemoteKeysRequest + (*DeleteRemoteKeysResponse)(nil), // 15: ethereum.eth.service.DeleteRemoteKeysResponse + (*ImportedRemoteKeysStatus)(nil), // 16: ethereum.eth.service.ImportedRemoteKeysStatus + (*DeletedRemoteKeysStatus)(nil), // 17: ethereum.eth.service.DeletedRemoteKeysStatus + (*PubkeyRequest)(nil), // 18: ethereum.eth.service.PubkeyRequest + (*GetFeeRecipientByPubkeyResponse)(nil), // 19: ethereum.eth.service.GetFeeRecipientByPubkeyResponse + (*SetFeeRecipientByPubkeyRequest)(nil), // 20: ethereum.eth.service.SetFeeRecipientByPubkeyRequest + (*GetGasLimitResponse)(nil), // 21: ethereum.eth.service.GetGasLimitResponse + (*SetGasLimitRequest)(nil), // 22: ethereum.eth.service.SetGasLimitRequest + (*DeleteGasLimitRequest)(nil), // 23: ethereum.eth.service.DeleteGasLimitRequest + (*SetVoluntaryExitRequest)(nil), // 24: ethereum.eth.service.SetVoluntaryExitRequest + (*SetVoluntaryExitResponse)(nil), // 25: ethereum.eth.service.SetVoluntaryExitResponse + (*ListKeystoresResponse_Keystore)(nil), // 26: ethereum.eth.service.ListKeystoresResponse.Keystore + (*ListRemoteKeysResponse_Keystore)(nil), // 27: ethereum.eth.service.ListRemoteKeysResponse.Keystore + (*ImportRemoteKeysRequest_Keystore)(nil), // 28: ethereum.eth.service.ImportRemoteKeysRequest.Keystore + (*GetFeeRecipientByPubkeyResponse_FeeRecipient)(nil), // 29: ethereum.eth.service.GetFeeRecipientByPubkeyResponse.FeeRecipient + (*GetGasLimitResponse_GasLimit)(nil), // 30: ethereum.eth.service.GetGasLimitResponse.GasLimit + (*SetVoluntaryExitResponse_SignedVoluntaryExit)(nil), // 31: ethereum.eth.service.SetVoluntaryExitResponse.SignedVoluntaryExit + (*SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit)(nil), // 32: ethereum.eth.service.SetVoluntaryExitResponse.SignedVoluntaryExit.VoluntaryExit + (*empty.Empty)(nil), // 33: google.protobuf.Empty } var file_proto_eth_service_key_management_proto_depIdxs = []int32{ - 24, // 0: ethereum.eth.service.ListKeystoresResponse.data:type_name -> ethereum.eth.service.ListKeystoresResponse.Keystore + 26, // 0: ethereum.eth.service.ListKeystoresResponse.data:type_name -> ethereum.eth.service.ListKeystoresResponse.Keystore 9, // 1: ethereum.eth.service.ImportKeystoresResponse.data:type_name -> ethereum.eth.service.ImportedKeystoreStatus 10, // 2: ethereum.eth.service.DeleteKeystoresResponse.data:type_name -> ethereum.eth.service.DeletedKeystoreStatus 0, // 3: ethereum.eth.service.ImportedKeystoreStatus.status:type_name -> ethereum.eth.service.ImportedKeystoreStatus.Status 1, // 4: ethereum.eth.service.DeletedKeystoreStatus.status:type_name -> ethereum.eth.service.DeletedKeystoreStatus.Status - 25, // 5: ethereum.eth.service.ListRemoteKeysResponse.data:type_name -> ethereum.eth.service.ListRemoteKeysResponse.Keystore - 26, // 6: ethereum.eth.service.ImportRemoteKeysRequest.remote_keys:type_name -> ethereum.eth.service.ImportRemoteKeysRequest.Keystore + 27, // 5: ethereum.eth.service.ListRemoteKeysResponse.data:type_name -> ethereum.eth.service.ListRemoteKeysResponse.Keystore + 28, // 6: ethereum.eth.service.ImportRemoteKeysRequest.remote_keys:type_name -> ethereum.eth.service.ImportRemoteKeysRequest.Keystore 16, // 7: ethereum.eth.service.ImportRemoteKeysResponse.data:type_name -> ethereum.eth.service.ImportedRemoteKeysStatus 17, // 8: ethereum.eth.service.DeleteRemoteKeysResponse.data:type_name -> ethereum.eth.service.DeletedRemoteKeysStatus 2, // 9: ethereum.eth.service.ImportedRemoteKeysStatus.status:type_name -> ethereum.eth.service.ImportedRemoteKeysStatus.Status 3, // 10: ethereum.eth.service.DeletedRemoteKeysStatus.status:type_name -> ethereum.eth.service.DeletedRemoteKeysStatus.Status - 27, // 11: ethereum.eth.service.GetFeeRecipientByPubkeyResponse.data:type_name -> ethereum.eth.service.GetFeeRecipientByPubkeyResponse.FeeRecipient - 28, // 12: ethereum.eth.service.GetGasLimitResponse.data:type_name -> ethereum.eth.service.GetGasLimitResponse.GasLimit - 29, // 13: ethereum.eth.service.KeyManagement.ListKeystores:input_type -> google.protobuf.Empty - 5, // 14: ethereum.eth.service.KeyManagement.ImportKeystores:input_type -> ethereum.eth.service.ImportKeystoresRequest - 7, // 15: ethereum.eth.service.KeyManagement.DeleteKeystores:input_type -> ethereum.eth.service.DeleteKeystoresRequest - 29, // 16: ethereum.eth.service.KeyManagement.ListRemoteKeys:input_type -> google.protobuf.Empty - 12, // 17: ethereum.eth.service.KeyManagement.ImportRemoteKeys:input_type -> ethereum.eth.service.ImportRemoteKeysRequest - 14, // 18: ethereum.eth.service.KeyManagement.DeleteRemoteKeys:input_type -> ethereum.eth.service.DeleteRemoteKeysRequest - 18, // 19: ethereum.eth.service.KeyManagement.ListFeeRecipientByPubkey:input_type -> ethereum.eth.service.PubkeyRequest - 20, // 20: ethereum.eth.service.KeyManagement.SetFeeRecipientByPubkey:input_type -> ethereum.eth.service.SetFeeRecipientByPubkeyRequest - 18, // 21: ethereum.eth.service.KeyManagement.DeleteFeeRecipientByPubkey:input_type -> ethereum.eth.service.PubkeyRequest - 18, // 22: ethereum.eth.service.KeyManagement.GetGasLimit:input_type -> ethereum.eth.service.PubkeyRequest - 22, // 23: ethereum.eth.service.KeyManagement.SetGasLimit:input_type -> ethereum.eth.service.SetGasLimitRequest - 23, // 24: ethereum.eth.service.KeyManagement.DeleteGasLimit:input_type -> ethereum.eth.service.DeleteGasLimitRequest - 4, // 25: ethereum.eth.service.KeyManagement.ListKeystores:output_type -> ethereum.eth.service.ListKeystoresResponse - 6, // 26: ethereum.eth.service.KeyManagement.ImportKeystores:output_type -> ethereum.eth.service.ImportKeystoresResponse - 8, // 27: ethereum.eth.service.KeyManagement.DeleteKeystores:output_type -> ethereum.eth.service.DeleteKeystoresResponse - 11, // 28: ethereum.eth.service.KeyManagement.ListRemoteKeys:output_type -> ethereum.eth.service.ListRemoteKeysResponse - 13, // 29: ethereum.eth.service.KeyManagement.ImportRemoteKeys:output_type -> ethereum.eth.service.ImportRemoteKeysResponse - 15, // 30: ethereum.eth.service.KeyManagement.DeleteRemoteKeys:output_type -> ethereum.eth.service.DeleteRemoteKeysResponse - 19, // 31: ethereum.eth.service.KeyManagement.ListFeeRecipientByPubkey:output_type -> ethereum.eth.service.GetFeeRecipientByPubkeyResponse - 29, // 32: ethereum.eth.service.KeyManagement.SetFeeRecipientByPubkey:output_type -> google.protobuf.Empty - 29, // 33: ethereum.eth.service.KeyManagement.DeleteFeeRecipientByPubkey:output_type -> google.protobuf.Empty - 21, // 34: ethereum.eth.service.KeyManagement.GetGasLimit:output_type -> ethereum.eth.service.GetGasLimitResponse - 29, // 35: ethereum.eth.service.KeyManagement.SetGasLimit:output_type -> google.protobuf.Empty - 29, // 36: ethereum.eth.service.KeyManagement.DeleteGasLimit:output_type -> google.protobuf.Empty - 25, // [25:37] is the sub-list for method output_type - 13, // [13:25] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 29, // 11: ethereum.eth.service.GetFeeRecipientByPubkeyResponse.data:type_name -> ethereum.eth.service.GetFeeRecipientByPubkeyResponse.FeeRecipient + 30, // 12: ethereum.eth.service.GetGasLimitResponse.data:type_name -> ethereum.eth.service.GetGasLimitResponse.GasLimit + 31, // 13: ethereum.eth.service.SetVoluntaryExitResponse.data:type_name -> ethereum.eth.service.SetVoluntaryExitResponse.SignedVoluntaryExit + 32, // 14: ethereum.eth.service.SetVoluntaryExitResponse.SignedVoluntaryExit.message:type_name -> ethereum.eth.service.SetVoluntaryExitResponse.SignedVoluntaryExit.VoluntaryExit + 33, // 15: ethereum.eth.service.KeyManagement.ListKeystores:input_type -> google.protobuf.Empty + 5, // 16: ethereum.eth.service.KeyManagement.ImportKeystores:input_type -> ethereum.eth.service.ImportKeystoresRequest + 7, // 17: ethereum.eth.service.KeyManagement.DeleteKeystores:input_type -> ethereum.eth.service.DeleteKeystoresRequest + 33, // 18: ethereum.eth.service.KeyManagement.ListRemoteKeys:input_type -> google.protobuf.Empty + 12, // 19: ethereum.eth.service.KeyManagement.ImportRemoteKeys:input_type -> ethereum.eth.service.ImportRemoteKeysRequest + 14, // 20: ethereum.eth.service.KeyManagement.DeleteRemoteKeys:input_type -> ethereum.eth.service.DeleteRemoteKeysRequest + 18, // 21: ethereum.eth.service.KeyManagement.ListFeeRecipientByPubkey:input_type -> ethereum.eth.service.PubkeyRequest + 20, // 22: ethereum.eth.service.KeyManagement.SetFeeRecipientByPubkey:input_type -> ethereum.eth.service.SetFeeRecipientByPubkeyRequest + 18, // 23: ethereum.eth.service.KeyManagement.DeleteFeeRecipientByPubkey:input_type -> ethereum.eth.service.PubkeyRequest + 18, // 24: ethereum.eth.service.KeyManagement.GetGasLimit:input_type -> ethereum.eth.service.PubkeyRequest + 22, // 25: ethereum.eth.service.KeyManagement.SetGasLimit:input_type -> ethereum.eth.service.SetGasLimitRequest + 23, // 26: ethereum.eth.service.KeyManagement.DeleteGasLimit:input_type -> ethereum.eth.service.DeleteGasLimitRequest + 24, // 27: ethereum.eth.service.KeyManagement.SetVoluntaryExit:input_type -> ethereum.eth.service.SetVoluntaryExitRequest + 4, // 28: ethereum.eth.service.KeyManagement.ListKeystores:output_type -> ethereum.eth.service.ListKeystoresResponse + 6, // 29: ethereum.eth.service.KeyManagement.ImportKeystores:output_type -> ethereum.eth.service.ImportKeystoresResponse + 8, // 30: ethereum.eth.service.KeyManagement.DeleteKeystores:output_type -> ethereum.eth.service.DeleteKeystoresResponse + 11, // 31: ethereum.eth.service.KeyManagement.ListRemoteKeys:output_type -> ethereum.eth.service.ListRemoteKeysResponse + 13, // 32: ethereum.eth.service.KeyManagement.ImportRemoteKeys:output_type -> ethereum.eth.service.ImportRemoteKeysResponse + 15, // 33: ethereum.eth.service.KeyManagement.DeleteRemoteKeys:output_type -> ethereum.eth.service.DeleteRemoteKeysResponse + 19, // 34: ethereum.eth.service.KeyManagement.ListFeeRecipientByPubkey:output_type -> ethereum.eth.service.GetFeeRecipientByPubkeyResponse + 33, // 35: ethereum.eth.service.KeyManagement.SetFeeRecipientByPubkey:output_type -> google.protobuf.Empty + 33, // 36: ethereum.eth.service.KeyManagement.DeleteFeeRecipientByPubkey:output_type -> google.protobuf.Empty + 21, // 37: ethereum.eth.service.KeyManagement.GetGasLimit:output_type -> ethereum.eth.service.GetGasLimitResponse + 33, // 38: ethereum.eth.service.KeyManagement.SetGasLimit:output_type -> google.protobuf.Empty + 33, // 39: ethereum.eth.service.KeyManagement.DeleteGasLimit:output_type -> google.protobuf.Empty + 25, // 40: ethereum.eth.service.KeyManagement.SetVoluntaryExit:output_type -> ethereum.eth.service.SetVoluntaryExitResponse + 28, // [28:41] is the sub-list for method output_type + 15, // [15:28] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_proto_eth_service_key_management_proto_init() } @@ -2163,7 +2440,7 @@ func file_proto_eth_service_key_management_proto_init() { } } file_proto_eth_service_key_management_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListKeystoresResponse_Keystore); i { + switch v := v.(*SetVoluntaryExitRequest); i { case 0: return &v.state case 1: @@ -2175,7 +2452,7 @@ func file_proto_eth_service_key_management_proto_init() { } } file_proto_eth_service_key_management_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListRemoteKeysResponse_Keystore); i { + switch v := v.(*SetVoluntaryExitResponse); i { case 0: return &v.state case 1: @@ -2187,7 +2464,7 @@ func file_proto_eth_service_key_management_proto_init() { } } file_proto_eth_service_key_management_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImportRemoteKeysRequest_Keystore); i { + switch v := v.(*ListKeystoresResponse_Keystore); i { case 0: return &v.state case 1: @@ -2199,7 +2476,7 @@ func file_proto_eth_service_key_management_proto_init() { } } file_proto_eth_service_key_management_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFeeRecipientByPubkeyResponse_FeeRecipient); i { + switch v := v.(*ListRemoteKeysResponse_Keystore); i { case 0: return &v.state case 1: @@ -2211,6 +2488,30 @@ func file_proto_eth_service_key_management_proto_init() { } } file_proto_eth_service_key_management_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImportRemoteKeysRequest_Keystore); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_eth_service_key_management_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFeeRecipientByPubkeyResponse_FeeRecipient); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_eth_service_key_management_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetGasLimitResponse_GasLimit); i { case 0: return &v.state @@ -2222,6 +2523,30 @@ func file_proto_eth_service_key_management_proto_init() { return nil } } + file_proto_eth_service_key_management_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetVoluntaryExitResponse_SignedVoluntaryExit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_eth_service_key_management_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -2229,7 +2554,7 @@ func file_proto_eth_service_key_management_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_eth_service_key_management_proto_rawDesc, NumEnums: 4, - NumMessages: 25, + NumMessages: 29, NumExtensions: 0, NumServices: 1, }, @@ -2268,6 +2593,7 @@ type KeyManagementClient interface { GetGasLimit(ctx context.Context, in *PubkeyRequest, opts ...grpc.CallOption) (*GetGasLimitResponse, error) SetGasLimit(ctx context.Context, in *SetGasLimitRequest, opts ...grpc.CallOption) (*empty.Empty, error) DeleteGasLimit(ctx context.Context, in *DeleteGasLimitRequest, opts ...grpc.CallOption) (*empty.Empty, error) + SetVoluntaryExit(ctx context.Context, in *SetVoluntaryExitRequest, opts ...grpc.CallOption) (*SetVoluntaryExitResponse, error) } type keyManagementClient struct { @@ -2386,6 +2712,15 @@ func (c *keyManagementClient) DeleteGasLimit(ctx context.Context, in *DeleteGasL return out, nil } +func (c *keyManagementClient) SetVoluntaryExit(ctx context.Context, in *SetVoluntaryExitRequest, opts ...grpc.CallOption) (*SetVoluntaryExitResponse, error) { + out := new(SetVoluntaryExitResponse) + err := c.cc.Invoke(ctx, "/ethereum.eth.service.KeyManagement/SetVoluntaryExit", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // KeyManagementServer is the server API for KeyManagement service. type KeyManagementServer interface { ListKeystores(context.Context, *empty.Empty) (*ListKeystoresResponse, error) @@ -2400,6 +2735,7 @@ type KeyManagementServer interface { GetGasLimit(context.Context, *PubkeyRequest) (*GetGasLimitResponse, error) SetGasLimit(context.Context, *SetGasLimitRequest) (*empty.Empty, error) DeleteGasLimit(context.Context, *DeleteGasLimitRequest) (*empty.Empty, error) + SetVoluntaryExit(context.Context, *SetVoluntaryExitRequest) (*SetVoluntaryExitResponse, error) } // UnimplementedKeyManagementServer can be embedded to have forward compatible implementations. @@ -2442,6 +2778,9 @@ func (*UnimplementedKeyManagementServer) SetGasLimit(context.Context, *SetGasLim func (*UnimplementedKeyManagementServer) DeleteGasLimit(context.Context, *DeleteGasLimitRequest) (*empty.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteGasLimit not implemented") } +func (*UnimplementedKeyManagementServer) SetVoluntaryExit(context.Context, *SetVoluntaryExitRequest) (*SetVoluntaryExitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetVoluntaryExit not implemented") +} func RegisterKeyManagementServer(s *grpc.Server, srv KeyManagementServer) { s.RegisterService(&_KeyManagement_serviceDesc, srv) @@ -2663,6 +3002,24 @@ func _KeyManagement_DeleteGasLimit_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _KeyManagement_SetVoluntaryExit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetVoluntaryExitRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServer).SetVoluntaryExit(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ethereum.eth.service.KeyManagement/SetVoluntaryExit", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServer).SetVoluntaryExit(ctx, req.(*SetVoluntaryExitRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _KeyManagement_serviceDesc = grpc.ServiceDesc{ ServiceName: "ethereum.eth.service.KeyManagement", HandlerType: (*KeyManagementServer)(nil), @@ -2715,6 +3072,10 @@ var _KeyManagement_serviceDesc = grpc.ServiceDesc{ MethodName: "DeleteGasLimit", Handler: _KeyManagement_DeleteGasLimit_Handler, }, + { + MethodName: "SetVoluntaryExit", + Handler: _KeyManagement_SetVoluntaryExit_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "proto/eth/service/key_management.proto", diff --git a/proto/eth/service/key_management.pb.gw.go b/proto/eth/service/key_management.pb.gw.go index 52246e6f0c..cc446408b3 100755 --- a/proto/eth/service/key_management.pb.gw.go +++ b/proto/eth/service/key_management.pb.gw.go @@ -597,6 +597,76 @@ func local_request_KeyManagement_DeleteGasLimit_0(ctx context.Context, marshaler } +func request_KeyManagement_SetVoluntaryExit_0(ctx context.Context, marshaler runtime.Marshaler, client KeyManagementClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetVoluntaryExitRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["pubkey"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "pubkey") + } + + pubkey, err := runtime.Bytes(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "pubkey", err) + } + protoReq.Pubkey = (pubkey) + + msg, err := client.SetVoluntaryExit(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_KeyManagement_SetVoluntaryExit_0(ctx context.Context, marshaler runtime.Marshaler, server KeyManagementServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetVoluntaryExitRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["pubkey"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "pubkey") + } + + pubkey, err := runtime.Bytes(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "pubkey", err) + } + protoReq.Pubkey = (pubkey) + + msg, err := server.SetVoluntaryExit(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterKeyManagementHandlerServer registers the http handlers for service KeyManagement to "mux". // UnaryRPC :call KeyManagementServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -879,6 +949,29 @@ func RegisterKeyManagementHandlerServer(ctx context.Context, mux *runtime.ServeM }) + mux.Handle("POST", pattern_KeyManagement_SetVoluntaryExit_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/ethereum.eth.service.KeyManagement/SetVoluntaryExit") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_KeyManagement_SetVoluntaryExit_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_KeyManagement_SetVoluntaryExit_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1160,6 +1253,26 @@ func RegisterKeyManagementHandlerClient(ctx context.Context, mux *runtime.ServeM }) + mux.Handle("POST", pattern_KeyManagement_SetVoluntaryExit_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/ethereum.eth.service.KeyManagement/SetVoluntaryExit") + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_KeyManagement_SetVoluntaryExit_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_KeyManagement_SetVoluntaryExit_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1187,6 +1300,8 @@ var ( pattern_KeyManagement_SetGasLimit_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"internal", "eth", "v1", "validator", "pubkey", "gas_limit"}, "")) pattern_KeyManagement_DeleteGasLimit_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"internal", "eth", "v1", "validator", "pubkey", "gas_limit"}, "")) + + pattern_KeyManagement_SetVoluntaryExit_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"internal", "eth", "v1", "validator", "pubkey", "voluntary_exit"}, "")) ) var ( @@ -1213,4 +1328,6 @@ var ( forward_KeyManagement_SetGasLimit_0 = runtime.ForwardResponseMessage forward_KeyManagement_DeleteGasLimit_0 = runtime.ForwardResponseMessage + + forward_KeyManagement_SetVoluntaryExit_0 = runtime.ForwardResponseMessage ) diff --git a/proto/eth/service/key_management.proto b/proto/eth/service/key_management.proto index 337474f43b..9ebf4b9080 100644 --- a/proto/eth/service/key_management.proto +++ b/proto/eth/service/key_management.proto @@ -18,6 +18,7 @@ package ethereum.eth.service; import "google/api/annotations.proto"; import "google/protobuf/descriptor.proto"; import "google/protobuf/empty.proto"; +import "proto/eth/ext/options.proto"; option csharp_namespace = "Ethereum.Eth.Service"; option go_package = "github.com/prysmaticlabs/prysm/v4/proto/eth/service"; @@ -217,6 +218,24 @@ service KeyManagement { }; } + // SetVoluntaryExit creates a signed voluntary exit message and returns a VoluntaryExit object. + // + // Spec page: https://ethereum.github.io/keymanager-APIs/?urls.primaryName=dev#/Voluntary%20Exit/signVoluntaryExit + // + // HTTP response status codes: + // - 200: Successfully created and signed voluntary exit + // - 400: Bad request, malformed request + // - 401: Unauthorized, no token is found. + // - 403: Forbidden, a token is found but is invalid + // - 404: Path not found + // - 500: Validator internal error + rpc SetVoluntaryExit(SetVoluntaryExitRequest) returns (SetVoluntaryExitResponse) { + option (google.api.http) = { + post: "/internal/eth/v1/validator/{pubkey}/voluntary_exit", + body: "*" + }; + } + } message ListKeystoresResponse { @@ -352,3 +371,20 @@ message SetGasLimitRequest { message DeleteGasLimitRequest { bytes pubkey = 1; } + +message SetVoluntaryExitRequest { + bytes pubkey = 1 [(ethereum.eth.ext.ssz_size) = "48"]; + uint64 epoch = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.Epoch"]; +} + +message SetVoluntaryExitResponse { + message SignedVoluntaryExit { + message VoluntaryExit { + uint64 epoch = 1 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.Epoch"]; + uint64 validator_index = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives.ValidatorIndex"]; + } + VoluntaryExit message = 1; + bytes signature = 2; + } + SignedVoluntaryExit data = 1; +} diff --git a/validator/accounts/accounts_exit.go b/validator/accounts/accounts_exit.go index a4861479f6..0bacf2b9d9 100644 --- a/validator/accounts/accounts_exit.go +++ b/validator/accounts/accounts_exit.go @@ -84,11 +84,19 @@ func PerformVoluntaryExit( ctx context.Context, cfg PerformExitCfg, ) (rawExitedKeys [][]byte, formattedExitedKeys []string, err error) { var rawNotExitedKeys [][]byte + genesisResponse, err := cfg.NodeClient.GetGenesis(ctx, &emptypb.Empty{}) + if err != nil { + log.WithError(err).Errorf("voluntary exit failed: %v", err) + } for i, key := range cfg.RawPubKeys { // When output directory is present, only create the signed exit, but do not propose it. // Otherwise, propose the exit immediately. + epoch, err := client.CurrentEpoch(genesisResponse.GenesisTime) + if err != nil { + log.WithError(err).Errorf("voluntary exit failed: %v", err) + } if len(cfg.OutputDirectory) > 0 { - sve, err := client.CreateSignedVoluntaryExit(ctx, cfg.ValidatorClient, cfg.NodeClient, cfg.Keymanager.Sign, key) + sve, err := client.CreateSignedVoluntaryExit(ctx, cfg.ValidatorClient, cfg.Keymanager.Sign, key, epoch) if err != nil { rawNotExitedKeys = append(rawNotExitedKeys, key) msg := err.Error() @@ -101,7 +109,7 @@ func PerformVoluntaryExit( } else if err := writeSignedVoluntaryExitJSON(ctx, sve, cfg.OutputDirectory); err != nil { log.WithError(err).Error("failed to write voluntary exit") } - } else if err := client.ProposeExit(ctx, cfg.ValidatorClient, cfg.NodeClient, cfg.Keymanager.Sign, key); err != nil { + } else if err := client.ProposeExit(ctx, cfg.ValidatorClient, cfg.Keymanager.Sign, key, epoch); err != nil { rawNotExitedKeys = append(rawNotExitedKeys, key) msg := err.Error() diff --git a/validator/client/BUILD.bazel b/validator/client/BUILD.bazel index 46930c7ac3..6d85f48163 100644 --- a/validator/client/BUILD.bazel +++ b/validator/client/BUILD.bazel @@ -80,6 +80,7 @@ go_library( "@com_github_prysmaticlabs_go_bitfield//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@io_bazel_rules_go//proto/wkt:empty_go_proto", + "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", "@io_opencensus_go//plugin/ocgrpc:go_default_library", "@io_opencensus_go//trace:go_default_library", "@org_golang_google_grpc//:go_default_library", @@ -173,6 +174,5 @@ go_test( "@org_golang_google_grpc//metadata:go_default_library", "@org_golang_google_grpc//status:go_default_library", "@org_golang_google_protobuf//types/known/emptypb:go_default_library", - "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", ], ) diff --git a/validator/client/propose.go b/validator/client/propose.go index 13499f3352..8165d4c2f3 100644 --- a/validator/client/propose.go +++ b/validator/client/propose.go @@ -6,6 +6,7 @@ import ( "fmt" "time" + "github.com/golang/protobuf/ptypes/timestamp" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v4/async" "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing" @@ -25,7 +26,6 @@ import ( "github.com/prysmaticlabs/prysm/v4/validator/client/iface" "github.com/sirupsen/logrus" "go.opencensus.io/trace" - "google.golang.org/protobuf/types/known/emptypb" ) const domainDataErr = "could not get domain data" @@ -198,14 +198,14 @@ func (v *validator) ProposeBlock(ctx context.Context, slot primitives.Slot, pubK func ProposeExit( ctx context.Context, validatorClient iface.ValidatorClient, - nodeClient iface.NodeClient, signer iface.SigningFunc, pubKey []byte, + epoch primitives.Epoch, ) error { ctx, span := trace.StartSpan(ctx, "validator.ProposeExit") defer span.End() - signedExit, err := CreateSignedVoluntaryExit(ctx, validatorClient, nodeClient, signer, pubKey) + signedExit, err := CreateSignedVoluntaryExit(ctx, validatorClient, signer, pubKey, epoch) if err != nil { return errors.Wrap(err, "failed to create signed voluntary exit") } @@ -217,16 +217,22 @@ func ProposeExit( span.AddAttributes( trace.StringAttribute("exitRoot", fmt.Sprintf("%#x", exitResp.ExitRoot)), ) - return nil } +func CurrentEpoch(genesisTime *timestamp.Timestamp) (primitives.Epoch, error) { + totalSecondsPassed := prysmTime.Now().Unix() - genesisTime.Seconds + currentSlot := primitives.Slot((uint64(totalSecondsPassed)) / params.BeaconConfig().SecondsPerSlot) + currentEpoch := slots.ToEpoch(currentSlot) + return currentEpoch, nil +} + func CreateSignedVoluntaryExit( ctx context.Context, validatorClient iface.ValidatorClient, - nodeClient iface.NodeClient, signer iface.SigningFunc, pubKey []byte, + epoch primitives.Epoch, ) (*ethpb.SignedVoluntaryExit, error) { ctx, span := trace.StartSpan(ctx, "validator.CreateSignedVoluntaryExit") defer span.End() @@ -235,15 +241,12 @@ func CreateSignedVoluntaryExit( if err != nil { return nil, errors.Wrap(err, "gRPC call to get validator index failed") } - genesisResponse, err := nodeClient.GetGenesis(ctx, &emptypb.Empty{}) + exit := ðpb.VoluntaryExit{Epoch: epoch, ValidatorIndex: indexResponse.Index} + slot, err := slots.EpochStart(epoch) if err != nil { - return nil, errors.Wrap(err, "gRPC call to get genesis time failed") + return nil, errors.Wrap(err, "failed to retrieve slot") } - totalSecondsPassed := prysmTime.Now().Unix() - genesisResponse.GenesisTime.Seconds - currentEpoch := primitives.Epoch(uint64(totalSecondsPassed) / uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))) - currentSlot := slots.CurrentSlot(uint64(genesisResponse.GenesisTime.AsTime().Unix())) - exit := ðpb.VoluntaryExit{Epoch: currentEpoch, ValidatorIndex: indexResponse.Index} - sig, err := signVoluntaryExit(ctx, validatorClient, signer, pubKey, exit, currentSlot) + sig, err := signVoluntaryExit(ctx, validatorClient, signer, pubKey, exit, slot) if err != nil { return nil, errors.Wrap(err, "failed to sign voluntary exit") } diff --git a/validator/client/propose_test.go b/validator/client/propose_test.go index 59acb9b014..151c228e79 100644 --- a/validator/client/propose_test.go +++ b/validator/client/propose_test.go @@ -6,7 +6,6 @@ import ( "errors" "strings" "testing" - "time" "github.com/golang/mock/gomock" "github.com/prysmaticlabs/prysm/v4/beacon-chain/core/signing" @@ -28,7 +27,6 @@ import ( testing2 "github.com/prysmaticlabs/prysm/v4/validator/db/testing" "github.com/prysmaticlabs/prysm/v4/validator/graffiti" logTest "github.com/sirupsen/logrus/hooks/test" - "google.golang.org/protobuf/types/known/timestamppb" ) type mocks struct { @@ -648,39 +646,15 @@ func TestProposeExit_ValidatorIndexFailed(t *testing.T) { err := ProposeExit( context.Background(), m.validatorClient, - m.nodeClient, m.signfunc, validatorKey.PublicKey().Marshal(), + params.BeaconConfig().GenesisEpoch, ) assert.NotNil(t, err) assert.ErrorContains(t, "uh oh", err) assert.ErrorContains(t, "gRPC call to get validator index failed", err) } -func TestProposeExit_GetGenesisFailed(t *testing.T) { - _, m, validatorKey, finish := setup(t) - defer finish() - - m.validatorClient.EXPECT(). - ValidatorIndex(gomock.Any(), gomock.Any()). - Return(nil, nil) - - m.nodeClient.EXPECT(). - GetGenesis(gomock.Any(), gomock.Any()). - Return(nil, errors.New("uh oh")) - - err := ProposeExit( - context.Background(), - m.validatorClient, - m.nodeClient, - m.signfunc, - validatorKey.PublicKey().Marshal(), - ) - assert.NotNil(t, err) - assert.ErrorContains(t, "uh oh", err) - assert.ErrorContains(t, "gRPC call to get genesis time failed", err) -} - func TestProposeExit_DomainDataFailed(t *testing.T) { _, m, validatorKey, finish := setup(t) defer finish() @@ -689,15 +663,6 @@ func TestProposeExit_DomainDataFailed(t *testing.T) { ValidatorIndex(gomock.Any(), gomock.Any()). Return(ðpb.ValidatorIndexResponse{Index: 1}, nil) - // Any time in the past will suffice - genesisTime := ×tamppb.Timestamp{ - Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(), - } - - m.nodeClient.EXPECT(). - GetGenesis(gomock.Any(), gomock.Any()). - Return(ðpb.Genesis{GenesisTime: genesisTime}, nil) - m.validatorClient.EXPECT(). DomainData(gomock.Any(), gomock.Any()). Return(nil, errors.New("uh oh")) @@ -705,9 +670,9 @@ func TestProposeExit_DomainDataFailed(t *testing.T) { err := ProposeExit( context.Background(), m.validatorClient, - m.nodeClient, m.signfunc, validatorKey.PublicKey().Marshal(), + params.BeaconConfig().GenesisEpoch, ) assert.NotNil(t, err) assert.ErrorContains(t, domainDataErr, err) @@ -723,15 +688,6 @@ func TestProposeExit_DomainDataIsNil(t *testing.T) { ValidatorIndex(gomock.Any(), gomock.Any()). Return(ðpb.ValidatorIndexResponse{Index: 1}, nil) - // Any time in the past will suffice - genesisTime := ×tamppb.Timestamp{ - Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(), - } - - m.nodeClient.EXPECT(). - GetGenesis(gomock.Any(), gomock.Any()). - Return(ðpb.Genesis{GenesisTime: genesisTime}, nil) - m.validatorClient.EXPECT(). DomainData(gomock.Any(), gomock.Any()). Return(nil, nil) @@ -739,9 +695,9 @@ func TestProposeExit_DomainDataIsNil(t *testing.T) { err := ProposeExit( context.Background(), m.validatorClient, - m.nodeClient, m.signfunc, validatorKey.PublicKey().Marshal(), + params.BeaconConfig().GenesisEpoch, ) assert.NotNil(t, err) assert.ErrorContains(t, domainDataErr, err) @@ -756,15 +712,6 @@ func TestProposeBlock_ProposeExitFailed(t *testing.T) { ValidatorIndex(gomock.Any(), gomock.Any()). Return(ðpb.ValidatorIndexResponse{Index: 1}, nil) - // Any time in the past will suffice - genesisTime := ×tamppb.Timestamp{ - Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(), - } - - m.nodeClient.EXPECT(). - GetGenesis(gomock.Any(), gomock.Any()). - Return(ðpb.Genesis{GenesisTime: genesisTime}, nil) - m.validatorClient.EXPECT(). DomainData(gomock.Any(), gomock.Any()). Return(ðpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil) @@ -776,9 +723,9 @@ func TestProposeBlock_ProposeExitFailed(t *testing.T) { err := ProposeExit( context.Background(), m.validatorClient, - m.nodeClient, m.signfunc, validatorKey.PublicKey().Marshal(), + params.BeaconConfig().GenesisEpoch, ) assert.NotNil(t, err) assert.ErrorContains(t, "uh oh", err) @@ -793,15 +740,6 @@ func TestProposeExit_BroadcastsBlock(t *testing.T) { ValidatorIndex(gomock.Any(), gomock.Any()). Return(ðpb.ValidatorIndexResponse{Index: 1}, nil) - // Any time in the past will suffice - genesisTime := ×tamppb.Timestamp{ - Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(), - } - - m.nodeClient.EXPECT(). - GetGenesis(gomock.Any(), gomock.Any()). - Return(ðpb.Genesis{GenesisTime: genesisTime}, nil) - m.validatorClient.EXPECT(). DomainData(gomock.Any(), gomock.Any()). Return(ðpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil) @@ -813,9 +751,9 @@ func TestProposeExit_BroadcastsBlock(t *testing.T) { assert.NoError(t, ProposeExit( context.Background(), m.validatorClient, - m.nodeClient, m.signfunc, validatorKey.PublicKey().Marshal(), + params.BeaconConfig().GenesisEpoch, )) } diff --git a/validator/rpc/BUILD.bazel b/validator/rpc/BUILD.bazel index 180a298a24..dec9383f65 100644 --- a/validator/rpc/BUILD.bazel +++ b/validator/rpc/BUILD.bazel @@ -102,6 +102,7 @@ go_test( "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//config/validator/service:go_default_library", + "//consensus-types/primitives:go_default_library", "//consensus-types/validator:go_default_library", "//crypto/bls:go_default_library", "//crypto/rand:go_default_library", @@ -138,6 +139,7 @@ go_test( "@org_golang_google_grpc//:go_default_library", "@org_golang_google_grpc//codes:go_default_library", "@org_golang_google_grpc//metadata:go_default_library", + "@org_golang_google_protobuf//types/known/emptypb:go_default_library", "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", ], ) diff --git a/validator/rpc/accounts_test.go b/validator/rpc/accounts_test.go index f40a3422c7..d687b83298 100644 --- a/validator/rpc/accounts_test.go +++ b/validator/rpc/accounts_test.go @@ -205,7 +205,6 @@ func TestServer_VoluntaryExit(t *testing.T) { mockNodeClient.EXPECT(). GetGenesis(gomock.Any(), gomock.Any()). - Times(2). Return(ðpb.Genesis{GenesisTime: genesisTime}, nil) mockValidatorClient.EXPECT(). diff --git a/validator/rpc/apimiddleware/BUILD.bazel b/validator/rpc/apimiddleware/BUILD.bazel index 634d560005..5303b02c37 100644 --- a/validator/rpc/apimiddleware/BUILD.bazel +++ b/validator/rpc/apimiddleware/BUILD.bazel @@ -3,6 +3,7 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ + "custom_hooks.go", "endpoint_factory.go", "structs.go", ], @@ -16,11 +17,17 @@ go_library( go_test( name = "go_default_test", - srcs = ["structs_test.go"], + srcs = [ + "custom_hooks_test.go", + "structs_test.go", + ], embed = [":go_default_library"], deps = [ + "//api/gateway/apimiddleware:go_default_library", "//config/fieldparams:go_default_library", "//proto/eth/service:go_default_library", + "//testing/assert:go_default_library", "//testing/require:go_default_library", + "@com_github_pkg_errors//:go_default_library", ], ) diff --git a/validator/rpc/apimiddleware/custom_hooks.go b/validator/rpc/apimiddleware/custom_hooks.go new file mode 100644 index 0000000000..a00dd91345 --- /dev/null +++ b/validator/rpc/apimiddleware/custom_hooks.go @@ -0,0 +1,39 @@ +package apimiddleware + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "strconv" + + "github.com/prysmaticlabs/prysm/v4/api/gateway/apimiddleware" +) + +// "/eth/v1/validator/{pubkey}/voluntary_exit" POST expects epoch as a query param. +// This hook adds the query param to the body so that it is a valid POST request as +// grpc-gateway does not handle query params in POST requests. +func setVoluntaryExitEpoch( + endpoint *apimiddleware.Endpoint, + _ http.ResponseWriter, + req *http.Request, +) (apimiddleware.RunDefault, apimiddleware.ErrorJson) { + if _, ok := endpoint.PostRequest.(*SetVoluntaryExitRequestJson); ok { + var epoch = req.URL.Query().Get("epoch") + // To handle the request without the query param + if epoch == "" { + epoch = "0" + } + _, err := strconv.ParseUint(epoch, 10, 64) + if err != nil { + return false, apimiddleware.InternalServerErrorWithMessage(err, "invalid epoch") + } + j := &SetVoluntaryExitRequestJson{Epoch: epoch} + b, err := json.Marshal(j) + if err != nil { + return false, apimiddleware.InternalServerErrorWithMessage(err, "could not marshal epoch") + } + req.Body = io.NopCloser(bytes.NewReader(b)) + } + return true, nil +} diff --git a/validator/rpc/apimiddleware/custom_hooks_test.go b/validator/rpc/apimiddleware/custom_hooks_test.go new file mode 100644 index 0000000000..dbaa9a6487 --- /dev/null +++ b/validator/rpc/apimiddleware/custom_hooks_test.go @@ -0,0 +1,49 @@ +package apimiddleware + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http/httptest" + "testing" + + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v4/api/gateway/apimiddleware" + "github.com/prysmaticlabs/prysm/v4/testing/assert" + "github.com/prysmaticlabs/prysm/v4/testing/require" +) + +func TestSetVoluntaryExitEpoch(t *testing.T) { + t.Run("ok", func(t *testing.T) { + endpoint := &apimiddleware.Endpoint{ + PostRequest: &SetVoluntaryExitRequestJson{}, + } + epoch := "300" + + var body bytes.Buffer + request := httptest.NewRequest("POST", fmt.Sprintf("http://foo.example?epoch=%s", epoch), &body) + + runDefault, errJson := setVoluntaryExitEpoch(endpoint, nil, request) + require.Equal(t, true, errJson == nil) + assert.Equal(t, apimiddleware.RunDefault(true), runDefault) + + var b SetVoluntaryExitRequestJson + err := json.NewDecoder(request.Body).Decode(&b) + require.NoError(t, err) + require.Equal(t, epoch, b.Epoch) + }) + t.Run("invalid query returns error", func(t *testing.T) { + endpoint := &apimiddleware.Endpoint{ + PostRequest: &SetVoluntaryExitRequestJson{}, + } + epoch := "/12" + var body bytes.Buffer + request := httptest.NewRequest("POST", fmt.Sprintf("http://foo.example?epoch=%s", epoch), &body) + + runDefault, errJson := setVoluntaryExitEpoch(endpoint, nil, request) + assert.NotNil(t, errJson) + assert.Equal(t, apimiddleware.RunDefault(false), runDefault) + err := errors.New(errJson.Msg()) + assert.ErrorContains(t, "invalid epoch", err) + }) +} diff --git a/validator/rpc/apimiddleware/endpoint_factory.go b/validator/rpc/apimiddleware/endpoint_factory.go index 50a6f875c6..92e92f6308 100644 --- a/validator/rpc/apimiddleware/endpoint_factory.go +++ b/validator/rpc/apimiddleware/endpoint_factory.go @@ -20,6 +20,7 @@ func (*ValidatorEndpointFactory) Paths() []string { "/eth/v1/remotekeys", "/eth/v1/validator/{pubkey}/feerecipient", "/eth/v1/validator/{pubkey}/gas_limit", + "/eth/v1/validator/{pubkey}/voluntary_exit", } } @@ -47,6 +48,12 @@ func (*ValidatorEndpointFactory) Create(path string) (*apimiddleware.Endpoint, e endpoint.GetResponse = &GetGasLimitResponseJson{} endpoint.PostRequest = &SetGasLimitRequestJson{} endpoint.DeleteRequest = &DeleteGasLimitRequestJson{} + case "/eth/v1/validator/{pubkey}/voluntary_exit": + endpoint.PostRequest = &SetVoluntaryExitRequestJson{} + endpoint.PostResponse = &SetVoluntaryExitResponseJson{} + endpoint.Hooks = apimiddleware.HookCollection{ + OnPreDeserializeRequestBodyIntoContainer: setVoluntaryExitEpoch, + } default: return nil, errors.New("invalid path") } diff --git a/validator/rpc/apimiddleware/structs.go b/validator/rpc/apimiddleware/structs.go index 6f3937c12d..9c80f1e064 100644 --- a/validator/rpc/apimiddleware/structs.go +++ b/validator/rpc/apimiddleware/structs.go @@ -100,3 +100,22 @@ type SetGasLimitRequestJson struct { type DeleteGasLimitRequestJson struct { Pubkey string `json:"pubkey" hex:"true"` } + +type SetVoluntaryExitRequestJson struct { + Pubkey string `json:"pubkey" hex:"true"` + Epoch string `json:"epoch"` +} + +type SetVoluntaryExitResponseJson struct { + SignedVoluntaryExit *SignedVoluntaryExitJson `json:"data"` +} + +type SignedVoluntaryExitJson struct { + VoluntaryExit *VoluntaryExitJson `json:"message"` + Signature string `json:"signature" hex:"true"` +} + +type VoluntaryExitJson struct { + Epoch string `json:"epoch"` + ValidatorIndex string `json:"validator_index"` +} diff --git a/validator/rpc/standard_api.go b/validator/rpc/standard_api.go index b40a26b827..19b38edd6e 100644 --- a/validator/rpc/standard_api.go +++ b/validator/rpc/standard_api.go @@ -16,6 +16,7 @@ import ( "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" ethpbservice "github.com/prysmaticlabs/prysm/v4/proto/eth/service" eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v4/validator/client" "github.com/prysmaticlabs/prysm/v4/validator/keymanager" "github.com/prysmaticlabs/prysm/v4/validator/keymanager/derived" slashingprotection "github.com/prysmaticlabs/prysm/v4/validator/slashing-protection-history" @@ -24,6 +25,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" ) // ListKeystores implements the standard validator key management API. @@ -679,3 +681,51 @@ func validatePublicKey(pubkey []byte) error { } return nil } + +// SetVoluntaryExit creates a signed voluntary exit message and returns a VoluntaryExit object. +func (s *Server) SetVoluntaryExit(ctx context.Context, req *ethpbservice.SetVoluntaryExitRequest) (*ethpbservice.SetVoluntaryExitResponse, error) { + if s.validatorService == nil { + return nil, status.Error(codes.FailedPrecondition, "Validator service not ready") + } + if err := validatePublicKey(req.Pubkey); err != nil { + return nil, status.Error(codes.FailedPrecondition, err.Error()) + } + if s.wallet == nil { + return nil, status.Error(codes.FailedPrecondition, "No wallet found") + } + km, err := s.validatorService.Keymanager() + if err != nil { + return nil, err + } + if req.Epoch == 0 { + genesisResponse, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not create voluntary exit: %v", err) + } + epoch, err := client.CurrentEpoch(genesisResponse.GenesisTime) + if err != nil { + return nil, status.Errorf(codes.Internal, "gRPC call to get genesis time failed: %v", err) + } + req.Epoch = epoch + } + sve, err := client.CreateSignedVoluntaryExit( + ctx, + s.beaconNodeValidatorClient, + km.Sign, + req.Pubkey, + req.Epoch, + ) + if err != nil { + return nil, status.Errorf(codes.Internal, "Could not create voluntary exit: %v", err) + } + + return ðpbservice.SetVoluntaryExitResponse{ + Data: ðpbservice.SetVoluntaryExitResponse_SignedVoluntaryExit{ + Message: ðpbservice.SetVoluntaryExitResponse_SignedVoluntaryExit_VoluntaryExit{ + Epoch: uint64(sve.Exit.Epoch), + ValidatorIndex: uint64(sve.Exit.ValidatorIndex), + }, + Signature: sve.Signature, + }, + }, nil +} diff --git a/validator/rpc/standard_api_test.go b/validator/rpc/standard_api_test.go index 95a7ebd8dc..586ca711d2 100644 --- a/validator/rpc/standard_api_test.go +++ b/validator/rpc/standard_api_test.go @@ -1,12 +1,14 @@ package rpc import ( + "bytes" "context" "encoding/hex" "encoding/json" "errors" "fmt" "testing" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -17,6 +19,7 @@ import ( fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" "github.com/prysmaticlabs/prysm/v4/config/params" validatorserviceconfig "github.com/prysmaticlabs/prysm/v4/config/validator/service" + "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/consensus-types/validator" "github.com/prysmaticlabs/prysm/v4/crypto/bls" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" @@ -41,6 +44,8 @@ import ( keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/timestamppb" ) func TestServer_ListKeystores(t *testing.T) { @@ -1540,3 +1545,116 @@ func TestServer_DeleteGasLimit(t *testing.T) { }) } } + +func TestServer_SetVoluntaryExit(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ctx := grpc.NewContextWithServerTransportStream(context.Background(), &runtime.ServerTransportStream{}) + defaultWalletPath = setupWalletDir(t) + opts := []accounts.Option{ + accounts.WithWalletDir(defaultWalletPath), + accounts.WithKeymanagerType(keymanager.Derived), + accounts.WithWalletPassword(strongPass), + accounts.WithSkipMnemonicConfirm(true), + } + acc, err := accounts.NewCLIManager(opts...) + require.NoError(t, err) + w, err := acc.WalletCreate(ctx) + require.NoError(t, err) + km, err := w.InitializeKeymanager(ctx, iface.InitKeymanagerConfig{ListenForChanges: false}) + require.NoError(t, err) + + m := &mock.MockValidator{Km: km} + vs, err := client.NewValidatorService(ctx, &client.Config{ + Validator: m, + }) + require.NoError(t, err) + + dr, ok := km.(*derived.Keymanager) + require.Equal(t, true, ok) + err = dr.RecoverAccountsFromMnemonic(ctx, mocks.TestMnemonic, derived.DefaultMnemonicLanguage, "", 1) + require.NoError(t, err) + pubKeys, err := dr.FetchValidatingPublicKeys(ctx) + require.NoError(t, err) + + beaconClient := validatormock.NewMockValidatorClient(ctrl) + mockNodeClient := validatormock.NewMockNodeClient(ctrl) + // Any time in the past will suffice + genesisTime := ×tamppb.Timestamp{ + Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(), + } + + beaconClient.EXPECT().ValidatorIndex(gomock.Any(), ð.ValidatorIndexRequest{PublicKey: pubKeys[0][:]}). + Times(3). + Return(ð.ValidatorIndexResponse{Index: 2}, nil) + + beaconClient.EXPECT().DomainData( + gomock.Any(), // ctx + gomock.Any(), // epoch + ).Times(3). + Return(ð.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/) + + mockNodeClient.EXPECT(). + GetGenesis(gomock.Any(), gomock.Any()). + Times(3). + Return(ð.Genesis{GenesisTime: genesisTime}, nil) + + s := &Server{ + validatorService: vs, + beaconNodeValidatorClient: beaconClient, + wallet: w, + beaconNodeClient: mockNodeClient, + } + + type want struct { + epoch primitives.Epoch + validatorIndex uint64 + signature []byte + } + + tests := []struct { + name string + pubkey []byte + epoch primitives.Epoch + w want + }{ + { + name: "Ok: with epoch", + epoch: 30000000, + w: want{ + epoch: 30000000, + validatorIndex: 2, + signature: []uint8{175, 157, 5, 134, 253, 2, 193, 35, 176, 43, 217, 36, 39, 240, 24, 79, 207, 133, 150, 7, 237, 16, 54, 244, 64, 27, 244, 17, 8, 225, 140, 1, 172, 24, 35, 95, 178, 116, 172, 213, 113, 182, 193, 61, 192, 65, 162, 253, 19, 202, 111, 164, 195, 215, 0, 205, 95, 7, 30, 251, 244, 157, 210, 155, 238, 30, 35, 219, 177, 232, 174, 62, 218, 69, 23, 249, 180, 140, 60, 29, 190, 249, 229, 95, 235, 236, 81, 33, 60, 4, 201, 227, 70, 239, 167, 2}, + }, + }, + { + name: "Ok: epoch not set", + w: want{ + epoch: 0, + validatorIndex: 2, + signature: []uint8{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resp, err := s.SetVoluntaryExit(ctx, ðpbservice.SetVoluntaryExitRequest{Pubkey: pubKeys[0][:], Epoch: tt.epoch}) + require.NoError(t, err) + if tt.w.epoch == 0 { + genesisResponse, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{}) + require.NoError(t, err) + tt.w.epoch, err = client.CurrentEpoch(genesisResponse.GenesisTime) + require.NoError(t, err) + resp2, err := s.SetVoluntaryExit(ctx, ðpbservice.SetVoluntaryExitRequest{Pubkey: pubKeys[0][:], Epoch: tt.epoch}) + require.NoError(t, err) + tt.w.signature = resp2.Data.Signature + } + require.Equal(t, uint64(tt.w.epoch), resp.Data.Message.Epoch) + require.Equal(t, tt.w.validatorIndex, resp.Data.Message.ValidatorIndex) + require.NotEmpty(t, resp.Data.Signature) + ok = bytes.Equal(tt.w.signature, resp.Data.Signature) + require.Equal(t, true, ok) + }) + } +}