forked from TrueCloudLab/frostfs-api-go
Compare commits
12 commits
f69d2ad83c
...
cd2e46a17c
Author | SHA1 | Date | |
---|---|---|---|
cd2e46a17c | |||
c46cd37f71 | |||
ec0d0274fa | |||
73fde0e37c | |||
611f73ad0f | |||
e073c996fc | |||
d005bf0393 | |||
63eb4dc3ea | |||
3f7cb1b5ef | |||
bd67469f43 | |||
3af7645abf | |||
5faee63f60 |
31 changed files with 603 additions and 587 deletions
70
.github/logo.svg
vendored
70
.github/logo.svg
vendored
|
@ -1,70 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 184.2 51.8" style="enable-background:new 0 0 184.2 51.8;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{display:none;}
|
|
||||||
.st1{display:inline;}
|
|
||||||
.st2{fill:#01E397;}
|
|
||||||
.st3{display:inline;fill:#010032;}
|
|
||||||
.st4{display:inline;fill:#00E599;}
|
|
||||||
.st5{display:inline;fill:#00AF92;}
|
|
||||||
.st6{fill:#00C3E5;}
|
|
||||||
</style>
|
|
||||||
<g id="Layer_2">
|
|
||||||
<g id="Layer_1-2" class="st0">
|
|
||||||
<g class="st1">
|
|
||||||
<path class="st2" d="M146.6,18.3v7.2h10.9V29h-10.9v10.7h-4V14.8h18v3.5H146.6z"/>
|
|
||||||
<path class="st2" d="M180,15.7c1.7,0.9,3,2.2,4,3.8l-3,2.7c-0.6-1.3-1.5-2.4-2.6-3.3c-1.3-0.7-2.8-1-4.3-1
|
|
||||||
c-1.4-0.1-2.8,0.3-4,1.1c-0.9,0.5-1.5,1.5-1.4,2.6c0,1,0.5,1.9,1.4,2.4c1.5,0.8,3.2,1.3,4.9,1.5c1.9,0.3,3.7,0.8,5.4,1.6
|
|
||||||
c1.2,0.5,2.2,1.3,2.9,2.3c0.6,1,1,2.2,0.9,3.4c0,1.4-0.5,2.7-1.3,3.8c-0.9,1.2-2.1,2.1-3.5,2.6c-1.7,0.6-3.4,0.9-5.2,0.8
|
|
||||||
c-5,0-8.6-1.6-10.7-5l2.9-2.8c0.7,1.4,1.8,2.5,3.1,3.3c1.5,0.7,3.1,1.1,4.7,1c1.5,0.1,2.9-0.2,4.2-0.9c0.9-0.5,1.5-1.5,1.5-2.6
|
|
||||||
c0-0.9-0.5-1.8-1.3-2.2c-1.5-0.7-3.1-1.2-4.8-1.5c-1.9-0.3-3.7-0.8-5.5-1.5c-1.2-0.5-2.2-1.4-3-2.4c-0.6-1-1-2.2-0.9-3.4
|
|
||||||
c0-1.4,0.4-2.7,1.2-3.8c0.8-1.2,2-2.2,3.3-2.8c1.6-0.7,3.4-1.1,5.2-1C176.1,14.3,178.2,14.8,180,15.7z"/>
|
|
||||||
</g>
|
|
||||||
<path class="st3" d="M73.3,16.3c1.9,1.9,2.9,4.5,2.7,7.1v15.9h-4V24.8c0-2.6-0.5-4.5-1.6-5.7c-1.2-1.2-2.8-1.8-4.5-1.7
|
|
||||||
c-1.3,0-2.5,0.3-3.7,0.8c-1.2,0.7-2.2,1.7-2.9,2.9c-0.8,1.5-1.1,3.2-1.1,4.9v13.3h-4V15.1l3.6,1.5v1.7c0.8-1.5,2.1-2.6,3.6-3.3
|
|
||||||
c1.5-0.8,3.2-1.2,4.9-1.1C68.9,13.8,71.3,14.7,73.3,16.3z"/>
|
|
||||||
<path class="st3" d="M104.4,28.3H85.6c0.1,2.2,1,4.3,2.5,5.9c1.5,1.4,3.5,2.2,5.6,2.1c1.6,0.1,3.2-0.2,4.6-0.9
|
|
||||||
c1.1-0.6,2-1.6,2.5-2.8l3.3,1.8c-0.9,1.7-2.3,3.1-4,4c-2,1-4.2,1.5-6.4,1.4c-3.7,0-6.7-1.1-8.8-3.4s-3.2-5.5-3.2-9.6s1-7.2,3-9.5
|
|
||||||
s5-3.4,8.7-3.4c2.1-0.1,4.2,0.5,6.1,1.5c1.6,1,3,2.5,3.8,4.2c0.9,1.8,1.3,3.9,1.3,5.9C104.6,26.4,104.6,27.4,104.4,28.3z
|
|
||||||
M88.1,19.3c-1.4,1.5-2.2,3.4-2.4,5.5h15.1c-0.2-2-1-3.9-2.3-5.5c-1.4-1.3-3.2-2-5.1-1.9C91.5,17.3,89.6,18,88.1,19.3z"/>
|
|
||||||
<path class="st3" d="M131,17.3c2.2,2.3,3.2,5.5,3.2,9.5s-1,7.3-3.2,9.6s-5.1,3.4-8.8,3.4s-6.7-1.1-8.9-3.4s-3.2-5.5-3.2-9.6
|
|
||||||
s1.1-7.2,3.2-9.5s5.1-3.4,8.9-3.4S128.9,15,131,17.3z M116.2,19.9c-1.5,2-2.2,4.4-2.1,6.9c-0.2,2.5,0.6,5,2.1,7
|
|
||||||
c1.5,1.7,3.7,2.7,6,2.6c2.3,0.1,4.4-0.9,5.9-2.6c1.5-2,2.3-4.5,2.1-7c0.1-2.5-0.6-4.9-2.1-6.9c-1.5-1.7-3.6-2.7-5.9-2.6
|
|
||||||
C119.9,17.2,117.7,18.2,116.2,19.9z"/>
|
|
||||||
<polygon class="st4" points="0,9.1 0,43.7 22.5,51.8 22.5,16.9 46.8,7.9 24.8,0 "/>
|
|
||||||
<polygon class="st5" points="24.3,17.9 24.3,36.8 46.8,44.9 46.8,9.6 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path class="st6" d="M41.6,17.5H28.2v6.9h10.4v3.3H28.2v10.2h-3.9V14.2h17.2V17.5z"/>
|
|
||||||
<path class="st6" d="M45.8,37.9v-18h3.3l0.4,3.2c0.5-1.2,1.2-2.1,2.1-2.7c0.9-0.6,2.1-0.9,3.5-0.9c0.4,0,0.7,0,1.1,0.1
|
|
||||||
c0.4,0.1,0.7,0.2,0.9,0.3l-0.5,3.4c-0.3-0.1-0.6-0.2-0.9-0.2C55.4,23,54.9,23,54.4,23c-0.7,0-1.5,0.2-2.2,0.6
|
|
||||||
c-0.7,0.4-1.3,1-1.8,1.8s-0.7,1.8-0.7,3v9.5H45.8z"/>
|
|
||||||
<path class="st6" d="M68.6,19.6c1.8,0,3.3,0.4,4.6,1.1c1.3,0.7,2.4,1.8,3.1,3.2s1.1,3.1,1.1,5c0,1.9-0.4,3.6-1.1,5
|
|
||||||
c-0.8,1.4-1.8,2.5-3.1,3.2c-1.3,0.7-2.9,1.1-4.6,1.1s-3.3-0.4-4.6-1.1c-1.3-0.7-2.4-1.8-3.2-3.2c-0.8-1.4-1.2-3.1-1.2-5
|
|
||||||
c0-1.9,0.4-3.6,1.2-5s1.8-2.5,3.2-3.2C65.3,19.9,66.8,19.6,68.6,19.6z M68.6,22.6c-1.1,0-2,0.2-2.8,0.7c-0.8,0.5-1.3,1.2-1.7,2.1
|
|
||||||
s-0.6,2.1-0.6,3.5c0,1.3,0.2,2.5,0.6,3.4s1,1.7,1.7,2.2s1.7,0.7,2.8,0.7c1.1,0,2-0.2,2.7-0.7c0.7-0.5,1.3-1.2,1.7-2.2
|
|
||||||
s0.6-2.1,0.6-3.4c0-1.4-0.2-2.5-0.6-3.5s-1-1.6-1.7-2.1C70.6,22.8,69.6,22.6,68.6,22.6z"/>
|
|
||||||
<path class="st6" d="M89.2,38.3c-1.8,0-3.4-0.3-4.9-1c-1.5-0.7-2.7-1.7-3.5-3l2.7-2.3c0.5,1,1.3,1.8,2.3,2.4
|
|
||||||
c1,0.6,2.2,0.9,3.6,0.9c1.1,0,2-0.2,2.6-0.6c0.6-0.4,1-0.9,1-1.6c0-0.5-0.2-0.9-0.5-1.2s-0.9-0.6-1.7-0.8l-3.8-0.8
|
|
||||||
c-1.9-0.4-3.3-1-4.1-1.9c-0.8-0.9-1.2-1.9-1.2-3.3c0-1,0.3-1.9,0.9-2.7c0.6-0.8,1.4-1.5,2.5-2s2.5-0.8,4-0.8c1.8,0,3.3,0.3,4.6,1
|
|
||||||
c1.3,0.6,2.2,1.5,2.9,2.7l-2.7,2.2c-0.5-1-1.1-1.7-2-2.1c-0.9-0.5-1.8-0.7-2.8-0.7c-0.8,0-1.4,0.1-2,0.3c-0.6,0.2-1,0.5-1.3,0.8
|
|
||||||
c-0.3,0.3-0.4,0.7-0.4,1.2c0,0.5,0.2,0.9,0.5,1.3s1,0.6,1.9,0.8l4.1,0.9c1.7,0.3,2.9,0.9,3.7,1.7c0.7,0.8,1.1,1.8,1.1,2.9
|
|
||||||
c0,1.2-0.3,2.2-0.9,3c-0.6,0.9-1.5,1.6-2.6,2C92.1,38.1,90.7,38.3,89.2,38.3z"/>
|
|
||||||
<path class="st6" d="M112.8,19.9v3H99.3v-3H112.8z M106.6,14.6v17.9c0,0.9,0.2,1.5,0.7,1.9c0.5,0.4,1.1,0.6,1.9,0.6
|
|
||||||
c0.6,0,1.2-0.1,1.7-0.3c0.5-0.2,0.9-0.5,1.3-0.8l0.9,2.8c-0.6,0.5-1.2,0.9-2,1.1c-0.8,0.3-1.7,0.4-2.7,0.4c-1,0-2-0.2-2.8-0.5
|
|
||||||
s-1.5-0.9-2-1.6c-0.5-0.8-0.7-1.7-0.8-3V15.7L106.6,14.6z"/>
|
|
||||||
<path d="M137.9,17.5h-13.3v6.9h10.4v3.3h-10.4v10.2h-3.9V14.2h17.2V17.5z"/>
|
|
||||||
<path d="M150.9,13.8c2.1,0,4,0.4,5.5,1.2c1.6,0.8,2.9,2,4,3.5l-2.6,2.5c-0.9-1.4-1.9-2.4-3.1-3c-1.1-0.6-2.5-0.9-4-0.9
|
|
||||||
c-1.2,0-2.1,0.2-2.8,0.5c-0.7,0.3-1.3,0.7-1.6,1.2c-0.3,0.5-0.5,1.1-0.5,1.7c0,0.7,0.3,1.4,0.8,1.9c0.5,0.6,1.5,1,2.9,1.3
|
|
||||||
l4.8,1.1c2.3,0.5,3.9,1.3,4.9,2.3c1,1,1.4,2.3,1.4,3.9c0,1.5-0.4,2.7-1.2,3.8c-0.8,1.1-1.9,1.9-3.3,2.5s-3.1,0.9-5,0.9
|
|
||||||
c-1.7,0-3.2-0.2-4.5-0.6c-1.3-0.4-2.5-1-3.5-1.8c-1-0.7-1.8-1.6-2.5-2.6l2.7-2.7c0.5,0.8,1.1,1.6,1.9,2.2
|
|
||||||
c0.8,0.7,1.7,1.2,2.7,1.5c1,0.4,2.2,0.5,3.4,0.5c1.1,0,2.1-0.1,2.9-0.4c0.8-0.3,1.4-0.7,1.8-1.2c0.4-0.5,0.6-1.1,0.6-1.9
|
|
||||||
c0-0.7-0.2-1.3-0.7-1.8c-0.5-0.5-1.3-0.9-2.6-1.2l-5.2-1.2c-1.4-0.3-2.6-0.8-3.6-1.3c-0.9-0.6-1.6-1.3-2.1-2.1s-0.7-1.8-0.7-2.8
|
|
||||||
c0-1.3,0.4-2.6,1.1-3.7c0.7-1.1,1.8-2,3.2-2.6C147.3,14.1,148.9,13.8,150.9,13.8z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 5.5 KiB |
21
.github/workflows/dco.yml
vendored
21
.github/workflows/dco.yml
vendored
|
@ -1,21 +0,0 @@
|
||||||
name: DCO check
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
commits_check_job:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Commits Check
|
|
||||||
steps:
|
|
||||||
- name: Get PR Commits
|
|
||||||
id: 'get-pr-commits'
|
|
||||||
uses: tim-actions/get-pr-commits@master
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: DCO Check
|
|
||||||
uses: tim-actions/dco@master
|
|
||||||
with:
|
|
||||||
commits: ${{ steps.get-pr-commits.outputs.commits }}
|
|
64
.github/workflows/go.yml
vendored
64
.github/workflows/go.yml
vendored
|
@ -1,64 +0,0 @@
|
||||||
name: neofs-api-go tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- '*.md'
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- '*.md'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go: [ '1.17.x', '1.18.x', '1.19.x' ]
|
|
||||||
steps:
|
|
||||||
- name: Setup go
|
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go }}
|
|
||||||
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Cache go mod
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/go/pkg/mod
|
|
||||||
key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('**/go.sum') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-go-${{ matrix.go }}-
|
|
||||||
|
|
||||||
- name: Get dependencies
|
|
||||||
run: make dep
|
|
||||||
|
|
||||||
- name: Run go test
|
|
||||||
run: go test -coverprofile=coverage.txt -covermode=atomic ./...
|
|
||||||
|
|
||||||
- name: Codecov
|
|
||||||
env:
|
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
run: bash <(curl -s https://codecov.io/bash)
|
|
||||||
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Setup go
|
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: 1.19
|
|
||||||
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: golangci-lint
|
|
||||||
uses: golangci/golangci-lint-action@v3
|
|
||||||
with:
|
|
||||||
version: v1.48.0
|
|
||||||
only-new-issues: true
|
|
10
.gitlint
Normal file
10
.gitlint
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[general]
|
||||||
|
fail-without-commits=true
|
||||||
|
contrib=CC1
|
||||||
|
|
||||||
|
[title-match-regex]
|
||||||
|
regex=^\[\#[0-9]+\]\s
|
||||||
|
|
||||||
|
[ignore-by-title]
|
||||||
|
regex=^Release(.*)
|
||||||
|
ignore=title-match-regex
|
|
@ -11,7 +11,7 @@ run:
|
||||||
|
|
||||||
skip-files:
|
skip-files:
|
||||||
- (^|.*/)grpc/(.*)
|
- (^|.*/)grpc/(.*)
|
||||||
|
|
||||||
# output configuration options
|
# output configuration options
|
||||||
output:
|
output:
|
||||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||||
|
@ -64,4 +64,4 @@ issues:
|
||||||
|
|
||||||
- linters: # ignore SA6002 since we use pool of []byte, however we can switch to *bytes.Buffer
|
- linters: # ignore SA6002 since we use pool of []byte, however we can switch to *bytes.Buffer
|
||||||
- staticcheck
|
- staticcheck
|
||||||
text: "SA6002:"
|
text: "SA6002:"
|
||||||
|
|
30
.pre-commit-config.yaml
Normal file
30
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
ci:
|
||||||
|
autofix_prs: false
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.4.0
|
||||||
|
hooks:
|
||||||
|
- id: check-added-large-files
|
||||||
|
- id: check-case-conflict
|
||||||
|
- id: check-executables-have-shebangs
|
||||||
|
- id: check-shebang-scripts-are-executable
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: check-json
|
||||||
|
- id: check-xml
|
||||||
|
- id: check-yaml
|
||||||
|
- id: trailing-whitespace
|
||||||
|
args: [--markdown-linebreak-ext=md]
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
exclude: ".key$"
|
||||||
|
|
||||||
|
- repo: https://github.com/golangci/golangci-lint
|
||||||
|
rev: v1.51.2
|
||||||
|
hooks:
|
||||||
|
- id: golangci-lint
|
||||||
|
|
||||||
|
- repo: https://github.com/jorisroovers/gitlint
|
||||||
|
rev: v0.18.0
|
||||||
|
hooks:
|
||||||
|
- id: gitlint
|
||||||
|
stages: [commit-msg]
|
34
CHANGELOG.md
34
CHANGELOG.md
|
@ -22,7 +22,7 @@
|
||||||
- Mark all expiration methods as deprecated (#417)
|
- Mark all expiration methods as deprecated (#417)
|
||||||
|
|
||||||
### Updated
|
### Updated
|
||||||
- Minimal go version to 1.17 (#412)
|
- Minimal go version to 1.17 (#412)
|
||||||
- `neofs-crypto` to `v0.4.0` (#412)
|
- `neofs-crypto` to `v0.4.0` (#412)
|
||||||
- `google.golang.org/grpc` to `v1.48.0` (#415)
|
- `google.golang.org/grpc` to `v1.48.0` (#415)
|
||||||
- `google.golang.org/protobuf` to `v1.28.0` (#415)
|
- `google.golang.org/protobuf` to `v1.28.0` (#415)
|
||||||
|
@ -60,7 +60,7 @@ NeoFS API v2.13 support
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Incompatible changes in signature scheme (#380)
|
- Incompatible changes in signature scheme (#380)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Public URI-parsing function `client.ParseURI()` (#383)
|
- Public URI-parsing function `client.ParseURI()` (#383)
|
||||||
|
|
||||||
|
@ -92,9 +92,9 @@ NeoFS API v2.12 support
|
||||||
|
|
||||||
## [2.11.0] - 2021-12-02 - Sinjido (신지도, 薪智島)
|
## [2.11.0] - 2021-12-02 - Sinjido (신지도, 薪智島)
|
||||||
|
|
||||||
NeoFS API v2.11 support. High level packages are moved to
|
NeoFS API v2.11 support. High level packages are moved to
|
||||||
[neofs-sdk-go](https://github.com/nspcc-dev/neofs-sdk-go) repository.
|
[neofs-sdk-go](https://github.com/nspcc-dev/neofs-sdk-go) repository.
|
||||||
Repository restructured as Go module version 2 and synced with
|
Repository restructured as Go module version 2 and synced with
|
||||||
[neofs-api](https://github.com/nspcc-dev/neofs-api) release version.
|
[neofs-api](https://github.com/nspcc-dev/neofs-api) release version.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -109,7 +109,7 @@ Repository restructured as Go module version 2 and synced with
|
||||||
- neofs-api-go is now Go module version 2 (#201)
|
- neofs-api-go is now Go module version 2 (#201)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- All packages from `pkg` moved to
|
- All packages from `pkg` moved to
|
||||||
[neofs-sdk-go](https://github.com/nspcc-dev/neofs-sdk-go) (#201)
|
[neofs-sdk-go](https://github.com/nspcc-dev/neofs-sdk-go) (#201)
|
||||||
|
|
||||||
## [1.30.0] - 2021-10-19 - Udo (우도, 牛島)
|
## [1.30.0] - 2021-10-19 - Udo (우도, 牛島)
|
||||||
|
@ -126,7 +126,7 @@ NeoFS API v2.10 support.
|
||||||
- pkg/client callback to parse internal response information (#337)
|
- pkg/client callback to parse internal response information (#337)
|
||||||
- Service filter type in extended ACL from API v2.10 (#338)
|
- Service filter type in extended ACL from API v2.10 (#338)
|
||||||
- Enhanced network info structures from API v2.10 (#339)
|
- Enhanced network info structures from API v2.10 (#339)
|
||||||
- Well-known public-append basic ACL constant (#341)
|
- Well-known public-append basic ACL constant (#341)
|
||||||
- Native contract names support (#351)
|
- Native contract names support (#351)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -258,7 +258,7 @@ Raw client and support of NeoFS API v2.5.0 "Jebudo" release.
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Raw client for peer to peer communication.
|
- Raw client for peer to peer communication.
|
||||||
- `client.WithKey` option to sign messages with different keys within single
|
- `client.WithKey` option to sign messages with different keys within single
|
||||||
client.
|
client.
|
||||||
- `Content-Type` well-known object attribute constant.
|
- `Content-Type` well-known object attribute constant.
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ Raw client and support of NeoFS API v2.5.0 "Jebudo" release.
|
||||||
|
|
||||||
Support changes from NeoFS API v2.4.0 "Ganghwado" release.
|
Support changes from NeoFS API v2.4.0 "Ganghwado" release.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `netmap.NetworkInfo` definitions in `v2` and `pkg/netmap`.
|
- `netmap.NetworkInfo` definitions in `v2` and `pkg/netmap`.
|
||||||
- `netmap.NetworkInfo` RPC support in `pkg/client`.
|
- `netmap.NetworkInfo` RPC support in `pkg/client`.
|
||||||
|
@ -322,7 +322,7 @@ Support changes from NeoFS API v2.2.1 release.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Remarks of the updated linter.
|
- Remarks of the updated linter.
|
||||||
|
|
||||||
## [1.22.0] - 2020-12-30 - Yeouido (여의도, 汝矣島)
|
## [1.22.0] - 2020-12-30 - Yeouido (여의도, 汝矣島)
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ Support changes from NeoFS API v2.2.0 "Yeouido" release.
|
||||||
- Support of `StorageGroup` message.
|
- Support of `StorageGroup` message.
|
||||||
- Support of `DataAuditResult` message.
|
- Support of `DataAuditResult` message.
|
||||||
- Stringer and string parser for `Checksum` type of client library.
|
- Stringer and string parser for `Checksum` type of client library.
|
||||||
- Stringer and string parser for `Type` message.
|
- Stringer and string parser for `Type` message.
|
||||||
- Stringer and string parser for `Type` type of client library.
|
- Stringer and string parser for `Type` type of client library.
|
||||||
- `AddTypeFilter` method on `SearchFilters` type of client library
|
- `AddTypeFilter` method on `SearchFilters` type of client library
|
||||||
that adds filter by object type.
|
that adds filter by object type.
|
||||||
|
@ -350,7 +350,7 @@ Support changes from NeoFS API v2.2.0 "Yeouido" release.
|
||||||
- `Container.SetNonceUUID` setter of container nonce in UUID format.
|
- `Container.SetNonceUUID` setter of container nonce in UUID format.
|
||||||
- `NewVerifiedContainerFromV2` container constructor that preliminary
|
- `NewVerifiedContainerFromV2` container constructor that preliminary
|
||||||
checks if container message argument meets NeoFS API V2 specification.
|
checks if container message argument meets NeoFS API V2 specification.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `Container.Nonce`/`Container.SetNonce` marked as deprecated.
|
- `Container.Nonce`/`Container.SetNonce` marked as deprecated.
|
||||||
|
@ -368,7 +368,7 @@ Support neofs-api v2.1.1.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `client.GetVerifiedContainerStructure` function to check
|
- `client.GetVerifiedContainerStructure` function to check
|
||||||
that the container structure matches the requested identifier.
|
that the container structure matches the requested identifier.
|
||||||
|
|
||||||
## [1.21.0] - 2020-12-11 - Modo (모도, 茅島)
|
## [1.21.0] - 2020-12-11 - Modo (모도, 茅島)
|
||||||
|
@ -391,7 +391,7 @@ Support neofs-api v2.1.1.
|
||||||
|
|
||||||
### Renamed
|
### Renamed
|
||||||
|
|
||||||
- `AddLeafFilter` to `AddPhyFilter`
|
- `AddLeafFilter` to `AddPhyFilter`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -425,9 +425,9 @@ Support neofs-api v2.1.1.
|
||||||
|
|
||||||
## [1.20.0] - 2020-11-16 - Jindo (진도, 珍島)
|
## [1.20.0] - 2020-11-16 - Jindo (진도, 珍島)
|
||||||
|
|
||||||
Major API refactoring and simplification. From now on this library will have
|
Major API refactoring and simplification. From now on this library will have
|
||||||
backward compatibility and support of major versions of NeoFS-API by having
|
backward compatibility and support of major versions of NeoFS-API by having
|
||||||
**version specific** files in `vN` dirs and **version independent** SDK
|
**version specific** files in `vN` dirs and **version independent** SDK
|
||||||
structures and client in `pkg`. This version supports NeoFS-API v2.0.X
|
structures and client in `pkg`. This version supports NeoFS-API v2.0.X
|
||||||
|
|
||||||
|
|
||||||
|
|
0
Makefile
Normal file → Executable file
0
Makefile
Normal file → Executable file
|
@ -1,7 +1,7 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
// SysAttributePrefix is a prefix of key to system attribute.
|
// SysAttributePrefix is a prefix of key to system attribute.
|
||||||
const SysAttributePrefix = "__NEOFS__"
|
const SysAttributePrefix = "__FROSTFS__"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// SysAttributeSubnet is a string ID of container's storage subnet.
|
// SysAttributeSubnet is a string ID of container's storage subnet.
|
||||||
|
@ -17,6 +17,23 @@ const (
|
||||||
SysAttributeHomomorphicHashing = SysAttributePrefix + "DISABLE_HOMOMORPHIC_HASHING"
|
SysAttributeHomomorphicHashing = SysAttributePrefix + "DISABLE_HOMOMORPHIC_HASHING"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SysAttributePrefixNeoFS is a prefix of key to system attribute.
|
||||||
|
const SysAttributePrefixNeoFS = "__NEOFS__"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SysAttributeSubnetNeoFS is a string ID of container's storage subnet.
|
||||||
|
SysAttributeSubnetNeoFS = SysAttributePrefixNeoFS + "SUBNET"
|
||||||
|
|
||||||
|
// SysAttributeNameNeoFS is a string of human-friendly container name registered as the domain in NNS contract.
|
||||||
|
SysAttributeNameNeoFS = SysAttributePrefixNeoFS + "NAME"
|
||||||
|
|
||||||
|
// SysAttributeZoneNeoFS is a string of zone for container name.
|
||||||
|
SysAttributeZoneNeoFS = SysAttributePrefixNeoFS + "ZONE"
|
||||||
|
|
||||||
|
// SysAttributeHomomorphicHashingNeoFS is a container's homomorphic hashing state.
|
||||||
|
SysAttributeHomomorphicHashingNeoFS = SysAttributePrefixNeoFS + "DISABLE_HOMOMORPHIC_HASHING"
|
||||||
|
)
|
||||||
|
|
||||||
// SysAttributeZoneDefault is a default value for SysAttributeZone attribute.
|
// SysAttributeZoneDefault is a default value for SysAttributeZone attribute.
|
||||||
const SysAttributeZoneDefault = "container"
|
const SysAttributeZoneDefault = "container"
|
||||||
|
|
||||||
|
@ -33,7 +50,7 @@ const disabledHomomorphicHashingValue = "true"
|
||||||
// See also SetHomomorphicHashingState.
|
// See also SetHomomorphicHashingState.
|
||||||
func (c Container) HomomorphicHashingState() bool {
|
func (c Container) HomomorphicHashingState() bool {
|
||||||
for i := range c.attr {
|
for i := range c.attr {
|
||||||
if c.attr[i].GetKey() == SysAttributeHomomorphicHashing {
|
if c.attr[i].GetKey() == SysAttributeHomomorphicHashing || c.attr[i].GetKey() == SysAttributeHomomorphicHashingNeoFS {
|
||||||
return c.attr[i].GetValue() != disabledHomomorphicHashingValue
|
return c.attr[i].GetValue() != disabledHomomorphicHashingValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +67,7 @@ func (c Container) HomomorphicHashingState() bool {
|
||||||
// See also HomomorphicHashingState.
|
// See also HomomorphicHashingState.
|
||||||
func (c *Container) SetHomomorphicHashingState(enable bool) {
|
func (c *Container) SetHomomorphicHashingState(enable bool) {
|
||||||
for i := range c.attr {
|
for i := range c.attr {
|
||||||
if c.attr[i].GetKey() == SysAttributeHomomorphicHashing {
|
if c.attr[i].GetKey() == SysAttributeHomomorphicHashing || c.attr[i].GetKey() == SysAttributeHomomorphicHashingNeoFS {
|
||||||
if enable {
|
if enable {
|
||||||
// approach without allocation/waste
|
// approach without allocation/waste
|
||||||
// coping works since the attributes
|
// coping works since the attributes
|
||||||
|
|
10
container/grpc/types.pb.go
generated
10
container/grpc/types.pb.go
generated
|
@ -131,16 +131,16 @@ func (x *Container) GetPlacementPolicy() *grpc1.PlacementPolicy {
|
||||||
//
|
//
|
||||||
// There are some "well-known" attributes affecting system behaviour:
|
// There are some "well-known" attributes affecting system behaviour:
|
||||||
//
|
//
|
||||||
// - __NEOFS__SUBNET \
|
// - [ __NEOFS__SUBNET | __FROSTFS__SUBNET ] \
|
||||||
// String ID of a container's storage subnet. Any container can be attached to
|
// String ID of a container's storage subnet. Any container can be attached to
|
||||||
// one subnet only.
|
// one subnet only.
|
||||||
// - __NEOFS__NAME \
|
// - [ __NEOFS__NAME | __FROSTFS__NAME ] \
|
||||||
// String of a human-friendly container name registered as a domain in
|
// String of a human-friendly container name registered as a domain in
|
||||||
// NNS contract.
|
// NNS contract.
|
||||||
// - __NEOFS__ZONE \
|
// - [ __NEOFS__ZONE | __FROSTFS__ZONE ] \
|
||||||
// String of a zone for `__NEOFS__NAME`. Used as a TLD of a domain name in NNS
|
// String of a zone for `__NEOFS__NAME`/`__FROSTFS__NAME`. Used as a TLD of a domain name in NNS
|
||||||
// contract. If no zone is specified, use default zone: `container`.
|
// contract. If no zone is specified, use default zone: `container`.
|
||||||
// - __NEOFS__DISABLE_HOMOMORPHIC_HASHING \
|
// - [ __NEOFS__DISABLE_HOMOMORPHIC_HASHING | __FROSTFS__DISABLE_HOMOMORPHIC_HASHING ] \
|
||||||
// Disables homomorphic hashing for the container if the value equals "true" string.
|
// Disables homomorphic hashing for the container if the value equals "true" string.
|
||||||
// Any other values are interpreted as missing attribute. Container could be
|
// Any other values are interpreted as missing attribute. Container could be
|
||||||
// accepted in a NeoFS network only if the global network hashing configuration
|
// accepted in a NeoFS network only if the global network hashing configuration
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -1,10 +1,11 @@
|
||||||
module git.frostfs.info/TrueCloudLab/frostfs-api-go/v2
|
module git.frostfs.info/TrueCloudLab/frostfs-api-go/v2
|
||||||
|
|
||||||
go 1.17
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0
|
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
golang.org/x/sync v0.1.0
|
||||||
google.golang.org/grpc v1.48.0
|
google.golang.org/grpc v1.48.0
|
||||||
google.golang.org/protobuf v1.28.0
|
google.golang.org/protobuf v1.28.0
|
||||||
)
|
)
|
||||||
|
@ -13,10 +14,11 @@ require (
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 // indirect
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.8 // indirect
|
||||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
|
golang.org/x/sys v0.1.0 // indirect
|
||||||
golang.org/x/text v0.3.3 // indirect
|
golang.org/x/text v0.3.3 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
|
|
9
go.sum
9
go.sum
|
@ -46,8 +46,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||||
|
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||||
|
@ -82,13 +83,16 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||||
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
@ -98,7 +102,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
|
2
lock/grpc/types.pb.go
generated
2
lock/grpc/types.pb.go
generated
|
@ -23,7 +23,7 @@ const (
|
||||||
|
|
||||||
// Lock objects protects a list of objects from being deleted. The lifetime of a
|
// Lock objects protects a list of objects from being deleted. The lifetime of a
|
||||||
// lock object is limited similar to regular objects in
|
// lock object is limited similar to regular objects in
|
||||||
// `__NEOFS__EXPIRATION_EPOCH` attribute. Lock object MUST have expiration epoch.
|
// `__NEOFS__EXPIRATION_EPOCH`/`__FROSTFS__EXPIRATION_EPOCH` attribute. Lock object MUST have expiration epoch.
|
||||||
// It is impossible to delete a lock object via ObjectService.Delete RPC call.
|
// It is impossible to delete a lock object via ObjectService.Delete RPC call.
|
||||||
type Lock struct {
|
type Lock struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
|
|
|
@ -9,7 +9,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// prefix of keys to subnet attributes.
|
// prefix of keys to subnet attributes.
|
||||||
const attrSubnetPrefix = "__NEOFS__SUBNET_"
|
const attrSubnetPrefix = "__FROSTFS__SUBNET_"
|
||||||
|
|
||||||
|
// prefix of keys to subnet attributes.
|
||||||
|
const attrSubnetPrefixNeoFS = "__NEOFS__SUBNET_"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// subnet attribute's value denoting subnet entry
|
// subnet attribute's value denoting subnet entry
|
||||||
|
@ -62,7 +65,7 @@ func subnetAttributeKey(id *refs.SubnetID) string {
|
||||||
// - disables non-zero subnet;
|
// - disables non-zero subnet;
|
||||||
// - enables zero subnet.
|
// - enables zero subnet.
|
||||||
//
|
//
|
||||||
// Attribute key is calculated from ID using format `__NEOFS__SUBNET_%s`.
|
// Attribute key is calculated from ID using format `__FROSTFS__SUBNET_%s`.
|
||||||
// Attribute Value is:
|
// Attribute Value is:
|
||||||
// - `True` if node enters the subnet;
|
// - `True` if node enters the subnet;
|
||||||
// - `False`, otherwise.
|
// - `False`, otherwise.
|
||||||
|
@ -143,8 +146,11 @@ func IterateSubnets(node *NodeInfo, f func(refs.SubnetID) error) error {
|
||||||
// cut subnet ID string
|
// cut subnet ID string
|
||||||
idTxt := strings.TrimPrefix(key, attrSubnetPrefix)
|
idTxt := strings.TrimPrefix(key, attrSubnetPrefix)
|
||||||
if len(idTxt) == len(key) {
|
if len(idTxt) == len(key) {
|
||||||
// not a subnet attribute
|
idTxt = strings.TrimPrefix(key, attrSubnetPrefixNeoFS)
|
||||||
continue
|
if len(idTxt) == len(key) {
|
||||||
|
// not a subnet attribute
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check value
|
// check value
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func subnetAttrKey(val string) string {
|
func subnetAttrKey(val string) string {
|
||||||
return "__NEOFS__SUBNET_" + val
|
return "__FROSTFS__SUBNET_" + val
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertSubnetAttrKey(t *testing.T, attr *netmap.Attribute, num uint32) {
|
func assertSubnetAttrKey(t *testing.T, attr *netmap.Attribute, num uint32) {
|
||||||
|
|
2
netmap/grpc/types.pb.go
generated
2
netmap/grpc/types.pb.go
generated
|
@ -827,7 +827,7 @@ func (x *NetworkInfo) GetNetworkConfig() *NetworkConfig {
|
||||||
// attributes it's a string presenting floating point number with comma or
|
// attributes it's a string presenting floating point number with comma or
|
||||||
// point delimiter for decimal part. In the Network Map it will be saved as
|
// point delimiter for decimal part. In the Network Map it will be saved as
|
||||||
// 64-bit unsigned integer representing number of minimal token fractions.
|
// 64-bit unsigned integer representing number of minimal token fractions.
|
||||||
// - __NEOFS__SUBNET_%s \
|
// - [ __NEOFS__SUBNET_%s | __FROSTFS__SUBNET_%s ] \
|
||||||
// `True` or `False`. Defines if the node is included in the `%s` subnetwork
|
// `True` or `False`. Defines if the node is included in the `%s` subnetwork
|
||||||
// or not. `%s` must be an existing subnetwork's ID (non-negative integer number).
|
// or not. `%s` must be an existing subnetwork's ID (non-negative integer number).
|
||||||
// A node can be included in more than one subnetwork and, therefore, can contain
|
// A node can be included in more than one subnetwork and, therefore, can contain
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// SysAttributePrefix is a prefix of key to system attribute.
|
// SysAttributePrefix is a prefix of key to system attribute.
|
||||||
const SysAttributePrefix = "__NEOFS__"
|
const SysAttributePrefix = "__FROSTFS__"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// SysAttributeUploadID marks smaller parts of a split bigger object.
|
// SysAttributeUploadID marks smaller parts of a split bigger object.
|
||||||
|
@ -25,6 +25,25 @@ const (
|
||||||
SysAttributeTickTopic = SysAttributePrefix + "TICK_TOPIC"
|
SysAttributeTickTopic = SysAttributePrefix + "TICK_TOPIC"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SysAttributePrefixNeoFS is a prefix of key to system attribute.
|
||||||
|
const SysAttributePrefixNeoFS = "__NEOFS__"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SysAttributeUploadIDNeoFS marks smaller parts of a split bigger object.
|
||||||
|
SysAttributeUploadIDNeoFS = SysAttributePrefixNeoFS + "UPLOAD_ID"
|
||||||
|
|
||||||
|
// SysAttributeExpEpochNeoFS tells GC to delete object after that epoch.
|
||||||
|
SysAttributeExpEpochNeoFS = SysAttributePrefixNeoFS + "EXPIRATION_EPOCH"
|
||||||
|
|
||||||
|
// SysAttributeTickEpochNeoFS defines what epoch must produce object
|
||||||
|
// notification.
|
||||||
|
SysAttributeTickEpochNeoFS = SysAttributePrefixNeoFS + "TICK_EPOCH"
|
||||||
|
|
||||||
|
// SysAttributeTickTopicNeoFS defines what topic object notification
|
||||||
|
// must be sent to.
|
||||||
|
SysAttributeTickTopicNeoFS = SysAttributePrefixNeoFS + "TICK_TOPIC"
|
||||||
|
)
|
||||||
|
|
||||||
// NotificationInfo groups information about object notification
|
// NotificationInfo groups information about object notification
|
||||||
// that can be written to object.
|
// that can be written to object.
|
||||||
//
|
//
|
||||||
|
@ -81,10 +100,10 @@ func WriteNotificationInfo(o *Object, ni NotificationInfo) {
|
||||||
|
|
||||||
for i := range attrs {
|
for i := range attrs {
|
||||||
switch attrs[i].GetKey() {
|
switch attrs[i].GetKey() {
|
||||||
case SysAttributeTickEpoch:
|
case SysAttributeTickEpoch, SysAttributeTickEpochNeoFS:
|
||||||
attrs[i].SetValue(epoch)
|
attrs[i].SetValue(epoch)
|
||||||
changedEpoch = true
|
changedEpoch = true
|
||||||
case SysAttributeTickTopic:
|
case SysAttributeTickTopic, SysAttributeTickTopicNeoFS:
|
||||||
changedTopic = true
|
changedTopic = true
|
||||||
|
|
||||||
if topic == "" {
|
if topic == "" {
|
||||||
|
@ -141,7 +160,7 @@ func GetNotificationInfo(o *Object) (*NotificationInfo, error) {
|
||||||
|
|
||||||
for _, attr := range o.GetHeader().GetAttributes() {
|
for _, attr := range o.GetHeader().GetAttributes() {
|
||||||
switch key := attr.GetKey(); key {
|
switch key := attr.GetKey(); key {
|
||||||
case SysAttributeTickEpoch:
|
case SysAttributeTickEpoch, SysAttributeTickEpochNeoFS:
|
||||||
epoch, err := strconv.ParseUint(attr.GetValue(), 10, 64)
|
epoch, err := strconv.ParseUint(attr.GetValue(), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse epoch: %w", err)
|
return nil, fmt.Errorf("could not parse epoch: %w", err)
|
||||||
|
@ -150,7 +169,7 @@ func GetNotificationInfo(o *Object) (*NotificationInfo, error) {
|
||||||
ni.SetEpoch(epoch)
|
ni.SetEpoch(epoch)
|
||||||
|
|
||||||
foundEpoch = true
|
foundEpoch = true
|
||||||
case SysAttributeTickTopic:
|
case SysAttributeTickTopic, SysAttributeTickTopicNeoFS:
|
||||||
ni.SetTopic(attr.GetValue())
|
ni.SetTopic(attr.GetValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
44
object/grpc/service_grpc.pb.go
generated
44
object/grpc/service_grpc.pb.go
generated
|
@ -30,11 +30,11 @@ type ObjectServiceClient interface {
|
||||||
// keeping the receiving order.
|
// keeping the receiving order.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Get` behaviour:
|
// Extended headers can change `Get` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
// - __NEOFS__NETMAP_LOOKUP_DEPTH \
|
// - [ __NEOFS__NETMAP_LOOKUP_DEPTH | __FROSTFS__NETMAP_LOOKUP_DEPTH ] \
|
||||||
// Will try older versions (starting from `__NEOFS__NETMAP_EPOCH` if specified or
|
// Will try older versions (starting from `__NEOFS__NETMAP_EPOCH`/`__FROSTFS__NETMAP_EPOCH` if specified or
|
||||||
// the latest one otherwise) of Network Map to find an object until the depth
|
// the latest one otherwise) of Network Map to find an object until the depth
|
||||||
// limit is reached.
|
// limit is reached.
|
||||||
//
|
//
|
||||||
|
@ -63,7 +63,7 @@ type ObjectServiceClient interface {
|
||||||
// Chunk messages SHOULD be sent in the direct order of fragmentation.
|
// Chunk messages SHOULD be sent in the direct order of fragmentation.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Put` behaviour:
|
// Extended headers can change `Put` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -94,7 +94,7 @@ type ObjectServiceClient interface {
|
||||||
// guarantee. Object will be marked for removal and deleted eventually.
|
// guarantee. Object will be marked for removal and deleted eventually.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Delete` behaviour:
|
// Extended headers can change `Delete` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -118,7 +118,7 @@ type ObjectServiceClient interface {
|
||||||
// the very minimal information will be returned instead.
|
// the very minimal information will be returned instead.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Head` behaviour:
|
// Extended headers can change `Head` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -144,7 +144,7 @@ type ObjectServiceClient interface {
|
||||||
// Specification section for more details.
|
// Specification section for more details.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Search` behaviour:
|
// Extended headers can change `Search` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -167,10 +167,10 @@ type ObjectServiceClient interface {
|
||||||
// order.
|
// order.
|
||||||
//
|
//
|
||||||
// Extended headers can change `GetRange` behaviour:
|
// Extended headers can change `GetRange` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
// - __NEOFS__NETMAP_LOOKUP_DEPTH \
|
// - [ __NEOFS__NETMAP_LOOKUP_DEPTH | __FROSTFS__NETMAP_LOOKUP_DEPTH ] \
|
||||||
// Will try older versions of Network Map to find an object until the depth
|
// Will try older versions of Network Map to find an object until the depth
|
||||||
// limit is reached.
|
// limit is reached.
|
||||||
//
|
//
|
||||||
|
@ -199,10 +199,10 @@ type ObjectServiceClient interface {
|
||||||
// the request. Note that hash is calculated for XORed data.
|
// the request. Note that hash is calculated for XORed data.
|
||||||
//
|
//
|
||||||
// Extended headers can change `GetRangeHash` behaviour:
|
// Extended headers can change `GetRangeHash` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
// - __NEOFS__NETMAP_LOOKUP_DEPTH \
|
// - [ __NEOFS__NETMAP_LOOKUP_DEPTH | __FROSTFS__NETMAP_LOOKUP_DEPTH ] \
|
||||||
// Will try older versions of Network Map to find an object until the depth
|
// Will try older versions of Network Map to find an object until the depth
|
||||||
// limit is reached.
|
// limit is reached.
|
||||||
//
|
//
|
||||||
|
@ -402,11 +402,11 @@ type ObjectServiceServer interface {
|
||||||
// keeping the receiving order.
|
// keeping the receiving order.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Get` behaviour:
|
// Extended headers can change `Get` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
// - __NEOFS__NETMAP_LOOKUP_DEPTH \
|
// - [ __NEOFS__NETMAP_LOOKUP_DEPTH | __FROSTFS__NETMAP_LOOKUP_DEPTH ] \
|
||||||
// Will try older versions (starting from `__NEOFS__NETMAP_EPOCH` if specified or
|
// Will try older versions (starting from `__NEOFS__NETMAP_EPOCH`/`__FROSTFS__NETMAP_EPOCH` if specified or
|
||||||
// the latest one otherwise) of Network Map to find an object until the depth
|
// the latest one otherwise) of Network Map to find an object until the depth
|
||||||
// limit is reached.
|
// limit is reached.
|
||||||
//
|
//
|
||||||
|
@ -435,7 +435,7 @@ type ObjectServiceServer interface {
|
||||||
// Chunk messages SHOULD be sent in the direct order of fragmentation.
|
// Chunk messages SHOULD be sent in the direct order of fragmentation.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Put` behaviour:
|
// Extended headers can change `Put` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -466,7 +466,7 @@ type ObjectServiceServer interface {
|
||||||
// guarantee. Object will be marked for removal and deleted eventually.
|
// guarantee. Object will be marked for removal and deleted eventually.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Delete` behaviour:
|
// Extended headers can change `Delete` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -490,7 +490,7 @@ type ObjectServiceServer interface {
|
||||||
// the very minimal information will be returned instead.
|
// the very minimal information will be returned instead.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Head` behaviour:
|
// Extended headers can change `Head` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -516,7 +516,7 @@ type ObjectServiceServer interface {
|
||||||
// Specification section for more details.
|
// Specification section for more details.
|
||||||
//
|
//
|
||||||
// Extended headers can change `Search` behaviour:
|
// Extended headers can change `Search` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
//
|
//
|
||||||
|
@ -539,10 +539,10 @@ type ObjectServiceServer interface {
|
||||||
// order.
|
// order.
|
||||||
//
|
//
|
||||||
// Extended headers can change `GetRange` behaviour:
|
// Extended headers can change `GetRange` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
// - __NEOFS__NETMAP_LOOKUP_DEPTH \
|
// - [ __NEOFS__NETMAP_LOOKUP_DEPTH | __FROSTFS__NETMAP_LOOKUP_DEPTH ] \
|
||||||
// Will try older versions of Network Map to find an object until the depth
|
// Will try older versions of Network Map to find an object until the depth
|
||||||
// limit is reached.
|
// limit is reached.
|
||||||
//
|
//
|
||||||
|
@ -571,10 +571,10 @@ type ObjectServiceServer interface {
|
||||||
// the request. Note that hash is calculated for XORed data.
|
// the request. Note that hash is calculated for XORed data.
|
||||||
//
|
//
|
||||||
// Extended headers can change `GetRangeHash` behaviour:
|
// Extended headers can change `GetRangeHash` behaviour:
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Will use the requsted version of Network Map for object placement
|
// Will use the requsted version of Network Map for object placement
|
||||||
// calculation.
|
// calculation.
|
||||||
// - __NEOFS__NETMAP_LOOKUP_DEPTH \
|
// - [ __NEOFS__NETMAP_LOOKUP_DEPTH | __FROSTFS__NETMAP_LOOKUP_DEPTH ] \
|
||||||
// Will try older versions of Network Map to find an object until the depth
|
// Will try older versions of Network Map to find an object until the depth
|
||||||
// limit is reached.
|
// limit is reached.
|
||||||
//
|
//
|
||||||
|
|
10
object/grpc/types.pb.go
generated
10
object/grpc/types.pb.go
generated
|
@ -556,19 +556,19 @@ func (x *SplitInfo) GetLink() *grpc.ObjectID {
|
||||||
// Objects with duplicated attribute names or attributes with empty values
|
// Objects with duplicated attribute names or attributes with empty values
|
||||||
// will be considered invalid.
|
// will be considered invalid.
|
||||||
//
|
//
|
||||||
// There are some "well-known" attributes starting with `__NEOFS__` prefix
|
// There are some "well-known" attributes starting with `__NEOFS__`/`__FROSTFS__` prefix
|
||||||
// that affect system behaviour:
|
// that affect system behaviour:
|
||||||
//
|
//
|
||||||
// - __NEOFS__UPLOAD_ID \
|
// - [ __NEOFS__UPLOAD_ID | __FROSTFS__UPLOAD_ID ] \
|
||||||
// Marks smaller parts of a split bigger object
|
// Marks smaller parts of a split bigger object
|
||||||
// - __NEOFS__EXPIRATION_EPOCH \
|
// - [ __NEOFS__EXPIRATION_EPOCH | __FROSTFS__EXPIRATION_EPOCH ] \
|
||||||
// Tells GC to delete object after that epoch
|
// Tells GC to delete object after that epoch
|
||||||
// - __NEOFS__TICK_EPOCH \
|
// - [ __NEOFS__TICK_EPOCH | __FROSTFS__TICK_EPOCH ] \
|
||||||
// Decimal number that defines what epoch must produce
|
// Decimal number that defines what epoch must produce
|
||||||
// object notification with UTF-8 object address in a
|
// object notification with UTF-8 object address in a
|
||||||
// body (`0` value produces notification right after
|
// body (`0` value produces notification right after
|
||||||
// object put)
|
// object put)
|
||||||
// - __NEOFS__TICK_TOPIC \
|
// - [ __NEOFS__TICK_TOPIC | __FROSTFS__TICK_TOPIC ] \
|
||||||
// UTF-8 string topic ID that is used for object notification
|
// UTF-8 string topic ID that is used for object notification
|
||||||
//
|
//
|
||||||
// And some well-known attributes used by applications only:
|
// And some well-known attributes used by applications only:
|
||||||
|
|
6
session/grpc/types.pb.go
generated
6
session/grpc/types.pb.go
generated
|
@ -349,14 +349,14 @@ func (x *SessionToken) GetSignature() *grpc.Signature {
|
||||||
// Responses with duplicated header names or headers with empty values will be
|
// Responses with duplicated header names or headers with empty values will be
|
||||||
// considered invalid.
|
// considered invalid.
|
||||||
//
|
//
|
||||||
// There are some "well-known" headers starting with `__NEOFS__` prefix that
|
// There are some "well-known" headers starting with `__NEOFS__` or `__FROSTFS__` prefix that
|
||||||
// affect system behaviour:
|
// affect system behaviour:
|
||||||
//
|
//
|
||||||
// - __NEOFS__NETMAP_EPOCH \
|
// - [ __NEOFS__NETMAP_EPOCH | __FROSTFS__NETMAP_EPOCH ] \
|
||||||
// Netmap epoch to use for object placement calculation. The `value` is string
|
// Netmap epoch to use for object placement calculation. The `value` is string
|
||||||
// encoded `uint64` in decimal presentation. If set to '0' or not set, the
|
// encoded `uint64` in decimal presentation. If set to '0' or not set, the
|
||||||
// current epoch only will be used.
|
// current epoch only will be used.
|
||||||
// - __NEOFS__NETMAP_LOOKUP_DEPTH \
|
// - [ __NEOFS__NETMAP_LOOKUP_DEPTH | __FROSTFS__NETMAP_LOOKUP_DEPTH ] \
|
||||||
// If object can't be found using current epoch's netmap, this header limits
|
// If object can't be found using current epoch's netmap, this header limits
|
||||||
// how many past epochs the node can look up through. The `value` is string
|
// how many past epochs the node can look up through. The `value` is string
|
||||||
// encoded `uint64` in decimal presentation. If set to '0' or not set, only the
|
// encoded `uint64` in decimal presentation. If set to '0' or not set, only the
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package session
|
package session
|
||||||
|
|
||||||
// ReservedXHeaderPrefix is a prefix of keys to "well-known" X-headers.
|
// ReservedXHeaderPrefix is a prefix of keys to "well-known" X-headers.
|
||||||
const ReservedXHeaderPrefix = "__NEOFS__"
|
const ReservedXHeaderPrefix = "__FROSTFS__"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// XHeaderNetmapEpoch is a key to the reserved X-header that specifies netmap epoch
|
// XHeaderNetmapEpoch is a key to the reserved X-header that specifies netmap epoch
|
||||||
|
@ -14,3 +14,18 @@ const (
|
||||||
// set, the current epoch only will be used.
|
// set, the current epoch only will be used.
|
||||||
XHeaderNetmapLookupDepth = ReservedXHeaderPrefix + "NETMAP_LOOKUP_DEPTH"
|
XHeaderNetmapLookupDepth = ReservedXHeaderPrefix + "NETMAP_LOOKUP_DEPTH"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ReservedXHeaderPrefixNeoFS is a prefix of keys to "well-known" X-headers.
|
||||||
|
const ReservedXHeaderPrefixNeoFS = "__NEOFS__"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// XHeaderNetmapEpochNeoFS is a key to the reserved X-header that specifies netmap epoch
|
||||||
|
// to use for object placement calculation. If set to '0' or not set, the current
|
||||||
|
// epoch only will be used.
|
||||||
|
XHeaderNetmapEpochNeoFS = ReservedXHeaderPrefixNeoFS + "NETMAP_EPOCH"
|
||||||
|
|
||||||
|
// XHeaderNetmapLookupDepthNeoFS is a key to the reserved X-header that limits
|
||||||
|
// how many past epochs back the node will can lookup. If set to '0' or not
|
||||||
|
// set, the current epoch only will be used.
|
||||||
|
XHeaderNetmapLookupDepthNeoFS = ReservedXHeaderPrefixNeoFS + "NETMAP_LOOKUP_DEPTH"
|
||||||
|
)
|
||||||
|
|
115
signature/body.go
Normal file
115
signature/body.go
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
package signature
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||||
|
)
|
||||||
|
|
||||||
|
func serviceMessageBody(req interface{}) stableMarshaler {
|
||||||
|
switch v := req.(type) {
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unsupported session message %T", req))
|
||||||
|
|
||||||
|
/* Accounting */
|
||||||
|
case *accounting.BalanceRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *accounting.BalanceResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
|
||||||
|
/* Session */
|
||||||
|
case *session.CreateRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *session.CreateResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
|
||||||
|
/* Container */
|
||||||
|
case *container.PutRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.PutResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.DeleteRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.DeleteResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.GetRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.GetResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.ListRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.ListResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.SetExtendedACLRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.SetExtendedACLResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.GetExtendedACLRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.GetExtendedACLResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.AnnounceUsedSpaceRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *container.AnnounceUsedSpaceResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
|
||||||
|
/* Object */
|
||||||
|
case *object.PutRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.PutResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.GetRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.GetResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.HeadRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.HeadResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.SearchRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.SearchResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.DeleteRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.DeleteResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.GetRangeRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.GetRangeResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.GetRangeHashRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *object.GetRangeHashResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
|
||||||
|
/* Netmap */
|
||||||
|
case *netmap.LocalNodeInfoRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *netmap.LocalNodeInfoResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *netmap.NetworkInfoRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *netmap.NetworkInfoResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *netmap.SnapshotRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *netmap.SnapshotResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
|
||||||
|
/* Reputation */
|
||||||
|
case *reputation.AnnounceLocalTrustRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *reputation.AnnounceLocalTrustResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
case *reputation.AnnounceIntermediateResultRequest:
|
||||||
|
return v.GetBody()
|
||||||
|
case *reputation.AnnounceIntermediateResultResponse:
|
||||||
|
return v.GetBody()
|
||||||
|
}
|
||||||
|
}
|
26
signature/marshaller.go
Normal file
26
signature/marshaller.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package signature
|
||||||
|
|
||||||
|
type stableMarshaler interface {
|
||||||
|
StableMarshal([]byte) []byte
|
||||||
|
StableSize() int
|
||||||
|
}
|
||||||
|
|
||||||
|
type StableMarshalerWrapper struct {
|
||||||
|
SM stableMarshaler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s StableMarshalerWrapper) ReadSignedData(buf []byte) ([]byte, error) {
|
||||||
|
if s.SM != nil {
|
||||||
|
return s.SM.StableMarshal(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s StableMarshalerWrapper) SignedDataSize() int {
|
||||||
|
if s.SM != nil {
|
||||||
|
return s.SM.StableSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
|
@ -2,17 +2,12 @@ package signature
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/signature"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/signature"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
type serviceRequest interface {
|
type serviceRequest interface {
|
||||||
|
@ -27,179 +22,92 @@ type serviceResponse interface {
|
||||||
SetVerificationHeader(*session.ResponseVerificationHeader)
|
SetVerificationHeader(*session.ResponseVerificationHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
type stableMarshaler interface {
|
type signatureReceiver interface {
|
||||||
StableMarshal([]byte) []byte
|
|
||||||
StableSize() int
|
|
||||||
}
|
|
||||||
|
|
||||||
type StableMarshalerWrapper struct {
|
|
||||||
SM stableMarshaler
|
|
||||||
}
|
|
||||||
|
|
||||||
type metaHeader interface {
|
|
||||||
stableMarshaler
|
|
||||||
getOrigin() metaHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
type verificationHeader interface {
|
|
||||||
stableMarshaler
|
|
||||||
|
|
||||||
GetBodySignature() *refs.Signature
|
|
||||||
SetBodySignature(*refs.Signature)
|
SetBodySignature(*refs.Signature)
|
||||||
GetMetaSignature() *refs.Signature
|
|
||||||
SetMetaSignature(*refs.Signature)
|
SetMetaSignature(*refs.Signature)
|
||||||
GetOriginSignature() *refs.Signature
|
|
||||||
SetOriginSignature(*refs.Signature)
|
SetOriginSignature(*refs.Signature)
|
||||||
|
|
||||||
setOrigin(stableMarshaler)
|
|
||||||
getOrigin() verificationHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
type requestMetaHeader struct {
|
|
||||||
*session.RequestMetaHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
type responseMetaHeader struct {
|
|
||||||
*session.ResponseMetaHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
type requestVerificationHeader struct {
|
|
||||||
*session.RequestVerificationHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
type responseVerificationHeader struct {
|
|
||||||
*session.ResponseVerificationHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *requestMetaHeader) getOrigin() metaHeader {
|
|
||||||
return &requestMetaHeader{
|
|
||||||
RequestMetaHeader: h.GetOrigin(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *responseMetaHeader) getOrigin() metaHeader {
|
|
||||||
return &responseMetaHeader{
|
|
||||||
ResponseMetaHeader: h.GetOrigin(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *requestVerificationHeader) getOrigin() verificationHeader {
|
|
||||||
if origin := h.GetOrigin(); origin != nil {
|
|
||||||
return &requestVerificationHeader{
|
|
||||||
RequestVerificationHeader: origin,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *requestVerificationHeader) setOrigin(m stableMarshaler) {
|
|
||||||
if m != nil {
|
|
||||||
h.SetOrigin(m.(*session.RequestVerificationHeader))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *responseVerificationHeader) getOrigin() verificationHeader {
|
|
||||||
if origin := r.GetOrigin(); origin != nil {
|
|
||||||
return &responseVerificationHeader{
|
|
||||||
ResponseVerificationHeader: origin,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *responseVerificationHeader) setOrigin(m stableMarshaler) {
|
|
||||||
if m != nil {
|
|
||||||
r.SetOrigin(m.(*session.ResponseVerificationHeader))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s StableMarshalerWrapper) ReadSignedData(buf []byte) ([]byte, error) {
|
|
||||||
if s.SM != nil {
|
|
||||||
return s.SM.StableMarshal(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s StableMarshalerWrapper) SignedDataSize() int {
|
|
||||||
if s.SM != nil {
|
|
||||||
return s.SM.StableSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SignServiceMessage signes service message with key.
|
||||||
func SignServiceMessage(key *ecdsa.PrivateKey, msg interface{}) error {
|
func SignServiceMessage(key *ecdsa.PrivateKey, msg interface{}) error {
|
||||||
var (
|
|
||||||
body, meta, verifyOrigin stableMarshaler
|
|
||||||
verifyHdr verificationHeader
|
|
||||||
verifyHdrSetter func(verificationHeader)
|
|
||||||
)
|
|
||||||
|
|
||||||
switch v := msg.(type) {
|
switch v := msg.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
return nil
|
return nil
|
||||||
case serviceRequest:
|
case serviceRequest:
|
||||||
body = serviceMessageBody(v)
|
return signServiceRequest(key, v)
|
||||||
meta = v.GetMetaHeader()
|
|
||||||
verifyHdr = &requestVerificationHeader{new(session.RequestVerificationHeader)}
|
|
||||||
verifyHdrSetter = func(h verificationHeader) {
|
|
||||||
v.SetVerificationHeader(h.(*requestVerificationHeader).RequestVerificationHeader)
|
|
||||||
}
|
|
||||||
|
|
||||||
if h := v.GetVerificationHeader(); h != nil {
|
|
||||||
verifyOrigin = h
|
|
||||||
}
|
|
||||||
case serviceResponse:
|
case serviceResponse:
|
||||||
body = serviceMessageBody(v)
|
return signServiceResponse(key, v)
|
||||||
meta = v.GetMetaHeader()
|
|
||||||
verifyHdr = &responseVerificationHeader{new(session.ResponseVerificationHeader)}
|
|
||||||
verifyHdrSetter = func(h verificationHeader) {
|
|
||||||
v.SetVerificationHeader(h.(*responseVerificationHeader).ResponseVerificationHeader)
|
|
||||||
}
|
|
||||||
|
|
||||||
if h := v.GetVerificationHeader(); h != nil {
|
|
||||||
verifyOrigin = h
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported session message %T", v))
|
panic(fmt.Sprintf("unsupported session message %T", v))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if verifyOrigin == nil {
|
func signServiceRequest(key *ecdsa.PrivateKey, v serviceRequest) error {
|
||||||
|
result := &session.RequestVerificationHeader{}
|
||||||
|
body := serviceMessageBody(v)
|
||||||
|
meta := v.GetMetaHeader()
|
||||||
|
header := v.GetVerificationHeader()
|
||||||
|
if err := signMessageParts(key, body, meta, header, header != nil, result); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
result.SetOrigin(header)
|
||||||
|
v.SetVerificationHeader(result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func signServiceResponse(key *ecdsa.PrivateKey, v serviceResponse) error {
|
||||||
|
result := &session.ResponseVerificationHeader{}
|
||||||
|
body := serviceMessageBody(v)
|
||||||
|
meta := v.GetMetaHeader()
|
||||||
|
header := v.GetVerificationHeader()
|
||||||
|
if err := signMessageParts(key, body, meta, header, header != nil, result); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
result.SetOrigin(header)
|
||||||
|
v.SetVerificationHeader(result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func signMessageParts(key *ecdsa.PrivateKey, body, meta, header stableMarshaler, hasHeader bool, result signatureReceiver) error {
|
||||||
|
eg := &errgroup.Group{}
|
||||||
|
if !hasHeader {
|
||||||
// sign session message body
|
// sign session message body
|
||||||
if err := signServiceMessagePart(key, body, verifyHdr.SetBodySignature); err != nil {
|
eg.Go(func() error {
|
||||||
return fmt.Errorf("could not sign body: %w", err)
|
if err := signServiceMessagePart(key, body, result.SetBodySignature); err != nil {
|
||||||
}
|
return fmt.Errorf("could not sign body: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign meta header
|
// sign meta header
|
||||||
if err := signServiceMessagePart(key, meta, verifyHdr.SetMetaSignature); err != nil {
|
eg.Go(func() error {
|
||||||
return fmt.Errorf("could not sign meta header: %w", err)
|
if err := signServiceMessagePart(key, meta, result.SetMetaSignature); err != nil {
|
||||||
}
|
return fmt.Errorf("could not sign meta header: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
// sign verification header origin
|
// sign verification header origin
|
||||||
if err := signServiceMessagePart(key, verifyOrigin, verifyHdr.SetOriginSignature); err != nil {
|
eg.Go(func() error {
|
||||||
return fmt.Errorf("could not sign origin of verification header: %w", err)
|
if err := signServiceMessagePart(key, header, result.SetOriginSignature); err != nil {
|
||||||
}
|
return fmt.Errorf("could not sign origin of verification header: %w", err)
|
||||||
|
}
|
||||||
// wrap origin verification header
|
return nil
|
||||||
verifyHdr.setOrigin(verifyOrigin)
|
})
|
||||||
|
return eg.Wait()
|
||||||
// update matryoshka verification header
|
|
||||||
verifyHdrSetter(verifyHdr)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func signServiceMessagePart(key *ecdsa.PrivateKey, part stableMarshaler, sigWrite func(*refs.Signature)) error {
|
func signServiceMessagePart(key *ecdsa.PrivateKey, part stableMarshaler, sigWrite func(*refs.Signature)) error {
|
||||||
var sig *refs.Signature
|
var sig *refs.Signature
|
||||||
|
|
||||||
|
wrapper := StableMarshalerWrapper{
|
||||||
|
SM: part,
|
||||||
|
}
|
||||||
// sign part
|
// sign part
|
||||||
if err := signature.SignDataWithHandler(
|
if err := signature.SignDataWithHandler(
|
||||||
key,
|
key,
|
||||||
&StableMarshalerWrapper{part},
|
wrapper,
|
||||||
func(s *refs.Signature) {
|
func(s *refs.Signature) {
|
||||||
sig = s
|
sig = s
|
||||||
},
|
},
|
||||||
|
@ -212,182 +120,3 @@ func signServiceMessagePart(key *ecdsa.PrivateKey, part stableMarshaler, sigWrit
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyServiceMessage(msg interface{}) error {
|
|
||||||
var (
|
|
||||||
meta metaHeader
|
|
||||||
verify verificationHeader
|
|
||||||
)
|
|
||||||
|
|
||||||
switch v := msg.(type) {
|
|
||||||
case nil:
|
|
||||||
return nil
|
|
||||||
case serviceRequest:
|
|
||||||
meta = &requestMetaHeader{
|
|
||||||
RequestMetaHeader: v.GetMetaHeader(),
|
|
||||||
}
|
|
||||||
|
|
||||||
verify = &requestVerificationHeader{
|
|
||||||
RequestVerificationHeader: v.GetVerificationHeader(),
|
|
||||||
}
|
|
||||||
case serviceResponse:
|
|
||||||
meta = &responseMetaHeader{
|
|
||||||
ResponseMetaHeader: v.GetMetaHeader(),
|
|
||||||
}
|
|
||||||
|
|
||||||
verify = &responseVerificationHeader{
|
|
||||||
ResponseVerificationHeader: v.GetVerificationHeader(),
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unsupported session message %T", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
body := serviceMessageBody(msg)
|
|
||||||
size := body.StableSize()
|
|
||||||
if sz := meta.StableSize(); sz > size {
|
|
||||||
size = sz
|
|
||||||
}
|
|
||||||
if sz := verify.StableSize(); sz > size {
|
|
||||||
size = sz
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := make([]byte, 0, size)
|
|
||||||
return verifyMatryoshkaLevel(body, meta, verify, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyMatryoshkaLevel(body stableMarshaler, meta metaHeader, verify verificationHeader, buf []byte) error {
|
|
||||||
if err := verifyServiceMessagePart(meta, verify.GetMetaSignature, buf); err != nil {
|
|
||||||
return fmt.Errorf("could not verify meta header: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
origin := verify.getOrigin()
|
|
||||||
|
|
||||||
if err := verifyServiceMessagePart(origin, verify.GetOriginSignature, buf); err != nil {
|
|
||||||
return fmt.Errorf("could not verify origin of verification header: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if origin == nil {
|
|
||||||
if err := verifyServiceMessagePart(body, verify.GetBodySignature, buf); err != nil {
|
|
||||||
return fmt.Errorf("could not verify body: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if verify.GetBodySignature() != nil {
|
|
||||||
return errors.New("body signature at the matryoshka upper level")
|
|
||||||
}
|
|
||||||
|
|
||||||
return verifyMatryoshkaLevel(body, meta.getOrigin(), origin, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyServiceMessagePart(part stableMarshaler, sigRdr func() *refs.Signature, buf []byte) error {
|
|
||||||
return signature.VerifyDataWithSource(
|
|
||||||
&StableMarshalerWrapper{part},
|
|
||||||
sigRdr,
|
|
||||||
signature.WithBuffer(buf),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceMessageBody(req interface{}) stableMarshaler {
|
|
||||||
switch v := req.(type) {
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unsupported session message %T", req))
|
|
||||||
|
|
||||||
/* Accounting */
|
|
||||||
case *accounting.BalanceRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *accounting.BalanceResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
|
|
||||||
/* Session */
|
|
||||||
case *session.CreateRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *session.CreateResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
|
|
||||||
/* Container */
|
|
||||||
case *container.PutRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.PutResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.DeleteRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.DeleteResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.GetRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.GetResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.ListRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.ListResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.SetExtendedACLRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.SetExtendedACLResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.GetExtendedACLRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.GetExtendedACLResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.AnnounceUsedSpaceRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *container.AnnounceUsedSpaceResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
|
|
||||||
/* Object */
|
|
||||||
case *object.PutRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.PutResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.GetRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.GetResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.HeadRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.HeadResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.SearchRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.SearchResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.DeleteRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.DeleteResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.GetRangeRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.GetRangeResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.GetRangeHashRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *object.GetRangeHashResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
|
|
||||||
/* Netmap */
|
|
||||||
case *netmap.LocalNodeInfoRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *netmap.LocalNodeInfoResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *netmap.NetworkInfoRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *netmap.NetworkInfoResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *netmap.SnapshotRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *netmap.SnapshotResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
|
|
||||||
/* Reputation */
|
|
||||||
case *reputation.AnnounceLocalTrustRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *reputation.AnnounceLocalTrustResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
case *reputation.AnnounceIntermediateResultRequest:
|
|
||||||
return v.GetBody()
|
|
||||||
case *reputation.AnnounceIntermediateResultResponse:
|
|
||||||
return v.GetBody()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -70,3 +70,56 @@ func TestBalanceResponse(t *testing.T) {
|
||||||
// verification must fail
|
// verification must fail
|
||||||
require.Error(t, VerifyServiceMessage(req))
|
require.Error(t, VerifyServiceMessage(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkSignRequest(b *testing.B) {
|
||||||
|
key, _ := crypto.LoadPrivateKey("Kwk6k2eC3L3QuPvD8aiaNyoSXgQ2YL1bwS5CP1oKoA9waeAze97s")
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
dec := new(accounting.Decimal)
|
||||||
|
dec.SetValue(100)
|
||||||
|
|
||||||
|
body := new(accounting.BalanceResponseBody)
|
||||||
|
body.SetBalance(dec)
|
||||||
|
|
||||||
|
meta := new(session.ResponseMetaHeader)
|
||||||
|
meta.SetTTL(1)
|
||||||
|
|
||||||
|
resp := new(accounting.BalanceResponse)
|
||||||
|
resp.SetBody(body)
|
||||||
|
resp.SetMetaHeader(meta)
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
SignServiceMessage(key, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkVerifyRequest(b *testing.B) {
|
||||||
|
key, _ := crypto.LoadPrivateKey("Kwk6k2eC3L3QuPvD8aiaNyoSXgQ2YL1bwS5CP1oKoA9waeAze97s")
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
dec := new(accounting.Decimal)
|
||||||
|
dec.SetValue(100)
|
||||||
|
|
||||||
|
body := new(accounting.BalanceResponseBody)
|
||||||
|
body.SetBalance(dec)
|
||||||
|
|
||||||
|
meta := new(session.ResponseMetaHeader)
|
||||||
|
meta.SetTTL(1)
|
||||||
|
|
||||||
|
resp := new(accounting.BalanceResponse)
|
||||||
|
resp.SetBody(body)
|
||||||
|
resp.SetMetaHeader(meta)
|
||||||
|
SignServiceMessage(key, resp)
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
VerifyServiceMessage(resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
127
signature/verify.go
Normal file
127
signature/verify.go
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
package signature
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/signature"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
type signatureProvider interface {
|
||||||
|
GetBodySignature() *refs.Signature
|
||||||
|
GetMetaSignature() *refs.Signature
|
||||||
|
GetOriginSignature() *refs.Signature
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyServiceMessage verifies service message.
|
||||||
|
func VerifyServiceMessage(msg interface{}) error {
|
||||||
|
switch v := msg.(type) {
|
||||||
|
case nil:
|
||||||
|
return nil
|
||||||
|
case serviceRequest:
|
||||||
|
return verifyServiceRequest(v)
|
||||||
|
case serviceResponse:
|
||||||
|
return verifyServiceResponse(v)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unsupported session message %T", v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyServiceRequest(v serviceRequest) error {
|
||||||
|
meta := v.GetMetaHeader()
|
||||||
|
verificationHeader := v.GetVerificationHeader()
|
||||||
|
body := serviceMessageBody(v)
|
||||||
|
return verifyServiceRequestRecursive(body, meta, verificationHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyServiceRequestRecursive(body stableMarshaler, meta *session.RequestMetaHeader, verify *session.RequestVerificationHeader) error {
|
||||||
|
verificationHeaderOrigin := verify.GetOrigin()
|
||||||
|
metaOrigin := meta.GetOrigin()
|
||||||
|
|
||||||
|
stop, err := verifyMessageParts(body, meta, verificationHeaderOrigin, verificationHeaderOrigin != nil, verify)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if stop {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifyServiceRequestRecursive(body, metaOrigin, verificationHeaderOrigin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyMessageParts(body, meta, originHeader stableMarshaler, hasOriginHeader bool, sigProvider signatureProvider) (stop bool, err error) {
|
||||||
|
eg := &errgroup.Group{}
|
||||||
|
|
||||||
|
eg.Go(func() error {
|
||||||
|
if err := verifyServiceMessagePart(meta, sigProvider.GetMetaSignature); err != nil {
|
||||||
|
return fmt.Errorf("could not verify meta header: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
eg.Go(func() error {
|
||||||
|
if err := verifyServiceMessagePart(originHeader, sigProvider.GetOriginSignature); err != nil {
|
||||||
|
return fmt.Errorf("could not verify origin of verification header: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if !hasOriginHeader {
|
||||||
|
eg.Go(func() error {
|
||||||
|
if err := verifyServiceMessagePart(body, sigProvider.GetBodySignature); err != nil {
|
||||||
|
return fmt.Errorf("could not verify body: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := eg.Wait(); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasOriginHeader {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if sigProvider.GetBodySignature() != nil {
|
||||||
|
return false, errors.New("body signature misses at the matryoshka upper level")
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyServiceResponse(v serviceResponse) error {
|
||||||
|
meta := v.GetMetaHeader()
|
||||||
|
verificationHeader := v.GetVerificationHeader()
|
||||||
|
body := serviceMessageBody(v)
|
||||||
|
return verifyServiceResponseRecursive(body, meta, verificationHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyServiceResponseRecursive(body stableMarshaler, meta *session.ResponseMetaHeader, verify *session.ResponseVerificationHeader) error {
|
||||||
|
verificationHeaderOrigin := verify.GetOrigin()
|
||||||
|
metaOrigin := meta.GetOrigin()
|
||||||
|
|
||||||
|
stop, err := verifyMessageParts(body, meta, verificationHeaderOrigin, verificationHeaderOrigin != nil, verify)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if stop {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifyServiceResponseRecursive(body, metaOrigin, verificationHeaderOrigin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyServiceMessagePart(part stableMarshaler, sigRdr func() *refs.Signature) error {
|
||||||
|
wrapper := StableMarshalerWrapper{
|
||||||
|
SM: part,
|
||||||
|
}
|
||||||
|
|
||||||
|
return signature.VerifyDataWithSource(
|
||||||
|
wrapper,
|
||||||
|
sigRdr,
|
||||||
|
)
|
||||||
|
}
|
2
storagegroup/grpc/types.pb.go
generated
2
storagegroup/grpc/types.pb.go
generated
|
@ -27,7 +27,7 @@ const (
|
||||||
// contains objects from the same container.
|
// contains objects from the same container.
|
||||||
//
|
//
|
||||||
// Being an object payload, StorageGroup may have expiration Epoch set with
|
// Being an object payload, StorageGroup may have expiration Epoch set with
|
||||||
// `__NEOFS__EXPIRATION_EPOCH` well-known attribute. When expired, StorageGroup
|
// `__NEOFS__EXPIRATION_EPOCH`/`__FROSTFS__EXPIRATION_EPOCH` well-known attribute. When expired, StorageGroup
|
||||||
// will be ignored by InnerRing nodes during Data Audit cycles and will be
|
// will be ignored by InnerRing nodes during Data Audit cycles and will be
|
||||||
// deleted by Storage Nodes.
|
// deleted by Storage Nodes.
|
||||||
type StorageGroup struct {
|
type StorageGroup struct {
|
||||||
|
|
2
tombstone/grpc/types.pb.go
generated
2
tombstone/grpc/types.pb.go
generated
|
@ -30,7 +30,7 @@ type Tombstone struct {
|
||||||
|
|
||||||
// Last NeoFS epoch number of the tombstone lifetime. It's set by the tombstone
|
// Last NeoFS epoch number of the tombstone lifetime. It's set by the tombstone
|
||||||
// creator depending on the current NeoFS network settings. A tombstone object
|
// creator depending on the current NeoFS network settings. A tombstone object
|
||||||
// must have the same expiration epoch value in `__NEOFS__EXPIRATION_EPOCH`
|
// must have the same expiration epoch value in `__NEOFS__EXPIRATION_EPOCH`/`__FROSTFS__EXPIRATION_EPOCH`
|
||||||
// attribute. Otherwise, the tombstone will be rejected by a storage node.
|
// attribute. Otherwise, the tombstone will be rejected by a storage node.
|
||||||
ExpirationEpoch uint64 `protobuf:"varint,1,opt,name=expiration_epoch,json=expirationEpoch,proto3" json:"expiration_epoch,omitempty"`
|
ExpirationEpoch uint64 `protobuf:"varint,1,opt,name=expiration_epoch,json=expirationEpoch,proto3" json:"expiration_epoch,omitempty"`
|
||||||
// 16 byte UUID used to identify the split object hierarchy parts. Must be
|
// 16 byte UUID used to identify the split object hierarchy parts. Must be
|
||||||
|
|
29
util/signature/buffer.go
Normal file
29
util/signature/buffer.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package signature
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
const poolSliceMaxSize = 64 * 1024
|
||||||
|
|
||||||
|
var buffersPool = sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
return make([]byte, 0)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBufferFromPool(size int) []byte {
|
||||||
|
result := buffersPool.Get().([]byte)
|
||||||
|
if cap(result) < size {
|
||||||
|
result = make([]byte, size)
|
||||||
|
} else {
|
||||||
|
result = result[:size]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func returnBufferToPool(buf []byte) {
|
||||||
|
if cap(buf) > poolSliceMaxSize {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buf = buf[:0]
|
||||||
|
buffersPool.Put(buf)
|
||||||
|
}
|
|
@ -35,7 +35,10 @@ func SignDataWithHandler(key *ecdsa.PrivateKey, src DataSource, handler KeySigna
|
||||||
opts[i](cfg)
|
opts[i](cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := readSignedData(cfg, src)
|
buffer := newBufferFromPool(src.SignedDataSize())
|
||||||
|
defer returnBufferToPool(buffer)
|
||||||
|
|
||||||
|
data, err := src.ReadSignedData(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -61,7 +64,10 @@ func VerifyDataWithSource(dataSrc DataSource, sigSrc KeySignatureSource, opts ..
|
||||||
opts[i](cfg)
|
opts[i](cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := readSignedData(cfg, dataSrc)
|
buffer := newBufferFromPool(dataSrc.SignedDataSize())
|
||||||
|
defer returnBufferToPool(buffer)
|
||||||
|
|
||||||
|
data, err := dataSrc.ReadSignedData(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -76,13 +82,3 @@ func SignData(key *ecdsa.PrivateKey, v DataWithSignature, opts ...SignOption) er
|
||||||
func VerifyData(src DataWithSignature, opts ...SignOption) error {
|
func VerifyData(src DataWithSignature, opts ...SignOption) error {
|
||||||
return VerifyDataWithSource(src, src.GetSignature, opts...)
|
return VerifyDataWithSource(src, src.GetSignature, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSignedData(cfg *cfg, src DataSource) ([]byte, error) {
|
|
||||||
size := src.SignedDataSize()
|
|
||||||
if cfg.buffer == nil || cap(cfg.buffer) < size {
|
|
||||||
cfg.buffer = make([]byte, size)
|
|
||||||
} else {
|
|
||||||
cfg.buffer = cfg.buffer[:size]
|
|
||||||
}
|
|
||||||
return src.ReadSignedData(cfg.buffer)
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
type cfg struct {
|
type cfg struct {
|
||||||
schemeFixed bool
|
schemeFixed bool
|
||||||
scheme refs.SignatureScheme
|
scheme refs.SignatureScheme
|
||||||
buffer []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultCfg() *cfg {
|
func defaultCfg() *cfg {
|
||||||
|
@ -36,9 +35,10 @@ func verify(cfg *cfg, data []byte, sig *refs.Signature) error {
|
||||||
case refs.ECDSA_RFC6979_SHA256:
|
case refs.ECDSA_RFC6979_SHA256:
|
||||||
return crypto.VerifyRFC6979(pub, data, sig.GetSign())
|
return crypto.VerifyRFC6979(pub, data, sig.GetSign())
|
||||||
case refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT:
|
case refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT:
|
||||||
buf := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
|
buffer := newBufferFromPool(base64.StdEncoding.EncodedLen(len(data)))
|
||||||
base64.StdEncoding.Encode(buf, data)
|
defer returnBufferToPool(buffer)
|
||||||
if !walletconnect.Verify(pub, buf, sig.GetSign()) {
|
base64.StdEncoding.Encode(buffer, data)
|
||||||
|
if !walletconnect.Verify(pub, buffer, sig.GetSign()) {
|
||||||
return crypto.ErrInvalidSignature
|
return crypto.ErrInvalidSignature
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -54,9 +54,10 @@ func sign(cfg *cfg, key *ecdsa.PrivateKey, data []byte) ([]byte, error) {
|
||||||
case refs.ECDSA_RFC6979_SHA256:
|
case refs.ECDSA_RFC6979_SHA256:
|
||||||
return crypto.SignRFC6979(key, data)
|
return crypto.SignRFC6979(key, data)
|
||||||
case refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT:
|
case refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT:
|
||||||
buf := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
|
buffer := newBufferFromPool(base64.StdEncoding.EncodedLen(len(data)))
|
||||||
base64.StdEncoding.Encode(buf, data)
|
defer returnBufferToPool(buffer)
|
||||||
return walletconnect.Sign(key, buf)
|
base64.StdEncoding.Encode(buffer, data)
|
||||||
|
return walletconnect.Sign(key, buffer)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported scheme %s", cfg.scheme))
|
panic(fmt.Sprintf("unsupported scheme %s", cfg.scheme))
|
||||||
}
|
}
|
||||||
|
@ -69,13 +70,6 @@ func SignWithRFC6979() SignOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithBuffer allows providing pre-allocated buffer for signature verification.
|
|
||||||
func WithBuffer(buf []byte) SignOption {
|
|
||||||
return func(c *cfg) {
|
|
||||||
c.buffer = buf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SignWithWalletConnect() SignOption {
|
func SignWithWalletConnect() SignOption {
|
||||||
return func(c *cfg) {
|
return func(c *cfg) {
|
||||||
c.scheme = refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT
|
c.scheme = refs.ECDSA_RFC6979_SHA256_WALLET_CONNECT
|
||||||
|
|
Loading…
Add table
Reference in a new issue