From e2f4b50e25ab87b0268454d13305c4410ea34095 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 11 Dec 2023 14:32:22 +0400 Subject: [PATCH] object: Separate op for node-to-node replication Previously, object replication between container nodes was performed via `ObjectService.Put` RPC. This approach had a number of problems: - system operations inside the container were mixed with user requests - it was not possible to send an object in one message To improve this, a separate `Replicate` RPC is added. It's intended for usage by nodes of the containers only to comply with their storage policies. Within a request, any object is packaged into one message. Only the object itself is signed, which simplifies and speeds up the formation and processing of the request. Signed-off-by: Leonard Lyubich --- object/service.proto | 34 ++++++++++++++++++++++++++++++++ proto-docs/object.md | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/object/service.proto b/object/service.proto index c1f9622..dbbb8af 100644 --- a/object/service.proto +++ b/object/service.proto @@ -8,6 +8,7 @@ option csharp_namespace = "Neo.FileStorage.API.Object"; import "object/types.proto"; import "refs/types.proto"; import "session/types.proto"; +import "status/types.proto"; // `ObjectService` provides API for manipulating objects. Object operations do // not affect the sidechain and are only served by nodes in p2p style. @@ -218,6 +219,23 @@ service ObjectService { // - **TOKEN_EXPIRED** (4097, SECTION_SESSION): \ // provided session token has expired. rpc GetRangeHash(GetRangeHashRequest) returns (GetRangeHashResponse); + + // Save replica of the object on the NeoFS storage node. Both client and + // server must authenticate NeoFS storage nodes matching storage policy of + // the container referenced by the replicated object. Thus, this operation is + // purely system: regular users should not pay attention to it but use Put. + // + // Statuses: + // - **OK** (0, SECTION_SUCCESS): \ + // the object has been successfully replicated; + // - **INTERNAL_SERVER_ERROR** (1024, SECTION_FAILURE_COMMON): \ + // internal server error described in the text message; + // - **ACCESS_DENIED** (2048, SECTION_OBJECT): \ + // the client does not authenticate any NeoFS storage node matching storage + // policy of the container referenced by the replicated object + // - **CONTAINER_NOT_FOUND** (3072, SECTION_CONTAINER): \ + // the container to which the replicated object is associated was not found. + rpc Replicate(ReplicateRequest) returns (ReplicateResponse); } // GET object request @@ -688,3 +706,19 @@ message GetRangeHashResponse { // transmission. neo.fs.v2.session.ResponseVerificationHeader verify_header = 3; } + +// Replicate RPC request +message ReplicateRequest { + // Object to be replicated. + neo.fs.v2.object.Object object = 1; + + // Signature of all other request fields serialized in Protocol Buffers v3 + // format in ascending order of fields. + neo.fs.v2.refs.Signature signature = 2; +} + +// Replicate RPC response +message ReplicateResponse { + // Operation execution status with one of the enumerated codes. + neo.fs.v2.status.Status status = 1; +} diff --git a/proto-docs/object.md b/proto-docs/object.md index b46673a..7913487 100644 --- a/proto-docs/object.md +++ b/proto-docs/object.md @@ -36,6 +36,8 @@ - [PutResponse](#neo.fs.v2.object.PutResponse) - [PutResponse.Body](#neo.fs.v2.object.PutResponse.Body) - [Range](#neo.fs.v2.object.Range) + - [ReplicateRequest](#neo.fs.v2.object.ReplicateRequest) + - [ReplicateResponse](#neo.fs.v2.object.ReplicateResponse) - [SearchRequest](#neo.fs.v2.object.SearchRequest) - [SearchRequest.Body](#neo.fs.v2.object.SearchRequest.Body) - [SearchRequest.Body.Filter](#neo.fs.v2.object.SearchRequest.Body.Filter) @@ -80,6 +82,7 @@ rpc Head(HeadRequest) returns (HeadResponse); rpc Search(SearchRequest) returns (stream SearchResponse); rpc GetRange(GetRangeRequest) returns (stream GetRangeResponse); rpc GetRangeHash(GetRangeHashRequest) returns (GetRangeHashResponse); +rpc Replicate(ReplicateRequest) returns (ReplicateResponse); ``` @@ -318,6 +321,27 @@ Statuses: | Name | Input | Output | | ---- | ----- | ------ | | GetRangeHash | [GetRangeHashRequest](#neo.fs.v2.object.GetRangeHashRequest) | [GetRangeHashResponse](#neo.fs.v2.object.GetRangeHashResponse) | +#### Method Replicate + +Save replica of the object on the NeoFS storage node. Both client and +server must authenticate NeoFS storage nodes matching storage policy of +the container referenced by the replicated object. Thus, this operation is +purely system: regular users should not pay attention to it but use Put. + +Statuses: +- **OK** (0, SECTION_SUCCESS): \ + the object has been successfully replicated; +- **INTERNAL_SERVER_ERROR** (1024, SECTION_FAILURE_COMMON): \ + internal server error described in the text message; +- **ACCESS_DENIED** (2048, SECTION_OBJECT): \ + the client does not authenticate any NeoFS storage node matching storage + policy of the container referenced by the replicated object +- **CONTAINER_NOT_FOUND** (3072, SECTION_CONTAINER): \ + the container to which the replicated object is associated was not found. + +| Name | Input | Output | +| ---- | ----- | ------ | +| Replicate | [ReplicateRequest](#neo.fs.v2.object.ReplicateRequest) | [ReplicateResponse](#neo.fs.v2.object.ReplicateResponse) | @@ -687,6 +711,29 @@ Object payload range. Ranges of zero length SHOULD be considered as invalid. | length | [uint64](#uint64) | | Length in bytes of the object payload range | + + +### Message ReplicateRequest +Replicate RPC request + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| object | [Object](#neo.fs.v2.object.Object) | | Object to be replicated. | +| signature | [neo.fs.v2.refs.Signature](#neo.fs.v2.refs.Signature) | | Signature of all other request fields serialized in Protocol Buffers v3 format in ascending order of fields. | + + + + +### Message ReplicateResponse +Replicate RPC response + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| status | [neo.fs.v2.status.Status](#neo.fs.v2.status.Status) | | Operation execution status with one of the enumerated codes. | + + ### Message SearchRequest