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