diff --git a/cmd/frostfs-cli/modules/control/ir.go b/cmd/frostfs-cli/modules/control/ir.go index e89dda076..ae3f8502c 100644 --- a/cmd/frostfs-cli/modules/control/ir.go +++ b/cmd/frostfs-cli/modules/control/ir.go @@ -10,6 +10,8 @@ var irCmd = &cobra.Command{ func initControlIRCmd() { irCmd.AddCommand(tickEpochCmd) + irCmd.AddCommand(removeNodeCmd) initControlIRTickEpochCmd() + initControlIRRemoveNodeCmd() } diff --git a/cmd/frostfs-cli/modules/control/ir_remove_node.go b/cmd/frostfs-cli/modules/control/ir_remove_node.go new file mode 100644 index 000000000..f5b968b7f --- /dev/null +++ b/cmd/frostfs-cli/modules/control/ir_remove_node.go @@ -0,0 +1,58 @@ +package control + +import ( + "encoding/hex" + "errors" + + rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client" + "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" + commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" + ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" + ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server" + "github.com/spf13/cobra" +) + +var removeNodeCmd = &cobra.Command{ + Use: "remove-node", + Short: "Forces a node removal from netmap", + Long: "Forces a node removal from netmap via a notary request. It should be executed on other IR nodes as well.", + Run: removeNode, +} + +func initControlIRRemoveNodeCmd() { + initControlFlags(removeNodeCmd) + + flags := removeNodeCmd.Flags() + flags.String("node", "", "Node public key as a hex string") + _ = removeNodeCmd.MarkFlagRequired("node") +} + +func removeNode(cmd *cobra.Command, _ []string) { + pk := key.Get(cmd) + c := getClient(cmd, pk) + + nodeKeyStr, _ := cmd.Flags().GetString("node") + if len(nodeKeyStr) == 0 { + commonCmd.ExitOnErr(cmd, "parsing node public key: ", errors.New("key cannot be empty")) + } + nodeKey, err := hex.DecodeString(nodeKeyStr) + commonCmd.ExitOnErr(cmd, "can't decode node public key: %w", err) + + req := new(ircontrol.RemoveNodeRequest) + req.SetBody(&ircontrol.RemoveNodeRequest_Body{ + Key: nodeKey, + }) + + commonCmd.ExitOnErr(cmd, "could not sign request: %w", ircontrolsrv.SignMessage(pk, req)) + + var resp *ircontrol.RemoveNodeResponse + err = c.ExecRaw(func(client *rawclient.Client) error { + resp, err = ircontrol.RemoveNode(client, req) + return err + }) + commonCmd.ExitOnErr(cmd, "rpc error: %w", err) + + verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) + + cmd.Println("Node removed") +} diff --git a/pkg/morph/client/netmap/add_peer.go b/pkg/morph/client/netmap/peer.go similarity index 70% rename from pkg/morph/client/netmap/add_peer.go rename to pkg/morph/client/netmap/peer.go index dc6c25540..7ceaa0250 100644 --- a/pkg/morph/client/netmap/add_peer.go +++ b/pkg/morph/client/netmap/peer.go @@ -41,3 +41,19 @@ func (c *Client) AddPeer(p AddPeerPrm) error { } return nil } + +// ForceRemovePeer marks the given peer as offline via a notary control transaction. +func (c *Client) ForceRemovePeer(nodeInfo netmap.NodeInfo) error { + if !c.client.WithNotary() { + return fmt.Errorf("peer can be forcefully removed only in notary environment") + } + + prm := UpdatePeerPrm{} + prm.SetKey(nodeInfo.PublicKey()) + prm.SetControlTX(true) + + if err := c.UpdatePeerState(prm); err != nil { + return fmt.Errorf("updating peer state: %v", err) + } + return nil +} diff --git a/pkg/services/control/ir/rpc.go b/pkg/services/control/ir/rpc.go index 6b2234954..1b635c149 100644 --- a/pkg/services/control/ir/rpc.go +++ b/pkg/services/control/ir/rpc.go @@ -11,6 +11,7 @@ const serviceName = "ircontrol.ControlService" const ( rpcHealthCheck = "HealthCheck" rpcTickEpoch = "TickEpoch" + rpcRemoveNode = "RemoveNode" ) // HealthCheck executes ControlService.HealthCheck RPC. @@ -31,6 +32,14 @@ func TickEpoch( return sendUnary[TickEpochRequest, TickEpochResponse](cli, rpcTickEpoch, req, opts...) } +func RemoveNode( + cli *client.Client, + req *RemoveNodeRequest, + opts ...client.CallOption, +) (*RemoveNodeResponse, error) { + return sendUnary[RemoveNodeRequest, RemoveNodeResponse](cli, rpcRemoveNode, req, opts...) +} + func sendUnary[I, O grpc.Message](cli *client.Client, rpcName string, req *I, opts ...client.CallOption) (*O, error) { var resp O wResp := &responseWrapper[*O]{ diff --git a/pkg/services/control/ir/server/calls.go b/pkg/services/control/ir/server/calls.go index 56e2e3f79..680d1e606 100644 --- a/pkg/services/control/ir/server/calls.go +++ b/pkg/services/control/ir/server/calls.go @@ -1,9 +1,11 @@ package control import ( + "bytes" "context" "fmt" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" control "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -57,3 +59,43 @@ func (s *Server) TickEpoch(_ context.Context, req *control.TickEpochRequest) (*c return resp, nil } + +// RemoveNode forces a node removal. +// +// If request is not signed with a key from white list, permission error returns. +func (s *Server) RemoveNode(_ context.Context, req *control.RemoveNodeRequest) (*control.RemoveNodeResponse, error) { + if err := s.isValidRequest(req); err != nil { + return nil, status.Error(codes.PermissionDenied, err.Error()) + } + + resp := new(control.RemoveNodeResponse) + resp.SetBody(new(control.RemoveNodeResponse_Body)) + + nm, err := s.netmapClient.NetMap() + if err != nil { + return nil, fmt.Errorf("getting netmap: %w", err) + } + var nodeInfo netmap.NodeInfo + for _, info := range nm.Nodes() { + if bytes.Equal(info.PublicKey(), req.GetBody().GetKey()) { + nodeInfo = info + break + } + } + if len(nodeInfo.PublicKey()) == 0 { + return nil, status.Error(codes.NotFound, "no such node") + } + if nodeInfo.IsOffline() { + return nil, status.Error(codes.FailedPrecondition, "node is already offline") + } + + if err := s.netmapClient.ForceRemovePeer(nodeInfo); err != nil { + return nil, fmt.Errorf("forcing node removal: %w", err) + } + + if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return resp, nil +} diff --git a/pkg/services/control/ir/service.go b/pkg/services/control/ir/service.go index 1aaec2c87..b2db2b43a 100644 --- a/pkg/services/control/ir/service.go +++ b/pkg/services/control/ir/service.go @@ -32,3 +32,15 @@ func (x *TickEpochResponse) SetBody(v *TickEpochResponse_Body) { x.Body = v } } + +func (x *RemoveNodeRequest) SetBody(v *RemoveNodeRequest_Body) { + if x != nil { + x.Body = v + } +} + +func (x *RemoveNodeResponse) SetBody(v *RemoveNodeResponse_Body) { + if x != nil { + x.Body = v + } +} diff --git a/pkg/services/control/ir/service.pb.go b/pkg/services/control/ir/service.pb.go index 84acdfc82..bec74a3be 100644 --- a/pkg/services/control/ir/service.pb.go +++ b/pkg/services/control/ir/service.pb.go @@ -248,6 +248,116 @@ func (x *TickEpochResponse) GetSignature() *Signature { return nil } +type RemoveNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *RemoveNodeRequest_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *RemoveNodeRequest) Reset() { + *x = RemoveNodeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveNodeRequest) ProtoMessage() {} + +func (x *RemoveNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[4] + 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 RemoveNodeRequest.ProtoReflect.Descriptor instead. +func (*RemoveNodeRequest) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{4} +} + +func (x *RemoveNodeRequest) GetBody() *RemoveNodeRequest_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *RemoveNodeRequest) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type RemoveNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body *RemoveNodeResponse_Body `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *RemoveNodeResponse) Reset() { + *x = RemoveNodeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveNodeResponse) ProtoMessage() {} + +func (x *RemoveNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[5] + 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 RemoveNodeResponse.ProtoReflect.Descriptor instead. +func (*RemoveNodeResponse) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{5} +} + +func (x *RemoveNodeResponse) GetBody() *RemoveNodeResponse_Body { + if x != nil { + return x.Body + } + return nil +} + +func (x *RemoveNodeResponse) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + // Health check request body. type HealthCheckRequest_Body struct { state protoimpl.MessageState @@ -258,7 +368,7 @@ type HealthCheckRequest_Body struct { func (x *HealthCheckRequest_Body) Reset() { *x = HealthCheckRequest_Body{} if protoimpl.UnsafeEnabled { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[4] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -271,7 +381,7 @@ func (x *HealthCheckRequest_Body) String() string { func (*HealthCheckRequest_Body) ProtoMessage() {} func (x *HealthCheckRequest_Body) ProtoReflect() protoreflect.Message { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[4] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -300,7 +410,7 @@ type HealthCheckResponse_Body struct { func (x *HealthCheckResponse_Body) Reset() { *x = HealthCheckResponse_Body{} if protoimpl.UnsafeEnabled { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[5] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -313,7 +423,7 @@ func (x *HealthCheckResponse_Body) String() string { func (*HealthCheckResponse_Body) ProtoMessage() {} func (x *HealthCheckResponse_Body) ProtoReflect() protoreflect.Message { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[5] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -345,7 +455,7 @@ type TickEpochRequest_Body struct { func (x *TickEpochRequest_Body) Reset() { *x = TickEpochRequest_Body{} if protoimpl.UnsafeEnabled { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[6] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -358,7 +468,7 @@ func (x *TickEpochRequest_Body) String() string { func (*TickEpochRequest_Body) ProtoMessage() {} func (x *TickEpochRequest_Body) ProtoReflect() protoreflect.Message { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[6] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -383,7 +493,7 @@ type TickEpochResponse_Body struct { func (x *TickEpochResponse_Body) Reset() { *x = TickEpochResponse_Body{} if protoimpl.UnsafeEnabled { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[7] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -396,7 +506,7 @@ func (x *TickEpochResponse_Body) String() string { func (*TickEpochResponse_Body) ProtoMessage() {} func (x *TickEpochResponse_Body) ProtoReflect() protoreflect.Message { - mi := &file_pkg_services_control_ir_service_proto_msgTypes[7] + mi := &file_pkg_services_control_ir_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -412,6 +522,91 @@ func (*TickEpochResponse_Body) Descriptor() ([]byte, []int) { return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{3, 0} } +type RemoveNodeRequest_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *RemoveNodeRequest_Body) Reset() { + *x = RemoveNodeRequest_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveNodeRequest_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveNodeRequest_Body) ProtoMessage() {} + +func (x *RemoveNodeRequest_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[10] + 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 RemoveNodeRequest_Body.ProtoReflect.Descriptor instead. +func (*RemoveNodeRequest_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *RemoveNodeRequest_Body) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +type RemoveNodeResponse_Body struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RemoveNodeResponse_Body) Reset() { + *x = RemoveNodeResponse_Body{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveNodeResponse_Body) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveNodeResponse_Body) ProtoMessage() {} + +func (x *RemoveNodeResponse_Body) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_ir_service_proto_msgTypes[11] + 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 RemoveNodeResponse_Body.ProtoReflect.Descriptor instead. +func (*RemoveNodeResponse_Body) Descriptor() ([]byte, []int) { + return file_pkg_services_control_ir_service_proto_rawDescGZIP(), []int{5, 0} +} + var File_pkg_services_control_ir_service_proto protoreflect.FileDescriptor var file_pkg_services_control_ir_service_proto_rawDesc = []byte{ @@ -458,23 +653,46 @@ var file_pkg_services_control_ir_service_proto_rawDesc = []byte{ 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x32, 0xa6, 0x01, - 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x4c, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, - 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, - 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, - 0x0a, 0x09, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x69, 0x72, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, - 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, - 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, - 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x98, 0x01, + 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x18, + 0x0a, 0x04, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x88, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x36, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x42, 0x6f, 0x64, + 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x32, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x72, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x06, 0x0a, 0x04, 0x42, + 0x6f, 0x64, 0x79, 0x32, 0xf1, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x54, 0x69, 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, + 0x68, 0x12, 0x1b, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, + 0x63, 0x6b, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x54, 0x69, 0x63, 0x6b, 0x45, + 0x70, 0x6f, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0a, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x2e, 0x69, 0x72, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x69, 0x72, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x2e, 0x66, + 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, + 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2f, 0x69, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -489,38 +707,48 @@ func file_pkg_services_control_ir_service_proto_rawDescGZIP() []byte { return file_pkg_services_control_ir_service_proto_rawDescData } -var file_pkg_services_control_ir_service_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_pkg_services_control_ir_service_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_pkg_services_control_ir_service_proto_goTypes = []interface{}{ (*HealthCheckRequest)(nil), // 0: ircontrol.HealthCheckRequest (*HealthCheckResponse)(nil), // 1: ircontrol.HealthCheckResponse (*TickEpochRequest)(nil), // 2: ircontrol.TickEpochRequest (*TickEpochResponse)(nil), // 3: ircontrol.TickEpochResponse - (*HealthCheckRequest_Body)(nil), // 4: ircontrol.HealthCheckRequest.Body - (*HealthCheckResponse_Body)(nil), // 5: ircontrol.HealthCheckResponse.Body - (*TickEpochRequest_Body)(nil), // 6: ircontrol.TickEpochRequest.Body - (*TickEpochResponse_Body)(nil), // 7: ircontrol.TickEpochResponse.Body - (*Signature)(nil), // 8: ircontrol.Signature - (HealthStatus)(0), // 9: ircontrol.HealthStatus + (*RemoveNodeRequest)(nil), // 4: ircontrol.RemoveNodeRequest + (*RemoveNodeResponse)(nil), // 5: ircontrol.RemoveNodeResponse + (*HealthCheckRequest_Body)(nil), // 6: ircontrol.HealthCheckRequest.Body + (*HealthCheckResponse_Body)(nil), // 7: ircontrol.HealthCheckResponse.Body + (*TickEpochRequest_Body)(nil), // 8: ircontrol.TickEpochRequest.Body + (*TickEpochResponse_Body)(nil), // 9: ircontrol.TickEpochResponse.Body + (*RemoveNodeRequest_Body)(nil), // 10: ircontrol.RemoveNodeRequest.Body + (*RemoveNodeResponse_Body)(nil), // 11: ircontrol.RemoveNodeResponse.Body + (*Signature)(nil), // 12: ircontrol.Signature + (HealthStatus)(0), // 13: ircontrol.HealthStatus } var file_pkg_services_control_ir_service_proto_depIdxs = []int32{ - 4, // 0: ircontrol.HealthCheckRequest.body:type_name -> ircontrol.HealthCheckRequest.Body - 8, // 1: ircontrol.HealthCheckRequest.signature:type_name -> ircontrol.Signature - 5, // 2: ircontrol.HealthCheckResponse.body:type_name -> ircontrol.HealthCheckResponse.Body - 8, // 3: ircontrol.HealthCheckResponse.signature:type_name -> ircontrol.Signature - 6, // 4: ircontrol.TickEpochRequest.body:type_name -> ircontrol.TickEpochRequest.Body - 8, // 5: ircontrol.TickEpochRequest.signature:type_name -> ircontrol.Signature - 7, // 6: ircontrol.TickEpochResponse.body:type_name -> ircontrol.TickEpochResponse.Body - 8, // 7: ircontrol.TickEpochResponse.signature:type_name -> ircontrol.Signature - 9, // 8: ircontrol.HealthCheckResponse.Body.health_status:type_name -> ircontrol.HealthStatus - 0, // 9: ircontrol.ControlService.HealthCheck:input_type -> ircontrol.HealthCheckRequest - 2, // 10: ircontrol.ControlService.TickEpoch:input_type -> ircontrol.TickEpochRequest - 1, // 11: ircontrol.ControlService.HealthCheck:output_type -> ircontrol.HealthCheckResponse - 3, // 12: ircontrol.ControlService.TickEpoch:output_type -> ircontrol.TickEpochResponse - 11, // [11:13] is the sub-list for method output_type - 9, // [9:11] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 6, // 0: ircontrol.HealthCheckRequest.body:type_name -> ircontrol.HealthCheckRequest.Body + 12, // 1: ircontrol.HealthCheckRequest.signature:type_name -> ircontrol.Signature + 7, // 2: ircontrol.HealthCheckResponse.body:type_name -> ircontrol.HealthCheckResponse.Body + 12, // 3: ircontrol.HealthCheckResponse.signature:type_name -> ircontrol.Signature + 8, // 4: ircontrol.TickEpochRequest.body:type_name -> ircontrol.TickEpochRequest.Body + 12, // 5: ircontrol.TickEpochRequest.signature:type_name -> ircontrol.Signature + 9, // 6: ircontrol.TickEpochResponse.body:type_name -> ircontrol.TickEpochResponse.Body + 12, // 7: ircontrol.TickEpochResponse.signature:type_name -> ircontrol.Signature + 10, // 8: ircontrol.RemoveNodeRequest.body:type_name -> ircontrol.RemoveNodeRequest.Body + 12, // 9: ircontrol.RemoveNodeRequest.signature:type_name -> ircontrol.Signature + 11, // 10: ircontrol.RemoveNodeResponse.body:type_name -> ircontrol.RemoveNodeResponse.Body + 12, // 11: ircontrol.RemoveNodeResponse.signature:type_name -> ircontrol.Signature + 13, // 12: ircontrol.HealthCheckResponse.Body.health_status:type_name -> ircontrol.HealthStatus + 0, // 13: ircontrol.ControlService.HealthCheck:input_type -> ircontrol.HealthCheckRequest + 2, // 14: ircontrol.ControlService.TickEpoch:input_type -> ircontrol.TickEpochRequest + 4, // 15: ircontrol.ControlService.RemoveNode:input_type -> ircontrol.RemoveNodeRequest + 1, // 16: ircontrol.ControlService.HealthCheck:output_type -> ircontrol.HealthCheckResponse + 3, // 17: ircontrol.ControlService.TickEpoch:output_type -> ircontrol.TickEpochResponse + 5, // 18: ircontrol.ControlService.RemoveNode:output_type -> ircontrol.RemoveNodeResponse + 16, // [16:19] is the sub-list for method output_type + 13, // [13:16] 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 } func init() { file_pkg_services_control_ir_service_proto_init() } @@ -579,7 +807,7 @@ func file_pkg_services_control_ir_service_proto_init() { } } file_pkg_services_control_ir_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HealthCheckRequest_Body); i { + switch v := v.(*RemoveNodeRequest); i { case 0: return &v.state case 1: @@ -591,7 +819,7 @@ func file_pkg_services_control_ir_service_proto_init() { } } file_pkg_services_control_ir_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HealthCheckResponse_Body); i { + switch v := v.(*RemoveNodeResponse); i { case 0: return &v.state case 1: @@ -603,7 +831,7 @@ func file_pkg_services_control_ir_service_proto_init() { } } file_pkg_services_control_ir_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TickEpochRequest_Body); i { + switch v := v.(*HealthCheckRequest_Body); i { case 0: return &v.state case 1: @@ -615,6 +843,30 @@ func file_pkg_services_control_ir_service_proto_init() { } } file_pkg_services_control_ir_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckResponse_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_control_ir_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TickEpochRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_control_ir_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TickEpochResponse_Body); i { case 0: return &v.state @@ -626,6 +878,30 @@ func file_pkg_services_control_ir_service_proto_init() { return nil } } + file_pkg_services_control_ir_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveNodeRequest_Body); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_control_ir_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveNodeResponse_Body); 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{ @@ -633,7 +909,7 @@ func file_pkg_services_control_ir_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pkg_services_control_ir_service_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/services/control/ir/service.proto b/pkg/services/control/ir/service.proto index 5862e8fbd..d647db0df 100644 --- a/pkg/services/control/ir/service.proto +++ b/pkg/services/control/ir/service.proto @@ -12,6 +12,8 @@ service ControlService { rpc HealthCheck (HealthCheckRequest) returns (HealthCheckResponse); // Forces a new epoch to be signaled by the IR node with high probability. rpc TickEpoch (TickEpochRequest) returns (TickEpochResponse); + // Forces a node removal to be signaled by the IR node with high probability. + rpc RemoveNode (RemoveNodeRequest) returns (RemoveNodeResponse); } // Health check request. @@ -57,3 +59,19 @@ message TickEpochResponse { Body body = 1; Signature signature = 2; } + +message RemoveNodeRequest { + message Body{ + bytes key = 1; + } + + Body body = 1; + Signature signature = 2; +} + +message RemoveNodeResponse { + message Body{} + + Body body = 1; + Signature signature = 2; +} diff --git a/pkg/services/control/ir/service_frostfs.pb.go b/pkg/services/control/ir/service_frostfs.pb.go index d480f0b50..c93253105 100644 --- a/pkg/services/control/ir/service_frostfs.pb.go +++ b/pkg/services/control/ir/service_frostfs.pb.go @@ -296,3 +296,154 @@ func (x *TickEpochResponse) ReadSignedData(buf []byte) ([]byte, error) { func (x *TickEpochResponse) SetSignature(sig *Signature) { x.Signature = sig } + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveNodeRequest_Body) StableSize() (size int) { + size += proto.BytesSize(1, x.Key) + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveNodeRequest_Body) StableMarshal(buf []byte) []byte { + if x == nil { + return []byte{} + } + if buf == nil { + buf = make([]byte, x.StableSize()) + } + var offset int + offset += proto.BytesMarshal(1, buf[offset:], x.Key) + return buf +} + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveNodeRequest) StableSize() (size int) { + size += proto.NestedStructureSize(1, x.Body) + size += proto.NestedStructureSize(2, x.Signature) + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveNodeRequest) StableMarshal(buf []byte) []byte { + if x == nil { + return []byte{} + } + if buf == nil { + buf = make([]byte, x.StableSize()) + } + var offset int + offset += proto.NestedStructureMarshal(1, buf[offset:], x.Body) + offset += proto.NestedStructureMarshal(2, buf[offset:], x.Signature) + return buf +} + +// ReadSignedData fills buf with signed data of x. +// If buffer length is less than x.SignedDataSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same signed data. +func (x *RemoveNodeRequest) SignedDataSize() int { + return x.GetBody().StableSize() +} + +// SignedDataSize returns size of the request signed data in bytes. +// +// Structures with the same field values have the same signed data size. +func (x *RemoveNodeRequest) ReadSignedData(buf []byte) ([]byte, error) { + return x.GetBody().StableMarshal(buf), nil +} + +func (x *RemoveNodeRequest) SetSignature(sig *Signature) { + x.Signature = sig +} + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveNodeResponse_Body) StableSize() (size int) { + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveNodeResponse_Body) StableMarshal(buf []byte) []byte { + return buf +} + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *RemoveNodeResponse) StableSize() (size int) { + size += proto.NestedStructureSize(1, x.Body) + size += proto.NestedStructureSize(2, x.Signature) + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *RemoveNodeResponse) StableMarshal(buf []byte) []byte { + if x == nil { + return []byte{} + } + if buf == nil { + buf = make([]byte, x.StableSize()) + } + var offset int + offset += proto.NestedStructureMarshal(1, buf[offset:], x.Body) + offset += proto.NestedStructureMarshal(2, buf[offset:], x.Signature) + return buf +} + +// ReadSignedData fills buf with signed data of x. +// If buffer length is less than x.SignedDataSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same signed data. +func (x *RemoveNodeResponse) SignedDataSize() int { + return x.GetBody().StableSize() +} + +// SignedDataSize returns size of the request signed data in bytes. +// +// Structures with the same field values have the same signed data size. +func (x *RemoveNodeResponse) ReadSignedData(buf []byte) ([]byte, error) { + return x.GetBody().StableMarshal(buf), nil +} + +func (x *RemoveNodeResponse) SetSignature(sig *Signature) { + x.Signature = sig +} diff --git a/pkg/services/control/ir/service_grpc.pb.go b/pkg/services/control/ir/service_grpc.pb.go index 700d340ca..6ba214da0 100644 --- a/pkg/services/control/ir/service_grpc.pb.go +++ b/pkg/services/control/ir/service_grpc.pb.go @@ -26,6 +26,8 @@ type ControlServiceClient interface { HealthCheck(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) // Forces a new epoch to be signaled by the IR node with high probability. TickEpoch(ctx context.Context, in *TickEpochRequest, opts ...grpc.CallOption) (*TickEpochResponse, error) + // Forces a node removal to be signaled by the IR node with high probability. + RemoveNode(ctx context.Context, in *RemoveNodeRequest, opts ...grpc.CallOption) (*RemoveNodeResponse, error) } type controlServiceClient struct { @@ -54,6 +56,15 @@ func (c *controlServiceClient) TickEpoch(ctx context.Context, in *TickEpochReque return out, nil } +func (c *controlServiceClient) RemoveNode(ctx context.Context, in *RemoveNodeRequest, opts ...grpc.CallOption) (*RemoveNodeResponse, error) { + out := new(RemoveNodeResponse) + err := c.cc.Invoke(ctx, "/ircontrol.ControlService/RemoveNode", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ControlServiceServer is the server API for ControlService service. // All implementations should embed UnimplementedControlServiceServer // for forward compatibility @@ -62,6 +73,8 @@ type ControlServiceServer interface { HealthCheck(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) // Forces a new epoch to be signaled by the IR node with high probability. TickEpoch(context.Context, *TickEpochRequest) (*TickEpochResponse, error) + // Forces a node removal to be signaled by the IR node with high probability. + RemoveNode(context.Context, *RemoveNodeRequest) (*RemoveNodeResponse, error) } // UnimplementedControlServiceServer should be embedded to have forward compatible implementations. @@ -74,6 +87,9 @@ func (UnimplementedControlServiceServer) HealthCheck(context.Context, *HealthChe func (UnimplementedControlServiceServer) TickEpoch(context.Context, *TickEpochRequest) (*TickEpochResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method TickEpoch not implemented") } +func (UnimplementedControlServiceServer) RemoveNode(context.Context, *RemoveNodeRequest) (*RemoveNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveNode not implemented") +} // UnsafeControlServiceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ControlServiceServer will @@ -122,6 +138,24 @@ func _ControlService_TickEpoch_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _ControlService_RemoveNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServiceServer).RemoveNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ircontrol.ControlService/RemoveNode", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServiceServer).RemoveNode(ctx, req.(*RemoveNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ControlService_ServiceDesc is the grpc.ServiceDesc for ControlService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -137,6 +171,10 @@ var ControlService_ServiceDesc = grpc.ServiceDesc{ MethodName: "TickEpoch", Handler: _ControlService_TickEpoch_Handler, }, + { + MethodName: "RemoveNode", + Handler: _ControlService_RemoveNode_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "pkg/services/control/ir/service.proto",