diff --git a/object/service.proto b/object/service.proto index 0a03383..6f13d55 100644 --- a/object/service.proto +++ b/object/service.proto @@ -9,111 +9,132 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto"; option (gogoproto.stable_marshaler_all) = true; +// Object service provides API for manipulating with the object. service Service { - // Get the object from a container + + // Get the object from container. Response uses gRPC stream. First response + // message carry object of requested address. Chunk messages are parts of + // the object's payload if it is needed. All messages except first carry + // chunks. Requested object can be restored by concatenation of object + // message payload and all chunks keeping receiving order. rpc Get(GetRequest) returns (stream GetResponse); - // Put the object into a container + // Put the object into container. Request uses gRPC stream. First message + // SHOULD BE type of PutHeader. Container id and Owner id of object SHOULD + // BE set. Session token SHOULD BE obtained before put operation (see + // session package). Chunk messages considered by server as part of object + // payload. All messages except first SHOULD BE chunks. Chunk messages + // SHOULD BE sent in direct order of fragmentation. rpc Put(stream PutRequest) returns (PutResponse); // Delete the object from a container rpc Delete(DeleteRequest) returns (DeleteResponse); - // Get MetaInfo + // Head returns the object without data payload. Object in the + // response has system header only. If full headers flag is set, extended + // headers are also present. rpc Head(HeadRequest) returns (HeadResponse); - // Search by MetaInfo + // Search objects in container. Version of query language format SHOULD BE + // set to 1. Search query represented in serialized format (see query + // package). rpc Search(SearchRequest) returns (SearchResponse); - // Get ranges of object payload + // GetRange of data payload. Ranges are set of pairs (offset, length). + // Fragments order in response corresponds to ranges order in request. rpc GetRange(GetRangeRequest) returns (GetRangeResponse); - // Get hashes of object ranges + // GetRangeHash returns homomorphic hash of object payload range after XOR + // operation. Ranges are set of pairs (offset, length). Hashes order in + // response corresponds to ranges order in request. Homomorphic hash is + // calculated for XORed data. rpc GetRangeHash(GetRangeHashRequest) returns (GetRangeHashResponse); } message GetRequest { - uint64 Epoch = 1; - refs.Address Address = 2 [(gogoproto.nullable) = false]; - uint32 TTL = 3; + uint64 Epoch = 1; // Epoch is set by user to 0, node set epoch to the actual value + refs.Address Address = 2 [(gogoproto.nullable) = false]; // Address of object (container id + object id) + uint32 TTL = 3; // TTL must be larger than zero, it decreased in every neofs-node } message GetResponse { oneof R { - Object object = 1; - bytes Chunk = 2; + Object object = 1; // Object header and some payload + bytes Chunk = 2; // Chunk of remaining payload } } message PutRequest { message PutHeader { - uint64 Epoch = 1; - Object Object = 2; - uint32 TTL = 3; - session.Token Token = 4; + uint64 Epoch = 1; // Epoch is set by user to 0, node set epoch to the actual value + Object Object = 2; // Object with at least container id and owner id fields + uint32 TTL = 3; // TTL must be larger than zero, it decreased in every neofs-node + session.Token Token = 4; // Token with session public key and user's signature } oneof R { - PutHeader Header = 1; - bytes Chunk = 2; + PutHeader Header = 1; // Header should be the first message in the stream + bytes Chunk = 2; // Chunk should be a remaining message in stream should be chunks } } message PutResponse { - refs.Address Address = 1 [(gogoproto.nullable) = false]; + refs.Address Address = 1 [(gogoproto.nullable) = false]; // Address of object (container id + object id) } message DeleteRequest { - uint64 Epoch = 1; - refs.Address Address = 2 [(gogoproto.nullable) = false]; - bytes OwnerID = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "OwnerID"]; - uint32 TTL = 4; - session.Token Token = 5; + uint64 Epoch = 1; // Epoch is set by user to 0, node set epoch to the actual value + refs.Address Address = 2 [(gogoproto.nullable) = false]; // Address of object (container id + object id) + bytes OwnerID = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "OwnerID"]; // OwnerID is a wallet address + uint32 TTL = 4; // TTL must be larger than zero, it decreased in every neofs-node + session.Token Token = 5; // Token with session public key and user's signature } + +// DeleteResponse is empty because we cannot guarantee permanent object removal +// in distributed system. message DeleteResponse {} -// HeadRequest.FullHeader == true, for fetch all headers message HeadRequest { - uint64 Epoch = 1; - refs.Address Address = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "Address"]; - bool FullHeaders = 3; - uint32 TTL = 4; + uint64 Epoch = 1; // Epoch is set by user to 0, node set epoch to the actual value + refs.Address Address = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "Address"]; // Address of object (container id + object id) + bool FullHeaders = 3; // FullHeaders can be set true for extended headers in the object + uint32 TTL = 4; // TTL must be larger than zero, it decreased in every neofs-node } message HeadResponse { - Object Object = 1; + Object Object = 1; // Object without payload } message SearchRequest { - uint64 Epoch = 1; - uint32 Version = 2; - bytes ContainerID = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "CID"]; - bytes Query = 4; - uint32 TTL = 5; + uint64 Epoch = 1; // Epoch is set by user to 0, node set epoch to the actual value + uint32 Version = 2; // Version of search query format + bytes ContainerID = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "CID"]; // ContainerID for searching the object + bytes Query = 4; // Query in the binary serialized format + uint32 TTL = 5; // TTL must be larger than zero, it decreased in every neofs-node } message SearchResponse { - repeated refs.Address Addresses = 1 [(gogoproto.nullable) = false]; + repeated refs.Address Addresses = 1 [(gogoproto.nullable) = false]; // Addresses of found objects } message GetRangeRequest { - uint64 Epoch = 1; - refs.Address Address = 2 [(gogoproto.nullable) = false]; - repeated Range Ranges = 3 [(gogoproto.nullable) = false]; - uint32 TTL = 4; + uint64 Epoch = 1; // Epoch is set by user to 0, node set epoch to the actual value + refs.Address Address = 2 [(gogoproto.nullable) = false]; // Address of object (container id + object id) + repeated Range Ranges = 3 [(gogoproto.nullable) = false]; // Ranges of object's payload to return + uint32 TTL = 4; // TTL must be larger than zero, it decreased in every neofs-node } message GetRangeResponse { - repeated bytes Fragments = 1; + repeated bytes Fragments = 1; // Fragments of object's payload } message GetRangeHashRequest { - uint64 Epoch = 1; - refs.Address Address = 2 [(gogoproto.nullable) = false]; - repeated Range Ranges = 3 [(gogoproto.nullable) = false]; - bytes Salt = 4; - uint32 TTL = 5; + uint64 Epoch = 1; // Epoch is set by user to 0, node set epoch to the actual value + refs.Address Address = 2 [(gogoproto.nullable) = false]; // Address of object (container id + object id) + repeated Range Ranges = 3 [(gogoproto.nullable) = false]; // Ranges of object's payload to calculate homomorphic hash + bytes Salt = 4; // Salt is used to XOR object's payload ranges before hashing, it can be nil + uint32 TTL = 5; // TTL must be larger than zero, it decreased in every neofs-node } message GetRangeHashResponse { - repeated bytes Hashes = 1 [(gogoproto.customtype) = "Hash", (gogoproto.nullable) = false]; + repeated bytes Hashes = 1 [(gogoproto.customtype) = "Hash", (gogoproto.nullable) = false]; // Homomorphic hashes of all ranges } diff --git a/object/types.proto b/object/types.proto index a7cbd8c..30e468e 100644 --- a/object/types.proto +++ b/object/types.proto @@ -9,99 +9,97 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto"; option (gogoproto.stable_marshaler_all) = true; message Range { - uint64 Offset = 1; - uint64 Length = 2; + uint64 Offset = 1; // Offset of the data range + uint64 Length = 2; // Length of the data range } message UserHeader { - string Key = 1; - string Value = 2; + string Key = 1; // Key of the user's header + string Value = 2; // Value of the user's header } message Header { oneof Value { - Link Link = 1; - refs.Address Redirect = 2; - UserHeader UserHeader = 3; - Transform Transform = 4; - Tombstone Tombstone = 5; - // session-related info: session.VerificationHeader - session.VerificationHeader Verify = 6; - // integrity-related info - bytes HomoHash = 7 [(gogoproto.customtype) = "Hash"]; - bytes PayloadChecksum = 8; - IntegrityHeader Integrity = 9; - StorageGroup StorageGroup = 10; + Link Link = 1; // Link to other objects + refs.Address Redirect = 2; // RedirectNot used yet + UserHeader UserHeader = 3; // UserHeader defined by user + Transform Transform = 4; // Transform defines transform operation (e.g. payload split) + Tombstone Tombstone = 5; // Tombstone header that set up in deleted objects + session.VerificationHeader Verify = 6; // Verify header that contains session public key and user's signature + bytes HomoHash = 7 [(gogoproto.customtype) = "Hash"]; // Homomorphic hash of original object payload + bytes PayloadChecksum = 8; // PayloadChecksum of actual object's payload + IntegrityHeader Integrity = 9; // Integrity header with checksum of all above headers in the object + StorageGroup StorageGroup = 10; // StorageGroup contains meta information for the data audit } } message Tombstone { - uint64 Epoch = 1; + uint64 Epoch = 1; // Epoch when tombstone was created } message SystemHeader { - uint64 Version = 1; - uint64 PayloadLength = 2; + uint64 Version = 1; // Version of the object structure + uint64 PayloadLength = 2; // Object payload length - bytes ID = 3 [(gogoproto.customtype) = "ID", (gogoproto.nullable) = false]; - bytes OwnerID = 4 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; - bytes CID = 5 [(gogoproto.customtype) = "CID", (gogoproto.nullable) = false]; - CreationPoint CreatedAt = 6 [(gogoproto.nullable) = false]; + bytes ID = 3 [(gogoproto.customtype) = "ID", (gogoproto.nullable) = false]; // ObjectID is a UUID + bytes OwnerID = 4 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; // OwnerID is a wallet address + bytes CID = 5 [(gogoproto.customtype) = "CID", (gogoproto.nullable) = false]; // ContainerID is a SHA256 hash of the container structure + CreationPoint CreatedAt = 6 [(gogoproto.nullable) = false]; // Timestamp of object creation } message CreationPoint { - int64 UnixTime = 1; - uint64 Epoch = 2; + int64 UnixTime = 1; // Date of creation in unixtime format + uint64 Epoch = 2; // Date of creation in NeoFS epochs } message IntegrityHeader { - bytes HeadersChecksum = 1; - bytes ChecksumSignature = 2; + bytes HeadersChecksum = 1; // Checksum of all above headers in the object + bytes ChecksumSignature = 2; // User's signature of checksum to verify if it is correct } message Link { enum Type { Unknown = 0; - Parent = 1; - Previous = 2; - Next = 3; - Child = 4; - StorageGroup = 5; + Parent = 1; // Parent object created during object transformation + Previous = 2; // Previous object in the linked list created during object transformation + Next = 3; // Next object in the linked list created during object transformation + Child = 4; // Child object created during object transformation + StorageGroup = 5; // Object that included into this storage group } - Type type = 1; - bytes ID = 2 [(gogoproto.customtype) = "ID", (gogoproto.nullable) = false]; + Type type = 1; // Link type + bytes ID = 2 [(gogoproto.customtype) = "ID", (gogoproto.nullable) = false]; // Object id } message Transform { enum Type { Unknown = 0; - Split = 1; - Sign = 2; - Mould = 3; + Split = 1; // Object created after payload split + Sign = 2; // Object created after re-signing (doesn't used) + Mould = 3; // Object created after filling missing headers in the object } - Type type = 1; + Type type = 1; // Type of object transformation } message Object { - SystemHeader SystemHeader = 1 [(gogoproto.nullable) = false]; - repeated Header Headers = 2 [(gogoproto.nullable) = false]; - bytes Payload = 3; + SystemHeader SystemHeader = 1 [(gogoproto.nullable) = false]; // System header + repeated Header Headers = 2 [(gogoproto.nullable) = false]; // Extended headers + bytes Payload = 3; // Object's payload } message StorageGroup { - uint64 ValidationDataSize = 1; - bytes ValidationHash = 2 [(gogoproto.customtype) = "Hash", (gogoproto.nullable) = false]; + uint64 ValidationDataSize = 1; // Size of the all object's payloads included into storage group + bytes ValidationHash = 2 [(gogoproto.customtype) = "Hash", (gogoproto.nullable) = false]; // Homomorphic hash of all object's payloads included into storage group message Lifetime { enum Unit { - Unlimited = 0; - NeoFSEpoch = 1; - UnixTime = 2; + Unlimited = 0; // Storage group always valid + NeoFSEpoch = 1; // Storage group is valid until lifetime NeoFS epoch + UnixTime = 2; // Storage group is valid until lifetime unix timestamp } - Unit unit = 1 [(gogoproto.customname) = "Unit"]; - int64 Value = 2; + Unit unit = 1 [(gogoproto.customname) = "Unit"]; // Lifetime type + int64 Value = 2; // Lifetime value } - Lifetime lifetime = 3 [(gogoproto.customname) = "Lifetime"]; + Lifetime lifetime = 3 [(gogoproto.customname) = "Lifetime"]; // Time until storage group is valid }