Merge branch 'release/0.2.0'
This commit is contained in:
commit
50e5566aab
43 changed files with 1005 additions and 349 deletions
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
|
@ -38,4 +38,6 @@ jobs:
|
||||||
run: go test -coverprofile=coverage.txt -covermode=atomic ./...
|
run: go test -coverprofile=coverage.txt -covermode=atomic ./...
|
||||||
|
|
||||||
- name: Codecov
|
- name: Codecov
|
||||||
|
env:
|
||||||
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
run: bash <(curl -s https://codecov.io/bash)
|
run: bash <(curl -s https://codecov.io/bash)
|
||||||
|
|
22
CHANGELOG.md
Normal file
22
CHANGELOG.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Changelog
|
||||||
|
This is the changelog for NeoFS Proto
|
||||||
|
|
||||||
|
## [0.2.0] - 2019-11-21
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Container not found error
|
||||||
|
- GitHub Actions as CI and Codecov
|
||||||
|
- Auto-generated proto documentation
|
||||||
|
- RequestMetaHeader to all RPC requests
|
||||||
|
- RequestVerificationHeader to all RPC requests
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Moved TTL and Epoch fields to RequestMetaHeader
|
||||||
|
- Renamed Version in object.SearchRequest to QueryVersion
|
||||||
|
- Removed SetTTL, GetTTL, SetEpoch, GetEpoch from all RPC requests
|
||||||
|
|
||||||
|
## 0.1.0 - 2019-11-18
|
||||||
|
|
||||||
|
Initial public release
|
||||||
|
|
||||||
|
[0.2.0]: https://github.com/nspcc-dev/neofs-proto/compare/v0.1.0...v0.2.0
|
|
@ -31,9 +31,6 @@ const (
|
||||||
ErrEmptyParentAddress = internal.Error("empty parent address")
|
ErrEmptyParentAddress = internal.Error("empty parent address")
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTTL sets ttl to BalanceRequest to satisfy TTLRequest interface.
|
|
||||||
func (m BalanceRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SumFunds goes through all accounts and sums up active funds.
|
// SumFunds goes through all accounts and sums up active funds.
|
||||||
func SumFunds(accounts []*Account) (res *decimal.Decimal) {
|
func SumFunds(accounts []*Account) (res *decimal.Decimal) {
|
||||||
res = decimal.Zero.Copy()
|
res = decimal.Zero.Copy()
|
||||||
|
|
Binary file not shown.
|
@ -2,6 +2,8 @@ syntax = "proto3";
|
||||||
package accounting;
|
package accounting;
|
||||||
option go_package = "github.com/nspcc-dev/neofs-proto/accounting";
|
option go_package = "github.com/nspcc-dev/neofs-proto/accounting";
|
||||||
|
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
import "decimal/decimal.proto";
|
import "decimal/decimal.proto";
|
||||||
import "accounting/types.proto";
|
import "accounting/types.proto";
|
||||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
@ -18,9 +20,10 @@ service Accounting {
|
||||||
message BalanceRequest {
|
message BalanceRequest {
|
||||||
// OwnerID is a wallet address
|
// OwnerID is a wallet address
|
||||||
bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 2;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message BalanceResponse {
|
message BalanceResponse {
|
||||||
|
|
|
@ -11,18 +11,6 @@ type (
|
||||||
MessageID = refs.MessageID
|
MessageID = refs.MessageID
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTTL sets ttl to GetRequest to satisfy TTLRequest interface.
|
|
||||||
func (m *GetRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SetTTL sets ttl to PutRequest to satisfy TTLRequest interface.
|
|
||||||
func (m *PutRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SetTTL sets ttl to ListRequest to satisfy TTLRequest interface.
|
|
||||||
func (m *ListRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SetTTL sets ttl to DeleteRequest to satisfy TTLRequest interface.
|
|
||||||
func (m *DeleteRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SetSignature sets signature to PutRequest to satisfy SignedRequest interface.
|
// SetSignature sets signature to PutRequest to satisfy SignedRequest interface.
|
||||||
func (m *PutRequest) SetSignature(v []byte) { m.Signature = v }
|
func (m *PutRequest) SetSignature(v []byte) { m.Signature = v }
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -2,6 +2,8 @@ syntax = "proto3";
|
||||||
package accounting;
|
package accounting;
|
||||||
option go_package = "github.com/nspcc-dev/neofs-proto/accounting";
|
option go_package = "github.com/nspcc-dev/neofs-proto/accounting";
|
||||||
|
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
import "decimal/decimal.proto";
|
import "decimal/decimal.proto";
|
||||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
|
@ -37,9 +39,10 @@ message GetRequest {
|
||||||
bytes ID = 1 [(gogoproto.customtype) = "ChequeID", (gogoproto.nullable) = false];
|
bytes ID = 1 [(gogoproto.customtype) = "ChequeID", (gogoproto.nullable) = false];
|
||||||
// OwnerID is a wallet address
|
// OwnerID is a wallet address
|
||||||
bytes OwnerID = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
bytes OwnerID = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 3;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetResponse {
|
message GetResponse {
|
||||||
|
@ -58,9 +61,10 @@ message PutRequest {
|
||||||
bytes MessageID = 4 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false];
|
bytes MessageID = 4 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false];
|
||||||
// Signature is a signature of the sent request
|
// Signature is a signature of the sent request
|
||||||
bytes Signature = 5;
|
bytes Signature = 5;
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 6;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
message PutResponse {
|
message PutResponse {
|
||||||
// ID is cheque identifier
|
// ID is cheque identifier
|
||||||
|
@ -70,9 +74,10 @@ message PutResponse {
|
||||||
message ListRequest {
|
message ListRequest {
|
||||||
// OwnerID is a wallet address
|
// OwnerID is a wallet address
|
||||||
bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 2;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListResponse {
|
message ListResponse {
|
||||||
|
@ -89,9 +94,10 @@ message DeleteRequest {
|
||||||
bytes MessageID = 3 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false];
|
bytes MessageID = 3 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false];
|
||||||
// Signature is a signature of the sent request
|
// Signature is a signature of the sent request
|
||||||
bytes Signature = 4;
|
bytes Signature = 4;
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 5;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResponse is empty
|
// DeleteResponse is empty
|
||||||
|
|
|
@ -6,6 +6,3 @@ import (
|
||||||
|
|
||||||
// NodeType type alias.
|
// NodeType type alias.
|
||||||
type NodeType = service.NodeRole
|
type NodeType = service.NodeRole
|
||||||
|
|
||||||
// SetTTL sets ttl to Request to satisfy TTLRequest interface.
|
|
||||||
func (m *Request) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
Binary file not shown.
|
@ -2,6 +2,8 @@ syntax = "proto3";
|
||||||
package bootstrap;
|
package bootstrap;
|
||||||
option go_package = "github.com/nspcc-dev/neofs-proto/bootstrap";
|
option go_package = "github.com/nspcc-dev/neofs-proto/bootstrap";
|
||||||
|
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
import "bootstrap/types.proto";
|
import "bootstrap/types.proto";
|
||||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
|
@ -20,7 +22,8 @@ message Request {
|
||||||
int32 type = 1 [(gogoproto.customname) = "Type" , (gogoproto.nullable) = false, (gogoproto.customtype) = "NodeType"];
|
int32 type = 1 [(gogoproto.customname) = "Type" , (gogoproto.nullable) = false, (gogoproto.customtype) = "NodeType"];
|
||||||
// Info contains information about node
|
// Info contains information about node
|
||||||
bootstrap.NodeInfo info = 2 [(gogoproto.nullable) = false];
|
bootstrap.NodeInfo info = 2 [(gogoproto.nullable) = false];
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 3;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-proto/internal"
|
||||||
"github.com/nspcc-dev/neofs-proto/refs"
|
"github.com/nspcc-dev/neofs-proto/refs"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -19,17 +20,10 @@ type (
|
||||||
MessageID = refs.MessageID
|
MessageID = refs.MessageID
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTTL sets ttl to GetRequest to satisfy TTLRequest interface.
|
const (
|
||||||
func (m *GetRequest) SetTTL(v uint32) { m.TTL = v }
|
// ErrNotFound is raised when container could not be found.
|
||||||
|
ErrNotFound = internal.Error("could not find container")
|
||||||
// SetTTL sets ttl to PutRequest to satisfy TTLRequest interface.
|
)
|
||||||
func (m *PutRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SetTTL sets ttl to ListRequest to satisfy TTLRequest interface.
|
|
||||||
func (m *ListRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SetTTL sets ttl to DeleteRequest to satisfy TTLRequest interface.
|
|
||||||
func (m *DeleteRequest) SetTTL(v uint32) { m.TTL = v }
|
|
||||||
|
|
||||||
// SetSignature sets signature to PutRequest to satisfy SignedRequest interface.
|
// SetSignature sets signature to PutRequest to satisfy SignedRequest interface.
|
||||||
func (m *PutRequest) SetSignature(v []byte) { m.Signature = v }
|
func (m *PutRequest) SetSignature(v []byte) { m.Signature = v }
|
||||||
|
|
Binary file not shown.
|
@ -2,6 +2,8 @@ syntax = "proto3";
|
||||||
package container;
|
package container;
|
||||||
option go_package = "github.com/nspcc-dev/neofs-proto/container";
|
option go_package = "github.com/nspcc-dev/neofs-proto/container";
|
||||||
|
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
import "container/types.proto";
|
import "container/types.proto";
|
||||||
import "github.com/nspcc-dev/netmap/selector.proto";
|
import "github.com/nspcc-dev/netmap/selector.proto";
|
||||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
@ -42,9 +44,10 @@ message PutRequest {
|
||||||
// Signature of the user (owner id)
|
// Signature of the user (owner id)
|
||||||
bytes Signature = 5;
|
bytes Signature = 5;
|
||||||
|
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 6;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message PutResponse {
|
message PutResponse {
|
||||||
|
@ -56,12 +59,13 @@ message DeleteRequest {
|
||||||
// CID (container id) is a SHA256 hash of the container structure
|
// CID (container id) is a SHA256 hash of the container structure
|
||||||
bytes CID = 1 [(gogoproto.customtype) = "CID", (gogoproto.nullable) = false];
|
bytes CID = 1 [(gogoproto.customtype) = "CID", (gogoproto.nullable) = false];
|
||||||
|
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint32 TTL = 2;
|
|
||||||
|
|
||||||
// Signature of the container owner
|
// Signature of the container owner
|
||||||
bytes Signature = 3;
|
bytes Signature = 2;
|
||||||
|
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResponse is empty because delete operation is asynchronous and done
|
// DeleteResponse is empty because delete operation is asynchronous and done
|
||||||
|
@ -73,9 +77,10 @@ message GetRequest {
|
||||||
// CID (container id) is a SHA256 hash of the container structure
|
// CID (container id) is a SHA256 hash of the container structure
|
||||||
bytes CID = 1 [(gogoproto.customtype) = "CID", (gogoproto.nullable) = false];
|
bytes CID = 1 [(gogoproto.customtype) = "CID", (gogoproto.nullable) = false];
|
||||||
|
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 2;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetResponse {
|
message GetResponse {
|
||||||
|
@ -86,10 +91,10 @@ message GetResponse {
|
||||||
message ListRequest {
|
message ListRequest {
|
||||||
// OwnerID is a wallet address
|
// OwnerID is a wallet address
|
||||||
bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false];
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
uint32 TTL = 2;
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListResponse {
|
message ListResponse {
|
||||||
|
|
|
@ -87,7 +87,8 @@ Balance returns current balance status of the NeoFS user
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="accounting.BalanceResponse"></a>
|
<a name="accounting.BalanceResponse"></a>
|
||||||
|
@ -362,7 +363,8 @@ Delete allows user to remove unused cheque
|
||||||
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
||||||
| MessageID | [bytes](#bytes) | | MessageID is a nonce for uniq request (UUIDv4) |
|
| MessageID | [bytes](#bytes) | | MessageID is a nonce for uniq request (UUIDv4) |
|
||||||
| Signature | [bytes](#bytes) | | Signature is a signature of the sent request |
|
| Signature | [bytes](#bytes) | | Signature is a signature of the sent request |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="accounting.DeleteResponse"></a>
|
<a name="accounting.DeleteResponse"></a>
|
||||||
|
@ -382,7 +384,8 @@ DeleteResponse is empty
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| ID | [bytes](#bytes) | | ID is cheque identifier |
|
| ID | [bytes](#bytes) | | ID is cheque identifier |
|
||||||
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="accounting.GetResponse"></a>
|
<a name="accounting.GetResponse"></a>
|
||||||
|
@ -420,7 +423,8 @@ DeleteResponse is empty
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="accounting.ListResponse"></a>
|
<a name="accounting.ListResponse"></a>
|
||||||
|
@ -447,7 +451,8 @@ DeleteResponse is empty
|
||||||
| Height | [uint64](#uint64) | | Height is the neo blockchain height until the cheque is valid |
|
| Height | [uint64](#uint64) | | Height is the neo blockchain height until the cheque is valid |
|
||||||
| MessageID | [bytes](#bytes) | | MessageID is a nonce for uniq request (UUIDv4) |
|
| MessageID | [bytes](#bytes) | | MessageID is a nonce for uniq request (UUIDv4) |
|
||||||
| Signature | [bytes](#bytes) | | Signature is a signature of the sent request |
|
| Signature | [bytes](#bytes) | | Signature is a signature of the sent request |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="accounting.PutResponse"></a>
|
<a name="accounting.PutResponse"></a>
|
||||||
|
|
|
@ -62,7 +62,8 @@ Process is method that allows to register node in the network and receive actual
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| type | [int32](#int32) | | Type is NodeType, can be InnerRingNode (type=1) or StorageNode (type=2) |
|
| type | [int32](#int32) | | Type is NodeType, can be InnerRingNode (type=1) or StorageNode (type=2) |
|
||||||
| info | [NodeInfo](#bootstrap.NodeInfo) | | Info contains information about node |
|
| info | [NodeInfo](#bootstrap.NodeInfo) | | Info contains information about node |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
<!-- end messages -->
|
<!-- end messages -->
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,9 @@ List returns all user's containers
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| CID | [bytes](#bytes) | | CID (container id) is a SHA256 hash of the container structure |
|
| CID | [bytes](#bytes) | | CID (container id) is a SHA256 hash of the container structure |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Signature | [bytes](#bytes) | | Signature of the container owner |
|
| Signature | [bytes](#bytes) | | Signature of the container owner |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="container.DeleteResponse"></a>
|
<a name="container.DeleteResponse"></a>
|
||||||
|
@ -113,7 +114,8 @@ via consensus in inner ring nodes
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| CID | [bytes](#bytes) | | CID (container id) is a SHA256 hash of the container structure |
|
| CID | [bytes](#bytes) | | CID (container id) is a SHA256 hash of the container structure |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="container.GetResponse"></a>
|
<a name="container.GetResponse"></a>
|
||||||
|
@ -136,7 +138,8 @@ via consensus in inner ring nodes
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="container.ListResponse"></a>
|
<a name="container.ListResponse"></a>
|
||||||
|
@ -163,7 +166,8 @@ via consensus in inner ring nodes
|
||||||
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
||||||
| rules | [netmap.PlacementRule](#netmap.PlacementRule) | | Rules define storage policy for the object inside the container. |
|
| rules | [netmap.PlacementRule](#netmap.PlacementRule) | | Rules define storage policy for the object inside the container. |
|
||||||
| Signature | [bytes](#bytes) | | Signature of the user (owner id) |
|
| Signature | [bytes](#bytes) | | Signature of the user (owner id) |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="container.PutResponse"></a>
|
<a name="container.PutResponse"></a>
|
||||||
|
|
|
@ -147,11 +147,11 @@ calculated for XORed data.
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
||||||
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
| OwnerID | [bytes](#bytes) | | OwnerID is a wallet address |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Token | [session.Token](#session.Token) | | Token with session public key and user's signature |
|
| Token | [session.Token](#session.Token) | | Token with session public key and user's signature |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="object.DeleteResponse"></a>
|
<a name="object.DeleteResponse"></a>
|
||||||
|
@ -170,11 +170,11 @@ in distributed system.
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
||||||
| Ranges | [Range](#object.Range) | repeated | Ranges of object's payload to calculate homomorphic hash |
|
| Ranges | [Range](#object.Range) | repeated | Ranges of object's payload to calculate homomorphic hash |
|
||||||
| Salt | [bytes](#bytes) | | Salt is used to XOR object's payload ranges before hashing, it can be nil |
|
| Salt | [bytes](#bytes) | | Salt is used to XOR object's payload ranges before hashing, it can be nil |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="object.GetRangeHashResponse"></a>
|
<a name="object.GetRangeHashResponse"></a>
|
||||||
|
@ -196,10 +196,10 @@ in distributed system.
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
||||||
| Ranges | [Range](#object.Range) | repeated | Ranges of object's payload to return |
|
| Ranges | [Range](#object.Range) | repeated | Ranges of object's payload to return |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="object.GetRangeResponse"></a>
|
<a name="object.GetRangeResponse"></a>
|
||||||
|
@ -221,9 +221,9 @@ in distributed system.
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="object.GetResponse"></a>
|
<a name="object.GetResponse"></a>
|
||||||
|
@ -246,10 +246,10 @@ in distributed system.
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Epoch | [uint64](#uint64) | | Epoch should be empty on user side, node sets epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
| Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) |
|
||||||
| FullHeaders | [bool](#bool) | | FullHeaders can be set true for extended headers in the object |
|
| FullHeaders | [bool](#bool) | | FullHeaders can be set true for extended headers in the object |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="object.HeadResponse"></a>
|
<a name="object.HeadResponse"></a>
|
||||||
|
@ -273,6 +273,8 @@ in distributed system.
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Header | [PutRequest.PutHeader](#object.PutRequest.PutHeader) | | Header should be the first message in the stream |
|
| Header | [PutRequest.PutHeader](#object.PutRequest.PutHeader) | | Header should be the first message in the stream |
|
||||||
| Chunk | [bytes](#bytes) | | Chunk should be a remaining message in stream should be chunks |
|
| Chunk | [bytes](#bytes) | | Chunk should be a remaining message in stream should be chunks |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="object.PutRequest.PutHeader"></a>
|
<a name="object.PutRequest.PutHeader"></a>
|
||||||
|
@ -283,9 +285,7 @@ in distributed system.
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Object | [Object](#object.Object) | | Object with at least container id and owner id fields |
|
| Object | [Object](#object.Object) | | Object with at least container id and owner id fields |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Token | [session.Token](#session.Token) | | Token with session public key and user's signature |
|
| Token | [session.Token](#session.Token) | | Token with session public key and user's signature |
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,11 +308,11 @@ in distributed system.
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
|
||||||
| Version | [uint32](#uint32) | | Version of search query format |
|
|
||||||
| ContainerID | [bytes](#bytes) | | ContainerID for searching the object |
|
| ContainerID | [bytes](#bytes) | | ContainerID for searching the object |
|
||||||
| Query | [bytes](#bytes) | | Query in the binary serialized format |
|
| Query | [bytes](#bytes) | | Query in the binary serialized format |
|
||||||
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) |
|
| QueryVersion | [uint32](#uint32) | | QueryVersion is a version of search query format |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="object.SearchResponse"></a>
|
<a name="object.SearchResponse"></a>
|
||||||
|
|
157
docs/service.md
Normal file
157
docs/service.md
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
# Protocol Documentation
|
||||||
|
<a name="top"></a>
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [service/meta.proto](#service/meta.proto)
|
||||||
|
|
||||||
|
- Messages
|
||||||
|
- [RequestMetaHeader](#service.RequestMetaHeader)
|
||||||
|
|
||||||
|
|
||||||
|
- [service/verify.proto](#service/verify.proto)
|
||||||
|
|
||||||
|
- Messages
|
||||||
|
- [RequestVerificationHeader](#service.RequestVerificationHeader)
|
||||||
|
- [RequestVerificationHeader.Sign](#service.RequestVerificationHeader.Sign)
|
||||||
|
- [RequestVerificationHeader.Signature](#service.RequestVerificationHeader.Signature)
|
||||||
|
|
||||||
|
|
||||||
|
- [service/verify_test.proto](#service/verify_test.proto)
|
||||||
|
|
||||||
|
- Messages
|
||||||
|
- [TestRequest](#service.TestRequest)
|
||||||
|
|
||||||
|
|
||||||
|
- [Scalar Value Types](#scalar-value-types)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service/meta.proto"></a>
|
||||||
|
<p align="right"><a href="#top">Top</a></p>
|
||||||
|
|
||||||
|
## service/meta.proto
|
||||||
|
|
||||||
|
|
||||||
|
<!-- end services -->
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service.RequestMetaHeader"></a>
|
||||||
|
|
||||||
|
### Message RequestMetaHeader
|
||||||
|
RequestMetaHeader contains information about request meta headers
|
||||||
|
(should be embedded into message)
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every NeoFS Node |
|
||||||
|
| Epoch | [uint64](#uint64) | | Epoch for user can be empty, because node sets epoch to the actual value |
|
||||||
|
| Version | [uint32](#uint32) | | Version defines protocol version TODO: not used for now, should be implemented in future |
|
||||||
|
|
||||||
|
<!-- end messages -->
|
||||||
|
|
||||||
|
<!-- end enums -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service/verify.proto"></a>
|
||||||
|
<p align="right"><a href="#top">Top</a></p>
|
||||||
|
|
||||||
|
## service/verify.proto
|
||||||
|
|
||||||
|
|
||||||
|
<!-- end services -->
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service.RequestVerificationHeader"></a>
|
||||||
|
|
||||||
|
### Message RequestVerificationHeader
|
||||||
|
RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request
|
||||||
|
(should be embedded into message).
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| Signatures | [RequestVerificationHeader.Signature](#service.RequestVerificationHeader.Signature) | repeated | Signatures is a set of signatures of every passed NeoFS Node |
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service.RequestVerificationHeader.Sign"></a>
|
||||||
|
|
||||||
|
### Message RequestVerificationHeader.Sign
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| Sign | [bytes](#bytes) | | Sign is signature of the request or session key. |
|
||||||
|
| Peer | [bytes](#bytes) | | Peer is compressed public key used for signature. |
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service.RequestVerificationHeader.Signature"></a>
|
||||||
|
|
||||||
|
### Message RequestVerificationHeader.Signature
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| Sign | [RequestVerificationHeader.Sign](#service.RequestVerificationHeader.Sign) | | Sign is a signature and public key of the request. |
|
||||||
|
| Origin | [RequestVerificationHeader.Sign](#service.RequestVerificationHeader.Sign) | | Origin used for requests, when trusted node changes it and re-sign with session key. If session key used for signature request, then Origin should contain public key of user and signed session key. |
|
||||||
|
|
||||||
|
<!-- end messages -->
|
||||||
|
|
||||||
|
<!-- end enums -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service/verify_test.proto"></a>
|
||||||
|
<p align="right"><a href="#top">Top</a></p>
|
||||||
|
|
||||||
|
## service/verify_test.proto
|
||||||
|
|
||||||
|
|
||||||
|
<!-- end services -->
|
||||||
|
|
||||||
|
|
||||||
|
<a name="service.TestRequest"></a>
|
||||||
|
|
||||||
|
### Message TestRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| IntField | [int32](#int32) | | |
|
||||||
|
| StringField | [string](#string) | | |
|
||||||
|
| BytesField | [bytes](#bytes) | | |
|
||||||
|
| CustomField | [bytes](#bytes) | | |
|
||||||
|
| Meta | [RequestMetaHeader](#service.RequestMetaHeader) | | |
|
||||||
|
| Header | [RequestVerificationHeader](#service.RequestVerificationHeader) | | |
|
||||||
|
|
||||||
|
<!-- end messages -->
|
||||||
|
|
||||||
|
<!-- end enums -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Scalar Value Types
|
||||||
|
|
||||||
|
| .proto Type | Notes | C++ Type | Java Type | Python Type |
|
||||||
|
| ----------- | ----- | -------- | --------- | ----------- |
|
||||||
|
| <a name="double" /> double | | double | double | float |
|
||||||
|
| <a name="float" /> float | | float | float | float |
|
||||||
|
| <a name="int32" /> int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int |
|
||||||
|
| <a name="int64" /> int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long |
|
||||||
|
| <a name="uint32" /> uint32 | Uses variable-length encoding. | uint32 | int | int/long |
|
||||||
|
| <a name="uint64" /> uint64 | Uses variable-length encoding. | uint64 | long | int/long |
|
||||||
|
| <a name="sint32" /> sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int |
|
||||||
|
| <a name="sint64" /> sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long |
|
||||||
|
| <a name="fixed32" /> fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int |
|
||||||
|
| <a name="fixed64" /> fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long |
|
||||||
|
| <a name="sfixed32" /> sfixed32 | Always four bytes. | int32 | int | int |
|
||||||
|
| <a name="sfixed64" /> sfixed64 | Always eight bytes. | int64 | long | int/long |
|
||||||
|
| <a name="bool" /> bool | | bool | boolean | boolean |
|
||||||
|
| <a name="string" /> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode |
|
||||||
|
| <a name="bytes" /> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str |
|
||||||
|
|
|
@ -70,6 +70,8 @@ session key. Session is established during 4-step handshake in one gRPC stream
|
||||||
| ----- | ---- | ----- | ----------- |
|
| ----- | ---- | ----- | ----------- |
|
||||||
| Init | [Token](#session.Token) | | Init is a message to initialize session opening. Carry: owner of manipulation object; ID of manipulation object; token lifetime bounds. |
|
| Init | [Token](#session.Token) | | Init is a message to initialize session opening. Carry: owner of manipulation object; ID of manipulation object; token lifetime bounds. |
|
||||||
| Signed | [Token](#session.Token) | | Signed Init message response (Unsigned) from server with user private key |
|
| Signed | [Token](#session.Token) | | Signed Init message response (Unsigned) from server with user private key |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="session.CreateResponse"></a>
|
<a name="session.CreateResponse"></a>
|
||||||
|
|
|
@ -70,6 +70,11 @@ If node unhealthy field Status would contains detailed info.
|
||||||
HealthRequest message to check current state
|
HealthRequest message to check current state
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="state.HealthResponse"></a>
|
<a name="state.HealthResponse"></a>
|
||||||
|
|
||||||
|
@ -89,6 +94,11 @@ HealthResponse message with current state
|
||||||
MetricsRequest message to request node metrics
|
MetricsRequest message to request node metrics
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
|
|
||||||
<a name="state.MetricsResponse"></a>
|
<a name="state.MetricsResponse"></a>
|
||||||
|
|
||||||
|
@ -109,6 +119,11 @@ from github.com/prometheus/client_model/metrics.proto
|
||||||
NetmapRequest message to request current node netmap
|
NetmapRequest message to request current node netmap
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Label | Description |
|
||||||
|
| ----- | ---- | ----- | ----------- |
|
||||||
|
| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) |
|
||||||
|
| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) |
|
||||||
|
|
||||||
<!-- end messages -->
|
<!-- end messages -->
|
||||||
|
|
||||||
<!-- end enums -->
|
<!-- end enums -->
|
||||||
|
|
|
@ -31,8 +31,7 @@ type (
|
||||||
// All object operations must have TTL, Epoch, Container ID and
|
// All object operations must have TTL, Epoch, Container ID and
|
||||||
// permission of usage previous network map.
|
// permission of usage previous network map.
|
||||||
Request interface {
|
Request interface {
|
||||||
service.TTLRequest
|
service.MetaHeader
|
||||||
service.EpochRequest
|
|
||||||
|
|
||||||
CID() CID
|
CID() CID
|
||||||
AllowPreviousNetMap() bool
|
AllowPreviousNetMap() bool
|
||||||
|
@ -124,54 +123,6 @@ func (m *GetResponse) NotFull() bool { return checkIsNotFull(m) }
|
||||||
// NotFull checks if protobuf stream provided whole object for put operation.
|
// NotFull checks if protobuf stream provided whole object for put operation.
|
||||||
func (m *PutRequest) NotFull() bool { return checkIsNotFull(m) }
|
func (m *PutRequest) NotFull() bool { return checkIsNotFull(m) }
|
||||||
|
|
||||||
// GetTTL returns TTL value from object put request.
|
|
||||||
func (m *PutRequest) GetTTL() uint32 { return m.GetHeader().TTL }
|
|
||||||
|
|
||||||
// GetEpoch returns epoch value from object put request.
|
|
||||||
func (m *PutRequest) GetEpoch() uint64 { return m.GetHeader().GetEpoch() }
|
|
||||||
|
|
||||||
// SetTTL sets TTL value into object put request.
|
|
||||||
func (m *PutRequest) SetTTL(ttl uint32) { m.GetHeader().TTL = ttl }
|
|
||||||
|
|
||||||
// SetTTL sets TTL value into object get request.
|
|
||||||
func (m *GetRequest) SetTTL(ttl uint32) { m.TTL = ttl }
|
|
||||||
|
|
||||||
// SetTTL sets TTL value into object head request.
|
|
||||||
func (m *HeadRequest) SetTTL(ttl uint32) { m.TTL = ttl }
|
|
||||||
|
|
||||||
// SetTTL sets TTL value into object search request.
|
|
||||||
func (m *SearchRequest) SetTTL(ttl uint32) { m.TTL = ttl }
|
|
||||||
|
|
||||||
// SetTTL sets TTL value into object delete request.
|
|
||||||
func (m *DeleteRequest) SetTTL(ttl uint32) { m.TTL = ttl }
|
|
||||||
|
|
||||||
// SetTTL sets TTL value into object get range request.
|
|
||||||
func (m *GetRangeRequest) SetTTL(ttl uint32) { m.TTL = ttl }
|
|
||||||
|
|
||||||
// SetTTL sets TTL value into object get range hash request.
|
|
||||||
func (m *GetRangeHashRequest) SetTTL(ttl uint32) { m.TTL = ttl }
|
|
||||||
|
|
||||||
// SetEpoch sets epoch value into object put request.
|
|
||||||
func (m *PutRequest) SetEpoch(v uint64) { m.GetHeader().Epoch = v }
|
|
||||||
|
|
||||||
// SetEpoch sets epoch value into object get request.
|
|
||||||
func (m *GetRequest) SetEpoch(v uint64) { m.Epoch = v }
|
|
||||||
|
|
||||||
// SetEpoch sets epoch value into object head request.
|
|
||||||
func (m *HeadRequest) SetEpoch(v uint64) { m.Epoch = v }
|
|
||||||
|
|
||||||
// SetEpoch sets epoch value into object search request.
|
|
||||||
func (m *SearchRequest) SetEpoch(v uint64) { m.Epoch = v }
|
|
||||||
|
|
||||||
// SetEpoch sets epoch value into object delete request.
|
|
||||||
func (m *DeleteRequest) SetEpoch(v uint64) { m.Epoch = v }
|
|
||||||
|
|
||||||
// SetEpoch sets epoch value into object get range request.
|
|
||||||
func (m *GetRangeRequest) SetEpoch(v uint64) { m.Epoch = v }
|
|
||||||
|
|
||||||
// SetEpoch sets epoch value into object get range hash request.
|
|
||||||
func (m *GetRangeHashRequest) SetEpoch(v uint64) { m.Epoch = v }
|
|
||||||
|
|
||||||
// CID returns container id value from object put request.
|
// CID returns container id value from object put request.
|
||||||
func (m *PutRequest) CID() CID { return m.GetHeader().Object.SystemHeader.CID }
|
func (m *PutRequest) CID() CID { return m.GetHeader().Object.SystemHeader.CID }
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -5,6 +5,8 @@ option go_package = "github.com/nspcc-dev/neofs-proto/object";
|
||||||
import "refs/types.proto";
|
import "refs/types.proto";
|
||||||
import "object/types.proto";
|
import "object/types.proto";
|
||||||
import "session/types.proto";
|
import "session/types.proto";
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
option (gogoproto.stable_marshaler_all) = true;
|
option (gogoproto.stable_marshaler_all) = true;
|
||||||
|
@ -52,14 +54,12 @@ service Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRequest {
|
message GetRequest {
|
||||||
// Epoch is set by user to 0, node set epoch to the actual value
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint64 Epoch = 1;
|
|
||||||
// Address of object (container id + object id)
|
// Address of object (container id + object id)
|
||||||
refs.Address Address = 2 [(gogoproto.nullable) = false];
|
refs.Address Address = 1 [(gogoproto.nullable) = false];
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 3;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetResponse {
|
message GetResponse {
|
||||||
|
@ -73,16 +73,10 @@ message GetResponse {
|
||||||
|
|
||||||
message PutRequest {
|
message PutRequest {
|
||||||
message PutHeader {
|
message PutHeader {
|
||||||
// Epoch is set by user to 0, node set epoch to the actual value
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint64 Epoch = 1;
|
|
||||||
// Object with at least container id and owner id fields
|
// Object with at least container id and owner id fields
|
||||||
Object Object = 2;
|
Object Object = 1;
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint32 TTL = 3;
|
|
||||||
// Token with session public key and user's signature
|
// Token with session public key and user's signature
|
||||||
session.Token Token = 4;
|
session.Token Token = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
oneof R {
|
oneof R {
|
||||||
|
@ -91,6 +85,11 @@ message PutRequest {
|
||||||
// Chunk should be a remaining message in stream should be chunks
|
// Chunk should be a remaining message in stream should be chunks
|
||||||
bytes Chunk = 2;
|
bytes Chunk = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message PutResponse {
|
message PutResponse {
|
||||||
|
@ -98,18 +97,16 @@ message PutResponse {
|
||||||
refs.Address Address = 1 [(gogoproto.nullable) = false];
|
refs.Address Address = 1 [(gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
message DeleteRequest {
|
message DeleteRequest {
|
||||||
// Epoch is set by user to 0, node set epoch to the actual value
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint64 Epoch = 1;
|
|
||||||
// Address of object (container id + object id)
|
// Address of object (container id + object id)
|
||||||
refs.Address Address = 2 [(gogoproto.nullable) = false];
|
refs.Address Address = 1 [(gogoproto.nullable) = false];
|
||||||
// OwnerID is a wallet address
|
// OwnerID is a wallet address
|
||||||
bytes OwnerID = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "OwnerID"];
|
bytes OwnerID = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "OwnerID"];
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint32 TTL = 4;
|
|
||||||
// Token with session public key and user's signature
|
// Token with session public key and user's signature
|
||||||
session.Token Token = 5;
|
session.Token Token = 3;
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResponse is empty because we cannot guarantee permanent object removal
|
// DeleteResponse is empty because we cannot guarantee permanent object removal
|
||||||
|
@ -117,16 +114,14 @@ message DeleteRequest {
|
||||||
message DeleteResponse {}
|
message DeleteResponse {}
|
||||||
|
|
||||||
message HeadRequest {
|
message HeadRequest {
|
||||||
// Epoch should be empty on user side, node sets epoch to the actual value
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint64 Epoch = 1;
|
|
||||||
// Address of object (container id + object id)
|
// Address of object (container id + object id)
|
||||||
refs.Address Address = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "Address"];
|
refs.Address Address = 1 [(gogoproto.nullable) = false, (gogoproto.customtype) = "Address"];
|
||||||
// FullHeaders can be set true for extended headers in the object
|
// FullHeaders can be set true for extended headers in the object
|
||||||
bool FullHeaders = 3;
|
bool FullHeaders = 2;
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 4;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
message HeadResponse {
|
message HeadResponse {
|
||||||
// Object without payload
|
// Object without payload
|
||||||
|
@ -134,18 +129,16 @@ message HeadResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
message SearchRequest {
|
message SearchRequest {
|
||||||
// Epoch is set by user to 0, node set epoch to the actual value
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint64 Epoch = 1;
|
|
||||||
// Version of search query format
|
|
||||||
uint32 Version = 2;
|
|
||||||
// ContainerID for searching the object
|
// ContainerID for searching the object
|
||||||
bytes ContainerID = 3 [(gogoproto.nullable) = false, (gogoproto.customtype) = "CID"];
|
bytes ContainerID = 1 [(gogoproto.nullable) = false, (gogoproto.customtype) = "CID"];
|
||||||
// Query in the binary serialized format
|
// Query in the binary serialized format
|
||||||
bytes Query = 4;
|
bytes Query = 2;
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// QueryVersion is a version of search query format
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
uint32 QueryVersion = 3;
|
||||||
uint32 TTL = 5;
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message SearchResponse {
|
message SearchResponse {
|
||||||
|
@ -154,16 +147,14 @@ message SearchResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRangeRequest {
|
message GetRangeRequest {
|
||||||
// Epoch is set by user to 0, node set epoch to the actual value
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint64 Epoch = 1;
|
|
||||||
// Address of object (container id + object id)
|
// Address of object (container id + object id)
|
||||||
refs.Address Address = 2 [(gogoproto.nullable) = false];
|
refs.Address Address = 1 [(gogoproto.nullable) = false];
|
||||||
// Ranges of object's payload to return
|
// Ranges of object's payload to return
|
||||||
repeated Range Ranges = 3 [(gogoproto.nullable) = false];
|
repeated Range Ranges = 2 [(gogoproto.nullable) = false];
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 4;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRangeResponse {
|
message GetRangeResponse {
|
||||||
|
@ -172,18 +163,16 @@ message GetRangeResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRangeHashRequest {
|
message GetRangeHashRequest {
|
||||||
// Epoch is set by user to 0, node set epoch to the actual value
|
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
|
||||||
uint64 Epoch = 1;
|
|
||||||
// Address of object (container id + object id)
|
// Address of object (container id + object id)
|
||||||
refs.Address Address = 2 [(gogoproto.nullable) = false];
|
refs.Address Address = 1 [(gogoproto.nullable) = false];
|
||||||
// Ranges of object's payload to calculate homomorphic hash
|
// Ranges of object's payload to calculate homomorphic hash
|
||||||
repeated Range Ranges = 3 [(gogoproto.nullable) = false];
|
repeated Range Ranges = 2 [(gogoproto.nullable) = false];
|
||||||
// Salt is used to XOR object's payload ranges before hashing, it can be nil
|
// Salt is used to XOR object's payload ranges before hashing, it can be nil
|
||||||
bytes Salt = 4;
|
bytes Salt = 3;
|
||||||
// TTL must be larger than zero, it decreased in every neofs-node
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
// Deprecated: will be replaced with RequestMetaHeader (see develop branch)
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
uint32 TTL = 5;
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetRangeHashResponse {
|
message GetRangeHashResponse {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"code.cloudfoundry.org/bytefmt"
|
"code.cloudfoundry.org/bytefmt"
|
||||||
|
"github.com/nspcc-dev/neofs-proto/service"
|
||||||
"github.com/nspcc-dev/neofs-proto/session"
|
"github.com/nspcc-dev/neofs-proto/session"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -49,14 +50,11 @@ func SendPutRequest(s Service_PutClient, obj *Object, epoch uint64, ttl uint32)
|
||||||
// into header of object put request.
|
// into header of object put request.
|
||||||
func MakePutRequestHeader(obj *Object, epoch uint64, ttl uint32, token *session.Token) *PutRequest {
|
func MakePutRequestHeader(obj *Object, epoch uint64, ttl uint32, token *session.Token) *PutRequest {
|
||||||
return &PutRequest{
|
return &PutRequest{
|
||||||
R: &PutRequest_Header{
|
RequestMetaHeader: service.RequestMetaHeader{TTL: ttl, Epoch: epoch},
|
||||||
Header: &PutRequest_PutHeader{
|
R: &PutRequest_Header{Header: &PutRequest_PutHeader{
|
||||||
Epoch: epoch,
|
|
||||||
Object: obj,
|
Object: obj,
|
||||||
TTL: ttl,
|
|
||||||
Token: token,
|
Token: token,
|
||||||
},
|
}},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
111
service/meta.go
Normal file
111
service/meta.go
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neofs-proto/internal"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// MetaHeader contains meta information of request.
|
||||||
|
// It provides methods to get or set meta information meta header.
|
||||||
|
// Also contains methods to reset and restore meta header.
|
||||||
|
// Also contains methods to get or set request protocol version
|
||||||
|
MetaHeader interface {
|
||||||
|
ResetMeta() RequestMetaHeader
|
||||||
|
RestoreMeta(RequestMetaHeader)
|
||||||
|
|
||||||
|
// TTLRequest to verify and update ttl requests.
|
||||||
|
GetTTL() uint32
|
||||||
|
SetTTL(uint32)
|
||||||
|
|
||||||
|
// EpochRequest gives possibility to get or set epoch in RPC Requests.
|
||||||
|
GetEpoch() uint64
|
||||||
|
SetEpoch(uint64)
|
||||||
|
|
||||||
|
// VersionHeader allows get or set version of protocol request
|
||||||
|
VersionHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
// VersionHeader allows get or set version of protocol request
|
||||||
|
VersionHeader interface {
|
||||||
|
GetVersion() uint32
|
||||||
|
SetVersion(uint32)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TTLCondition is closure, that allows to validate request with ttl.
|
||||||
|
TTLCondition func(ttl uint32) error
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ZeroTTL is empty ttl, should produce ErrZeroTTL.
|
||||||
|
ZeroTTL = iota
|
||||||
|
|
||||||
|
// NonForwardingTTL is a ttl that allows direct connections only.
|
||||||
|
NonForwardingTTL
|
||||||
|
|
||||||
|
// SingleForwardingTTL is a ttl that allows connections through another node.
|
||||||
|
SingleForwardingTTL
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ErrZeroTTL is raised when zero ttl is passed.
|
||||||
|
ErrZeroTTL = internal.Error("zero ttl")
|
||||||
|
|
||||||
|
// ErrIncorrectTTL is raised when NonForwardingTTL is passed and NodeRole != InnerRingNode.
|
||||||
|
ErrIncorrectTTL = internal.Error("incorrect ttl")
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetVersion sets protocol version to RequestMetaHeader.
|
||||||
|
func (m *RequestMetaHeader) SetVersion(v uint32) { m.Version = v }
|
||||||
|
|
||||||
|
// SetTTL sets TTL to RequestMetaHeader.
|
||||||
|
func (m *RequestMetaHeader) SetTTL(v uint32) { m.TTL = v }
|
||||||
|
|
||||||
|
// SetEpoch sets Epoch to RequestMetaHeader.
|
||||||
|
func (m *RequestMetaHeader) SetEpoch(v uint64) { m.Epoch = v }
|
||||||
|
|
||||||
|
// ResetMeta returns current value and sets RequestMetaHeader to empty value.
|
||||||
|
func (m *RequestMetaHeader) ResetMeta() RequestMetaHeader {
|
||||||
|
cp := *m
|
||||||
|
m.Reset()
|
||||||
|
return cp
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestoreMeta sets current RequestMetaHeader to passed value.
|
||||||
|
func (m *RequestMetaHeader) RestoreMeta(v RequestMetaHeader) { *m = v }
|
||||||
|
|
||||||
|
// IRNonForwarding condition that allows NonForwardingTTL only for IR
|
||||||
|
func IRNonForwarding(role NodeRole) TTLCondition {
|
||||||
|
return func(ttl uint32) error {
|
||||||
|
if ttl == NonForwardingTTL && role != InnerRingNode {
|
||||||
|
return ErrIncorrectTTL
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessRequestTTL validates and update ttl requests.
|
||||||
|
func ProcessRequestTTL(req MetaHeader, cond ...TTLCondition) error {
|
||||||
|
var ttl = req.GetTTL()
|
||||||
|
|
||||||
|
if ttl == ZeroTTL {
|
||||||
|
return status.New(codes.InvalidArgument, ErrZeroTTL.Error()).Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range cond {
|
||||||
|
if cond[i] == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// check specific condition:
|
||||||
|
if err := cond[i](ttl); err != nil {
|
||||||
|
return status.New(codes.InvalidArgument, err.Error()).Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.SetTTL(ttl - 1)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
BIN
service/meta.pb.go
Normal file
BIN
service/meta.pb.go
Normal file
Binary file not shown.
19
service/meta.proto
Normal file
19
service/meta.proto
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
package service;
|
||||||
|
option go_package = "github.com/nspcc-dev/neofs-proto/service";
|
||||||
|
|
||||||
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
|
option (gogoproto.stable_marshaler_all) = true;
|
||||||
|
|
||||||
|
// RequestMetaHeader contains information about request meta headers
|
||||||
|
// (should be embedded into message)
|
||||||
|
message RequestMetaHeader {
|
||||||
|
// TTL must be larger than zero, it decreased in every NeoFS Node
|
||||||
|
uint32 TTL = 1;
|
||||||
|
// Epoch for user can be empty, because node sets epoch to the actual value
|
||||||
|
uint64 Epoch = 2;
|
||||||
|
// Version defines protocol version
|
||||||
|
// TODO: not used for now, should be implemented in future
|
||||||
|
uint32 Version = 3;
|
||||||
|
}
|
70
service/meta_test.go
Normal file
70
service/meta_test.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockedRequest struct {
|
||||||
|
msg string
|
||||||
|
name string
|
||||||
|
role NodeRole
|
||||||
|
code codes.Code
|
||||||
|
RequestMetaHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMetaRequest(t *testing.T) {
|
||||||
|
tests := []mockedRequest{
|
||||||
|
{
|
||||||
|
role: InnerRingNode,
|
||||||
|
name: "direct to ir node",
|
||||||
|
RequestMetaHeader: RequestMetaHeader{TTL: NonForwardingTTL},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: StorageNode,
|
||||||
|
code: codes.InvalidArgument,
|
||||||
|
msg: ErrIncorrectTTL.Error(),
|
||||||
|
name: "direct to storage node",
|
||||||
|
RequestMetaHeader: RequestMetaHeader{TTL: NonForwardingTTL},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: StorageNode,
|
||||||
|
msg: ErrZeroTTL.Error(),
|
||||||
|
code: codes.InvalidArgument,
|
||||||
|
name: "zero ttl",
|
||||||
|
RequestMetaHeader: RequestMetaHeader{TTL: ZeroTTL},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: InnerRingNode,
|
||||||
|
name: "default to ir node",
|
||||||
|
RequestMetaHeader: RequestMetaHeader{TTL: SingleForwardingTTL},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: StorageNode,
|
||||||
|
name: "default to storage node",
|
||||||
|
RequestMetaHeader: RequestMetaHeader{TTL: SingleForwardingTTL},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range tests {
|
||||||
|
tt := tests[i]
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
before := tt.GetTTL()
|
||||||
|
err := ProcessRequestTTL(&tt, IRNonForwarding(tt.role))
|
||||||
|
if tt.msg != "" {
|
||||||
|
require.Errorf(t, err, tt.msg)
|
||||||
|
|
||||||
|
state, ok := status.FromError(err)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, state.Code(), tt.code)
|
||||||
|
require.Equal(t, state.Message(), tt.msg)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEqualf(t, before, tt.GetTTL(), "ttl should be changed: %d vs %d", before, tt.GetTTL())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNodeRole_String(t *testing.T) {
|
func TestNodeRole_String(t *testing.T) {
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neofs-proto/internal"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TTLRequest to verify and update ttl requests.
|
|
||||||
type TTLRequest interface {
|
|
||||||
GetTTL() uint32
|
|
||||||
SetTTL(uint32)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ZeroTTL is empty ttl, should produce ErrZeroTTL.
|
|
||||||
ZeroTTL = iota
|
|
||||||
|
|
||||||
// NonForwardingTTL is a ttl that allows direct connections only.
|
|
||||||
NonForwardingTTL
|
|
||||||
|
|
||||||
// SingleForwardingTTL is a ttl that allows connections through another node.
|
|
||||||
SingleForwardingTTL
|
|
||||||
|
|
||||||
// ErrZeroTTL is raised when zero ttl is passed.
|
|
||||||
ErrZeroTTL = internal.Error("zero ttl")
|
|
||||||
|
|
||||||
// ErrIncorrectTTL is raised when NonForwardingTTL is passed and NodeRole != InnerRingNode.
|
|
||||||
ErrIncorrectTTL = internal.Error("incorrect ttl")
|
|
||||||
)
|
|
||||||
|
|
||||||
// CheckTTLRequest validates and update ttl requests.
|
|
||||||
func CheckTTLRequest(req TTLRequest, role NodeRole) error {
|
|
||||||
var ttl = req.GetTTL()
|
|
||||||
|
|
||||||
if ttl == ZeroTTL {
|
|
||||||
return status.New(codes.InvalidArgument, ErrZeroTTL.Error()).Err()
|
|
||||||
} else if ttl == NonForwardingTTL && role != InnerRingNode {
|
|
||||||
return status.New(codes.InvalidArgument, ErrIncorrectTTL.Error()).Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
req.SetTTL(ttl - 1)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
type mockedRequest struct {
|
|
||||||
msg string
|
|
||||||
ttl uint32
|
|
||||||
name string
|
|
||||||
role NodeRole
|
|
||||||
code codes.Code
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockedRequest) SetTTL(v uint32) { m.ttl = v }
|
|
||||||
func (m mockedRequest) GetTTL() uint32 { return m.ttl }
|
|
||||||
|
|
||||||
func TestCheckTTLRequest(t *testing.T) {
|
|
||||||
tests := []mockedRequest{
|
|
||||||
{
|
|
||||||
ttl: NonForwardingTTL,
|
|
||||||
role: InnerRingNode,
|
|
||||||
name: "direct to ir node",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ttl: NonForwardingTTL,
|
|
||||||
role: StorageNode,
|
|
||||||
code: codes.InvalidArgument,
|
|
||||||
msg: ErrIncorrectTTL.Error(),
|
|
||||||
name: "direct to storage node",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ttl: ZeroTTL,
|
|
||||||
role: StorageNode,
|
|
||||||
msg: ErrZeroTTL.Error(),
|
|
||||||
code: codes.InvalidArgument,
|
|
||||||
name: "zero ttl",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ttl: SingleForwardingTTL,
|
|
||||||
role: InnerRingNode,
|
|
||||||
name: "default to ir node",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ttl: SingleForwardingTTL,
|
|
||||||
role: StorageNode,
|
|
||||||
name: "default to storage node",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range tests {
|
|
||||||
tt := tests[i]
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
before := tt.ttl
|
|
||||||
err := CheckTTLRequest(&tt, tt.role)
|
|
||||||
if tt.msg != "" {
|
|
||||||
require.Errorf(t, err, tt.msg)
|
|
||||||
|
|
||||||
state, ok := status.FromError(err)
|
|
||||||
require.True(t, ok)
|
|
||||||
require.Equal(t, state.Code(), tt.code)
|
|
||||||
require.Equal(t, state.Message(), tt.msg)
|
|
||||||
} else {
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotEqualf(t, before, tt.ttl, "ttl should be changed: %d vs %d", before, tt.ttl)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
219
service/verify.go
Normal file
219
service/verify.go
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
|
"github.com/nspcc-dev/neofs-proto/internal"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// VerifiableRequest adds possibility to sign and verify request header.
|
||||||
|
VerifiableRequest interface {
|
||||||
|
proto.Message
|
||||||
|
Marshal() ([]byte, error)
|
||||||
|
AddSignature(*RequestVerificationHeader_Signature)
|
||||||
|
GetSignatures() []*RequestVerificationHeader_Signature
|
||||||
|
SetSignatures([]*RequestVerificationHeader_Signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaintainableRequest adds possibility to set and get (+validate)
|
||||||
|
// owner (client) public key from RequestVerificationHeader.
|
||||||
|
MaintainableRequest interface {
|
||||||
|
proto.Message
|
||||||
|
GetOwner() (*ecdsa.PublicKey, error)
|
||||||
|
SetOwner(*ecdsa.PublicKey, []byte)
|
||||||
|
GetLastPeer() (*ecdsa.PublicKey, error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ErrCannotLoadPublicKey is raised when cannot unmarshal public key from RequestVerificationHeader_Sign.
|
||||||
|
ErrCannotLoadPublicKey = internal.Error("cannot load public key")
|
||||||
|
|
||||||
|
// ErrCannotFindOwner is raised when signatures empty in GetOwner.
|
||||||
|
ErrCannotFindOwner = internal.Error("cannot find owner public key")
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetSignatures replaces signatures stored in RequestVerificationHeader.
|
||||||
|
func (m *RequestVerificationHeader) SetSignatures(signatures []*RequestVerificationHeader_Signature) {
|
||||||
|
m.Signatures = signatures
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSignature adds new Signature into RequestVerificationHeader.
|
||||||
|
func (m *RequestVerificationHeader) AddSignature(sig *RequestVerificationHeader_Signature) {
|
||||||
|
if sig == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m.Signatures = append(m.Signatures, sig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOwner adds origin (sign and public key) of owner (client) into first signature.
|
||||||
|
func (m *RequestVerificationHeader) SetOwner(pub *ecdsa.PublicKey, sign []byte) {
|
||||||
|
if len(m.Signatures) == 0 || pub == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Signatures[0].Origin = &RequestVerificationHeader_Sign{
|
||||||
|
Sign: sign,
|
||||||
|
Peer: crypto.MarshalPublicKey(pub),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOwner tries to get owner (client) public key from signatures.
|
||||||
|
// If signatures contains not empty Origin, we should try to validate,
|
||||||
|
// that session key was signed by owner (client), otherwise return error.
|
||||||
|
func (m *RequestVerificationHeader) GetOwner() (*ecdsa.PublicKey, error) {
|
||||||
|
if len(m.Signatures) == 0 {
|
||||||
|
return nil, ErrCannotFindOwner
|
||||||
|
}
|
||||||
|
|
||||||
|
// if first signature contains origin, we should try to validate session key
|
||||||
|
if m.Signatures[0].Origin != nil {
|
||||||
|
owner := crypto.UnmarshalPublicKey(m.Signatures[0].Origin.Peer)
|
||||||
|
if owner == nil {
|
||||||
|
return nil, ErrCannotLoadPublicKey
|
||||||
|
} else if err := crypto.Verify(owner, m.Signatures[0].Peer, m.Signatures[0].Origin.Sign); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not verify session token")
|
||||||
|
}
|
||||||
|
|
||||||
|
return owner, nil
|
||||||
|
} else if key := crypto.UnmarshalPublicKey(m.Signatures[0].Peer); key != nil {
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, ErrCannotLoadPublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLastPeer tries to get last peer public key from signatures.
|
||||||
|
// If signatures has zero length, returns ErrCannotFindOwner.
|
||||||
|
// If signatures has length equal to one, uses GetOwner.
|
||||||
|
// Otherwise tries to unmarshal last peer public key.
|
||||||
|
func (m *RequestVerificationHeader) GetLastPeer() (*ecdsa.PublicKey, error) {
|
||||||
|
switch ln := len(m.Signatures); ln {
|
||||||
|
case 0:
|
||||||
|
return nil, ErrCannotFindOwner
|
||||||
|
case 1:
|
||||||
|
return m.GetOwner()
|
||||||
|
default:
|
||||||
|
if key := crypto.UnmarshalPublicKey(m.Signatures[ln-1].Peer); key != nil {
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, ErrCannotLoadPublicKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSignature(key *ecdsa.PrivateKey, data []byte) (*RequestVerificationHeader_Signature, error) {
|
||||||
|
sign, err := crypto.Sign(key, data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &RequestVerificationHeader_Signature{
|
||||||
|
RequestVerificationHeader_Sign: RequestVerificationHeader_Sign{
|
||||||
|
Sign: sign,
|
||||||
|
Peer: crypto.MarshalPublicKey(&key.PublicKey),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignRequestHeader receives private key and request with RequestVerificationHeader,
|
||||||
|
// tries to marshal and sign request with passed PrivateKey, after that adds
|
||||||
|
// new signature to headers. If something went wrong, returns error.
|
||||||
|
func SignRequestHeader(key *ecdsa.PrivateKey, msg VerifiableRequest) error {
|
||||||
|
// ignore meta header
|
||||||
|
if meta, ok := msg.(MetaHeader); ok {
|
||||||
|
h := meta.ResetMeta()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
meta.RestoreMeta(h)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := msg.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
signature, err := newSignature(key, data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.AddSignature(signature)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyRequestHeader receives request with RequestVerificationHeader,
|
||||||
|
// tries to marshal and verify each signature from request.
|
||||||
|
// If something went wrong, returns error.
|
||||||
|
func VerifyRequestHeader(msg VerifiableRequest) error {
|
||||||
|
// ignore meta header
|
||||||
|
if meta, ok := msg.(MetaHeader); ok {
|
||||||
|
h := meta.ResetMeta()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
meta.RestoreMeta(h)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
signatures := msg.GetSignatures()
|
||||||
|
defer func() {
|
||||||
|
msg.SetSignatures(signatures)
|
||||||
|
}()
|
||||||
|
|
||||||
|
for i := range signatures {
|
||||||
|
msg.SetSignatures(signatures[:i])
|
||||||
|
peer := signatures[i].GetPeer()
|
||||||
|
sign := signatures[i].GetSign()
|
||||||
|
|
||||||
|
key := crypto.UnmarshalPublicKey(peer)
|
||||||
|
if key == nil {
|
||||||
|
return errors.Wrapf(ErrCannotLoadPublicKey, "%d: %02x", i, peer)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data, err := msg.Marshal(); err != nil {
|
||||||
|
return errors.Wrapf(err, "%d: %02x", i, peer)
|
||||||
|
} else if err := crypto.Verify(key, data, sign); err != nil {
|
||||||
|
return errors.Wrapf(err, "%d: %02x", i, peer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// testCustomField for test usage only.
|
||||||
|
type testCustomField [8]uint32
|
||||||
|
|
||||||
|
var _ internal.Custom = (*testCustomField)(nil)
|
||||||
|
|
||||||
|
// Reset skip, it's for test usage only.
|
||||||
|
func (t testCustomField) Reset() {}
|
||||||
|
|
||||||
|
// ProtoMessage skip, it's for test usage only.
|
||||||
|
func (t testCustomField) ProtoMessage() {}
|
||||||
|
|
||||||
|
// Size skip, it's for test usage only.
|
||||||
|
func (t testCustomField) Size() int { return 32 }
|
||||||
|
|
||||||
|
// String skip, it's for test usage only.
|
||||||
|
func (t testCustomField) String() string { return "" }
|
||||||
|
|
||||||
|
// Bytes skip, it's for test usage only.
|
||||||
|
func (t testCustomField) Bytes() []byte { return nil }
|
||||||
|
|
||||||
|
// Unmarshal skip, it's for test usage only.
|
||||||
|
func (t testCustomField) Unmarshal(data []byte) error { return nil }
|
||||||
|
|
||||||
|
// Empty skip, it's for test usage only.
|
||||||
|
func (t testCustomField) Empty() bool { return false }
|
||||||
|
|
||||||
|
// UnmarshalTo skip, it's for test usage only.
|
||||||
|
func (t testCustomField) MarshalTo(data []byte) (int, error) { return 0, nil }
|
||||||
|
|
||||||
|
// Marshal skip, it's for test usage only.
|
||||||
|
func (t testCustomField) Marshal() ([]byte, error) { return nil, nil }
|
BIN
service/verify.pb.go
Normal file
BIN
service/verify.pb.go
Normal file
Binary file not shown.
30
service/verify.proto
Normal file
30
service/verify.proto
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
package service;
|
||||||
|
option go_package = "github.com/nspcc-dev/neofs-proto/service";
|
||||||
|
|
||||||
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
|
option (gogoproto.stable_marshaler_all) = true;
|
||||||
|
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request
|
||||||
|
// (should be embedded into message).
|
||||||
|
message RequestVerificationHeader {
|
||||||
|
message Sign {
|
||||||
|
// Sign is signature of the request or session key.
|
||||||
|
bytes Sign = 1;
|
||||||
|
// Peer is compressed public key used for signature.
|
||||||
|
bytes Peer = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Signature {
|
||||||
|
// Sign is a signature and public key of the request.
|
||||||
|
Sign Sign = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// Origin used for requests, when trusted node changes it and re-sign with session key.
|
||||||
|
// If session key used for signature request, then Origin should contain
|
||||||
|
// public key of user and signed session key.
|
||||||
|
Sign Origin = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signatures is a set of signatures of every passed NeoFS Node
|
||||||
|
repeated Signature Signatures = 1;
|
||||||
|
}
|
143
service/verify_test.go
Normal file
143
service/verify_test.go
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
|
"github.com/nspcc-dev/neofs-crypto/test"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSignRequestHeader(t *testing.T) {
|
||||||
|
req := &TestRequest{
|
||||||
|
IntField: math.MaxInt32,
|
||||||
|
StringField: "TestRequestStringField",
|
||||||
|
BytesField: []byte("TestRequestBytesField"),
|
||||||
|
}
|
||||||
|
|
||||||
|
key := test.DecodeKey(0)
|
||||||
|
peer := crypto.MarshalPublicKey(&key.PublicKey)
|
||||||
|
|
||||||
|
data, err := req.Marshal()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, SignRequestHeader(key, req))
|
||||||
|
|
||||||
|
require.Len(t, req.Signatures, 1)
|
||||||
|
for i := range req.Signatures {
|
||||||
|
sign := req.Signatures[i].GetSign()
|
||||||
|
require.Equal(t, peer, req.Signatures[i].GetPeer())
|
||||||
|
require.NoError(t, crypto.Verify(&key.PublicKey, data, sign))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVerifyRequestHeader(t *testing.T) {
|
||||||
|
req := &TestRequest{
|
||||||
|
IntField: math.MaxInt32,
|
||||||
|
StringField: "TestRequestStringField",
|
||||||
|
BytesField: []byte("TestRequestBytesField"),
|
||||||
|
RequestMetaHeader: RequestMetaHeader{TTL: 10},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
req.TTL--
|
||||||
|
require.NoError(t, SignRequestHeader(test.DecodeKey(i), req))
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, VerifyRequestHeader(req))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMaintainableRequest(t *testing.T) {
|
||||||
|
req := &TestRequest{
|
||||||
|
IntField: math.MaxInt32,
|
||||||
|
StringField: "TestRequestStringField",
|
||||||
|
BytesField: []byte("TestRequestBytesField"),
|
||||||
|
RequestMetaHeader: RequestMetaHeader{TTL: 10},
|
||||||
|
}
|
||||||
|
|
||||||
|
count := 10
|
||||||
|
owner := test.DecodeKey(count + 1)
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
req.TTL--
|
||||||
|
|
||||||
|
key := test.DecodeKey(i)
|
||||||
|
require.NoError(t, SignRequestHeader(key, req))
|
||||||
|
|
||||||
|
// sign first key (session key) by owner key
|
||||||
|
if i == 0 {
|
||||||
|
sign, err := crypto.Sign(owner, crypto.MarshalPublicKey(&key.PublicKey))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
req.SetOwner(&owner.PublicKey, sign)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Good case:
|
||||||
|
require.NoError(t, VerifyRequestHeader(req))
|
||||||
|
|
||||||
|
// validate, that first key (session key) was signed with owner
|
||||||
|
signatures := req.GetSignatures()
|
||||||
|
|
||||||
|
require.Len(t, signatures, count)
|
||||||
|
|
||||||
|
pub, err := req.GetOwner()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, &owner.PublicKey, pub)
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // wrong owner:
|
||||||
|
req.Signatures[0].Origin = nil
|
||||||
|
|
||||||
|
pub, err := req.GetOwner()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NotEqual(t, &owner.PublicKey, pub)
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Wrong signatures:
|
||||||
|
copy(req.Signatures[count-1].Sign, req.Signatures[count-1].Peer)
|
||||||
|
err := VerifyRequestHeader(req)
|
||||||
|
require.EqualError(t, errors.Cause(err), crypto.ErrInvalidSignature.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVerifyAndSignRequestHeaderWithoutCloning(t *testing.T) {
|
||||||
|
key := test.DecodeKey(0)
|
||||||
|
|
||||||
|
custom := testCustomField{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
|
||||||
|
b := &TestRequest{
|
||||||
|
IntField: math.MaxInt32,
|
||||||
|
StringField: "TestRequestStringField",
|
||||||
|
BytesField: []byte("TestRequestBytesField"),
|
||||||
|
CustomField: &custom,
|
||||||
|
RequestMetaHeader: RequestMetaHeader{
|
||||||
|
TTL: math.MaxInt32 - 8,
|
||||||
|
Epoch: math.MaxInt64 - 12,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, SignRequestHeader(key, b))
|
||||||
|
require.NoError(t, VerifyRequestHeader(b))
|
||||||
|
|
||||||
|
require.Len(t, b.Signatures, 1)
|
||||||
|
require.Equal(t, custom, *b.CustomField)
|
||||||
|
require.Equal(t, uint32(math.MaxInt32-8), b.GetTTL())
|
||||||
|
require.Equal(t, uint64(math.MaxInt64-12), b.GetEpoch())
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
log.SetOutput(buf)
|
||||||
|
|
||||||
|
cp, ok := proto.Clone(b).(*TestRequest)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.NotEqual(t, b, cp)
|
||||||
|
|
||||||
|
require.Contains(t, buf.String(), "proto: don't know how to copy")
|
||||||
|
}
|
BIN
service/verify_test.pb.go
Normal file
BIN
service/verify_test.pb.go
Normal file
Binary file not shown.
18
service/verify_test.proto
Normal file
18
service/verify_test.proto
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
package service;
|
||||||
|
option go_package = "github.com/nspcc-dev/neofs-proto/service";
|
||||||
|
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
|
option (gogoproto.stable_marshaler_all) = true;
|
||||||
|
|
||||||
|
message TestRequest {
|
||||||
|
int32 IntField = 1;
|
||||||
|
string StringField = 2;
|
||||||
|
bytes BytesField = 3;
|
||||||
|
bytes CustomField = 4 [(gogoproto.customtype) = "testCustomField"];
|
||||||
|
RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
RequestVerificationHeader Header = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
}
|
Binary file not shown.
|
@ -3,6 +3,8 @@ package session;
|
||||||
option go_package = "github.com/nspcc-dev/neofs-proto/session";
|
option go_package = "github.com/nspcc-dev/neofs-proto/session";
|
||||||
|
|
||||||
import "session/types.proto";
|
import "session/types.proto";
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
option (gogoproto.stable_marshaler_all) = true;
|
option (gogoproto.stable_marshaler_all) = true;
|
||||||
|
@ -34,6 +36,10 @@ message CreateRequest {
|
||||||
// Signed Init message response (Unsigned) from server with user private key
|
// Signed Init message response (Unsigned) from server with user private key
|
||||||
session.Token Signed = 2;
|
session.Token Signed = 2;
|
||||||
}
|
}
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateResponse {
|
message CreateResponse {
|
||||||
|
|
Binary file not shown.
|
@ -2,6 +2,8 @@ syntax = "proto3";
|
||||||
package state;
|
package state;
|
||||||
option go_package = "github.com/nspcc-dev/neofs-proto/state";
|
option go_package = "github.com/nspcc-dev/neofs-proto/state";
|
||||||
|
|
||||||
|
import "service/meta.proto";
|
||||||
|
import "service/verify.proto";
|
||||||
import "bootstrap/types.proto";
|
import "bootstrap/types.proto";
|
||||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||||
|
|
||||||
|
@ -19,10 +21,20 @@ service Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetmapRequest message to request current node netmap
|
// NetmapRequest message to request current node netmap
|
||||||
message NetmapRequest {}
|
message NetmapRequest {
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
// MetricsRequest message to request node metrics
|
// MetricsRequest message to request node metrics
|
||||||
message MetricsRequest {}
|
message MetricsRequest {
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
// MetricsResponse contains [][]byte,
|
// MetricsResponse contains [][]byte,
|
||||||
// every []byte is marshaled MetricFamily proto message
|
// every []byte is marshaled MetricFamily proto message
|
||||||
|
@ -32,7 +44,12 @@ message MetricsResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HealthRequest message to check current state
|
// HealthRequest message to check current state
|
||||||
message HealthRequest {}
|
message HealthRequest {
|
||||||
|
// RequestMetaHeader contains information about request meta headers (should be embedded into message)
|
||||||
|
service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message)
|
||||||
|
service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
// HealthResponse message with current state
|
// HealthResponse message with current state
|
||||||
message HealthResponse {
|
message HealthResponse {
|
||||||
|
|
Loading…
Reference in a new issue