diff --git a/object/service.proto b/object/service.proto
index c1f9622..d36ddf2 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,12 @@ 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.
+ rpc Replicate(ReplicateRequest) returns (ReplicateResponse);
}
// GET object request
@@ -688,3 +695,37 @@ 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 status codes.
+ enum Code {
+ // Object has been replicated successfully.
+ OK = 0;
+ // Internal server error described in the text message.
+ INTERNAL = 1;
+ // Request message format violation.
+ BAD_REQUEST = 2;
+ // Request signature is missing or incorrect.
+ UNAUTHORIZED = 3;
+ // The client does not authenticate any NeoFS storage node matching storage
+ // policy of the container referenced by the replicated object.
+ FORBIDDEN = 4;
+ // The server is not a NeoFS storage node matching storage policy of the
+ // container referenced by the replicated object.
+ PRECONDITION_FAILED = 5;
+ }
+
+ // 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..0ec42e8 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,16 @@ 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.
+
+| Name | Input | Output |
+| ---- | ----- | ------ |
+| Replicate | [ReplicateRequest](#neo.fs.v2.object.ReplicateRequest) | [ReplicateResponse](#neo.fs.v2.object.ReplicateResponse) |
@@ -687,6 +700,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
@@ -804,6 +840,22 @@ Object Search response body
+
+
+
+### ReplicateResponse.Code
+Operation status codes.
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| OK | 0 | Object has been replicated successfully. |
+| INTERNAL | 1 | Internal server error described in the text message. |
+| BAD_REQUEST | 2 | Request message format violation. |
+| UNAUTHORIZED | 3 | Request signature is missing or incorrect. |
+| FORBIDDEN | 4 | The client does not authenticate any NeoFS storage node matching storage policy of the container referenced by the replicated object. |
+| PRECONDITION_FAILED | 5 | The server is not a NeoFS storage node matching storage policy of the container referenced by the replicated object. |
+
+