Compare commits
No commits in common. "master" and "feat/stream-for-list" have entirely different histories.
master
...
feat/strea
281 changed files with 1785 additions and 2817 deletions
|
@ -1,28 +0,0 @@
|
|||
name: OCI image
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
image:
|
||||
name: Build container images
|
||||
runs-on: docker
|
||||
container: git.frostfs.info/truecloudlab/env:oci-image-builder-bookworm
|
||||
steps:
|
||||
- name: Clone git repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build OCI image
|
||||
run: make images
|
||||
|
||||
- name: Push image to OCI registry
|
||||
run: |
|
||||
echo "$REGISTRY_PASSWORD" \
|
||||
| docker login --username truecloudlab --password-stdin git.frostfs.info
|
||||
make push-images
|
||||
if: >-
|
||||
startsWith(github.ref, 'refs/tags/v') &&
|
||||
(github.event_name == 'workflow_dispatch' || github.event_name == 'push')
|
||||
env:
|
||||
REGISTRY_PASSWORD: ${{secrets.FORGEJO_OCI_REGISTRY_PUSH_TOKEN}}
|
|
@ -19,7 +19,6 @@ jobs:
|
|||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.23'
|
||||
check-latest: true
|
||||
|
||||
- name: Install govulncheck
|
||||
run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
|
|
@ -89,7 +89,5 @@ linters:
|
|||
- protogetter
|
||||
- intrange
|
||||
- tenv
|
||||
- unconvert
|
||||
- unparam
|
||||
disable-all: true
|
||||
fast: false
|
||||
|
|
21
Makefile
21
Makefile
|
@ -8,7 +8,7 @@ HUB_IMAGE ?= git.frostfs.info/truecloudlab/frostfs
|
|||
HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')"
|
||||
|
||||
GO_VERSION ?= 1.22
|
||||
LINT_VERSION ?= 1.62.2
|
||||
LINT_VERSION ?= 1.62.0
|
||||
TRUECLOUDLAB_LINT_VERSION ?= 0.0.8
|
||||
PROTOC_VERSION ?= 25.0
|
||||
PROTOGEN_FROSTFS_VERSION ?= $(shell go list -f '{{.Version}}' -m git.frostfs.info/TrueCloudLab/frostfs-sdk-go)
|
||||
|
@ -139,15 +139,6 @@ images: image-storage image-ir image-cli image-adm
|
|||
# Build dirty local Docker images
|
||||
dirty-images: image-dirty-storage image-dirty-ir image-dirty-cli image-dirty-adm
|
||||
|
||||
# Push FrostFS components' docker image to the registry
|
||||
push-image-%:
|
||||
@echo "⇒ Publish FrostFS $* docker image "
|
||||
@docker push $(HUB_IMAGE)-$*:$(HUB_TAG)
|
||||
|
||||
# Push all Docker images to the registry
|
||||
.PHONY: push-images
|
||||
push-images: push-image-storage push-image-ir push-image-cli push-image-adm
|
||||
|
||||
# Run `make %` in Golang container
|
||||
docker/%:
|
||||
docker run --rm -t \
|
||||
|
@ -279,12 +270,10 @@ env-up: all
|
|||
echo "Frostfs contracts not found"; exit 1; \
|
||||
fi
|
||||
${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph init --contracts ${FROSTFS_CONTRACTS_PATH}
|
||||
${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph refill-gas --gas 10.0 \
|
||||
--storage-wallet ./dev/storage/wallet01.json \
|
||||
--storage-wallet ./dev/storage/wallet02.json \
|
||||
--storage-wallet ./dev/storage/wallet03.json \
|
||||
--storage-wallet ./dev/storage/wallet04.json
|
||||
|
||||
${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph refill-gas --storage-wallet ./dev/storage/wallet01.json --gas 10.0
|
||||
${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph refill-gas --storage-wallet ./dev/storage/wallet02.json --gas 10.0
|
||||
${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph refill-gas --storage-wallet ./dev/storage/wallet03.json --gas 10.0
|
||||
${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph refill-gas --storage-wallet ./dev/storage/wallet04.json --gas 10.0
|
||||
@if [ ! -f "$(LOCODE_DB_PATH)" ]; then \
|
||||
make locode-download; \
|
||||
fi
|
||||
|
|
|
@ -16,16 +16,9 @@ const (
|
|||
EndpointFlagDesc = "N3 RPC node endpoint"
|
||||
EndpointFlagShort = "r"
|
||||
|
||||
WalletPath = "wallet"
|
||||
WalletPathShorthand = "w"
|
||||
WalletPathUsage = "Path to the wallet"
|
||||
|
||||
AlphabetWalletsFlag = "alphabet-wallets"
|
||||
AlphabetWalletsFlagDesc = "Path to alphabet wallets dir"
|
||||
|
||||
AdminWalletPath = "wallet-admin"
|
||||
AdminWalletUsage = "Path to the admin wallet"
|
||||
|
||||
LocalDumpFlag = "local-dump"
|
||||
ProtoConfigPath = "protocol"
|
||||
ContractsInitFlag = "contracts"
|
||||
|
|
|
@ -28,7 +28,6 @@ const (
|
|||
var (
|
||||
errNoPathsFound = errors.New("no metabase paths found")
|
||||
errNoMorphEndpointsFound = errors.New("no morph endpoints found")
|
||||
errUpgradeFailed = errors.New("upgrade failed")
|
||||
)
|
||||
|
||||
var UpgradeCmd = &cobra.Command{
|
||||
|
@ -92,19 +91,14 @@ func upgrade(cmd *cobra.Command, _ []string) error {
|
|||
if err := eg.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
allSuccess := true
|
||||
for mb, ok := range result {
|
||||
if ok {
|
||||
cmd.Println(mb, ": success")
|
||||
} else {
|
||||
cmd.Println(mb, ": failed")
|
||||
allSuccess = false
|
||||
}
|
||||
}
|
||||
if allSuccess {
|
||||
return nil
|
||||
}
|
||||
return errUpgradeFailed
|
||||
return nil
|
||||
}
|
||||
|
||||
func getMetabasePaths(appCfg *config.Config) ([]string, error) {
|
||||
|
|
|
@ -3,8 +3,6 @@ package ape
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
|
@ -78,8 +76,7 @@ func newPolicyContractInterface(cmd *cobra.Command) (*morph.ContractStorage, *he
|
|||
c, err := helper.NewRemoteClient(viper.GetViper())
|
||||
commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err)
|
||||
|
||||
walletDir := config.ResolveHomePath(viper.GetString(commonflags.AlphabetWalletsFlag))
|
||||
ac, err := helper.NewLocalActor(c, &helper.AlphabetWallets{Path: walletDir, Label: constants.ConsensusAccountName})
|
||||
ac, err := helper.NewLocalActor(cmd, c, constants.ConsensusAccountName)
|
||||
commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)
|
||||
|
||||
var ch util.Uint160
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package frostfsid
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sort"
|
||||
|
@ -39,11 +38,6 @@ const (
|
|||
groupIDFlag = "group-id"
|
||||
|
||||
rootNamespacePlaceholder = "<root>"
|
||||
|
||||
keyFlag = "key"
|
||||
keyDescFlag = "Key for storing a value in the subject's KV storage"
|
||||
valueFlag = "value"
|
||||
valueDescFlag = "Value to be stored in the subject's KV storage"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -157,23 +151,6 @@ var (
|
|||
},
|
||||
Run: frostfsidListGroupSubjects,
|
||||
}
|
||||
|
||||
frostfsidSetKVCmd = &cobra.Command{
|
||||
Use: "set-kv",
|
||||
Short: "Store a key-value pair in the subject's KV storage",
|
||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
},
|
||||
Run: frostfsidSetKV,
|
||||
}
|
||||
frostfsidDeleteKVCmd = &cobra.Command{
|
||||
Use: "delete-kv",
|
||||
Short: "Delete a value from the subject's KV storage",
|
||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
},
|
||||
Run: frostfsidDeleteKV,
|
||||
}
|
||||
)
|
||||
|
||||
func initFrostfsIDCreateNamespaceCmd() {
|
||||
|
@ -259,21 +236,6 @@ func initFrostfsIDListGroupSubjectsCmd() {
|
|||
frostfsidListGroupSubjectsCmd.Flags().Bool(includeNamesFlag, false, "Whether include subject name (require additional requests)")
|
||||
}
|
||||
|
||||
func initFrostfsIDSetKVCmd() {
|
||||
Cmd.AddCommand(frostfsidSetKVCmd)
|
||||
frostfsidSetKVCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
frostfsidSetKVCmd.Flags().String(subjectAddressFlag, "", "Subject address")
|
||||
frostfsidSetKVCmd.Flags().String(keyFlag, "", keyDescFlag)
|
||||
frostfsidSetKVCmd.Flags().String(valueFlag, "", valueDescFlag)
|
||||
}
|
||||
|
||||
func initFrostfsIDDeleteKVCmd() {
|
||||
Cmd.AddCommand(frostfsidDeleteKVCmd)
|
||||
frostfsidDeleteKVCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
frostfsidDeleteKVCmd.Flags().String(subjectAddressFlag, "", "Subject address")
|
||||
frostfsidDeleteKVCmd.Flags().String(keyFlag, "", keyDescFlag)
|
||||
}
|
||||
|
||||
func frostfsidCreateNamespace(cmd *cobra.Command, _ []string) {
|
||||
ns := getFrostfsIDNamespace(cmd)
|
||||
|
||||
|
@ -291,7 +253,7 @@ func frostfsidListNamespaces(cmd *cobra.Command, _ []string) {
|
|||
reader := frostfsidrpclient.NewReader(inv, hash)
|
||||
sessionID, it, err := reader.ListNamespaces()
|
||||
commonCmd.ExitOnErr(cmd, "can't get namespace: %w", err)
|
||||
items, err := readIterator(inv, &it, sessionID)
|
||||
items, err := readIterator(inv, &it, iteratorBatchSize, sessionID)
|
||||
commonCmd.ExitOnErr(cmd, "can't read iterator: %w", err)
|
||||
|
||||
namespaces, err := frostfsidclient.ParseNamespaces(items)
|
||||
|
@ -343,7 +305,7 @@ func frostfsidListSubjects(cmd *cobra.Command, _ []string) {
|
|||
sessionID, it, err := reader.ListNamespaceSubjects(ns)
|
||||
commonCmd.ExitOnErr(cmd, "can't get namespace: %w", err)
|
||||
|
||||
subAddresses, err := frostfsidclient.UnwrapArrayOfUint160(readIterator(inv, &it, sessionID))
|
||||
subAddresses, err := frostfsidclient.UnwrapArrayOfUint160(readIterator(inv, &it, iteratorBatchSize, sessionID))
|
||||
commonCmd.ExitOnErr(cmd, "can't unwrap: %w", err)
|
||||
|
||||
sort.Slice(subAddresses, func(i, j int) bool { return subAddresses[i].Less(subAddresses[j]) })
|
||||
|
@ -357,7 +319,7 @@ func frostfsidListSubjects(cmd *cobra.Command, _ []string) {
|
|||
sessionID, it, err := reader.ListSubjects()
|
||||
commonCmd.ExitOnErr(cmd, "can't get subject: %w", err)
|
||||
|
||||
items, err := readIterator(inv, &it, sessionID)
|
||||
items, err := readIterator(inv, &it, iteratorBatchSize, sessionID)
|
||||
commonCmd.ExitOnErr(cmd, "can't read iterator: %w", err)
|
||||
|
||||
subj, err := frostfsidclient.ParseSubject(items)
|
||||
|
@ -403,7 +365,7 @@ func frostfsidListGroups(cmd *cobra.Command, _ []string) {
|
|||
sessionID, it, err := reader.ListGroups(ns)
|
||||
commonCmd.ExitOnErr(cmd, "can't get namespace: %w", err)
|
||||
|
||||
items, err := readIterator(inv, &it, sessionID)
|
||||
items, err := readIterator(inv, &it, iteratorBatchSize, sessionID)
|
||||
commonCmd.ExitOnErr(cmd, "can't list groups: %w", err)
|
||||
groups, err := frostfsidclient.ParseGroups(items)
|
||||
commonCmd.ExitOnErr(cmd, "can't parse groups: %w", err)
|
||||
|
@ -441,45 +403,6 @@ func frostfsidRemoveSubjectFromGroup(cmd *cobra.Command, _ []string) {
|
|||
commonCmd.ExitOnErr(cmd, "remove subject from group error: %w", err)
|
||||
}
|
||||
|
||||
func frostfsidSetKV(cmd *cobra.Command, _ []string) {
|
||||
subjectAddress := getFrostfsIDSubjectAddress(cmd)
|
||||
key, _ := cmd.Flags().GetString(keyFlag)
|
||||
value, _ := cmd.Flags().GetString(valueFlag)
|
||||
|
||||
if key == "" {
|
||||
commonCmd.ExitOnErr(cmd, "", errors.New("key can't be empty"))
|
||||
}
|
||||
|
||||
ffsid, err := newFrostfsIDClient(cmd)
|
||||
commonCmd.ExitOnErr(cmd, "init contract client: %w", err)
|
||||
|
||||
method, args := ffsid.roCli.SetSubjectKVCall(subjectAddress, key, value)
|
||||
|
||||
ffsid.addCall(method, args)
|
||||
|
||||
err = ffsid.sendWait()
|
||||
commonCmd.ExitOnErr(cmd, "set KV: %w", err)
|
||||
}
|
||||
|
||||
func frostfsidDeleteKV(cmd *cobra.Command, _ []string) {
|
||||
subjectAddress := getFrostfsIDSubjectAddress(cmd)
|
||||
key, _ := cmd.Flags().GetString(keyFlag)
|
||||
|
||||
if key == "" {
|
||||
commonCmd.ExitOnErr(cmd, "", errors.New("key can't be empty"))
|
||||
}
|
||||
|
||||
ffsid, err := newFrostfsIDClient(cmd)
|
||||
commonCmd.ExitOnErr(cmd, "init contract client: %w", err)
|
||||
|
||||
method, args := ffsid.roCli.DeleteSubjectKVCall(subjectAddress, key)
|
||||
|
||||
ffsid.addCall(method, args)
|
||||
|
||||
err = ffsid.sendWait()
|
||||
commonCmd.ExitOnErr(cmd, "delete KV: %w", err)
|
||||
}
|
||||
|
||||
func frostfsidListGroupSubjects(cmd *cobra.Command, _ []string) {
|
||||
ns := getFrostfsIDNamespace(cmd)
|
||||
groupID := getFrostfsIDGroupID(cmd)
|
||||
|
@ -492,7 +415,7 @@ func frostfsidListGroupSubjects(cmd *cobra.Command, _ []string) {
|
|||
sessionID, it, err := reader.ListGroupSubjects(ns, big.NewInt(groupID))
|
||||
commonCmd.ExitOnErr(cmd, "can't list groups: %w", err)
|
||||
|
||||
items, err := readIterator(inv, &it, sessionID)
|
||||
items, err := readIterator(inv, &it, iteratorBatchSize, sessionID)
|
||||
commonCmd.ExitOnErr(cmd, "can't read iterator: %w", err)
|
||||
|
||||
subjects, err := frostfsidclient.UnwrapArrayOfUint160(items, err)
|
||||
|
@ -569,17 +492,17 @@ func (f *frostfsidClient) sendWaitRes() (*state.AppExecResult, error) {
|
|||
return f.roCli.Wait(f.wCtx.SentTxs[0].Hash, f.wCtx.SentTxs[0].Vub, nil)
|
||||
}
|
||||
|
||||
func readIterator(inv *invoker.Invoker, iter *result.Iterator, sessionID uuid.UUID) ([]stackitem.Item, error) {
|
||||
func readIterator(inv *invoker.Invoker, iter *result.Iterator, batchSize int, sessionID uuid.UUID) ([]stackitem.Item, error) {
|
||||
var shouldStop bool
|
||||
res := make([]stackitem.Item, 0)
|
||||
for !shouldStop {
|
||||
items, err := inv.TraverseIterator(sessionID, iter, iteratorBatchSize)
|
||||
items, err := inv.TraverseIterator(sessionID, iter, batchSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = append(res, items...)
|
||||
shouldStop = len(items) < iteratorBatchSize
|
||||
shouldStop = len(items) < batchSize
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
|
|
@ -12,8 +12,6 @@ func init() {
|
|||
initFrostfsIDAddSubjectToGroupCmd()
|
||||
initFrostfsIDRemoveSubjectFromGroupCmd()
|
||||
initFrostfsIDListGroupSubjectsCmd()
|
||||
initFrostfsIDSetKVCmd()
|
||||
initFrostfsIDDeleteKVCmd()
|
||||
initFrostfsIDAddSubjectKeyCmd()
|
||||
initFrostfsIDRemoveSubjectKeyCmd()
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
|
@ -140,29 +141,60 @@ func addMultisigAccount(w *wallet.Wallet, m int, name, password string, pubs key
|
|||
}
|
||||
|
||||
func generateStorageCreds(cmd *cobra.Command, _ []string) error {
|
||||
walletPath, _ := cmd.Flags().GetString(commonflags.StorageWalletFlag)
|
||||
w, err := wallet.NewWallet(walletPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create wallet: %w", err)
|
||||
}
|
||||
|
||||
label, _ := cmd.Flags().GetString(storageWalletLabelFlag)
|
||||
password, err := config.GetStoragePassword(viper.GetViper(), label)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't fetch password: %w", err)
|
||||
}
|
||||
|
||||
if label == "" {
|
||||
label = constants.SingleAccountName
|
||||
}
|
||||
|
||||
if err := w.CreateAccount(label, password); err != nil {
|
||||
return fmt.Errorf("can't create account: %w", err)
|
||||
}
|
||||
return refillGas(cmd, storageGasConfigFlag, w.Accounts[0].ScriptHash())
|
||||
return refillGas(cmd, storageGasConfigFlag, true)
|
||||
}
|
||||
|
||||
func refillGas(cmd *cobra.Command, gasFlag string, gasReceivers ...util.Uint160) (err error) {
|
||||
func refillGas(cmd *cobra.Command, gasFlag string, createWallet bool) (err error) {
|
||||
// storage wallet path is not part of the config
|
||||
storageWalletPath, _ := cmd.Flags().GetString(commonflags.StorageWalletFlag)
|
||||
// wallet address is not part of the config
|
||||
walletAddress, _ := cmd.Flags().GetString(walletAddressFlag)
|
||||
|
||||
var gasReceiver util.Uint160
|
||||
|
||||
if len(walletAddress) != 0 {
|
||||
gasReceiver, err = address.StringToUint160(walletAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid wallet address %s: %w", walletAddress, err)
|
||||
}
|
||||
} else {
|
||||
if storageWalletPath == "" {
|
||||
return fmt.Errorf("missing wallet path (use '--%s <out.json>')", commonflags.StorageWalletFlag)
|
||||
}
|
||||
|
||||
var w *wallet.Wallet
|
||||
|
||||
if createWallet {
|
||||
w, err = wallet.NewWallet(storageWalletPath)
|
||||
} else {
|
||||
w, err = wallet.NewWalletFromFile(storageWalletPath)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't create wallet: %w", err)
|
||||
}
|
||||
|
||||
if createWallet {
|
||||
var password string
|
||||
|
||||
label, _ := cmd.Flags().GetString(storageWalletLabelFlag)
|
||||
password, err := config.GetStoragePassword(viper.GetViper(), label)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't fetch password: %w", err)
|
||||
}
|
||||
|
||||
if label == "" {
|
||||
label = constants.SingleAccountName
|
||||
}
|
||||
|
||||
if err := w.CreateAccount(label, password); err != nil {
|
||||
return fmt.Errorf("can't create account: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
gasReceiver = w.Accounts[0].Contract.ScriptHash()
|
||||
}
|
||||
|
||||
gasStr := viper.GetString(gasFlag)
|
||||
|
||||
gasAmount, err := helper.ParseGASAmount(gasStr)
|
||||
|
@ -176,11 +208,9 @@ func refillGas(cmd *cobra.Command, gasFlag string, gasReceivers ...util.Uint160)
|
|||
}
|
||||
|
||||
bw := io.NewBufBinWriter()
|
||||
for _, gasReceiver := range gasReceivers {
|
||||
emit.AppCall(bw.BinWriter, gas.Hash, "transfer", callflag.All,
|
||||
wCtx.CommitteeAcc.Contract.ScriptHash(), gasReceiver, int64(gasAmount), nil)
|
||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||
}
|
||||
emit.AppCall(bw.BinWriter, gas.Hash, "transfer", callflag.All,
|
||||
wCtx.CommitteeAcc.Contract.ScriptHash(), gasReceiver, int64(gasAmount), nil)
|
||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||
if bw.Err != nil {
|
||||
return fmt.Errorf("BUG: invalid transfer arguments: %w", bw.Err)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
package generate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
@ -38,27 +33,7 @@ var (
|
|||
_ = viper.BindPFlag(commonflags.RefillGasAmountFlag, cmd.Flags().Lookup(commonflags.RefillGasAmountFlag))
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
storageWalletPaths, _ := cmd.Flags().GetStringArray(commonflags.StorageWalletFlag)
|
||||
walletAddresses, _ := cmd.Flags().GetStringArray(walletAddressFlag)
|
||||
|
||||
var gasReceivers []util.Uint160
|
||||
for _, walletAddress := range walletAddresses {
|
||||
addr, err := address.StringToUint160(walletAddress)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid wallet address %s: %w", walletAddress, err)
|
||||
}
|
||||
|
||||
gasReceivers = append(gasReceivers, addr)
|
||||
}
|
||||
for _, storageWalletPath := range storageWalletPaths {
|
||||
w, err := wallet.NewWalletFromFile(storageWalletPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't create wallet: %w", err)
|
||||
}
|
||||
|
||||
gasReceivers = append(gasReceivers, w.Accounts[0].Contract.ScriptHash())
|
||||
}
|
||||
return refillGas(cmd, commonflags.RefillGasAmountFlag, gasReceivers...)
|
||||
return refillGas(cmd, commonflags.RefillGasAmountFlag, false)
|
||||
},
|
||||
}
|
||||
GenerateAlphabetCmd = &cobra.Command{
|
||||
|
@ -75,10 +50,10 @@ var (
|
|||
func initRefillGasCmd() {
|
||||
RefillGasCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
RefillGasCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
RefillGasCmd.Flags().StringArray(commonflags.StorageWalletFlag, nil, "Path to storage node wallet")
|
||||
RefillGasCmd.Flags().StringArray(walletAddressFlag, nil, "Address of wallet")
|
||||
RefillGasCmd.Flags().String(commonflags.StorageWalletFlag, "", "Path to storage node wallet")
|
||||
RefillGasCmd.Flags().String(walletAddressFlag, "", "Address of wallet")
|
||||
RefillGasCmd.Flags().String(commonflags.RefillGasAmountFlag, "", "Additional amount of GAS to transfer")
|
||||
RefillGasCmd.MarkFlagsOneRequired(walletAddressFlag, commonflags.StorageWalletFlag)
|
||||
RefillGasCmd.MarkFlagsMutuallyExclusive(walletAddressFlag, commonflags.StorageWalletFlag)
|
||||
}
|
||||
|
||||
func initGenerateStorageCmd() {
|
||||
|
|
|
@ -3,6 +3,9 @@ package helper
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
|
@ -13,6 +16,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
|
@ -24,86 +28,32 @@ type LocalActor struct {
|
|||
rpcInvoker invoker.RPCInvoke
|
||||
}
|
||||
|
||||
type AlphabetWallets struct {
|
||||
Label string
|
||||
Path string
|
||||
}
|
||||
|
||||
func (a *AlphabetWallets) GetAccount(v *viper.Viper) ([]*wallet.Account, error) {
|
||||
w, err := GetAlphabetWallets(v, a.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var accounts []*wallet.Account
|
||||
for _, wall := range w {
|
||||
acc, err := GetWalletAccount(wall, a.Label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
accounts = append(accounts, acc)
|
||||
}
|
||||
return accounts, nil
|
||||
}
|
||||
|
||||
type RegularWallets struct{ Path string }
|
||||
|
||||
func (r *RegularWallets) GetAccount() ([]*wallet.Account, error) {
|
||||
w, err := getRegularWallet(r.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []*wallet.Account{w.GetAccount(w.GetChangeAddress())}, nil
|
||||
}
|
||||
|
||||
// NewLocalActor create LocalActor with accounts form provided wallets.
|
||||
// In case of empty wallets provided created actor with dummy account only for read operation.
|
||||
//
|
||||
// If wallets are provided, the contract client will use accounts with accName name from these wallets.
|
||||
// To determine which account name should be used in a contract client, refer to how the contract
|
||||
// verifies the transaction signature.
|
||||
func NewLocalActor(c actor.RPCActor, alphabet *AlphabetWallets, regularWallets ...*RegularWallets) (*LocalActor, error) {
|
||||
func NewLocalActor(cmd *cobra.Command, c actor.RPCActor, accName string) (*LocalActor, error) {
|
||||
walletDir := config.ResolveHomePath(viper.GetString(commonflags.AlphabetWalletsFlag))
|
||||
var act *actor.Actor
|
||||
var accounts []*wallet.Account
|
||||
var signers []actor.SignerAccount
|
||||
|
||||
if alphabet != nil {
|
||||
account, err := alphabet.GetAccount(viper.GetViper())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wallets, err := GetAlphabetWallets(viper.GetViper(), walletDir)
|
||||
commonCmd.ExitOnErr(cmd, "unable to get alphabet wallets: %w", err)
|
||||
|
||||
accounts = append(accounts, account...)
|
||||
signers = append(signers, actor.SignerAccount{
|
||||
Signer: transaction.Signer{
|
||||
Account: account[0].Contract.ScriptHash(),
|
||||
Scopes: transaction.Global,
|
||||
},
|
||||
Account: account[0],
|
||||
})
|
||||
for _, w := range wallets {
|
||||
acc, err := GetWalletAccount(w, accName)
|
||||
commonCmd.ExitOnErr(cmd, fmt.Sprintf("can't find %s account: %%w", accName), err)
|
||||
accounts = append(accounts, acc)
|
||||
}
|
||||
|
||||
for _, w := range regularWallets {
|
||||
if w == nil {
|
||||
continue
|
||||
}
|
||||
account, err := w.GetAccount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accounts = append(accounts, account...)
|
||||
signers = append(signers, actor.SignerAccount{
|
||||
Signer: transaction.Signer{
|
||||
Account: account[0].Contract.ScriptHash(),
|
||||
Scopes: transaction.Global,
|
||||
},
|
||||
Account: account[0],
|
||||
})
|
||||
}
|
||||
|
||||
act, err := actor.New(c, signers)
|
||||
act, err = actor.New(c, []actor.SignerAccount{{
|
||||
Signer: transaction.Signer{
|
||||
Account: accounts[0].Contract.ScriptHash(),
|
||||
Scopes: transaction.Global,
|
||||
},
|
||||
Account: accounts[0],
|
||||
}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||
|
@ -23,27 +22,6 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func getRegularWallet(walletPath string) (*wallet.Wallet, error) {
|
||||
w, err := wallet.NewWalletFromFile(walletPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
password, err := input.ReadPassword("Enter password for wallet:")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't fetch password: %w", err)
|
||||
}
|
||||
|
||||
for i := range w.Accounts {
|
||||
if err = w.Accounts[i].Decrypt(password, keys.NEP2ScryptParams()); err != nil {
|
||||
err = fmt.Errorf("can't unlock wallet: %w", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return w, err
|
||||
}
|
||||
|
||||
func GetAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, error) {
|
||||
wallets, err := openAlphabetWallets(v, walletDir)
|
||||
if err != nil {
|
||||
|
@ -73,7 +51,7 @@ func openAlphabetWallets(v *viper.Viper, walletDir string) ([]*wallet.Wallet, er
|
|||
if errors.Is(err, os.ErrNotExist) {
|
||||
err = nil
|
||||
} else {
|
||||
err = fmt.Errorf("can't open alphabet wallet: %w", err)
|
||||
err = fmt.Errorf("can't open wallet: %w", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
|
|
@ -6,9 +6,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func initRegisterCmd() {
|
||||
|
@ -21,7 +19,6 @@ func initRegisterCmd() {
|
|||
registerCmd.Flags().Int64(nnsRetryFlag, constants.NNSRetryDefVal, "SOA record RETRY parameter")
|
||||
registerCmd.Flags().Int64(nnsExpireFlag, int64(constants.DefaultExpirationTime), "SOA record EXPIRE parameter")
|
||||
registerCmd.Flags().Int64(nnsTTLFlag, constants.NNSTtlDefVal, "SOA record TTL parameter")
|
||||
registerCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, "", commonflags.WalletPathUsage)
|
||||
|
||||
_ = cobra.MarkFlagRequired(registerCmd.Flags(), nnsNameFlag)
|
||||
}
|
||||
|
@ -51,7 +48,6 @@ func initDeleteCmd() {
|
|||
deleteCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
deleteCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
deleteCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc)
|
||||
deleteCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, "", commonflags.WalletPathUsage)
|
||||
|
||||
_ = cobra.MarkFlagRequired(deleteCmd.Flags(), nnsNameFlag)
|
||||
}
|
||||
|
@ -66,28 +62,3 @@ func deleteDomain(cmd *cobra.Command, _ []string) {
|
|||
commonCmd.ExitOnErr(cmd, "delete domain error: %w", err)
|
||||
cmd.Println("Domain deleted successfully")
|
||||
}
|
||||
|
||||
func initSetAdminCmd() {
|
||||
Cmd.AddCommand(setAdminCmd)
|
||||
setAdminCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
setAdminCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
setAdminCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc)
|
||||
setAdminCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, "", commonflags.WalletPathUsage)
|
||||
setAdminCmd.Flags().String(commonflags.AdminWalletPath, "", commonflags.AdminWalletUsage)
|
||||
_ = setAdminCmd.MarkFlagRequired(commonflags.AdminWalletPath)
|
||||
|
||||
_ = cobra.MarkFlagRequired(setAdminCmd.Flags(), nnsNameFlag)
|
||||
}
|
||||
|
||||
func setAdmin(cmd *cobra.Command, _ []string) {
|
||||
c, actor := nnsWriter(cmd)
|
||||
|
||||
name, _ := cmd.Flags().GetString(nnsNameFlag)
|
||||
w, err := wallet.NewWalletFromFile(viper.GetString(commonflags.AdminWalletPath))
|
||||
commonCmd.ExitOnErr(cmd, "can't get admin wallet: %w", err)
|
||||
h, vub, err := c.SetAdmin(name, w.GetAccount(w.GetChangeAddress()).ScriptHash())
|
||||
|
||||
_, err = actor.Wait(h, vub, err)
|
||||
commonCmd.ExitOnErr(cmd, "Set admin error: %w", err)
|
||||
cmd.Println("Set admin successfully")
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package nns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
client "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/nns"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
|
@ -20,32 +16,7 @@ func nnsWriter(cmd *cobra.Command) (*client.Contract, *helper.LocalActor) {
|
|||
c, err := helper.NewRemoteClient(v)
|
||||
commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err)
|
||||
|
||||
alphabetWalletPath := config.ResolveHomePath(v.GetString(commonflags.AlphabetWalletsFlag))
|
||||
walletPath := config.ResolveHomePath(v.GetString(commonflags.WalletPath))
|
||||
adminWalletPath := config.ResolveHomePath(v.GetString(commonflags.AdminWalletPath))
|
||||
|
||||
var (
|
||||
alphabet *helper.AlphabetWallets
|
||||
regularWallets []*helper.RegularWallets
|
||||
)
|
||||
|
||||
if alphabetWalletPath != "" {
|
||||
alphabet = &helper.AlphabetWallets{Path: alphabetWalletPath, Label: constants.ConsensusAccountName}
|
||||
}
|
||||
|
||||
if walletPath != "" {
|
||||
regularWallets = append(regularWallets, &helper.RegularWallets{Path: walletPath})
|
||||
}
|
||||
|
||||
if adminWalletPath != "" {
|
||||
regularWallets = append(regularWallets, &helper.RegularWallets{Path: adminWalletPath})
|
||||
}
|
||||
|
||||
if alphabet == nil && regularWallets == nil {
|
||||
commonCmd.ExitOnErr(cmd, "", errors.New("no wallets provided"))
|
||||
}
|
||||
|
||||
ac, err := helper.NewLocalActor(c, alphabet, regularWallets...)
|
||||
ac, err := helper.NewLocalActor(cmd, c, constants.CommitteeAccountName)
|
||||
commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)
|
||||
|
||||
r := management.NewReader(ac.Invoker)
|
||||
|
|
|
@ -19,7 +19,6 @@ func initAddRecordCmd() {
|
|||
addRecordCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc)
|
||||
addRecordCmd.Flags().String(nnsRecordTypeFlag, "", nnsRecordTypeFlagDesc)
|
||||
addRecordCmd.Flags().String(nnsRecordDataFlag, "", nnsRecordDataFlagDesc)
|
||||
addRecordCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, "", commonflags.WalletPathUsage)
|
||||
|
||||
_ = cobra.MarkFlagRequired(addRecordCmd.Flags(), nnsNameFlag)
|
||||
_ = cobra.MarkFlagRequired(addRecordCmd.Flags(), nnsRecordTypeFlag)
|
||||
|
@ -41,7 +40,6 @@ func initDelRecordsCmd() {
|
|||
delRecordsCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
delRecordsCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc)
|
||||
delRecordsCmd.Flags().String(nnsRecordTypeFlag, "", nnsRecordTypeFlagDesc)
|
||||
delRecordsCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, "", commonflags.WalletPathUsage)
|
||||
|
||||
_ = cobra.MarkFlagRequired(delRecordsCmd.Flags(), nnsNameFlag)
|
||||
_ = cobra.MarkFlagRequired(delRecordsCmd.Flags(), nnsRecordTypeFlag)
|
||||
|
@ -54,7 +52,6 @@ func initDelRecordCmd() {
|
|||
delRecordCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc)
|
||||
delRecordCmd.Flags().String(nnsRecordTypeFlag, "", nnsRecordTypeFlagDesc)
|
||||
delRecordCmd.Flags().String(nnsRecordDataFlag, "", nnsRecordDataFlagDesc)
|
||||
delRecordCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, "", commonflags.WalletPathUsage)
|
||||
|
||||
_ = cobra.MarkFlagRequired(delRecordCmd.Flags(), nnsNameFlag)
|
||||
_ = cobra.MarkFlagRequired(delRecordCmd.Flags(), nnsRecordTypeFlag)
|
||||
|
|
|
@ -39,7 +39,6 @@ var (
|
|||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
_ = viper.BindPFlag(commonflags.WalletPath, cmd.Flags().Lookup(commonflags.WalletPath))
|
||||
},
|
||||
Run: registerDomain,
|
||||
}
|
||||
|
@ -49,7 +48,6 @@ var (
|
|||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
_ = viper.BindPFlag(commonflags.WalletPath, cmd.Flags().Lookup(commonflags.WalletPath))
|
||||
},
|
||||
Run: deleteDomain,
|
||||
}
|
||||
|
@ -77,7 +75,6 @@ var (
|
|||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
_ = viper.BindPFlag(commonflags.WalletPath, cmd.Flags().Lookup(commonflags.WalletPath))
|
||||
},
|
||||
Run: addRecord,
|
||||
}
|
||||
|
@ -95,7 +92,6 @@ var (
|
|||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
_ = viper.BindPFlag(commonflags.WalletPath, cmd.Flags().Lookup(commonflags.WalletPath))
|
||||
},
|
||||
Run: delRecords,
|
||||
}
|
||||
|
@ -105,21 +101,9 @@ var (
|
|||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
_ = viper.BindPFlag(commonflags.WalletPath, cmd.Flags().Lookup(commonflags.WalletPath))
|
||||
},
|
||||
Run: delRecord,
|
||||
}
|
||||
setAdminCmd = &cobra.Command{
|
||||
Use: "set-admin",
|
||||
Short: "Sets admin for domain",
|
||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
_ = viper.BindPFlag(commonflags.WalletPath, cmd.Flags().Lookup(commonflags.WalletPath))
|
||||
_ = viper.BindPFlag(commonflags.AdminWalletPath, cmd.Flags().Lookup(commonflags.AdminWalletPath))
|
||||
},
|
||||
Run: setAdmin,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -132,5 +116,4 @@ func init() {
|
|||
initGetRecordsCmd()
|
||||
initDelRecordsCmd()
|
||||
initDelRecordCmd()
|
||||
initSetAdminCmd()
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
|
||||
|
@ -40,8 +41,7 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
|
|||
}
|
||||
|
||||
accHash := w.GetChangeAddress()
|
||||
addr, _ := cmd.Flags().GetString(walletAccountFlag)
|
||||
if addr != "" {
|
||||
if addr, err := cmd.Flags().GetString(walletAccountFlag); err == nil {
|
||||
accHash, err = address.StringToUint160(addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid address: %s", addr)
|
||||
|
@ -53,7 +53,7 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
|
|||
return fmt.Errorf("can't find account for %s", accHash)
|
||||
}
|
||||
|
||||
prompt := fmt.Sprintf("Enter password for %s > ", address.Uint160ToString(accHash))
|
||||
prompt := fmt.Sprintf("Enter password for %s >", address.Uint160ToString(accHash))
|
||||
pass, err := input.ReadPassword(prompt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get password: %v", err)
|
||||
|
@ -73,9 +73,16 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
till, _ := cmd.Flags().GetInt64(notaryDepositTillFlag)
|
||||
if till <= 0 {
|
||||
return errInvalidNotaryDepositLifetime
|
||||
till := int64(defaultNotaryDepositLifetime)
|
||||
tillStr, err := cmd.Flags().GetString(notaryDepositTillFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tillStr != "" {
|
||||
till, err = strconv.ParseInt(tillStr, 10, 64)
|
||||
if err != nil || till <= 0 {
|
||||
return errInvalidNotaryDepositLifetime
|
||||
}
|
||||
}
|
||||
|
||||
return transferGas(cmd, acc, accHash, gasAmount, till)
|
||||
|
|
|
@ -20,7 +20,7 @@ func initDepositoryNotaryCmd() {
|
|||
DepositCmd.Flags().String(commonflags.StorageWalletFlag, "", "Path to storage node wallet")
|
||||
DepositCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
|
||||
DepositCmd.Flags().String(commonflags.RefillGasAmountFlag, "", "Amount of GAS to deposit")
|
||||
DepositCmd.Flags().Int64(notaryDepositTillFlag, defaultNotaryDepositLifetime, "Notary deposit duration in blocks")
|
||||
DepositCmd.Flags().String(notaryDepositTillFlag, "", "Notary deposit duration in blocks")
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -20,32 +20,23 @@ const (
|
|||
accountAddressFlag = "account"
|
||||
)
|
||||
|
||||
func parseAddresses(cmd *cobra.Command) []util.Uint160 {
|
||||
var addrs []util.Uint160
|
||||
|
||||
accs, _ := cmd.Flags().GetStringArray(accountAddressFlag)
|
||||
for _, acc := range accs {
|
||||
addr, err := address.StringToUint160(acc)
|
||||
commonCmd.ExitOnErr(cmd, "invalid account: %w", err)
|
||||
|
||||
addrs = append(addrs, addr)
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
func addProxyAccount(cmd *cobra.Command, _ []string) {
|
||||
addrs := parseAddresses(cmd)
|
||||
err := processAccount(cmd, addrs, "addAccount")
|
||||
acc, _ := cmd.Flags().GetString(accountAddressFlag)
|
||||
addr, err := address.StringToUint160(acc)
|
||||
commonCmd.ExitOnErr(cmd, "invalid account: %w", err)
|
||||
err = processAccount(cmd, addr, "addAccount")
|
||||
commonCmd.ExitOnErr(cmd, "processing error: %w", err)
|
||||
}
|
||||
|
||||
func removeProxyAccount(cmd *cobra.Command, _ []string) {
|
||||
addrs := parseAddresses(cmd)
|
||||
err := processAccount(cmd, addrs, "removeAccount")
|
||||
acc, _ := cmd.Flags().GetString(accountAddressFlag)
|
||||
addr, err := address.StringToUint160(acc)
|
||||
commonCmd.ExitOnErr(cmd, "invalid account: %w", err)
|
||||
err = processAccount(cmd, addr, "removeAccount")
|
||||
commonCmd.ExitOnErr(cmd, "processing error: %w", err)
|
||||
}
|
||||
|
||||
func processAccount(cmd *cobra.Command, addrs []util.Uint160, method string) error {
|
||||
func processAccount(cmd *cobra.Command, addr util.Uint160, method string) error {
|
||||
wCtx, err := helper.NewInitializeContext(cmd, viper.GetViper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't initialize context: %w", err)
|
||||
|
@ -63,9 +54,7 @@ func processAccount(cmd *cobra.Command, addrs []util.Uint160, method string) err
|
|||
}
|
||||
|
||||
bw := io.NewBufBinWriter()
|
||||
for _, addr := range addrs {
|
||||
emit.AppCall(bw.BinWriter, proxyHash, method, callflag.All, addr)
|
||||
}
|
||||
emit.AppCall(bw.BinWriter, proxyHash, method, callflag.All, addr)
|
||||
|
||||
if err := wCtx.SendConsensusTx(bw.Bytes()); err != nil {
|
||||
return err
|
||||
|
|
|
@ -29,15 +29,13 @@ var (
|
|||
|
||||
func initProxyAddAccount() {
|
||||
AddAccountCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
AddAccountCmd.Flags().StringArray(accountAddressFlag, nil, "Wallet address string")
|
||||
_ = AddAccountCmd.MarkFlagRequired(accountAddressFlag)
|
||||
AddAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string")
|
||||
AddAccountCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
}
|
||||
|
||||
func initProxyRemoveAccount() {
|
||||
RemoveAccountCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
RemoveAccountCmd.Flags().StringArray(accountAddressFlag, nil, "Wallet address string")
|
||||
_ = AddAccountCmd.MarkFlagRequired(accountAddressFlag)
|
||||
RemoveAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string")
|
||||
RemoveAccountCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
@ -106,7 +105,7 @@ func storageConfig(cmd *cobra.Command, args []string) {
|
|||
fatalOnErr(errors.New("can't find account in wallet"))
|
||||
}
|
||||
|
||||
c.Wallet.Password, err = input.ReadPassword(fmt.Sprintf("Enter password for %s > ", c.Wallet.Account))
|
||||
c.Wallet.Password, err = input.ReadPassword(fmt.Sprintf("Account password for %s: ", c.Wallet.Account))
|
||||
fatalOnErr(err)
|
||||
|
||||
err = acc.Decrypt(c.Wallet.Password, keys.NEP2ScryptParams())
|
||||
|
@ -411,7 +410,8 @@ func initClient(rpc []string) *rpcclient.Client {
|
|||
var c *rpcclient.Client
|
||||
var err error
|
||||
|
||||
shuffled := slices.Clone(rpc)
|
||||
shuffled := make([]string, len(rpc))
|
||||
copy(shuffled, rpc)
|
||||
rand.Shuffle(len(shuffled), func(i, j int) { shuffled[i], shuffled[j] = shuffled[j], shuffled[i] })
|
||||
|
||||
for _, endpoint := range shuffled {
|
||||
|
|
|
@ -52,7 +52,7 @@ func genereateAPEOverride(cmd *cobra.Command, _ []string) {
|
|||
|
||||
outputPath, _ := cmd.Flags().GetString(outputFlag)
|
||||
if outputPath != "" {
|
||||
err := os.WriteFile(outputPath, overrideMarshalled, 0o644)
|
||||
err := os.WriteFile(outputPath, []byte(overrideMarshalled), 0o644)
|
||||
commonCmd.ExitOnErr(cmd, "dump error: %w", err)
|
||||
} else {
|
||||
fmt.Print("\n")
|
||||
|
|
|
@ -23,11 +23,11 @@ type policyPlaygroundREPL struct {
|
|||
nodes map[string]netmap.NodeInfo
|
||||
}
|
||||
|
||||
func newPolicyPlaygroundREPL(cmd *cobra.Command) *policyPlaygroundREPL {
|
||||
func newPolicyPlaygroundREPL(cmd *cobra.Command) (*policyPlaygroundREPL, error) {
|
||||
return &policyPlaygroundREPL{
|
||||
cmd: cmd,
|
||||
nodes: map[string]netmap.NodeInfo{},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (repl *policyPlaygroundREPL) handleLs(args []string) error {
|
||||
|
@ -246,7 +246,8 @@ var policyPlaygroundCmd = &cobra.Command{
|
|||
Long: `A REPL for testing placement policies.
|
||||
If a wallet and endpoint is provided, the initial netmap data will be loaded from the snapshot of the node. Otherwise, an empty playground is created.`,
|
||||
Run: func(cmd *cobra.Command, _ []string) {
|
||||
repl := newPolicyPlaygroundREPL(cmd)
|
||||
repl, err := newPolicyPlaygroundREPL(cmd)
|
||||
commonCmd.ExitOnErr(cmd, "could not create policy playground: %w", err)
|
||||
commonCmd.ExitOnErr(cmd, "policy playground failed: %w", repl.run())
|
||||
},
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ func awaitSetNetmapStatus(cmd *cobra.Command, pk *ecdsa.PrivateKey, cli *client.
|
|||
var resp *control.GetNetmapStatusResponse
|
||||
var err error
|
||||
err = cli.ExecRaw(func(client *rawclient.Client) error {
|
||||
resp, err = control.GetNetmapStatus(cmd.Context(), client, req)
|
||||
resp, err = control.GetNetmapStatus(client, req)
|
||||
return err
|
||||
})
|
||||
commonCmd.ExitOnErr(cmd, "failed to get current netmap status: %w", err)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -41,9 +42,7 @@ func initObjectHashCmd() {
|
|||
flags.String(commonflags.OIDFlag, "", commonflags.OIDFlagUsage)
|
||||
_ = objectHashCmd.MarkFlagRequired(commonflags.OIDFlag)
|
||||
|
||||
flags.StringSlice("range", nil, "Range to take hash from in the form offset1:length1,...")
|
||||
_ = objectHashCmd.MarkFlagRequired("range")
|
||||
|
||||
flags.String("range", "", "Range to take hash from in the form offset1:length1,...")
|
||||
flags.String("type", hashSha256, "Hash type. Either 'sha256' or 'tz'")
|
||||
flags.String(getRangeHashSaltFlag, "", "Salt in hex format")
|
||||
}
|
||||
|
@ -67,6 +66,36 @@ func getObjectHash(cmd *cobra.Command, _ []string) {
|
|||
pk := key.GetOrGenerate(cmd)
|
||||
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
|
||||
|
||||
tz := typ == hashTz
|
||||
fullHash := len(ranges) == 0
|
||||
if fullHash {
|
||||
var headPrm internalclient.HeadObjectPrm
|
||||
headPrm.SetClient(cli)
|
||||
Prepare(cmd, &headPrm)
|
||||
headPrm.SetAddress(objAddr)
|
||||
|
||||
// get hash of full payload through HEAD (may be user can do it through dedicated command?)
|
||||
res, err := internalclient.HeadObject(cmd.Context(), headPrm)
|
||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
||||
|
||||
var cs checksum.Checksum
|
||||
var csSet bool
|
||||
|
||||
if tz {
|
||||
cs, csSet = res.Header().PayloadHomomorphicHash()
|
||||
} else {
|
||||
cs, csSet = res.Header().PayloadChecksum()
|
||||
}
|
||||
|
||||
if csSet {
|
||||
cmd.Println(hex.EncodeToString(cs.Value()))
|
||||
} else {
|
||||
cmd.Println("Missing checksum in object header.")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var hashPrm internalclient.HashPayloadRangesPrm
|
||||
hashPrm.SetClient(cli)
|
||||
Prepare(cmd, &hashPrm)
|
||||
|
@ -75,7 +104,7 @@ func getObjectHash(cmd *cobra.Command, _ []string) {
|
|||
hashPrm.SetSalt(salt)
|
||||
hashPrm.SetRanges(ranges)
|
||||
|
||||
if typ == hashTz {
|
||||
if tz {
|
||||
hashPrm.TZ()
|
||||
}
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ func getReplicaRequiredPlacement(cmd *cobra.Command, objects []phyObject, placem
|
|||
}
|
||||
placementBuilder := placement.NewNetworkMapBuilder(netmap)
|
||||
for _, object := range objects {
|
||||
placement, err := placementBuilder.BuildPlacement(cmd.Context(), object.containerID, &object.objectID, placementPolicy)
|
||||
placement, err := placementBuilder.BuildPlacement(object.containerID, &object.objectID, placementPolicy)
|
||||
commonCmd.ExitOnErr(cmd, "failed to get required placement for object: %w", err)
|
||||
for repIdx, rep := range placement {
|
||||
numOfReplicas := placementPolicy.ReplicaDescriptor(repIdx).NumberOfObjects()
|
||||
|
@ -358,7 +358,7 @@ func getECRequiredPlacementInternal(cmd *cobra.Command, object phyObject, placem
|
|||
placementObjectID = object.ecHeader.parent
|
||||
}
|
||||
placementBuilder := placement.NewNetworkMapBuilder(netmap)
|
||||
placement, err := placementBuilder.BuildPlacement(cmd.Context(), object.containerID, &placementObjectID, placementPolicy)
|
||||
placement, err := placementBuilder.BuildPlacement(object.containerID, &placementObjectID, placementPolicy)
|
||||
commonCmd.ExitOnErr(cmd, "failed to get required placement: %w", err)
|
||||
|
||||
for _, vector := range placement {
|
||||
|
|
|
@ -46,7 +46,7 @@ func initObjectPatchCmd() {
|
|||
flags.String(commonflags.OIDFlag, "", commonflags.OIDFlagUsage)
|
||||
_ = objectRangeCmd.MarkFlagRequired(commonflags.OIDFlag)
|
||||
|
||||
flags.StringSlice(newAttrsFlagName, nil, "New object attributes in form of Key1=Value1,Key2=Value2")
|
||||
flags.String(newAttrsFlagName, "", "New object attributes in form of Key1=Value1,Key2=Value2")
|
||||
flags.Bool(replaceAttrsFlagName, false, "Replace object attributes by new ones.")
|
||||
flags.StringSlice(rangeFlagName, []string{}, "Range to which patch payload is applied. Format: offset:length")
|
||||
flags.StringSlice(payloadFlagName, []string{}, "Path to file with patch payload.")
|
||||
|
@ -99,9 +99,11 @@ func patch(cmd *cobra.Command, _ []string) {
|
|||
}
|
||||
|
||||
func parseNewObjectAttrs(cmd *cobra.Command) ([]objectSDK.Attribute, error) {
|
||||
rawAttrs, err := cmd.Flags().GetStringSlice(newAttrsFlagName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var rawAttrs []string
|
||||
|
||||
raw := cmd.Flag(newAttrsFlagName).Value.String()
|
||||
if len(raw) != 0 {
|
||||
rawAttrs = strings.Split(raw, ",")
|
||||
}
|
||||
|
||||
attrs := make([]objectSDK.Attribute, len(rawAttrs), len(rawAttrs)+2) // name + timestamp attributes
|
||||
|
|
|
@ -50,7 +50,7 @@ func initObjectPutCmd() {
|
|||
|
||||
flags.String(commonflags.CIDFlag, "", commonflags.CIDFlagUsage)
|
||||
|
||||
flags.StringSlice("attributes", nil, "User attributes in form of Key1=Value1,Key2=Value2")
|
||||
flags.String("attributes", "", "User attributes in form of Key1=Value1,Key2=Value2")
|
||||
flags.Bool("disable-filename", false, "Do not set well-known filename attribute")
|
||||
flags.Bool("disable-timestamp", false, "Do not set well-known timestamp attribute")
|
||||
flags.Uint64VarP(&putExpiredOn, commonflags.ExpireAt, "e", 0, "The last active epoch in the life of the object")
|
||||
|
@ -214,9 +214,11 @@ func getAllObjectAttributes(cmd *cobra.Command) []objectSDK.Attribute {
|
|||
}
|
||||
|
||||
func parseObjectAttrs(cmd *cobra.Command) ([]objectSDK.Attribute, error) {
|
||||
rawAttrs, err := cmd.Flags().GetStringSlice("attributes")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var rawAttrs []string
|
||||
|
||||
raw := cmd.Flag("attributes").Value.String()
|
||||
if len(raw) != 0 {
|
||||
rawAttrs = strings.Split(raw, ",")
|
||||
}
|
||||
|
||||
attrs := make([]objectSDK.Attribute, len(rawAttrs), len(rawAttrs)+2) // name + timestamp attributes
|
||||
|
|
|
@ -38,7 +38,7 @@ func initObjectRangeCmd() {
|
|||
flags.String(commonflags.OIDFlag, "", commonflags.OIDFlagUsage)
|
||||
_ = objectRangeCmd.MarkFlagRequired(commonflags.OIDFlag)
|
||||
|
||||
flags.StringSlice("range", nil, "Range to take data from in the form offset:length")
|
||||
flags.String("range", "", "Range to take data from in the form offset:length")
|
||||
flags.String(fileFlag, "", "File to write object payload to. Default: stdout.")
|
||||
flags.Bool(rawFlag, false, rawFlagDesc)
|
||||
}
|
||||
|
@ -195,10 +195,11 @@ func marshalECInfo(cmd *cobra.Command, info *objectSDK.ECInfo) ([]byte, error) {
|
|||
}
|
||||
|
||||
func getRangeList(cmd *cobra.Command) ([]objectSDK.Range, error) {
|
||||
vs, err := cmd.Flags().GetStringSlice("range")
|
||||
if len(vs) == 0 || err != nil {
|
||||
return nil, err
|
||||
v := cmd.Flag("range").Value.String()
|
||||
if len(v) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
vs := strings.Split(v, ",")
|
||||
rs := make([]objectSDK.Range, len(vs))
|
||||
for i := range vs {
|
||||
before, after, found := strings.Cut(vs[i], rangeSep)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/tree"
|
||||
metrics "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics/grpc"
|
||||
tracing "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing/grpc"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -33,9 +34,11 @@ func _client() (tree.TreeServiceClient, error) {
|
|||
|
||||
opts := []grpc.DialOption{
|
||||
grpc.WithChainUnaryInterceptor(
|
||||
metrics.NewUnaryClientInterceptor(),
|
||||
tracing.NewUnaryClientInteceptor(),
|
||||
),
|
||||
grpc.WithChainStreamInterceptor(
|
||||
metrics.NewStreamClientInterceptor(),
|
||||
tracing.NewStreamClientInterceptor(),
|
||||
),
|
||||
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
|
||||
|
|
|
@ -124,7 +124,10 @@ func (v *BucketsView) loadNodeChildren(
|
|||
path := parentBucket.Path
|
||||
parser := parentBucket.NextParser
|
||||
|
||||
buffer := LoadBuckets(ctx, v.ui.db, path, v.ui.loadBufferSize)
|
||||
buffer, err := LoadBuckets(ctx, v.ui.db, path, v.ui.loadBufferSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for item := range buffer {
|
||||
if item.err != nil {
|
||||
|
@ -132,7 +135,6 @@ func (v *BucketsView) loadNodeChildren(
|
|||
}
|
||||
bucket := item.val
|
||||
|
||||
var err error
|
||||
bucket.Entry, bucket.NextParser, err = parser(bucket.Name, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -178,7 +180,10 @@ func (v *BucketsView) bucketSatisfiesFilter(
|
|||
defer cancel()
|
||||
|
||||
// Check the current bucket's nested buckets if exist
|
||||
bucketsBuffer := LoadBuckets(ctx, v.ui.db, bucket.Path, v.ui.loadBufferSize)
|
||||
bucketsBuffer, err := LoadBuckets(ctx, v.ui.db, bucket.Path, v.ui.loadBufferSize)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for item := range bucketsBuffer {
|
||||
if item.err != nil {
|
||||
|
@ -186,7 +191,6 @@ func (v *BucketsView) bucketSatisfiesFilter(
|
|||
}
|
||||
b := item.val
|
||||
|
||||
var err error
|
||||
b.Entry, b.NextParser, err = bucket.NextParser(b.Name, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -202,7 +206,10 @@ func (v *BucketsView) bucketSatisfiesFilter(
|
|||
}
|
||||
|
||||
// Check the current bucket's nested records if exist
|
||||
recordsBuffer := LoadRecords(ctx, v.ui.db, bucket.Path, v.ui.loadBufferSize)
|
||||
recordsBuffer, err := LoadRecords(ctx, v.ui.db, bucket.Path, v.ui.loadBufferSize)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for item := range recordsBuffer {
|
||||
if item.err != nil {
|
||||
|
@ -210,7 +217,6 @@ func (v *BucketsView) bucketSatisfiesFilter(
|
|||
}
|
||||
r := item.val
|
||||
|
||||
var err error
|
||||
r.Entry, _, err = bucket.NextParser(r.Key, r.Value)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
|
|
@ -35,7 +35,7 @@ func resolvePath(tx *bbolt.Tx, path [][]byte) (*bbolt.Bucket, error) {
|
|||
func load[T any](
|
||||
ctx context.Context, db *bbolt.DB, path [][]byte, bufferSize int,
|
||||
filter func(key, value []byte) bool, transform func(key, value []byte) T,
|
||||
) <-chan Item[T] {
|
||||
) (<-chan Item[T], error) {
|
||||
buffer := make(chan Item[T], bufferSize)
|
||||
|
||||
go func() {
|
||||
|
@ -77,13 +77,13 @@ func load[T any](
|
|||
}
|
||||
}()
|
||||
|
||||
return buffer
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
func LoadBuckets(
|
||||
ctx context.Context, db *bbolt.DB, path [][]byte, bufferSize int,
|
||||
) <-chan Item[*Bucket] {
|
||||
buffer := load(
|
||||
) (<-chan Item[*Bucket], error) {
|
||||
buffer, err := load(
|
||||
ctx, db, path, bufferSize,
|
||||
func(_, value []byte) bool {
|
||||
return value == nil
|
||||
|
@ -98,14 +98,17 @@ func LoadBuckets(
|
|||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't start iterating bucket: %w", err)
|
||||
}
|
||||
|
||||
return buffer
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
func LoadRecords(
|
||||
ctx context.Context, db *bbolt.DB, path [][]byte, bufferSize int,
|
||||
) <-chan Item[*Record] {
|
||||
buffer := load(
|
||||
) (<-chan Item[*Record], error) {
|
||||
buffer, err := load(
|
||||
ctx, db, path, bufferSize,
|
||||
func(_, value []byte) bool {
|
||||
return value != nil
|
||||
|
@ -121,8 +124,11 @@ func LoadRecords(
|
|||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't start iterating bucket: %w", err)
|
||||
}
|
||||
|
||||
return buffer
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
// HasBuckets checks if a bucket has nested buckets. It relies on assumption
|
||||
|
@ -131,21 +137,24 @@ func HasBuckets(ctx context.Context, db *bbolt.DB, path [][]byte) (bool, error)
|
|||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
buffer := load(
|
||||
buffer, err := load(
|
||||
ctx, db, path, 1,
|
||||
nil,
|
||||
func(_, value []byte) []byte { return value },
|
||||
)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
x, ok := <-buffer
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
if x.err != nil {
|
||||
return false, x.err
|
||||
return false, err
|
||||
}
|
||||
if x.val != nil {
|
||||
return false, nil
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -62,7 +62,10 @@ func (v *RecordsView) Mount(ctx context.Context) error {
|
|||
|
||||
ctx, v.onUnmount = context.WithCancel(ctx)
|
||||
|
||||
tempBuffer := LoadRecords(ctx, v.ui.db, v.bucket.Path, v.ui.loadBufferSize)
|
||||
tempBuffer, err := LoadRecords(ctx, v.ui.db, v.bucket.Path, v.ui.loadBufferSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.buffer = make(chan *Record, v.ui.loadBufferSize)
|
||||
go func() {
|
||||
|
@ -70,12 +73,11 @@ func (v *RecordsView) Mount(ctx context.Context) error {
|
|||
|
||||
for item := range tempBuffer {
|
||||
if item.err != nil {
|
||||
v.ui.stopOnError(item.err)
|
||||
v.ui.stopOnError(err)
|
||||
break
|
||||
}
|
||||
record := item.val
|
||||
|
||||
var err error
|
||||
record.Entry, _, err = v.bucket.NextParser(record.Key, record.Value)
|
||||
if err != nil {
|
||||
v.ui.stopOnError(err)
|
||||
|
|
|
@ -19,7 +19,6 @@ func initAPEManagerService(c *cfg) {
|
|||
c.cfgObject.cfgAccessPolicyEngine.policyContractHash)
|
||||
|
||||
execsvc := apemanager.New(c.cfgObject.cnrSource, contractStorage,
|
||||
c.cfgMorph.client,
|
||||
apemanager.WithLogger(c.log))
|
||||
sigsvc := apemanager.NewSignService(&c.key.PrivateKey, execsvc)
|
||||
auditSvc := apemanager.NewAuditService(sigsvc, c.log, c.audit)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -17,7 +16,7 @@ import (
|
|||
"github.com/hashicorp/golang-lru/v2/expirable"
|
||||
)
|
||||
|
||||
type netValueReader[K any, V any] func(ctx context.Context, cid K) (V, error)
|
||||
type netValueReader[K any, V any] func(K) (V, error)
|
||||
|
||||
type valueWithError[V any] struct {
|
||||
v V
|
||||
|
@ -50,7 +49,7 @@ func newNetworkTTLCache[K comparable, V any](sz int, ttl time.Duration, netRdr n
|
|||
// updates the value from the network on cache miss or by TTL.
|
||||
//
|
||||
// returned value should not be modified.
|
||||
func (c *ttlNetCache[K, V]) get(ctx context.Context, key K) (V, error) {
|
||||
func (c *ttlNetCache[K, V]) get(key K) (V, error) {
|
||||
hit := false
|
||||
startedAt := time.Now()
|
||||
defer func() {
|
||||
|
@ -72,7 +71,7 @@ func (c *ttlNetCache[K, V]) get(ctx context.Context, key K) (V, error) {
|
|||
return val.v, val.e
|
||||
}
|
||||
|
||||
v, err := c.netRdr(ctx, key)
|
||||
v, err := c.netRdr(key)
|
||||
|
||||
c.cache.Add(key, &valueWithError[V]{
|
||||
v: v,
|
||||
|
@ -136,7 +135,7 @@ func newNetworkLRUCache(sz int, netRdr netValueReader[uint64, *netmapSDK.NetMap]
|
|||
// updates the value from the network on cache miss.
|
||||
//
|
||||
// returned value should not be modified.
|
||||
func (c *lruNetCache) get(ctx context.Context, key uint64) (*netmapSDK.NetMap, error) {
|
||||
func (c *lruNetCache) get(key uint64) (*netmapSDK.NetMap, error) {
|
||||
hit := false
|
||||
startedAt := time.Now()
|
||||
defer func() {
|
||||
|
@ -149,7 +148,7 @@ func (c *lruNetCache) get(ctx context.Context, key uint64) (*netmapSDK.NetMap, e
|
|||
return val, nil
|
||||
}
|
||||
|
||||
val, err := c.netRdr(ctx, key)
|
||||
val, err := c.netRdr(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -167,11 +166,11 @@ type ttlContainerStorage struct {
|
|||
}
|
||||
|
||||
func newCachedContainerStorage(v container.Source, ttl time.Duration, containerCacheSize uint32) ttlContainerStorage {
|
||||
lruCnrCache := newNetworkTTLCache(int(containerCacheSize), ttl, func(ctx context.Context, id cid.ID) (*container.Container, error) {
|
||||
return v.Get(ctx, id)
|
||||
lruCnrCache := newNetworkTTLCache(int(containerCacheSize), ttl, func(id cid.ID) (*container.Container, error) {
|
||||
return v.Get(id)
|
||||
}, metrics.NewCacheMetrics("container"))
|
||||
lruDelInfoCache := newNetworkTTLCache(int(containerCacheSize), ttl, func(ctx context.Context, id cid.ID) (*container.DelInfo, error) {
|
||||
return v.DeletionInfo(ctx, id)
|
||||
lruDelInfoCache := newNetworkTTLCache(int(containerCacheSize), ttl, func(id cid.ID) (*container.DelInfo, error) {
|
||||
return v.DeletionInfo(id)
|
||||
}, metrics.NewCacheMetrics("container_deletion_info"))
|
||||
|
||||
return ttlContainerStorage{
|
||||
|
@ -189,12 +188,12 @@ func (s ttlContainerStorage) handleRemoval(cnr cid.ID) {
|
|||
|
||||
// Get returns container value from the cache. If value is missing in the cache
|
||||
// or expired, then it returns value from side chain and updates the cache.
|
||||
func (s ttlContainerStorage) Get(ctx context.Context, cnr cid.ID) (*container.Container, error) {
|
||||
return s.containerCache.get(ctx, cnr)
|
||||
func (s ttlContainerStorage) Get(cnr cid.ID) (*container.Container, error) {
|
||||
return s.containerCache.get(cnr)
|
||||
}
|
||||
|
||||
func (s ttlContainerStorage) DeletionInfo(ctx context.Context, cnr cid.ID) (*container.DelInfo, error) {
|
||||
return s.delInfoCache.get(ctx, cnr)
|
||||
func (s ttlContainerStorage) DeletionInfo(cnr cid.ID) (*container.DelInfo, error) {
|
||||
return s.delInfoCache.get(cnr)
|
||||
}
|
||||
|
||||
type lruNetmapSource struct {
|
||||
|
@ -206,8 +205,8 @@ type lruNetmapSource struct {
|
|||
func newCachedNetmapStorage(s netmap.State, v netmap.Source) netmap.Source {
|
||||
const netmapCacheSize = 10
|
||||
|
||||
lruNetmapCache := newNetworkLRUCache(netmapCacheSize, func(ctx context.Context, key uint64) (*netmapSDK.NetMap, error) {
|
||||
return v.GetNetMapByEpoch(ctx, key)
|
||||
lruNetmapCache := newNetworkLRUCache(netmapCacheSize, func(key uint64) (*netmapSDK.NetMap, error) {
|
||||
return v.GetNetMapByEpoch(key)
|
||||
}, metrics.NewCacheMetrics("netmap"))
|
||||
|
||||
return &lruNetmapSource{
|
||||
|
@ -216,16 +215,16 @@ func newCachedNetmapStorage(s netmap.State, v netmap.Source) netmap.Source {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *lruNetmapSource) GetNetMap(ctx context.Context, diff uint64) (*netmapSDK.NetMap, error) {
|
||||
return s.getNetMapByEpoch(ctx, s.netState.CurrentEpoch()-diff)
|
||||
func (s *lruNetmapSource) GetNetMap(diff uint64) (*netmapSDK.NetMap, error) {
|
||||
return s.getNetMapByEpoch(s.netState.CurrentEpoch() - diff)
|
||||
}
|
||||
|
||||
func (s *lruNetmapSource) GetNetMapByEpoch(ctx context.Context, epoch uint64) (*netmapSDK.NetMap, error) {
|
||||
return s.getNetMapByEpoch(ctx, epoch)
|
||||
func (s *lruNetmapSource) GetNetMapByEpoch(epoch uint64) (*netmapSDK.NetMap, error) {
|
||||
return s.getNetMapByEpoch(epoch)
|
||||
}
|
||||
|
||||
func (s *lruNetmapSource) getNetMapByEpoch(ctx context.Context, epoch uint64) (*netmapSDK.NetMap, error) {
|
||||
val, err := s.cache.get(ctx, epoch)
|
||||
func (s *lruNetmapSource) getNetMapByEpoch(epoch uint64) (*netmapSDK.NetMap, error) {
|
||||
val, err := s.cache.get(epoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -233,7 +232,7 @@ func (s *lruNetmapSource) getNetMapByEpoch(ctx context.Context, epoch uint64) (*
|
|||
return val, nil
|
||||
}
|
||||
|
||||
func (s *lruNetmapSource) Epoch(_ context.Context) (uint64, error) {
|
||||
func (s *lruNetmapSource) Epoch() (uint64, error) {
|
||||
return s.netState.CurrentEpoch(), nil
|
||||
}
|
||||
|
||||
|
@ -241,10 +240,7 @@ type cachedIRFetcher struct {
|
|||
*ttlNetCache[struct{}, [][]byte]
|
||||
}
|
||||
|
||||
func newCachedIRFetcher(f interface {
|
||||
InnerRingKeys(ctx context.Context) ([][]byte, error)
|
||||
},
|
||||
) cachedIRFetcher {
|
||||
func newCachedIRFetcher(f interface{ InnerRingKeys() ([][]byte, error) }) cachedIRFetcher {
|
||||
const (
|
||||
irFetcherCacheSize = 1 // we intend to store only one value
|
||||
|
||||
|
@ -258,8 +254,8 @@ func newCachedIRFetcher(f interface {
|
|||
)
|
||||
|
||||
irFetcherCache := newNetworkTTLCache(irFetcherCacheSize, irFetcherCacheTTL,
|
||||
func(ctx context.Context, _ struct{}) ([][]byte, error) {
|
||||
return f.InnerRingKeys(ctx)
|
||||
func(_ struct{}) ([][]byte, error) {
|
||||
return f.InnerRingKeys()
|
||||
}, metrics.NewCacheMetrics("ir_keys"),
|
||||
)
|
||||
|
||||
|
@ -269,8 +265,8 @@ func newCachedIRFetcher(f interface {
|
|||
// InnerRingKeys returns cached list of Inner Ring keys. If keys are missing in
|
||||
// the cache or expired, then it returns keys from side chain and updates
|
||||
// the cache.
|
||||
func (f cachedIRFetcher) InnerRingKeys(ctx context.Context) ([][]byte, error) {
|
||||
val, err := f.get(ctx, struct{}{})
|
||||
func (f cachedIRFetcher) InnerRingKeys() ([][]byte, error) {
|
||||
val, err := f.get(struct{}{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -293,7 +289,7 @@ func newCachedMaxObjectSizeSource(src objectwriter.MaxSizeSource) objectwriter.M
|
|||
}
|
||||
}
|
||||
|
||||
func (c *ttlMaxObjectSizeCache) MaxObjectSize(ctx context.Context) uint64 {
|
||||
func (c *ttlMaxObjectSizeCache) MaxObjectSize() uint64 {
|
||||
const ttl = time.Second * 30
|
||||
|
||||
hit := false
|
||||
|
@ -315,7 +311,7 @@ func (c *ttlMaxObjectSizeCache) MaxObjectSize(ctx context.Context) uint64 {
|
|||
c.mtx.Lock()
|
||||
size = c.lastSize
|
||||
if !c.lastUpdated.After(prevUpdated) {
|
||||
size = c.src.MaxObjectSize(ctx)
|
||||
size = c.src.MaxObjectSize()
|
||||
c.lastSize = size
|
||||
c.lastUpdated = time.Now()
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -18,7 +17,7 @@ func TestTTLNetCache(t *testing.T) {
|
|||
t.Run("Test Add and Get", func(t *testing.T) {
|
||||
ti := time.Now()
|
||||
cache.set(key, ti, nil)
|
||||
val, err := cache.get(context.Background(), key)
|
||||
val, err := cache.get(key)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ti, val)
|
||||
})
|
||||
|
@ -27,7 +26,7 @@ func TestTTLNetCache(t *testing.T) {
|
|||
ti := time.Now()
|
||||
cache.set(key, ti, nil)
|
||||
time.Sleep(2 * ttlDuration)
|
||||
val, err := cache.get(context.Background(), key)
|
||||
val, err := cache.get(key)
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, val, ti)
|
||||
})
|
||||
|
@ -36,20 +35,20 @@ func TestTTLNetCache(t *testing.T) {
|
|||
ti := time.Now()
|
||||
cache.set(key, ti, nil)
|
||||
cache.remove(key)
|
||||
val, err := cache.get(context.Background(), key)
|
||||
val, err := cache.get(key)
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, val, ti)
|
||||
})
|
||||
|
||||
t.Run("Test Cache Error", func(t *testing.T) {
|
||||
cache.set("error", time.Now(), errors.New("mock error"))
|
||||
_, err := cache.get(context.Background(), "error")
|
||||
_, err := cache.get("error")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, "mock error", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func testNetValueReader(_ context.Context, key string) (time.Time, error) {
|
||||
func testNetValueReader(key string) (time.Time, error) {
|
||||
if key == "error" {
|
||||
return time.Now(), errors.New("mock error")
|
||||
}
|
||||
|
|
|
@ -493,7 +493,6 @@ type cfg struct {
|
|||
cfgNetmap cfgNetmap
|
||||
cfgControlService cfgControlService
|
||||
cfgObject cfgObject
|
||||
cfgQoSService cfgQoSService
|
||||
}
|
||||
|
||||
// ReadCurrentNetMap reads network map which has been cached at the
|
||||
|
@ -699,7 +698,8 @@ func initCfg(appCfg *config.Config) *cfg {
|
|||
|
||||
netState.metrics = c.metricsCollector
|
||||
|
||||
logPrm := c.loggerPrm()
|
||||
logPrm, err := c.loggerPrm()
|
||||
fatalOnErr(err)
|
||||
logPrm.SamplingHook = c.metricsCollector.LogMetrics().GetSamplingHook()
|
||||
log, err := logger.NewLogger(logPrm)
|
||||
fatalOnErr(err)
|
||||
|
@ -853,8 +853,8 @@ func initFrostfsID(appCfg *config.Config) cfgFrostfsID {
|
|||
}
|
||||
|
||||
func initCfgGRPC() cfgGRPC {
|
||||
maxChunkSize := uint64(maxMsgSize) * 3 / 4 // 25% to meta, 75% to payload
|
||||
maxAddrAmount := maxChunkSize / addressSize // each address is about 72 bytes
|
||||
maxChunkSize := uint64(maxMsgSize) * 3 / 4 // 25% to meta, 75% to payload
|
||||
maxAddrAmount := uint64(maxChunkSize) / addressSize // each address is about 72 bytes
|
||||
|
||||
return cfgGRPC{
|
||||
maxChunkSize: maxChunkSize,
|
||||
|
@ -1059,7 +1059,7 @@ func (c *cfg) getShardOpts(ctx context.Context, shCfg shardCfg) shardOptsWithID
|
|||
return sh
|
||||
}
|
||||
|
||||
func (c *cfg) loggerPrm() *logger.Prm {
|
||||
func (c *cfg) loggerPrm() (*logger.Prm, error) {
|
||||
// check if it has been inited before
|
||||
if c.dynamicConfiguration.logger == nil {
|
||||
c.dynamicConfiguration.logger = new(logger.Prm)
|
||||
|
@ -1078,7 +1078,7 @@ func (c *cfg) loggerPrm() *logger.Prm {
|
|||
}
|
||||
c.dynamicConfiguration.logger.PrependTimestamp = c.LoggerCfg.timestamp
|
||||
|
||||
return c.dynamicConfiguration.logger
|
||||
return c.dynamicConfiguration.logger, nil
|
||||
}
|
||||
|
||||
func (c *cfg) LocalAddress() network.AddressGroup {
|
||||
|
@ -1147,7 +1147,7 @@ func initAccessPolicyEngine(ctx context.Context, c *cfg) {
|
|||
c.cfgObject.cfgAccessPolicyEngine.policyContractHash)
|
||||
|
||||
cacheSize := morphconfig.APEChainCacheSize(c.appCfg)
|
||||
if cacheSize > 0 && c.cfgMorph.cacheTTL > 0 {
|
||||
if cacheSize > 0 {
|
||||
morphRuleStorage = newMorphCache(morphRuleStorage, int(cacheSize), c.cfgMorph.cacheTTL)
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1206,7 @@ func (c *cfg) setContractNodeInfo(ni *netmap.NodeInfo) {
|
|||
}
|
||||
|
||||
func (c *cfg) updateContractNodeInfo(ctx context.Context, epoch uint64) {
|
||||
ni, err := c.netmapLocalNodeState(ctx, epoch)
|
||||
ni, err := c.netmapLocalNodeState(epoch)
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeCouldNotUpdateNodeStateOnNewEpoch,
|
||||
zap.Uint64("epoch", epoch),
|
||||
|
@ -1220,9 +1220,9 @@ func (c *cfg) updateContractNodeInfo(ctx context.Context, epoch uint64) {
|
|||
// bootstrapWithState calls "addPeer" method of the Sidechain Netmap contract
|
||||
// with the binary-encoded information from the current node's configuration.
|
||||
// The state is set using the provided setter which MUST NOT be nil.
|
||||
func (c *cfg) bootstrapWithState(ctx context.Context, state netmap.NodeState) error {
|
||||
func (c *cfg) bootstrapWithState(ctx context.Context, stateSetter func(*netmap.NodeInfo)) error {
|
||||
ni := c.cfgNodeInfo.localInfo
|
||||
ni.SetStatus(state)
|
||||
stateSetter(&ni)
|
||||
|
||||
prm := nmClient.AddPeerPrm{}
|
||||
prm.SetNodeInfo(ni)
|
||||
|
@ -1232,7 +1232,9 @@ func (c *cfg) bootstrapWithState(ctx context.Context, state netmap.NodeState) er
|
|||
|
||||
// bootstrapOnline calls cfg.bootstrapWithState with "online" state.
|
||||
func bootstrapOnline(ctx context.Context, c *cfg) error {
|
||||
return c.bootstrapWithState(ctx, netmap.Online)
|
||||
return c.bootstrapWithState(ctx, func(ni *netmap.NodeInfo) {
|
||||
ni.SetStatus(netmap.Online)
|
||||
})
|
||||
}
|
||||
|
||||
// bootstrap calls bootstrapWithState with:
|
||||
|
@ -1243,7 +1245,9 @@ func (c *cfg) bootstrap(ctx context.Context) error {
|
|||
st := c.cfgNetmap.state.controlNetmapStatus()
|
||||
if st == control.NetmapStatus_MAINTENANCE {
|
||||
c.log.Info(ctx, logs.FrostFSNodeBootstrappingWithTheMaintenanceState)
|
||||
return c.bootstrapWithState(ctx, netmap.Maintenance)
|
||||
return c.bootstrapWithState(ctx, func(ni *netmap.NodeInfo) {
|
||||
ni.SetStatus(netmap.Maintenance)
|
||||
})
|
||||
}
|
||||
|
||||
c.log.Info(ctx, logs.FrostFSNodeBootstrappingWithOnlineState,
|
||||
|
@ -1334,7 +1338,11 @@ func (c *cfg) reloadConfig(ctx context.Context) {
|
|||
|
||||
// Logger
|
||||
|
||||
logPrm := c.loggerPrm()
|
||||
logPrm, err := c.loggerPrm()
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeLoggerConfigurationPreparation, zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
components := c.getComponents(ctx, logPrm)
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
configViper "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/config"
|
||||
|
@ -53,5 +52,6 @@ func (x *Config) Value(name string) any {
|
|||
// It supports only one level of nesting and is intended to be used
|
||||
// to provide default values.
|
||||
func (x *Config) SetDefault(from *Config) {
|
||||
x.defaultPath = slices.Clone(from.path)
|
||||
x.defaultPath = make([]string, len(from.path))
|
||||
copy(x.defaultPath, from.path)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ const (
|
|||
subsection = "container"
|
||||
listStreamSubsection = "list_stream"
|
||||
|
||||
// ContainerBatchSizeDefault represents the maximum amount of containers to send via stream at once.
|
||||
// ContainerBatchSizeDefault represents he maximum amount of containers to send via stream at once.
|
||||
ContainerBatchSizeDefault = 1000
|
||||
)
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ func (l PersistentPolicyRulesConfig) Path() string {
|
|||
//
|
||||
// Returns PermDefault if the value is not a positive number.
|
||||
func (l PersistentPolicyRulesConfig) Perm() fs.FileMode {
|
||||
p := config.UintSafe(l.cfg, "perm")
|
||||
p := config.UintSafe((*config.Config)(l.cfg), "perm")
|
||||
if p == 0 {
|
||||
p = PermDefault
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ func (l PersistentPolicyRulesConfig) Perm() fs.FileMode {
|
|||
//
|
||||
// Returns false if the value is not a boolean.
|
||||
func (l PersistentPolicyRulesConfig) NoSync() bool {
|
||||
return config.BoolSafe(l.cfg, "no_sync")
|
||||
return config.BoolSafe((*config.Config)(l.cfg), "no_sync")
|
||||
}
|
||||
|
||||
// CompatibilityMode returns true if need to run node in compatibility with previous versions mode.
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
package qos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
)
|
||||
|
||||
const (
|
||||
subsection = "qos"
|
||||
criticalSubSection = "critical"
|
||||
internalSubSection = "internal"
|
||||
)
|
||||
|
||||
// CriticalAuthorizedKeys parses and returns an array of "critical.authorized_keys" config
|
||||
// parameter from "qos" section.
|
||||
//
|
||||
// Returns an empty list if not set.
|
||||
func CriticalAuthorizedKeys(c *config.Config) keys.PublicKeys {
|
||||
return authorizedKeys(c, criticalSubSection)
|
||||
}
|
||||
|
||||
// InternalAuthorizedKeys parses and returns an array of "internal.authorized_keys" config
|
||||
// parameter from "qos" section.
|
||||
//
|
||||
// Returns an empty list if not set.
|
||||
func InternalAuthorizedKeys(c *config.Config) keys.PublicKeys {
|
||||
return authorizedKeys(c, internalSubSection)
|
||||
}
|
||||
|
||||
func authorizedKeys(c *config.Config, sub string) keys.PublicKeys {
|
||||
strKeys := config.StringSliceSafe(c.Sub(subsection).Sub(sub), "authorized_keys")
|
||||
pubs := make(keys.PublicKeys, 0, len(strKeys))
|
||||
|
||||
for i := range strKeys {
|
||||
pub, err := keys.NewPublicKeyFromString(strKeys[i])
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("invalid authorized key %s for qos.%s: %w", strKeys[i], sub, err))
|
||||
}
|
||||
|
||||
pubs = append(pubs, pub)
|
||||
}
|
||||
|
||||
return pubs
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package qos
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
||||
configtest "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/test"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestQoSSection(t *testing.T) {
|
||||
t.Run("defaults", func(t *testing.T) {
|
||||
empty := configtest.EmptyConfig()
|
||||
|
||||
require.Empty(t, CriticalAuthorizedKeys(empty))
|
||||
require.Empty(t, InternalAuthorizedKeys(empty))
|
||||
})
|
||||
|
||||
const path = "../../../../config/example/node"
|
||||
|
||||
criticalPubs := make(keys.PublicKeys, 2)
|
||||
criticalPubs[0], _ = keys.NewPublicKeyFromString("035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11")
|
||||
criticalPubs[1], _ = keys.NewPublicKeyFromString("028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6")
|
||||
|
||||
internalPubs := make(keys.PublicKeys, 2)
|
||||
internalPubs[0], _ = keys.NewPublicKeyFromString("02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2")
|
||||
internalPubs[1], _ = keys.NewPublicKeyFromString("031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a")
|
||||
|
||||
fileConfigTest := func(c *config.Config) {
|
||||
require.Equal(t, criticalPubs, CriticalAuthorizedKeys(c))
|
||||
require.Equal(t, internalPubs, InternalAuthorizedKeys(c))
|
||||
}
|
||||
|
||||
configtest.ForEachFileType(path, fileConfigTest)
|
||||
|
||||
t.Run("ENV", func(t *testing.T) {
|
||||
configtest.ForEnvFileType(t, path, fileConfigTest)
|
||||
})
|
||||
}
|
|
@ -43,7 +43,7 @@ func initContainerService(_ context.Context, c *cfg) {
|
|||
fatalOnErr(err)
|
||||
|
||||
cacheSize := morphconfig.FrostfsIDCacheSize(c.appCfg)
|
||||
if cacheSize > 0 && c.cfgMorph.cacheTTL > 0 {
|
||||
if cacheSize > 0 {
|
||||
frostfsIDSubjectProvider = newMorphFrostfsIDCache(frostfsIDSubjectProvider, int(cacheSize), c.cfgMorph.cacheTTL, metrics.NewCacheMetrics("frostfs_id"))
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ func configureEACLAndContainerSources(c *cfg, client *cntClient.Client, cnrSrc c
|
|||
// TODO: use owner directly from the event after neofs-contract#256 will become resolved
|
||||
// but don't forget about the profit of reading the new container and caching it:
|
||||
// creation success are most commonly tracked by polling GET op.
|
||||
cnr, err := cnrSrc.Get(ctx, ev.ID)
|
||||
cnr, err := cnrSrc.Get(ev.ID)
|
||||
if err == nil {
|
||||
containerCache.containerCache.set(ev.ID, cnr, nil)
|
||||
} else {
|
||||
|
@ -221,25 +221,20 @@ type morphContainerReader struct {
|
|||
src containerCore.Source
|
||||
|
||||
lister interface {
|
||||
ContainersOf(context.Context, *user.ID) ([]cid.ID, error)
|
||||
IterateContainersOf(context.Context, *user.ID, func(cid.ID) error) error
|
||||
ContainersOf(*user.ID) ([]cid.ID, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *morphContainerReader) Get(ctx context.Context, id cid.ID) (*containerCore.Container, error) {
|
||||
return x.src.Get(ctx, id)
|
||||
func (x *morphContainerReader) Get(id cid.ID) (*containerCore.Container, error) {
|
||||
return x.src.Get(id)
|
||||
}
|
||||
|
||||
func (x *morphContainerReader) DeletionInfo(ctx context.Context, id cid.ID) (*containerCore.DelInfo, error) {
|
||||
return x.src.DeletionInfo(ctx, id)
|
||||
func (x *morphContainerReader) DeletionInfo(id cid.ID) (*containerCore.DelInfo, error) {
|
||||
return x.src.DeletionInfo(id)
|
||||
}
|
||||
|
||||
func (x *morphContainerReader) ContainersOf(ctx context.Context, id *user.ID) ([]cid.ID, error) {
|
||||
return x.lister.ContainersOf(ctx, id)
|
||||
}
|
||||
|
||||
func (x *morphContainerReader) IterateContainersOf(ctx context.Context, id *user.ID, processCID func(cid.ID) error) error {
|
||||
return x.lister.IterateContainersOf(ctx, id, processCID)
|
||||
func (x *morphContainerReader) ContainersOf(id *user.ID) ([]cid.ID, error) {
|
||||
return x.lister.ContainersOf(id)
|
||||
}
|
||||
|
||||
type morphContainerWriter struct {
|
||||
|
|
|
@ -7,12 +7,9 @@ import (
|
|||
|
||||
controlconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/qos"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
controlSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/sdnotify"
|
||||
metrics "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics/grpc"
|
||||
tracing "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing/grpc"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
@ -53,14 +50,7 @@ func initControlService(ctx context.Context, c *cfg) {
|
|||
return
|
||||
}
|
||||
|
||||
c.cfgControlService.server = grpc.NewServer(
|
||||
grpc.ChainUnaryInterceptor(
|
||||
qos.NewSetCriticalIOTagUnaryServerInterceptor(),
|
||||
metrics.NewUnaryServerInterceptor(),
|
||||
tracing.NewUnaryServerInterceptor(),
|
||||
),
|
||||
// control service has no stream methods, so no stream interceptors added
|
||||
)
|
||||
c.cfgControlService.server = grpc.NewServer()
|
||||
|
||||
c.onShutdown(func() {
|
||||
stopGRPC(ctx, "FrostFS Control API", c.cfgControlService.server, c.log)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -43,7 +42,7 @@ func newMorphFrostfsIDCache(subjProvider frostfsidcore.SubjectProvider, size int
|
|||
}
|
||||
}
|
||||
|
||||
func (m *morphFrostfsIDCache) GetSubject(ctx context.Context, addr util.Uint160) (*client.Subject, error) {
|
||||
func (m *morphFrostfsIDCache) GetSubject(addr util.Uint160) (*client.Subject, error) {
|
||||
hit := false
|
||||
startedAt := time.Now()
|
||||
defer func() {
|
||||
|
@ -56,7 +55,7 @@ func (m *morphFrostfsIDCache) GetSubject(ctx context.Context, addr util.Uint160)
|
|||
return result.subject, result.err
|
||||
}
|
||||
|
||||
subj, err := m.subjProvider.GetSubject(ctx, addr)
|
||||
subj, err := m.subjProvider.GetSubject(addr)
|
||||
if err != nil {
|
||||
if m.isCacheableError(err) {
|
||||
m.subjCache.Add(addr, subjectWithError{
|
||||
|
@ -70,7 +69,7 @@ func (m *morphFrostfsIDCache) GetSubject(ctx context.Context, addr util.Uint160)
|
|||
return subj, nil
|
||||
}
|
||||
|
||||
func (m *morphFrostfsIDCache) GetSubjectExtended(ctx context.Context, addr util.Uint160) (*client.SubjectExtended, error) {
|
||||
func (m *morphFrostfsIDCache) GetSubjectExtended(addr util.Uint160) (*client.SubjectExtended, error) {
|
||||
hit := false
|
||||
startedAt := time.Now()
|
||||
defer func() {
|
||||
|
@ -83,7 +82,7 @@ func (m *morphFrostfsIDCache) GetSubjectExtended(ctx context.Context, addr util.
|
|||
return result.subject, result.err
|
||||
}
|
||||
|
||||
subjExt, err := m.subjProvider.GetSubjectExtended(ctx, addr)
|
||||
subjExt, err := m.subjProvider.GetSubjectExtended(addr)
|
||||
if err != nil {
|
||||
if m.isCacheableError(err) {
|
||||
m.subjExtCache.Add(addr, subjectExtWithError{
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||
metrics "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics/grpc"
|
||||
tracing "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing/grpc"
|
||||
qos "git.frostfs.info/TrueCloudLab/frostfs-qos/tagging"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
@ -131,12 +130,10 @@ func getGrpcServerOpts(ctx context.Context, c *cfg, sc *grpcconfig.Config) ([]gr
|
|||
serverOpts := []grpc.ServerOption{
|
||||
grpc.MaxRecvMsgSize(maxRecvMsgSize),
|
||||
grpc.ChainUnaryInterceptor(
|
||||
qos.NewUnaryServerInterceptor(),
|
||||
metrics.NewUnaryServerInterceptor(),
|
||||
tracing.NewUnaryServerInterceptor(),
|
||||
),
|
||||
grpc.ChainStreamInterceptor(
|
||||
qos.NewStreamServerInterceptor(),
|
||||
metrics.NewStreamServerInterceptor(),
|
||||
tracing.NewStreamServerInterceptor(),
|
||||
),
|
||||
|
|
|
@ -101,7 +101,6 @@ func initApp(ctx context.Context, c *cfg) {
|
|||
|
||||
initAndLog(ctx, c, "gRPC", func(c *cfg) { initGRPC(ctx, c) })
|
||||
initAndLog(ctx, c, "netmap", func(c *cfg) { initNetmapService(ctx, c) })
|
||||
initAndLog(ctx, c, "qos", func(c *cfg) { initQoSService(c) })
|
||||
|
||||
initAccessPolicyEngine(ctx, c)
|
||||
initAndLog(ctx, c, "access policy engine", func(c *cfg) {
|
||||
|
|
|
@ -151,7 +151,7 @@ func makeNotaryDeposit(ctx context.Context, c *cfg) (util.Uint256, uint32, error
|
|||
}
|
||||
|
||||
func waitNotaryDeposit(ctx context.Context, c *cfg, tx util.Uint256, vub uint32) error {
|
||||
if err := c.cfgMorph.client.WaitTxHalt(ctx, vub, tx); err != nil {
|
||||
if err := c.cfgMorph.client.WaitTxHalt(ctx, client.InvokeRes{Hash: tx, VUB: vub}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ func (s *networkState) setNodeInfo(ni *netmapSDK.NodeInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
s.setControlNetmapStatus(ctrlNetSt)
|
||||
s.setControlNetmapStatus(control.NetmapStatus(ctrlNetSt))
|
||||
}
|
||||
|
||||
// sets the current node state to the given value. Subsequent cfg.bootstrap
|
||||
|
@ -239,7 +239,7 @@ func setNetmapNotificationParser(c *cfg, sTyp string, p event.NotificationParser
|
|||
// initNetmapState inits current Network map state.
|
||||
// Must be called after Morph components initialization.
|
||||
func initNetmapState(ctx context.Context, c *cfg) {
|
||||
epoch, err := c.cfgNetmap.wrapper.Epoch(ctx)
|
||||
epoch, err := c.cfgNetmap.wrapper.Epoch()
|
||||
fatalOnErrDetails("could not initialize current epoch number", err)
|
||||
|
||||
var ni *netmapSDK.NodeInfo
|
||||
|
@ -278,7 +278,7 @@ func nodeState(ni *netmapSDK.NodeInfo) string {
|
|||
}
|
||||
|
||||
func (c *cfg) netmapInitLocalNodeState(ctx context.Context, epoch uint64) (*netmapSDK.NodeInfo, error) {
|
||||
nmNodes, err := c.cfgNetmap.wrapper.GetCandidates(ctx)
|
||||
nmNodes, err := c.cfgNetmap.wrapper.GetCandidates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ func (c *cfg) netmapInitLocalNodeState(ctx context.Context, epoch uint64) (*netm
|
|||
}
|
||||
}
|
||||
|
||||
node, err := c.netmapLocalNodeState(ctx, epoch)
|
||||
node, err := c.netmapLocalNodeState(epoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -312,9 +312,9 @@ func (c *cfg) netmapInitLocalNodeState(ctx context.Context, epoch uint64) (*netm
|
|||
return candidate, nil
|
||||
}
|
||||
|
||||
func (c *cfg) netmapLocalNodeState(ctx context.Context, epoch uint64) (*netmapSDK.NodeInfo, error) {
|
||||
func (c *cfg) netmapLocalNodeState(epoch uint64) (*netmapSDK.NodeInfo, error) {
|
||||
// calculate current network state
|
||||
nm, err := c.cfgNetmap.wrapper.GetNetMapByEpoch(ctx, epoch)
|
||||
nm, err := c.cfgNetmap.wrapper.GetNetMapByEpoch(epoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -376,8 +376,8 @@ func (c *cfg) SetNetmapStatus(ctx context.Context, st control.NetmapStatus) erro
|
|||
return c.updateNetMapState(ctx, func(*nmClient.UpdatePeerPrm) {})
|
||||
}
|
||||
|
||||
func (c *cfg) GetNetmapStatus(ctx context.Context) (control.NetmapStatus, uint64, error) {
|
||||
epoch, err := c.netMapSource.Epoch(ctx)
|
||||
func (c *cfg) GetNetmapStatus() (control.NetmapStatus, uint64, error) {
|
||||
epoch, err := c.netMapSource.Epoch()
|
||||
if err != nil {
|
||||
return control.NetmapStatus_STATUS_UNDEFINED, 0, fmt.Errorf("failed to get current epoch: %w", err)
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ func (c *cfg) ForceMaintenance(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (c *cfg) setMaintenanceStatus(ctx context.Context, force bool) error {
|
||||
netSettings, err := c.cfgNetmap.wrapper.ReadNetworkConfiguration(ctx)
|
||||
netSettings, err := c.cfgNetmap.wrapper.ReadNetworkConfiguration()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("read network settings to check maintenance allowance: %w", err)
|
||||
} else if !netSettings.MaintenanceModeAllowed {
|
||||
|
@ -423,7 +423,7 @@ func (c *cfg) updateNetMapState(ctx context.Context, stateSetter func(*nmClient.
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.cfgNetmap.wrapper.Morph().WaitTxHalt(ctx, res.VUB, res.Hash)
|
||||
return c.cfgNetmap.wrapper.Morph().WaitTxHalt(ctx, res)
|
||||
}
|
||||
|
||||
type netInfo struct {
|
||||
|
@ -438,7 +438,7 @@ type netInfo struct {
|
|||
msPerBlockRdr func() (int64, error)
|
||||
}
|
||||
|
||||
func (n *netInfo) Dump(ctx context.Context, ver version.Version) (*netmapSDK.NetworkInfo, error) {
|
||||
func (n *netInfo) Dump(ver version.Version) (*netmapSDK.NetworkInfo, error) {
|
||||
magic, err := n.magic.MagicNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -448,7 +448,7 @@ func (n *netInfo) Dump(ctx context.Context, ver version.Version) (*netmapSDK.Net
|
|||
ni.SetCurrentEpoch(n.netState.CurrentEpoch())
|
||||
ni.SetMagicNumber(magic)
|
||||
|
||||
netInfoMorph, err := n.morphClientNetMap.ReadNetworkConfiguration(ctx)
|
||||
netInfoMorph, err := n.morphClientNetMap.ReadNetworkConfiguration()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read network configuration using netmap contract client: %w", err)
|
||||
}
|
||||
|
|
|
@ -54,10 +54,10 @@ type objectSvc struct {
|
|||
patch *patchsvc.Service
|
||||
}
|
||||
|
||||
func (c *cfg) MaxObjectSize(ctx context.Context) uint64 {
|
||||
sz, err := c.cfgNetmap.wrapper.MaxObjectSize(ctx)
|
||||
func (c *cfg) MaxObjectSize() uint64 {
|
||||
sz, err := c.cfgNetmap.wrapper.MaxObjectSize()
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeCouldNotGetMaxObjectSizeValue,
|
||||
c.log.Error(context.Background(), logs.FrostFSNodeCouldNotGetMaxObjectSizeValue,
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ type innerRingFetcherWithNotary struct {
|
|||
sidechain *morphClient.Client
|
||||
}
|
||||
|
||||
func (fn *innerRingFetcherWithNotary) InnerRingKeys(ctx context.Context) ([][]byte, error) {
|
||||
keys, err := fn.sidechain.NeoFSAlphabetList(ctx)
|
||||
func (fn *innerRingFetcherWithNotary) InnerRingKeys() ([][]byte, error) {
|
||||
keys, err := fn.sidechain.NeoFSAlphabetList()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get inner ring keys from alphabet role: %w", err)
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ func initObjectService(c *cfg) {
|
|||
sPatch := createPatchSvc(sGet, sPut)
|
||||
|
||||
// build service pipeline
|
||||
// grpc | audit | qos | <metrics> | signature | response | acl | ape | split
|
||||
// grpc | audit | <metrics> | signature | response | acl | ape | split
|
||||
|
||||
splitSvc := createSplitService(c, sPutV2, sGetV2, sSearchV2, sDeleteV2, sPatch)
|
||||
|
||||
|
@ -191,8 +191,7 @@ func initObjectService(c *cfg) {
|
|||
|
||||
c.shared.metricsSvc = objectService.NewMetricCollector(
|
||||
signSvc, c.metricsCollector.ObjectService(), metricsconfig.Enabled(c.appCfg))
|
||||
qosService := objectService.NewQoSObjectService(c.shared.metricsSvc, &c.cfgQoSService)
|
||||
auditSvc := objectService.NewAuditService(qosService, c.log, c.audit)
|
||||
auditSvc := objectService.NewAuditService(c.shared.metricsSvc, c.log, c.audit)
|
||||
server := objectTransportGRPC.New(auditSvc)
|
||||
|
||||
c.cfgGRPC.performAndSave(func(_ string, _ net.Listener, s *grpc.Server) {
|
||||
|
@ -216,7 +215,8 @@ func addPolicer(c *cfg, keyStorage *util.KeyStorage, clientConstructor *cache.Cl
|
|||
prm.MarkAsGarbage(addr)
|
||||
prm.WithForceRemoval()
|
||||
|
||||
return ls.Inhume(ctx, prm)
|
||||
_, err := ls.Inhume(ctx, prm)
|
||||
return err
|
||||
}
|
||||
|
||||
remoteReader := objectService.NewRemoteReader(keyStorage, clientConstructor)
|
||||
|
@ -266,7 +266,8 @@ func addPolicer(c *cfg, keyStorage *util.KeyStorage, clientConstructor *cache.Cl
|
|||
var inhumePrm engine.InhumePrm
|
||||
inhumePrm.MarkAsGarbage(addr)
|
||||
|
||||
if err := ls.Inhume(ctx, inhumePrm); err != nil {
|
||||
_, err := ls.Inhume(ctx, inhumePrm)
|
||||
if err != nil {
|
||||
c.log.Warn(ctx, logs.FrostFSNodeCouldNotInhumeMarkRedundantCopyAsGarbage,
|
||||
zap.Error(err),
|
||||
)
|
||||
|
@ -475,7 +476,8 @@ func (e engineWithoutNotifications) Delete(ctx context.Context, tombstone oid.Ad
|
|||
|
||||
prm.WithTarget(tombstone, addrs...)
|
||||
|
||||
return e.engine.Inhume(ctx, prm)
|
||||
_, err := e.engine.Inhume(ctx, prm)
|
||||
return err
|
||||
}
|
||||
|
||||
func (e engineWithoutNotifications) Lock(ctx context.Context, locker oid.Address, toLock []oid.ID) error {
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
qosconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/qos"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/qos"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||
qosTagging "git.frostfs.info/TrueCloudLab/frostfs-qos/tagging"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type cfgQoSService struct {
|
||||
netmapSource netmap.Source
|
||||
logger *logger.Logger
|
||||
allowedCriticalPubs [][]byte
|
||||
allowedInternalPubs [][]byte
|
||||
}
|
||||
|
||||
func initQoSService(c *cfg) {
|
||||
criticalPubs := qosconfig.CriticalAuthorizedKeys(c.appCfg)
|
||||
internalPubs := qosconfig.InternalAuthorizedKeys(c.appCfg)
|
||||
rawCriticalPubs := make([][]byte, 0, len(criticalPubs))
|
||||
rawInternalPubs := make([][]byte, 0, len(internalPubs))
|
||||
for i := range criticalPubs {
|
||||
rawCriticalPubs = append(rawCriticalPubs, criticalPubs[i].Bytes())
|
||||
}
|
||||
for i := range internalPubs {
|
||||
rawInternalPubs = append(rawInternalPubs, internalPubs[i].Bytes())
|
||||
}
|
||||
|
||||
c.cfgQoSService = cfgQoSService{
|
||||
netmapSource: c.netMapSource,
|
||||
logger: c.log,
|
||||
allowedCriticalPubs: rawCriticalPubs,
|
||||
allowedInternalPubs: rawInternalPubs,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *cfgQoSService) AdjustIncomingTag(ctx context.Context, requestSignPublicKey []byte) context.Context {
|
||||
rawTag, defined := qosTagging.IOTagFromContext(ctx)
|
||||
if !defined {
|
||||
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
||||
}
|
||||
ioTag, err := qos.FromRawString(rawTag)
|
||||
if err != nil {
|
||||
s.logger.Warn(ctx, logs.FailedToParseIncomingIOTag, zap.Error(err))
|
||||
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
||||
}
|
||||
|
||||
switch ioTag {
|
||||
case qos.IOTagClient:
|
||||
return ctx
|
||||
case qos.IOTagCritical:
|
||||
for _, pk := range s.allowedCriticalPubs {
|
||||
if bytes.Equal(pk, requestSignPublicKey) {
|
||||
return ctx
|
||||
}
|
||||
}
|
||||
nm, err := s.netmapSource.GetNetMap(ctx, 0)
|
||||
if err != nil {
|
||||
s.logger.Debug(ctx, logs.FailedToGetNetmapToAdjustIOTag, zap.Error(err))
|
||||
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
||||
}
|
||||
for _, node := range nm.Nodes() {
|
||||
if bytes.Equal(node.PublicKey(), requestSignPublicKey) {
|
||||
return ctx
|
||||
}
|
||||
}
|
||||
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
||||
case qos.IOTagInternal:
|
||||
for _, pk := range s.allowedInternalPubs {
|
||||
if bytes.Equal(pk, requestSignPublicKey) {
|
||||
return ctx
|
||||
}
|
||||
}
|
||||
nm, err := s.netmapSource.GetNetMap(ctx, 0)
|
||||
if err != nil {
|
||||
s.logger.Debug(ctx, logs.FailedToGetNetmapToAdjustIOTag, zap.Error(err))
|
||||
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
||||
}
|
||||
for _, node := range nm.Nodes() {
|
||||
if bytes.Equal(node.PublicKey(), requestSignPublicKey) {
|
||||
return ctx
|
||||
}
|
||||
}
|
||||
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
||||
default:
|
||||
s.logger.Warn(ctx, logs.NotSupportedIncomingIOTagReplacedWithClient, zap.Stringer("io_tag", ioTag))
|
||||
return qosTagging.ContextWithIOTag(ctx, qos.IOTagClient.String())
|
||||
}
|
||||
}
|
|
@ -29,16 +29,16 @@ type cnrSource struct {
|
|||
cli *containerClient.Client
|
||||
}
|
||||
|
||||
func (c cnrSource) Get(ctx context.Context, id cid.ID) (*container.Container, error) {
|
||||
return c.src.Get(ctx, id)
|
||||
func (c cnrSource) Get(id cid.ID) (*container.Container, error) {
|
||||
return c.src.Get(id)
|
||||
}
|
||||
|
||||
func (c cnrSource) DeletionInfo(ctx context.Context, cid cid.ID) (*container.DelInfo, error) {
|
||||
return c.src.DeletionInfo(ctx, cid)
|
||||
func (c cnrSource) DeletionInfo(cid cid.ID) (*container.DelInfo, error) {
|
||||
return c.src.DeletionInfo(cid)
|
||||
}
|
||||
|
||||
func (c cnrSource) List(ctx context.Context) ([]cid.ID, error) {
|
||||
return c.cli.ContainersOf(ctx, nil)
|
||||
func (c cnrSource) List() ([]cid.ID, error) {
|
||||
return c.cli.ContainersOf(nil)
|
||||
}
|
||||
|
||||
func initTreeService(c *cfg) {
|
||||
|
@ -72,7 +72,7 @@ func initTreeService(c *cfg) {
|
|||
)
|
||||
|
||||
c.cfgGRPC.performAndSave(func(_ string, _ net.Listener, s *grpc.Server) {
|
||||
tree.RegisterTreeServiceServer(s, tree.NewIOTagAdjustServer(c.treeService, &c.cfgQoSService))
|
||||
tree.RegisterTreeServiceServer(s, c.treeService)
|
||||
})
|
||||
|
||||
c.workers = append(c.workers, newWorkerFromFunc(func(ctx context.Context) {
|
||||
|
|
|
@ -225,6 +225,3 @@ FROSTFS_MULTINET_SUBNETS_1_SOURCE_IPS="10.78.70.185 10.78.71.185"
|
|||
FROSTFS_MULTINET_BALANCER=roundrobin
|
||||
FROSTFS_MULTINET_RESTRICT=false
|
||||
FROSTFS_MULTINET_FALLBACK_DELAY=350ms
|
||||
|
||||
FROSTFS_QOS_CRITICAL_AUTHORIZED_KEYS="035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11 028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6"
|
||||
FROSTFS_QOS_INTERNAL_AUTHORIZED_KEYS="02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2 031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a"
|
||||
|
|
|
@ -305,19 +305,5 @@
|
|||
"balancer": "roundrobin",
|
||||
"restrict": false,
|
||||
"fallback_delay": "350ms"
|
||||
},
|
||||
"qos": {
|
||||
"critical": {
|
||||
"authorized_keys": [
|
||||
"035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11",
|
||||
"028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6"
|
||||
]
|
||||
},
|
||||
"internal": {
|
||||
"authorized_keys": [
|
||||
"02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2",
|
||||
"031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,8 +79,7 @@ contracts: # side chain NEOFS contract script hashes; optional, override values
|
|||
|
||||
morph:
|
||||
dial_timeout: 30s # timeout for side chain NEO RPC client connection
|
||||
cache_ttl: 15s # Sidechain cache TTL value (min interval between similar calls).
|
||||
# Negative value disables caching. A zero value sets the default value.
|
||||
cache_ttl: 15s # Sidechain cache TTL value (min interval between similar calls). Negative value disables caching.
|
||||
# Default value: block time. It is recommended to have this value less or equal to block time.
|
||||
# Cached entities: containers, container lists, eACL tables.
|
||||
container_cache_size: 100 # container_cache_size is is the maximum number of containers in the cache.
|
||||
|
@ -270,13 +269,3 @@ multinet:
|
|||
balancer: roundrobin
|
||||
restrict: false
|
||||
fallback_delay: 350ms
|
||||
|
||||
qos:
|
||||
critical:
|
||||
authorized_keys: # list of hex-encoded public keys that have rights to use `critical` IO tag
|
||||
- 035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11
|
||||
- 028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6
|
||||
internal:
|
||||
authorized_keys: # list of hex-encoded public keys that have rights to use `internal` IO tag
|
||||
- 02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2
|
||||
- 031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"FROSTFS_MORPH_DIAL_TIMEOUT":"30s",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_ADDRESS":"ws://127.0.0.1:30333/ws",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_PRIORITY":"0",
|
||||
"FROSTFS_MORPH_INACTIVITY_TIMEOUT":"60s",
|
||||
"FROSTFS_NODE_WALLET_PATH":"${workspaceFolder}/dev/storage/wallet01.json",
|
||||
"FROSTFS_NODE_WALLET_PASSWORD":"",
|
||||
"FROSTFS_NODE_ADDRESSES":"127.0.0.1:8080",
|
||||
|
@ -97,6 +98,7 @@
|
|||
"FROSTFS_MORPH_DIAL_TIMEOUT":"30s",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_ADDRESS":"ws://127.0.0.1:30333/ws",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_PRIORITY":"0",
|
||||
"FROSTFS_MORPH_INACTIVITY_TIMEOUT":"60s",
|
||||
"FROSTFS_NODE_WALLET_PATH":"${workspaceFolder}/dev/storage/wallet02.json",
|
||||
"FROSTFS_NODE_WALLET_PASSWORD":"",
|
||||
"FROSTFS_NODE_ADDRESSES":"127.0.0.1:8082",
|
||||
|
@ -152,6 +154,7 @@
|
|||
"FROSTFS_MORPH_DIAL_TIMEOUT":"30s",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_ADDRESS":"ws://127.0.0.1:30333/ws",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_PRIORITY":"0",
|
||||
"FROSTFS_MORPH_INACTIVITY_TIMEOUT":"60s",
|
||||
"FROSTFS_NODE_WALLET_PATH":"${workspaceFolder}/dev/storage/wallet03.json",
|
||||
"FROSTFS_NODE_WALLET_PASSWORD":"",
|
||||
"FROSTFS_NODE_ADDRESSES":"127.0.0.1:8084",
|
||||
|
@ -207,6 +210,7 @@
|
|||
"FROSTFS_MORPH_DIAL_TIMEOUT":"30s",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_ADDRESS":"ws://127.0.0.1:30333/ws",
|
||||
"FROSTFS_MORPH_RPC_ENDPOINT_0_PRIORITY":"0",
|
||||
"FROSTFS_MORPH_INACTIVITY_TIMEOUT":"60s",
|
||||
"FROSTFS_NODE_WALLET_PATH":"${workspaceFolder}/dev/storage/wallet04.json",
|
||||
"FROSTFS_NODE_WALLET_PASSWORD":"",
|
||||
"FROSTFS_NODE_ADDRESSES":"127.0.0.1:8086",
|
||||
|
|
|
@ -95,15 +95,19 @@ $ git push origin ${FROSTFS_TAG_PREFIX}${FROSTFS_REVISION}
|
|||
|
||||
## Post-release
|
||||
|
||||
### Prepare and push images to a Docker registry (automated)
|
||||
### Prepare and push images to a Docker Hub (if not automated)
|
||||
|
||||
Create Docker images for all applications and push them into container registry
|
||||
(executed automatically in Forgejo Actions upon pushing a release tag):
|
||||
Create Docker images for all applications and push them into Docker Hub
|
||||
(requires [organization](https://hub.docker.com/u/truecloudlab) privileges)
|
||||
|
||||
```shell
|
||||
$ git checkout ${FROSTFS_TAG_PREFIX}${FROSTFS_REVISION}
|
||||
$ make images
|
||||
$ make push-images
|
||||
$ docker push truecloudlab/frostfs-storage:${FROSTFS_REVISION}
|
||||
$ docker push truecloudlab/frostfs-storage-testnet:${FROSTFS_REVISION}
|
||||
$ docker push truecloudlab/frostfs-ir:${FROSTFS_REVISION}
|
||||
$ docker push truecloudlab/frostfs-cli:${FROSTFS_REVISION}
|
||||
$ docker push truecloudlab/frostfs-adm:${FROSTFS_REVISION}
|
||||
```
|
||||
|
||||
### Make a proper release (if not automated)
|
||||
|
|
|
@ -26,8 +26,7 @@ There are some custom types used for brevity:
|
|||
| `storage` | [Storage engine configuration](#storage-section) |
|
||||
| `runtime` | [Runtime configuration](#runtime-section) |
|
||||
| `audit` | [Audit configuration](#audit-section) |
|
||||
| `multinet` | [Multinet configuration](#multinet-section) |
|
||||
| `qos` | [QoS configuration](#qos-section) |
|
||||
| `multinet` | [Multinet configuration](#multinet-section) |
|
||||
|
||||
# `control` section
|
||||
```yaml
|
||||
|
@ -472,20 +471,3 @@ multinet:
|
|||
| `balancer` | `string` | "" | Balancer to select network interfaces, allowed values are "" (no balancing, use first suitable interface) or "roundrobin". |
|
||||
| `restrict` | `bool` | false | If `true` then any requests that do not match `subnets` will fail. |
|
||||
| `fallback_delay` | `duration` | 350ms | Delay before fallback to secondary IP addresses in case of hostname resolve. |
|
||||
|
||||
# `qos` section
|
||||
```yaml
|
||||
qos:
|
||||
critical:
|
||||
authorized_keys:
|
||||
- 035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11
|
||||
- 028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6
|
||||
internal:
|
||||
authorized_keys:
|
||||
- 035839e45d472a3b7769a2a1bd7d54c4ccd4943c3b40f547870e83a8fcbfb3ce11
|
||||
- 028f42cfcb74499d7b15b35d9bff260a1c8d27de4f446a627406a382d8961486d6
|
||||
```
|
||||
| Parameter | Type | Default value | Description |
|
||||
| -------------------------- | -------------- | ------------- | --------------------------------------------------------------------------- |
|
||||
| `critical.authorized_keys` | `[]public key` | empty | List of public keys for which requests with the tag `critical` are allowed. |
|
||||
| `internal.authorized_keys` | `[]public key` | empty | List of public keys for which requests with the tag `internal` are allowed. |
|
||||
|
|
35
go.mod
35
go.mod
|
@ -7,9 +7,8 @@ require (
|
|||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.21.1-0.20241205083807-762d7f9f9f08
|
||||
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0
|
||||
git.frostfs.info/TrueCloudLab/frostfs-locode-db v0.4.1-0.20240710074952-65761deb5c0d
|
||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20250212111929-d34e1329c824
|
||||
git.frostfs.info/TrueCloudLab/frostfs-qos v0.0.0-20250128150313-cfbca7fa1dfe
|
||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250202151421-8389887a3421
|
||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88
|
||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20241210104938-c4463df8d467
|
||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1
|
||||
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972
|
||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240814080254-96225afacb88
|
||||
|
@ -28,7 +27,7 @@ require (
|
|||
github.com/klauspost/compress v1.17.4
|
||||
github.com/mailru/easyjson v0.7.7
|
||||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/multiformats/go-multiaddr v0.14.0
|
||||
github.com/multiformats/go-multiaddr v0.12.1
|
||||
github.com/nspcc-dev/neo-go v0.106.3
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/panjf2000/ants/v2 v2.9.0
|
||||
|
@ -41,15 +40,15 @@ require (
|
|||
github.com/ssgreg/journald v1.0.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.etcd.io/bbolt v1.3.10
|
||||
go.opentelemetry.io/otel v1.31.0
|
||||
go.opentelemetry.io/otel/trace v1.31.0
|
||||
go.opentelemetry.io/otel v1.28.0
|
||||
go.opentelemetry.io/otel/trace v1.28.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
golang.org/x/sync v0.10.0
|
||||
golang.org/x/sys v0.28.0
|
||||
golang.org/x/term v0.27.0
|
||||
google.golang.org/grpc v1.69.2
|
||||
google.golang.org/protobuf v1.36.1
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/sys v0.22.0
|
||||
golang.org/x/term v0.21.0
|
||||
google.golang.org/grpc v1.66.2
|
||||
google.golang.org/protobuf v1.34.2
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
|
@ -120,15 +119,15 @@ require (
|
|||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
lukechampine.com/blake3 v1.2.1 // indirect
|
||||
rsc.io/tmplfunc v0.0.3 // indirect
|
||||
|
|
74
go.sum
74
go.sum
|
@ -6,12 +6,10 @@ git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSV
|
|||
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0/go.mod h1:RUIKZATQLJ+TaYQa60X2fTDwfuhMfm8Ar60bQ5fr+vU=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-locode-db v0.4.1-0.20240710074952-65761deb5c0d h1:uJ/wvuMdepbkaV8XMS5uN9B0FQWMep0CttSuDZiDhq0=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-locode-db v0.4.1-0.20240710074952-65761deb5c0d/go.mod h1:7ZZq8iguY7qFsXajdHGmZd2AW4QbucyrJwhbsRfOfek=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20250212111929-d34e1329c824 h1:Mxw1c/8t96vFIUOffl28lFaHKi413oCBfLMGJmF9cFA=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20250212111929-d34e1329c824/go.mod h1:kbwB4v2o6RyOfCo9kEFeUDZIX3LKhmS0yXPrtvzkQ1g=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-qos v0.0.0-20250128150313-cfbca7fa1dfe h1:81gDNdWNLP24oMQukRiCE9R1wGSh0l0dRq3F1W+Oesc=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-qos v0.0.0-20250128150313-cfbca7fa1dfe/go.mod h1:PCijYq4oa8vKtIEcUX6jRiszI6XAW+nBwU+T1kB4d1U=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250202151421-8389887a3421 h1:pP19IawSdsLCKFv7HMNfWAeH6E3uSnntKZkwka+/2+4=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20250202151421-8389887a3421/go.mod h1:aQpPWfG8oyfJ2X+FenPTJpSRWZjwcP5/RAtkW+/VEX8=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88 h1:9bvBDLApbbO5sXBKdODpE9tzy3HV99nXxkDWNn22rdI=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88/go.mod h1:kbwB4v2o6RyOfCo9kEFeUDZIX3LKhmS0yXPrtvzkQ1g=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20241210104938-c4463df8d467 h1:MH9uHZFZNyUCL+YChiDcVeXPjhTDcFDeoGr8Mc8NY9M=
|
||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20241210104938-c4463df8d467/go.mod h1:eoK7+KZQ9GJxbzIs6vTnoUJqFDppavInLRHaN4MYgZg=
|
||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc=
|
||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
|
||||
git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972 h1:/960fWeyn2AFHwQUwDsWB3sbP6lTEnFnMzLMM6tx6N8=
|
||||
|
@ -108,8 +106,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
|
@ -192,8 +188,8 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG
|
|||
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||
github.com/multiformats/go-multiaddr v0.14.0 h1:bfrHrJhrRuh/NXH5mCnemjpbGjzRw/b+tJFOD41g2tU=
|
||||
github.com/multiformats/go-multiaddr v0.14.0/go.mod h1:6EkVAxtznq2yC3QT5CM1UTAwG0GTP3EWAIcjHuzQ+r4=
|
||||
github.com/multiformats/go-multiaddr v0.12.1 h1:vm+BA/WZA8QZDp1pF1FWhi5CT3g1tbi5GJmqpb6wnlk=
|
||||
github.com/multiformats/go-multiaddr v0.12.1/go.mod h1:7mPkiBMmLeFipt+nNSq9pHZUeJSt8lHBgH6yhj0YQzE=
|
||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
||||
|
@ -294,22 +290,20 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
|
||||
go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
|
||||
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
||||
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y=
|
||||
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
||||
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
||||
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
|
||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
|
@ -324,8 +318,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
|
@ -345,16 +339,16 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug
|
|||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -381,16 +375,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
@ -398,8 +392,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
|
@ -412,12 +406,12 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
|
||||
google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -426,8 +420,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
|||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
|
|
@ -146,6 +146,7 @@ const (
|
|||
ClientCantGetBlockchainHeight = "can't get blockchain height"
|
||||
ClientCantGetBlockchainHeight243 = "can't get blockchain height"
|
||||
EventCouldNotSubmitHandlerToWorkerPool = "could not Submit handler to worker pool"
|
||||
EventCouldNotStartListenToEvents = "could not start listen to events"
|
||||
EventStopEventListenerByError = "stop event listener by error"
|
||||
EventStopEventListenerByContext = "stop event listener by context"
|
||||
EventStopEventListenerByNotificationChannel = "stop event listener by notification channel"
|
||||
|
@ -383,6 +384,7 @@ const (
|
|||
FrostFSNodeShutdownSkip = "node is already shutting down, skipped shutdown"
|
||||
FrostFSNodeShutdownWhenNotReady = "node is going to shut down when subsystems are still initializing"
|
||||
FrostFSNodeConfigurationReading = "configuration reading"
|
||||
FrostFSNodeLoggerConfigurationPreparation = "logger configuration preparation"
|
||||
FrostFSNodeTracingConfigationUpdated = "tracing configation updated"
|
||||
FrostFSNodeStorageEngineConfigurationUpdate = "storage engine configuration update"
|
||||
FrostFSNodePoolConfigurationUpdate = "adjust pool configuration"
|
||||
|
@ -510,7 +512,4 @@ const (
|
|||
BlobovniczatreeFailedToRemoveRebuildTempFile = "failed to remove rebuild temp file"
|
||||
WritecacheCantGetObject = "can't get an object from fstree"
|
||||
FailedToUpdateMultinetConfiguration = "failed to update multinet configuration"
|
||||
FailedToParseIncomingIOTag = "failed to parse incoming IO tag"
|
||||
NotSupportedIncomingIOTagReplacedWithClient = "incoming IO tag is not supported, replaced with `client`"
|
||||
FailedToGetNetmapToAdjustIOTag = "failed to get netmap to adjust IO tag, replaced with `client`"
|
||||
)
|
||||
|
|
|
@ -12,9 +12,8 @@ type ApplicationInfo struct {
|
|||
func NewApplicationInfo(version string) *ApplicationInfo {
|
||||
appInfo := &ApplicationInfo{
|
||||
versionValue: metrics.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: namespace,
|
||||
Name: "app_info",
|
||||
Help: "General information about the application.",
|
||||
Name: "app_info",
|
||||
Help: "General information about the application.",
|
||||
}, []string{"version"}),
|
||||
}
|
||||
appInfo.versionValue.With(prometheus.Labels{"version": version})
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
package qos
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-qos/tagging"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func NewSetCriticalIOTagUnaryServerInterceptor() grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
|
||||
ctx = tagging.ContextWithIOTag(ctx, IOTagCritical.String())
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
func NewAdjustOutgoingIOTagUnaryClientInterceptor() grpc.UnaryClientInterceptor {
|
||||
return func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||
rawTag, ok := tagging.IOTagFromContext(ctx)
|
||||
if !ok {
|
||||
return invoker(ctx, method, req, reply, cc, opts...)
|
||||
}
|
||||
tag, err := FromRawString(rawTag)
|
||||
if err != nil {
|
||||
tag = IOTagClient
|
||||
}
|
||||
if tag == IOTagBackground || tag == IOTagPolicer || tag == IOTagWritecache {
|
||||
tag = IOTagInternal
|
||||
}
|
||||
ctx = tagging.ContextWithIOTag(ctx, tag.String())
|
||||
return invoker(ctx, method, req, reply, cc, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func NewAdjustOutgoingIOTagStreamClientInterceptor() grpc.StreamClientInterceptor {
|
||||
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||
rawTag, ok := tagging.IOTagFromContext(ctx)
|
||||
if !ok {
|
||||
return streamer(ctx, desc, cc, method, opts...)
|
||||
}
|
||||
tag, err := FromRawString(rawTag)
|
||||
if err != nil {
|
||||
tag = IOTagClient
|
||||
}
|
||||
if tag == IOTagBackground || tag == IOTagPolicer || tag == IOTagWritecache {
|
||||
tag = IOTagInternal
|
||||
}
|
||||
ctx = tagging.ContextWithIOTag(ctx, tag.String())
|
||||
return streamer(ctx, desc, cc, method, opts...)
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package qos
|
||||
|
||||
import "fmt"
|
||||
|
||||
type IOTag string
|
||||
|
||||
const (
|
||||
IOTagClient IOTag = "client"
|
||||
IOTagInternal IOTag = "internal"
|
||||
IOTagBackground IOTag = "background"
|
||||
IOTagWritecache IOTag = "writecache"
|
||||
IOTagPolicer IOTag = "policer"
|
||||
IOTagCritical IOTag = "critical"
|
||||
|
||||
ioTagUnknown IOTag = ""
|
||||
)
|
||||
|
||||
func FromRawString(s string) (IOTag, error) {
|
||||
switch s {
|
||||
case string(IOTagCritical):
|
||||
return IOTagCritical, nil
|
||||
case string(IOTagClient):
|
||||
return IOTagClient, nil
|
||||
case string(IOTagInternal):
|
||||
return IOTagInternal, nil
|
||||
case string(IOTagBackground):
|
||||
return IOTagBackground, nil
|
||||
case string(IOTagWritecache):
|
||||
return IOTagWritecache, nil
|
||||
case string(IOTagPolicer):
|
||||
return IOTagPolicer, nil
|
||||
default:
|
||||
return ioTagUnknown, fmt.Errorf("unknown tag %s", s)
|
||||
}
|
||||
}
|
||||
|
||||
func (t IOTag) String() string {
|
||||
return string(t)
|
||||
}
|
|
@ -31,7 +31,9 @@ type RPCActorProvider interface {
|
|||
type ProxyVerificationContractStorage struct {
|
||||
rpcActorProvider RPCActorProvider
|
||||
|
||||
cosigners []actor.SignerAccount
|
||||
acc *wallet.Account
|
||||
|
||||
proxyScriptHash util.Uint160
|
||||
|
||||
policyScriptHash util.Uint160
|
||||
}
|
||||
|
@ -39,27 +41,12 @@ type ProxyVerificationContractStorage struct {
|
|||
var _ ProxyAdaptedContractStorage = (*ProxyVerificationContractStorage)(nil)
|
||||
|
||||
func NewProxyVerificationContractStorage(rpcActorProvider RPCActorProvider, key *keys.PrivateKey, proxyScriptHash, policyScriptHash util.Uint160) *ProxyVerificationContractStorage {
|
||||
acc := wallet.NewAccountFromPrivateKey(key)
|
||||
return &ProxyVerificationContractStorage{
|
||||
rpcActorProvider: rpcActorProvider,
|
||||
|
||||
cosigners: []actor.SignerAccount{
|
||||
{
|
||||
Signer: transaction.Signer{
|
||||
Account: proxyScriptHash,
|
||||
Scopes: transaction.CustomContracts,
|
||||
AllowedContracts: []util.Uint160{policyScriptHash},
|
||||
},
|
||||
Account: notary.FakeContractAccount(proxyScriptHash),
|
||||
},
|
||||
{
|
||||
Signer: transaction.Signer{
|
||||
Account: acc.Contract.ScriptHash(),
|
||||
Scopes: transaction.CalledByEntry,
|
||||
},
|
||||
Account: acc,
|
||||
},
|
||||
},
|
||||
acc: wallet.NewAccountFromPrivateKey(key),
|
||||
|
||||
proxyScriptHash: proxyScriptHash,
|
||||
|
||||
policyScriptHash: policyScriptHash,
|
||||
}
|
||||
|
@ -77,7 +64,7 @@ func (n *contractStorageActorAdapter) GetRPCInvoker() invoker.RPCInvoke {
|
|||
|
||||
func (contractStorage *ProxyVerificationContractStorage) newContractStorageActor() (policy_morph.ContractStorageActor, error) {
|
||||
rpcActor := contractStorage.rpcActorProvider.GetRPCActor()
|
||||
act, err := actor.New(rpcActor, contractStorage.cosigners)
|
||||
act, err := actor.New(rpcActor, cosigners(contractStorage.acc, contractStorage.proxyScriptHash, contractStorage.policyScriptHash))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -111,16 +98,31 @@ func (contractStorage *ProxyVerificationContractStorage) RemoveMorphRuleChain(na
|
|||
|
||||
// ListMorphRuleChains lists morph rule chains from Policy contract using both Proxy contract and storage account as consigners.
|
||||
func (contractStorage *ProxyVerificationContractStorage) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) {
|
||||
rpcActor := contractStorage.rpcActorProvider.GetRPCActor()
|
||||
inv := &invokerAdapter{Invoker: invoker.New(rpcActor, nil), rpcInvoker: rpcActor}
|
||||
return policy_morph.NewContractStorageReader(inv, contractStorage.policyScriptHash).ListMorphRuleChains(name, target)
|
||||
// contractStorageActor is reconstructed per each method invocation because RPCActor's (that is, basically, WSClient) connection may get invalidated, but
|
||||
// ProxyVerificationContractStorage does not manage reconnections.
|
||||
contractStorageActor, err := contractStorage.newContractStorageActor()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return policy_morph.NewContractStorage(contractStorageActor, contractStorage.policyScriptHash).ListMorphRuleChains(name, target)
|
||||
}
|
||||
|
||||
type invokerAdapter struct {
|
||||
*invoker.Invoker
|
||||
rpcInvoker invoker.RPCInvoke
|
||||
}
|
||||
|
||||
func (n *invokerAdapter) GetRPCInvoker() invoker.RPCInvoke {
|
||||
return n.rpcInvoker
|
||||
func cosigners(acc *wallet.Account, proxyScriptHash, policyScriptHash util.Uint160) []actor.SignerAccount {
|
||||
return []actor.SignerAccount{
|
||||
{
|
||||
Signer: transaction.Signer{
|
||||
Account: proxyScriptHash,
|
||||
Scopes: transaction.CustomContracts,
|
||||
AllowedContracts: []util.Uint160{policyScriptHash},
|
||||
},
|
||||
Account: notary.FakeContractAccount(proxyScriptHash),
|
||||
},
|
||||
{
|
||||
Signer: transaction.Signer{
|
||||
Account: acc.Contract.ScriptHash(),
|
||||
Scopes: transaction.CalledByEntry,
|
||||
},
|
||||
Account: acc,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -13,9 +12,9 @@ import (
|
|||
)
|
||||
|
||||
// FormFrostfsIDRequestProperties forms frostfsid specific request properties like user-claim tags and group ID.
|
||||
func FormFrostfsIDRequestProperties(ctx context.Context, frostFSIDClient frostfsidcore.SubjectProvider, pk *keys.PublicKey) (map[string]string, error) {
|
||||
func FormFrostfsIDRequestProperties(frostFSIDClient frostfsidcore.SubjectProvider, pk *keys.PublicKey) (map[string]string, error) {
|
||||
reqProps := make(map[string]string)
|
||||
subj, err := frostFSIDClient.GetSubjectExtended(ctx, pk.GetScriptHash())
|
||||
subj, err := frostFSIDClient.GetSubjectExtended(pk.GetScriptHash())
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), frostfsidcore.SubjectNotFoundErrorMessage) {
|
||||
return nil, fmt.Errorf("get subject error: %w", err)
|
||||
|
@ -37,8 +36,8 @@ func FormFrostfsIDRequestProperties(ctx context.Context, frostFSIDClient frostfs
|
|||
}
|
||||
|
||||
// Groups return the actor's group ids from frostfsid contract.
|
||||
func Groups(ctx context.Context, frostFSIDClient frostfsidcore.SubjectProvider, pk *keys.PublicKey) ([]string, error) {
|
||||
subj, err := frostFSIDClient.GetSubjectExtended(ctx, pk.GetScriptHash())
|
||||
func Groups(frostFSIDClient frostfsidcore.SubjectProvider, pk *keys.PublicKey) ([]string, error) {
|
||||
subj, err := frostFSIDClient.GetSubjectExtended(pk.GetScriptHash())
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), frostfsidcore.SubjectNotFoundErrorMessage) {
|
||||
return nil, fmt.Errorf("get subject error: %w", err)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
utilSync "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/sync"
|
||||
|
@ -20,7 +19,7 @@ type infoValue struct {
|
|||
}
|
||||
|
||||
type InfoProvider interface {
|
||||
Info(ctx context.Context, id cid.ID) (Info, error)
|
||||
Info(id cid.ID) (Info, error)
|
||||
}
|
||||
|
||||
type infoProvider struct {
|
||||
|
@ -44,13 +43,13 @@ func NewInfoProvider(sourceFactory func() (Source, error)) InfoProvider {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *infoProvider) Info(ctx context.Context, id cid.ID) (Info, error) {
|
||||
func (r *infoProvider) Info(id cid.ID) (Info, error) {
|
||||
v, found := r.tryGetFromCache(id)
|
||||
if found {
|
||||
return v.info, v.err
|
||||
}
|
||||
|
||||
return r.getFromSource(ctx, id)
|
||||
return r.getFromSource(id)
|
||||
}
|
||||
|
||||
func (r *infoProvider) tryGetFromCache(id cid.ID) (infoValue, bool) {
|
||||
|
@ -61,7 +60,7 @@ func (r *infoProvider) tryGetFromCache(id cid.ID) (infoValue, bool) {
|
|||
return value, found
|
||||
}
|
||||
|
||||
func (r *infoProvider) getFromSource(ctx context.Context, id cid.ID) (Info, error) {
|
||||
func (r *infoProvider) getFromSource(id cid.ID) (Info, error) {
|
||||
r.kl.Lock(id)
|
||||
defer r.kl.Unlock(id)
|
||||
|
||||
|
@ -76,11 +75,11 @@ func (r *infoProvider) getFromSource(ctx context.Context, id cid.ID) (Info, erro
|
|||
return Info{}, r.sourceErr
|
||||
}
|
||||
|
||||
cnr, err := r.source.Get(ctx, id)
|
||||
cnr, err := r.source.Get(id)
|
||||
var civ infoValue
|
||||
if err != nil {
|
||||
if client.IsErrContainerNotFound(err) {
|
||||
removed, err := WasRemoved(ctx, r.source, id)
|
||||
removed, err := WasRemoved(r.source, id)
|
||||
if err != nil {
|
||||
civ.err = err
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
|
@ -43,9 +41,9 @@ type Source interface {
|
|||
//
|
||||
// Implementations must not retain the container pointer and modify
|
||||
// the container through it.
|
||||
Get(ctx context.Context, cid cid.ID) (*Container, error)
|
||||
Get(cid.ID) (*Container, error)
|
||||
|
||||
DeletionInfo(ctx context.Context, cid cid.ID) (*DelInfo, error)
|
||||
DeletionInfo(cid.ID) (*DelInfo, error)
|
||||
}
|
||||
|
||||
// EACL groups information about the FrostFS container's extended ACL stored in
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
|
@ -11,8 +10,8 @@ import (
|
|||
|
||||
// WasRemoved checks whether the container ever existed or
|
||||
// it just has not been created yet at the current epoch.
|
||||
func WasRemoved(ctx context.Context, s Source, cid cid.ID) (bool, error) {
|
||||
_, err := s.DeletionInfo(ctx, cid)
|
||||
func WasRemoved(s Source, cid cid.ID) (bool, error) {
|
||||
_, err := s.DeletionInfo(cid)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package frostfsid
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -13,6 +11,6 @@ const (
|
|||
|
||||
// SubjectProvider interface provides methods to get subject from FrostfsID contract.
|
||||
type SubjectProvider interface {
|
||||
GetSubject(ctx context.Context, addr util.Uint160) (*client.Subject, error)
|
||||
GetSubjectExtended(ctx context.Context, addr util.Uint160) (*client.SubjectExtended, error)
|
||||
GetSubject(util.Uint160) (*client.Subject, error)
|
||||
GetSubjectExtended(util.Uint160) (*client.SubjectExtended, error)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
|
@ -18,7 +16,7 @@ type Source interface {
|
|||
//
|
||||
// Implementations must not retain the network map pointer and modify
|
||||
// the network map through it.
|
||||
GetNetMap(ctx context.Context, diff uint64) (*netmap.NetMap, error)
|
||||
GetNetMap(diff uint64) (*netmap.NetMap, error)
|
||||
|
||||
// GetNetMapByEpoch reads network map by the epoch number from the storage.
|
||||
// It returns the pointer to the requested network map and any error encountered.
|
||||
|
@ -27,21 +25,21 @@ type Source interface {
|
|||
//
|
||||
// Implementations must not retain the network map pointer and modify
|
||||
// the network map through it.
|
||||
GetNetMapByEpoch(ctx context.Context, epoch uint64) (*netmap.NetMap, error)
|
||||
GetNetMapByEpoch(epoch uint64) (*netmap.NetMap, error)
|
||||
|
||||
// Epoch reads the current epoch from the storage.
|
||||
// It returns thw number of the current epoch and any error encountered.
|
||||
//
|
||||
// Must return exactly one non-default value.
|
||||
Epoch(ctx context.Context) (uint64, error)
|
||||
Epoch() (uint64, error)
|
||||
}
|
||||
|
||||
// GetLatestNetworkMap requests and returns the latest network map from the storage.
|
||||
func GetLatestNetworkMap(ctx context.Context, src Source) (*netmap.NetMap, error) {
|
||||
return src.GetNetMap(ctx, 0)
|
||||
func GetLatestNetworkMap(src Source) (*netmap.NetMap, error) {
|
||||
return src.GetNetMap(0)
|
||||
}
|
||||
|
||||
// GetPreviousNetworkMap requests and returns previous from the latest network map from the storage.
|
||||
func GetPreviousNetworkMap(ctx context.Context, src Source) (*netmap.NetMap, error) {
|
||||
return src.GetNetMap(ctx, 1)
|
||||
func GetPreviousNetworkMap(src Source) (*netmap.NetMap, error) {
|
||||
return src.GetNetMap(1)
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ func (v *FormatValidator) isIROrContainerNode(ctx context.Context, obj *objectSD
|
|||
cnrIDBin := make([]byte, sha256.Size)
|
||||
cnrID.Encode(cnrIDBin)
|
||||
|
||||
cnr, err := v.containers.Get(ctx, cnrID)
|
||||
cnr, err := v.containers.Get(cnrID)
|
||||
if err != nil {
|
||||
return acl.RoleOthers, fmt.Errorf("failed to get container (id=%s): %w", cnrID.EncodeToString(), err)
|
||||
}
|
||||
|
|
|
@ -578,7 +578,7 @@ type testIRSource struct {
|
|||
irNodes [][]byte
|
||||
}
|
||||
|
||||
func (s *testIRSource) InnerRingKeys(_ context.Context) ([][]byte, error) {
|
||||
func (s *testIRSource) InnerRingKeys() ([][]byte, error) {
|
||||
return s.irNodes, nil
|
||||
}
|
||||
|
||||
|
@ -586,14 +586,14 @@ type testContainerSource struct {
|
|||
containers map[cid.ID]*container.Container
|
||||
}
|
||||
|
||||
func (s *testContainerSource) Get(ctx context.Context, cnrID cid.ID) (*container.Container, error) {
|
||||
func (s *testContainerSource) Get(cnrID cid.ID) (*container.Container, error) {
|
||||
if cnr, found := s.containers[cnrID]; found {
|
||||
return cnr, nil
|
||||
}
|
||||
return nil, fmt.Errorf("container not found")
|
||||
}
|
||||
|
||||
func (s *testContainerSource) DeletionInfo(context.Context, cid.ID) (*container.DelInfo, error) {
|
||||
func (s *testContainerSource) DeletionInfo(cid.ID) (*container.DelInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -602,20 +602,20 @@ type testNetmapSource struct {
|
|||
currentEpoch uint64
|
||||
}
|
||||
|
||||
func (s *testNetmapSource) GetNetMap(ctx context.Context, diff uint64) (*netmap.NetMap, error) {
|
||||
func (s *testNetmapSource) GetNetMap(diff uint64) (*netmap.NetMap, error) {
|
||||
if diff >= s.currentEpoch {
|
||||
return nil, fmt.Errorf("invalid diff")
|
||||
}
|
||||
return s.GetNetMapByEpoch(ctx, s.currentEpoch-diff)
|
||||
return s.GetNetMapByEpoch(s.currentEpoch - diff)
|
||||
}
|
||||
|
||||
func (s *testNetmapSource) GetNetMapByEpoch(ctx context.Context, epoch uint64) (*netmap.NetMap, error) {
|
||||
func (s *testNetmapSource) GetNetMapByEpoch(epoch uint64) (*netmap.NetMap, error) {
|
||||
if nm, found := s.netmaps[epoch]; found {
|
||||
return nm, nil
|
||||
}
|
||||
return nil, fmt.Errorf("netmap not found")
|
||||
}
|
||||
|
||||
func (s *testNetmapSource) Epoch(ctx context.Context) (uint64, error) {
|
||||
func (s *testNetmapSource) Epoch() (uint64, error) {
|
||||
return s.currentEpoch, nil
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
)
|
||||
|
||||
type InnerRing interface {
|
||||
InnerRingKeys(ctx context.Context) ([][]byte, error)
|
||||
InnerRingKeys() ([][]byte, error)
|
||||
}
|
||||
|
||||
type SenderClassifier struct {
|
||||
|
@ -63,7 +63,7 @@ func (c SenderClassifier) Classify(
|
|||
}
|
||||
|
||||
func (c SenderClassifier) IsInnerRingOrContainerNode(ctx context.Context, ownerKeyInBytes []byte, idCnr cid.ID, cnr container.Container) (*ClassifyResult, error) {
|
||||
isInnerRingNode, err := c.isInnerRingKey(ctx, ownerKeyInBytes)
|
||||
isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes)
|
||||
if err != nil {
|
||||
// do not throw error, try best case matching
|
||||
c.log.Debug(ctx, logs.V2CantCheckIfRequestFromInnerRing,
|
||||
|
@ -78,7 +78,7 @@ func (c SenderClassifier) IsInnerRingOrContainerNode(ctx context.Context, ownerK
|
|||
binCnr := make([]byte, sha256.Size)
|
||||
idCnr.Encode(binCnr)
|
||||
|
||||
isContainerNode, err := c.isContainerKey(ctx, ownerKeyInBytes, binCnr, cnr)
|
||||
isContainerNode, err := c.isContainerKey(ownerKeyInBytes, binCnr, cnr)
|
||||
if err != nil {
|
||||
// error might happen if request has `RoleOther` key and placement
|
||||
// is not possible for previous epoch, so
|
||||
|
@ -99,8 +99,8 @@ func (c SenderClassifier) IsInnerRingOrContainerNode(ctx context.Context, ownerK
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c SenderClassifier) isInnerRingKey(ctx context.Context, owner []byte) (bool, error) {
|
||||
innerRingKeys, err := c.innerRing.InnerRingKeys(ctx)
|
||||
func (c SenderClassifier) isInnerRingKey(owner []byte) (bool, error) {
|
||||
innerRingKeys, err := c.innerRing.InnerRingKeys()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -116,11 +116,10 @@ func (c SenderClassifier) isInnerRingKey(ctx context.Context, owner []byte) (boo
|
|||
}
|
||||
|
||||
func (c SenderClassifier) isContainerKey(
|
||||
ctx context.Context,
|
||||
owner, idCnr []byte,
|
||||
cnr container.Container,
|
||||
) (bool, error) {
|
||||
nm, err := core.GetLatestNetworkMap(ctx, c.netmap) // first check current netmap
|
||||
nm, err := core.GetLatestNetworkMap(c.netmap) // first check current netmap
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -134,7 +133,7 @@ func (c SenderClassifier) isContainerKey(
|
|||
|
||||
// then check previous netmap, this can happen in-between epoch change
|
||||
// when node migrates data from last epoch container
|
||||
nm, err = core.GetPreviousNetworkMap(ctx, c.netmap)
|
||||
nm, err = core.GetPreviousNetworkMap(c.netmap)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package innerring
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -49,12 +47,12 @@ type IrFetcherWithoutNotary struct {
|
|||
|
||||
// InnerRingKeys fetches list of innerring keys from NeoFSAlphabet
|
||||
// role in the sidechain.
|
||||
func (fN IrFetcherWithNotary) InnerRingKeys(ctx context.Context) (keys.PublicKeys, error) {
|
||||
return fN.cli.NeoFSAlphabetList(ctx)
|
||||
func (fN IrFetcherWithNotary) InnerRingKeys() (keys.PublicKeys, error) {
|
||||
return fN.cli.NeoFSAlphabetList()
|
||||
}
|
||||
|
||||
// InnerRingKeys fetches list of innerring keys from netmap contract
|
||||
// in the sidechain.
|
||||
func (f IrFetcherWithoutNotary) InnerRingKeys(ctx context.Context) (keys.PublicKeys, error) {
|
||||
return f.nm.GetInnerRingList(ctx)
|
||||
func (f IrFetcherWithoutNotary) InnerRingKeys() (keys.PublicKeys, error) {
|
||||
return f.nm.GetInnerRingList()
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package innerring
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -11,7 +10,7 @@ import (
|
|||
|
||||
type (
|
||||
irFetcher interface {
|
||||
InnerRingKeys(ctx context.Context) (keys.PublicKeys, error)
|
||||
InnerRingKeys() (keys.PublicKeys, error)
|
||||
}
|
||||
|
||||
committeeFetcher interface {
|
||||
|
@ -46,7 +45,7 @@ func newInnerRingIndexer(comf committeeFetcher, irf irFetcher, key *keys.PublicK
|
|||
}
|
||||
}
|
||||
|
||||
func (s *innerRingIndexer) update(ctx context.Context) (ind indexes, err error) {
|
||||
func (s *innerRingIndexer) update() (ind indexes, err error) {
|
||||
s.RLock()
|
||||
|
||||
if time.Since(s.lastAccess) < s.timeout {
|
||||
|
@ -63,7 +62,7 @@ func (s *innerRingIndexer) update(ctx context.Context) (ind indexes, err error)
|
|||
return s.ind, nil
|
||||
}
|
||||
|
||||
innerRing, err := s.irFetcher.InnerRingKeys(ctx)
|
||||
innerRing, err := s.irFetcher.InnerRingKeys()
|
||||
if err != nil {
|
||||
return indexes{}, err
|
||||
}
|
||||
|
@ -82,8 +81,8 @@ func (s *innerRingIndexer) update(ctx context.Context) (ind indexes, err error)
|
|||
return s.ind, nil
|
||||
}
|
||||
|
||||
func (s *innerRingIndexer) InnerRingIndex(ctx context.Context) (int32, error) {
|
||||
ind, err := s.update(ctx)
|
||||
func (s *innerRingIndexer) InnerRingIndex() (int32, error) {
|
||||
ind, err := s.update()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't update index state: %w", err)
|
||||
}
|
||||
|
@ -91,8 +90,8 @@ func (s *innerRingIndexer) InnerRingIndex(ctx context.Context) (int32, error) {
|
|||
return ind.innerRingIndex, nil
|
||||
}
|
||||
|
||||
func (s *innerRingIndexer) InnerRingSize(ctx context.Context) (int32, error) {
|
||||
ind, err := s.update(ctx)
|
||||
func (s *innerRingIndexer) InnerRingSize() (int32, error) {
|
||||
ind, err := s.update()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't update index state: %w", err)
|
||||
}
|
||||
|
@ -100,8 +99,8 @@ func (s *innerRingIndexer) InnerRingSize(ctx context.Context) (int32, error) {
|
|||
return ind.innerRingSize, nil
|
||||
}
|
||||
|
||||
func (s *innerRingIndexer) AlphabetIndex(ctx context.Context) (int32, error) {
|
||||
ind, err := s.update(ctx)
|
||||
func (s *innerRingIndexer) AlphabetIndex() (int32, error) {
|
||||
ind, err := s.update()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't update index state: %w", err)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package innerring
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
@ -38,15 +37,15 @@ func TestIndexerReturnsIndexes(t *testing.T) {
|
|||
|
||||
indexer := newInnerRingIndexer(cf, irf, key, time.Second)
|
||||
|
||||
idx, err := indexer.AlphabetIndex(context.Background())
|
||||
idx, err := indexer.AlphabetIndex()
|
||||
require.NoError(t, err, "failed to get alphabet index")
|
||||
require.Equal(t, int32(1), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.NoError(t, err, "failed to get IR index")
|
||||
require.Equal(t, int32(2), idx, "invalid IR index")
|
||||
|
||||
size, err := indexer.InnerRingSize(context.Background())
|
||||
size, err := indexer.InnerRingSize()
|
||||
require.NoError(t, err, "failed to get IR size")
|
||||
require.Equal(t, int32(3), size, "invalid IR size")
|
||||
})
|
||||
|
@ -57,11 +56,11 @@ func TestIndexerReturnsIndexes(t *testing.T) {
|
|||
|
||||
indexer := newInnerRingIndexer(cf, irf, key, time.Second)
|
||||
|
||||
idx, err := indexer.AlphabetIndex(context.Background())
|
||||
idx, err := indexer.AlphabetIndex()
|
||||
require.NoError(t, err, "failed to get alphabet index")
|
||||
require.Equal(t, int32(-1), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.NoError(t, err, "failed to get IR index")
|
||||
require.Equal(t, int32(0), idx, "invalid IR index")
|
||||
})
|
||||
|
@ -72,11 +71,11 @@ func TestIndexerReturnsIndexes(t *testing.T) {
|
|||
|
||||
indexer := newInnerRingIndexer(cf, irf, key, time.Second)
|
||||
|
||||
idx, err := indexer.AlphabetIndex(context.Background())
|
||||
idx, err := indexer.AlphabetIndex()
|
||||
require.NoError(t, err, "failed to get alphabet index")
|
||||
require.Equal(t, int32(0), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.NoError(t, err, "failed to get IR index")
|
||||
require.Equal(t, int32(-1), idx, "invalid IR index")
|
||||
})
|
||||
|
@ -101,30 +100,30 @@ func TestIndexerCachesIndexes(t *testing.T) {
|
|||
|
||||
indexer := newInnerRingIndexer(cf, irf, key, time.Second)
|
||||
|
||||
idx, err := indexer.AlphabetIndex(context.Background())
|
||||
idx, err := indexer.AlphabetIndex()
|
||||
require.NoError(t, err, "failed to get alphabet index")
|
||||
require.Equal(t, int32(-1), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.NoError(t, err, "failed to get IR index")
|
||||
require.Equal(t, int32(-1), idx, "invalid IR index")
|
||||
|
||||
size, err := indexer.InnerRingSize(context.Background())
|
||||
size, err := indexer.InnerRingSize()
|
||||
require.NoError(t, err, "failed to get IR size")
|
||||
require.Equal(t, int32(0), size, "invalid IR size")
|
||||
|
||||
require.Equal(t, int32(1), cf.calls.Load(), "invalid commitee calls count")
|
||||
require.Equal(t, int32(1), irf.calls.Load(), "invalid IR calls count")
|
||||
|
||||
idx, err = indexer.AlphabetIndex(context.Background())
|
||||
idx, err = indexer.AlphabetIndex()
|
||||
require.NoError(t, err, "failed to get alphabet index")
|
||||
require.Equal(t, int32(-1), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.NoError(t, err, "failed to get IR index")
|
||||
require.Equal(t, int32(-1), idx, "invalid IR index")
|
||||
|
||||
size, err = indexer.InnerRingSize(context.Background())
|
||||
size, err = indexer.InnerRingSize()
|
||||
require.NoError(t, err, "failed to get IR size")
|
||||
require.Equal(t, int32(0), size, "invalid IR size")
|
||||
|
||||
|
@ -133,15 +132,15 @@ func TestIndexerCachesIndexes(t *testing.T) {
|
|||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
idx, err = indexer.AlphabetIndex(context.Background())
|
||||
idx, err = indexer.AlphabetIndex()
|
||||
require.NoError(t, err, "failed to get alphabet index")
|
||||
require.Equal(t, int32(-1), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.NoError(t, err, "failed to get IR index")
|
||||
require.Equal(t, int32(-1), idx, "invalid IR index")
|
||||
|
||||
size, err = indexer.InnerRingSize(context.Background())
|
||||
size, err = indexer.InnerRingSize()
|
||||
require.NoError(t, err, "failed to get IR size")
|
||||
require.Equal(t, int32(0), size, "invalid IR size")
|
||||
|
||||
|
@ -166,15 +165,15 @@ func TestIndexerThrowsErrors(t *testing.T) {
|
|||
|
||||
indexer := newInnerRingIndexer(cf, irf, key, time.Second)
|
||||
|
||||
idx, err := indexer.AlphabetIndex(context.Background())
|
||||
idx, err := indexer.AlphabetIndex()
|
||||
require.ErrorContains(t, err, "test commitee error", "error from commitee not throwed")
|
||||
require.Equal(t, int32(0), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.ErrorContains(t, err, "test commitee error", "error from IR not throwed")
|
||||
require.Equal(t, int32(0), idx, "invalid IR index")
|
||||
|
||||
size, err := indexer.InnerRingSize(context.Background())
|
||||
size, err := indexer.InnerRingSize()
|
||||
require.ErrorContains(t, err, "test commitee error", "error from IR not throwed")
|
||||
require.Equal(t, int32(0), size, "invalid IR size")
|
||||
|
||||
|
@ -190,15 +189,15 @@ func TestIndexerThrowsErrors(t *testing.T) {
|
|||
|
||||
indexer = newInnerRingIndexer(cf, irf, key, time.Second)
|
||||
|
||||
idx, err = indexer.AlphabetIndex(context.Background())
|
||||
idx, err = indexer.AlphabetIndex()
|
||||
require.ErrorContains(t, err, "test IR error", "error from commitee not throwed")
|
||||
require.Equal(t, int32(0), idx, "invalid alphabet index")
|
||||
|
||||
idx, err = indexer.InnerRingIndex(context.Background())
|
||||
idx, err = indexer.InnerRingIndex()
|
||||
require.ErrorContains(t, err, "test IR error", "error from IR not throwed")
|
||||
require.Equal(t, int32(0), idx, "invalid IR index")
|
||||
|
||||
size, err = indexer.InnerRingSize(context.Background())
|
||||
size, err = indexer.InnerRingSize()
|
||||
require.ErrorContains(t, err, "test IR error", "error from IR not throwed")
|
||||
require.Equal(t, int32(0), size, "invalid IR size")
|
||||
}
|
||||
|
@ -220,7 +219,7 @@ type testIRFetcher struct {
|
|||
calls atomic.Int32
|
||||
}
|
||||
|
||||
func (f *testIRFetcher) InnerRingKeys(context.Context) (keys.PublicKeys, error) {
|
||||
func (f *testIRFetcher) InnerRingKeys() (keys.PublicKeys, error) {
|
||||
f.calls.Add(1)
|
||||
return f.keys, f.err
|
||||
}
|
||||
|
|
|
@ -38,7 +38,10 @@ import (
|
|||
func (s *Server) initNetmapProcessor(ctx context.Context, cfg *viper.Viper,
|
||||
alphaSync event.Handler,
|
||||
) error {
|
||||
locodeValidator := s.newLocodeValidator(cfg)
|
||||
locodeValidator, err := s.newLocodeValidator(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
netSettings := (*networkSettings)(s.netmapClient)
|
||||
|
||||
|
@ -48,7 +51,6 @@ func (s *Server) initNetmapProcessor(ctx context.Context, cfg *viper.Viper,
|
|||
poolSize := cfg.GetInt("workers.netmap")
|
||||
s.log.Debug(ctx, logs.NetmapNetmapWorkerPool, zap.Int("size", poolSize))
|
||||
|
||||
var err error
|
||||
s.netmapProcessor, err = netmap.New(&netmap.Params{
|
||||
Log: s.log,
|
||||
Metrics: s.irMetrics,
|
||||
|
|
|
@ -575,19 +575,19 @@ func parseMultinetConfig(cfg *viper.Viper, m metrics.MultinetMetrics) internalNe
|
|||
|
||||
func (s *Server) initConfigFromBlockchain(ctx context.Context) error {
|
||||
// get current epoch
|
||||
epoch, err := s.netmapClient.Epoch(ctx)
|
||||
epoch, err := s.netmapClient.Epoch()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't read epoch number: %w", err)
|
||||
}
|
||||
|
||||
// get current epoch duration
|
||||
epochDuration, err := s.netmapClient.EpochDuration(ctx)
|
||||
epochDuration, err := s.netmapClient.EpochDuration()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't read epoch duration: %w", err)
|
||||
}
|
||||
|
||||
// get balance precision
|
||||
balancePrecision, err := s.balanceClient.Decimals(ctx)
|
||||
balancePrecision, err := s.balanceClient.Decimals()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't read balance contract precision: %w", err)
|
||||
}
|
||||
|
@ -597,7 +597,7 @@ func (s *Server) initConfigFromBlockchain(ctx context.Context) error {
|
|||
s.precision.SetBalancePrecision(balancePrecision)
|
||||
|
||||
// get next epoch delta tick
|
||||
s.initialEpochTickDelta, err = s.nextEpochBlockDelta(ctx)
|
||||
s.initialEpochTickDelta, err = s.nextEpochBlockDelta()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -613,8 +613,8 @@ func (s *Server) initConfigFromBlockchain(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) nextEpochBlockDelta(ctx context.Context) (uint32, error) {
|
||||
epochBlock, err := s.netmapClient.LastEpochBlock(ctx)
|
||||
func (s *Server) nextEpochBlockDelta() (uint32, error) {
|
||||
epochBlock, err := s.netmapClient.LastEpochBlock()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("can't read last epoch block: %w", err)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (s *Server) newLocodeValidator(cfg *viper.Viper) netmap.NodeValidator {
|
||||
func (s *Server) newLocodeValidator(cfg *viper.Viper) (netmap.NodeValidator, error) {
|
||||
locodeDB := locodebolt.New(locodebolt.Prm{
|
||||
Path: cfg.GetString("locode.db.path"),
|
||||
},
|
||||
|
@ -21,7 +21,7 @@ func (s *Server) newLocodeValidator(cfg *viper.Viper) netmap.NodeValidator {
|
|||
|
||||
return irlocode.New(irlocode.Prm{
|
||||
DB: (*locodeBoltDBWrapper)(locodeDB),
|
||||
})
|
||||
}), nil
|
||||
}
|
||||
|
||||
type locodeBoltEntryWrapper struct {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package innerring
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/netmap/nodevalidation/state"
|
||||
|
@ -18,8 +17,8 @@ type networkSettings netmapclient.Client
|
|||
// MaintenanceModeAllowed requests network configuration from the Sidechain
|
||||
// and check allowance of storage node's maintenance mode according to it.
|
||||
// Always returns state.ErrMaintenanceModeDisallowed.
|
||||
func (s *networkSettings) MaintenanceModeAllowed(ctx context.Context) error {
|
||||
allowed, err := (*netmapclient.Client)(s).MaintenanceModeAllowed(ctx)
|
||||
func (s *networkSettings) MaintenanceModeAllowed() error {
|
||||
allowed, err := (*netmapclient.Client)(s).MaintenanceModeAllowed()
|
||||
if err != nil {
|
||||
return fmt.Errorf("read maintenance mode's allowance from the Sidechain: %w", err)
|
||||
} else if allowed {
|
||||
|
|
|
@ -279,6 +279,6 @@ type testNetmapClient struct {
|
|||
netmap *netmap.NetMap
|
||||
}
|
||||
|
||||
func (c *testNetmapClient) NetMap(context.Context) (*netmap.NetMap, error) {
|
||||
func (c *testNetmapClient) NetMap() (*netmap.NetMap, error) {
|
||||
return c.netmap, nil
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ func (ap *Processor) processEmit(ctx context.Context) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
networkMap, err := ap.netmapClient.NetMap(ctx)
|
||||
networkMap, err := ap.netmapClient.NetMap()
|
||||
if err != nil {
|
||||
ap.log.Warn(ctx, logs.AlphabetCantGetNetmapSnapshotToEmitGasToStorageNodes,
|
||||
zap.Error(err))
|
||||
|
|
|
@ -36,7 +36,7 @@ type (
|
|||
}
|
||||
|
||||
netmapClient interface {
|
||||
NetMap(ctx context.Context) (*netmap.NetMap, error)
|
||||
NetMap() (*netmap.NetMap, error)
|
||||
}
|
||||
|
||||
morphClient interface {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -46,7 +45,7 @@ type signatureVerificationData struct {
|
|||
// - v.binPublicKey is a public session key
|
||||
// - session context corresponds to the container and verb in v
|
||||
// - session is "alive"
|
||||
func (cp *Processor) verifySignature(ctx context.Context, v signatureVerificationData) error {
|
||||
func (cp *Processor) verifySignature(v signatureVerificationData) error {
|
||||
var err error
|
||||
var key frostfsecdsa.PublicKeyRFC6979
|
||||
keyProvided := v.binPublicKey != nil
|
||||
|
@ -59,7 +58,7 @@ func (cp *Processor) verifySignature(ctx context.Context, v signatureVerificatio
|
|||
}
|
||||
|
||||
if len(v.binTokenSession) > 0 {
|
||||
return cp.verifyByTokenSession(ctx, v, &key, keyProvided)
|
||||
return cp.verifyByTokenSession(v, &key, keyProvided)
|
||||
}
|
||||
|
||||
if keyProvided {
|
||||
|
@ -78,8 +77,8 @@ func (cp *Processor) verifySignature(ctx context.Context, v signatureVerificatio
|
|||
return errors.New("signature is invalid or calculated with the key not bound to the container owner")
|
||||
}
|
||||
|
||||
func (cp *Processor) checkTokenLifetime(ctx context.Context, token session.Container) error {
|
||||
curEpoch, err := cp.netState.Epoch(ctx)
|
||||
func (cp *Processor) checkTokenLifetime(token session.Container) error {
|
||||
curEpoch, err := cp.netState.Epoch()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read current epoch: %w", err)
|
||||
}
|
||||
|
@ -91,7 +90,7 @@ func (cp *Processor) checkTokenLifetime(ctx context.Context, token session.Conta
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cp *Processor) verifyByTokenSession(ctx context.Context, v signatureVerificationData, key *frostfsecdsa.PublicKeyRFC6979, keyProvided bool) error {
|
||||
func (cp *Processor) verifyByTokenSession(v signatureVerificationData, key *frostfsecdsa.PublicKeyRFC6979, keyProvided bool) error {
|
||||
var tok session.Container
|
||||
|
||||
err := tok.Unmarshal(v.binTokenSession)
|
||||
|
@ -119,7 +118,7 @@ func (cp *Processor) verifyByTokenSession(ctx context.Context, v signatureVerifi
|
|||
return errors.New("owner differs with token owner")
|
||||
}
|
||||
|
||||
err = cp.checkTokenLifetime(ctx, tok)
|
||||
err = cp.checkTokenLifetime(tok)
|
||||
if err != nil {
|
||||
return fmt.Errorf("check session lifetime: %w", err)
|
||||
}
|
||||
|
|
|
@ -170,11 +170,11 @@ type testNetworkState struct {
|
|||
epoch uint64
|
||||
}
|
||||
|
||||
func (s *testNetworkState) HomomorphicHashDisabled(context.Context) (bool, error) {
|
||||
func (s *testNetworkState) HomomorphicHashDisabled() (bool, error) {
|
||||
return s.homHashDisabled, nil
|
||||
}
|
||||
|
||||
func (s *testNetworkState) Epoch(context.Context) (uint64, error) {
|
||||
func (s *testNetworkState) Epoch() (uint64, error) {
|
||||
return s.epoch, nil
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ func (c *testContainerClient) ContractAddress() util.Uint160 {
|
|||
return c.contractAddress
|
||||
}
|
||||
|
||||
func (c *testContainerClient) Get(ctx context.Context, cid []byte) (*containercore.Container, error) {
|
||||
func (c *testContainerClient) Get(cid []byte) (*containercore.Container, error) {
|
||||
key := hex.EncodeToString(cid)
|
||||
if cont, found := c.get[key]; found {
|
||||
return cont, nil
|
||||
|
@ -237,6 +237,6 @@ func (c *testMorphClient) NotarySignAndInvokeTX(mainTx *transaction.Transaction)
|
|||
|
||||
type testFrostFSIDClient struct{}
|
||||
|
||||
func (c *testFrostFSIDClient) GetSubject(ctx context.Context, addr util.Uint160) (*frostfsidclient.Subject, error) {
|
||||
func (c *testFrostFSIDClient) GetSubject(addr util.Uint160) (*frostfsidclient.Subject, error) {
|
||||
return &frostfsidclient.Subject{}, nil
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ func (cp *Processor) processContainerPut(ctx context.Context, put putEvent) bool
|
|||
e: put,
|
||||
}
|
||||
|
||||
err := cp.checkPutContainer(ctx, pctx)
|
||||
err := cp.checkPutContainer(pctx)
|
||||
if err != nil {
|
||||
cp.log.Error(ctx, logs.ContainerPutContainerCheckFailed,
|
||||
zap.Error(err),
|
||||
|
@ -66,8 +66,8 @@ func (cp *Processor) processContainerPut(ctx context.Context, put putEvent) bool
|
|||
return true
|
||||
}
|
||||
|
||||
func (cp *Processor) checkPutContainer(ctx context.Context, pctx *putContainerContext) error {
|
||||
binCnr := pctx.e.Container()
|
||||
func (cp *Processor) checkPutContainer(ctx *putContainerContext) error {
|
||||
binCnr := ctx.e.Container()
|
||||
var cnr containerSDK.Container
|
||||
|
||||
err := cnr.Unmarshal(binCnr)
|
||||
|
@ -75,12 +75,12 @@ func (cp *Processor) checkPutContainer(ctx context.Context, pctx *putContainerCo
|
|||
return fmt.Errorf("invalid binary container: %w", err)
|
||||
}
|
||||
|
||||
err = cp.verifySignature(ctx, signatureVerificationData{
|
||||
err = cp.verifySignature(signatureVerificationData{
|
||||
ownerContainer: cnr.Owner(),
|
||||
verb: session.VerbContainerPut,
|
||||
binTokenSession: pctx.e.SessionToken(),
|
||||
binPublicKey: pctx.e.PublicKey(),
|
||||
signature: pctx.e.Signature(),
|
||||
binTokenSession: ctx.e.SessionToken(),
|
||||
binPublicKey: ctx.e.PublicKey(),
|
||||
signature: ctx.e.Signature(),
|
||||
signedData: binCnr,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -88,13 +88,13 @@ func (cp *Processor) checkPutContainer(ctx context.Context, pctx *putContainerCo
|
|||
}
|
||||
|
||||
// check homomorphic hashing setting
|
||||
err = checkHomomorphicHashing(ctx, cp.netState, cnr)
|
||||
err = checkHomomorphicHashing(cp.netState, cnr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("incorrect homomorphic hashing setting: %w", err)
|
||||
}
|
||||
|
||||
// check native name and zone
|
||||
err = cp.checkNNS(ctx, pctx, cnr)
|
||||
err = cp.checkNNS(ctx, cnr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("NNS: %w", err)
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ func (cp *Processor) processContainerDelete(ctx context.Context, e containerEven
|
|||
return true
|
||||
}
|
||||
|
||||
err := cp.checkDeleteContainer(ctx, e)
|
||||
err := cp.checkDeleteContainer(e)
|
||||
if err != nil {
|
||||
cp.log.Error(ctx, logs.ContainerDeleteContainerCheckFailed,
|
||||
zap.Error(err),
|
||||
|
@ -130,7 +130,7 @@ func (cp *Processor) processContainerDelete(ctx context.Context, e containerEven
|
|||
return true
|
||||
}
|
||||
|
||||
func (cp *Processor) checkDeleteContainer(ctx context.Context, e containerEvent.Delete) error {
|
||||
func (cp *Processor) checkDeleteContainer(e containerEvent.Delete) error {
|
||||
binCnr := e.ContainerID()
|
||||
|
||||
var idCnr cid.ID
|
||||
|
@ -141,12 +141,12 @@ func (cp *Processor) checkDeleteContainer(ctx context.Context, e containerEvent.
|
|||
}
|
||||
|
||||
// receive owner of the related container
|
||||
cnr, err := cp.cnrClient.Get(ctx, binCnr)
|
||||
cnr, err := cp.cnrClient.Get(binCnr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not receive the container: %w", err)
|
||||
}
|
||||
|
||||
err = cp.verifySignature(ctx, signatureVerificationData{
|
||||
err = cp.verifySignature(signatureVerificationData{
|
||||
ownerContainer: cnr.Value.Owner(),
|
||||
verb: session.VerbContainerDelete,
|
||||
idContainerSet: true,
|
||||
|
@ -163,21 +163,21 @@ func (cp *Processor) checkDeleteContainer(ctx context.Context, e containerEvent.
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cp *Processor) checkNNS(ctx context.Context, pctx *putContainerContext, cnr containerSDK.Container) error {
|
||||
func (cp *Processor) checkNNS(ctx *putContainerContext, cnr containerSDK.Container) error {
|
||||
// fetch domain info
|
||||
pctx.d = containerSDK.ReadDomain(cnr)
|
||||
ctx.d = containerSDK.ReadDomain(cnr)
|
||||
|
||||
// if PutNamed event => check if values in container correspond to args
|
||||
if named, ok := pctx.e.(interface {
|
||||
if named, ok := ctx.e.(interface {
|
||||
Name() string
|
||||
Zone() string
|
||||
}); ok {
|
||||
if name := named.Name(); name != pctx.d.Name() {
|
||||
return fmt.Errorf("names differ %s/%s", name, pctx.d.Name())
|
||||
if name := named.Name(); name != ctx.d.Name() {
|
||||
return fmt.Errorf("names differ %s/%s", name, ctx.d.Name())
|
||||
}
|
||||
|
||||
if zone := named.Zone(); zone != pctx.d.Zone() {
|
||||
return fmt.Errorf("zones differ %s/%s", zone, pctx.d.Zone())
|
||||
if zone := named.Zone(); zone != ctx.d.Zone() {
|
||||
return fmt.Errorf("zones differ %s/%s", zone, ctx.d.Zone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,12 +186,12 @@ func (cp *Processor) checkNNS(ctx context.Context, pctx *putContainerContext, cn
|
|||
return fmt.Errorf("could not get container owner address: %w", err)
|
||||
}
|
||||
|
||||
subject, err := cp.frostFSIDClient.GetSubject(ctx, addr)
|
||||
subject, err := cp.frostFSIDClient.GetSubject(addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get subject from FrostfsID contract: %w", err)
|
||||
}
|
||||
|
||||
namespace, hasNamespace := strings.CutSuffix(pctx.d.Zone(), ".ns")
|
||||
namespace, hasNamespace := strings.CutSuffix(ctx.d.Zone(), ".ns")
|
||||
if !hasNamespace {
|
||||
return nil
|
||||
}
|
||||
|
@ -203,8 +203,8 @@ func (cp *Processor) checkNNS(ctx context.Context, pctx *putContainerContext, cn
|
|||
return nil
|
||||
}
|
||||
|
||||
func checkHomomorphicHashing(ctx context.Context, ns NetworkState, cnr containerSDK.Container) error {
|
||||
netSetting, err := ns.HomomorphicHashDisabled(ctx)
|
||||
func checkHomomorphicHashing(ns NetworkState, cnr containerSDK.Container) error {
|
||||
netSetting, err := ns.HomomorphicHashDisabled()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get setting in contract: %w", err)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ type (
|
|||
|
||||
ContClient interface {
|
||||
ContractAddress() util.Uint160
|
||||
Get(ctx context.Context, cid []byte) (*containercore.Container, error)
|
||||
Get(cid []byte) (*containercore.Container, error)
|
||||
}
|
||||
|
||||
MorphClient interface {
|
||||
|
@ -33,7 +33,7 @@ type (
|
|||
}
|
||||
|
||||
FrostFSIDClient interface {
|
||||
GetSubject(ctx context.Context, addr util.Uint160) (*frostfsidclient.Subject, error)
|
||||
GetSubject(addr util.Uint160) (*frostfsidclient.Subject, error)
|
||||
}
|
||||
|
||||
// Processor of events produced by container contract in the sidechain.
|
||||
|
@ -68,7 +68,7 @@ type NetworkState interface {
|
|||
//
|
||||
// Must return any error encountered
|
||||
// which did not allow reading the value.
|
||||
Epoch(ctx context.Context) (uint64, error)
|
||||
Epoch() (uint64, error)
|
||||
|
||||
// HomomorphicHashDisabled must return boolean that
|
||||
// represents homomorphic network state:
|
||||
|
@ -76,7 +76,7 @@ type NetworkState interface {
|
|||
// * false if hashing is enabled.
|
||||
//
|
||||
// which did not allow reading the value.
|
||||
HomomorphicHashDisabled(ctx context.Context) (bool, error)
|
||||
HomomorphicHashDisabled() (bool, error)
|
||||
}
|
||||
|
||||
// New creates a container contract processor instance.
|
||||
|
|
|
@ -236,7 +236,7 @@ type testIRFetcher struct {
|
|||
publicKeys keys.PublicKeys
|
||||
}
|
||||
|
||||
func (f *testIRFetcher) InnerRingKeys(context.Context) (keys.PublicKeys, error) {
|
||||
func (f *testIRFetcher) InnerRingKeys() (keys.PublicKeys, error) {
|
||||
return f.publicKeys, nil
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ type testMainnetClient struct {
|
|||
designateHash util.Uint160
|
||||
}
|
||||
|
||||
func (c *testMainnetClient) NeoFSAlphabetList(context.Context) (res keys.PublicKeys, err error) {
|
||||
func (c *testMainnetClient) NeoFSAlphabetList() (res keys.PublicKeys, err error) {
|
||||
return c.alphabetKeys, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ func (gp *Processor) processAlphabetSync(ctx context.Context, txHash util.Uint25
|
|||
return true
|
||||
}
|
||||
|
||||
mainnetAlphabet, err := gp.mainnetClient.NeoFSAlphabetList(ctx)
|
||||
mainnetAlphabet, err := gp.mainnetClient.NeoFSAlphabetList()
|
||||
if err != nil {
|
||||
gp.log.Error(ctx, logs.GovernanceCantFetchAlphabetListFromMainNet,
|
||||
zap.Error(err))
|
||||
|
@ -95,7 +95,7 @@ func prettyKeys(keys keys.PublicKeys) string {
|
|||
}
|
||||
|
||||
func (gp *Processor) updateNeoFSAlphabetRoleInSidechain(ctx context.Context, sidechainAlphabet, newAlphabet keys.PublicKeys, txHash util.Uint256) {
|
||||
innerRing, err := gp.irFetcher.InnerRingKeys(ctx)
|
||||
innerRing, err := gp.irFetcher.InnerRingKeys()
|
||||
if err != nil {
|
||||
gp.log.Error(ctx, logs.GovernanceCantFetchInnerRingListFromSideChain,
|
||||
zap.Error(err))
|
||||
|
|
|
@ -52,7 +52,7 @@ type (
|
|||
// Implementation must take into account availability of
|
||||
// the notary contract.
|
||||
IRFetcher interface {
|
||||
InnerRingKeys(ctx context.Context) (keys.PublicKeys, error)
|
||||
InnerRingKeys() (keys.PublicKeys, error)
|
||||
}
|
||||
|
||||
FrostFSClient interface {
|
||||
|
@ -64,7 +64,7 @@ type (
|
|||
}
|
||||
|
||||
MainnetClient interface {
|
||||
NeoFSAlphabetList(context.Context) (res keys.PublicKeys, err error)
|
||||
NeoFSAlphabetList() (res keys.PublicKeys, err error)
|
||||
GetDesignateHash() util.Uint160
|
||||
}
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ type testNodeStateSettings struct {
|
|||
maintAllowed bool
|
||||
}
|
||||
|
||||
func (s *testNodeStateSettings) MaintenanceModeAllowed(context.Context) error {
|
||||
func (s *testNodeStateSettings) MaintenanceModeAllowed() error {
|
||||
if s.maintAllowed {
|
||||
return nil
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ func (s *testNodeStateSettings) MaintenanceModeAllowed(context.Context) error {
|
|||
|
||||
type testValidator struct{}
|
||||
|
||||
func (v *testValidator) VerifyAndUpdate(context.Context, *netmap.NodeInfo) error {
|
||||
func (v *testValidator) VerifyAndUpdate(*netmap.NodeInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -381,7 +381,7 @@ func (c *testNetmapClient) ContractAddress() util.Uint160 {
|
|||
return c.contractAddress
|
||||
}
|
||||
|
||||
func (c *testNetmapClient) EpochDuration(context.Context) (uint64, error) {
|
||||
func (c *testNetmapClient) EpochDuration() (uint64, error) {
|
||||
return c.epochDuration, nil
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ func (c *testNetmapClient) MorphTxHeight(h util.Uint256) (uint32, error) {
|
|||
return 0, fmt.Errorf("not found")
|
||||
}
|
||||
|
||||
func (c *testNetmapClient) NetMap(context.Context) (*netmap.NetMap, error) {
|
||||
func (c *testNetmapClient) NetMap() (*netmap.NetMap, error) {
|
||||
return c.netmap, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package locode
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
@ -30,7 +29,7 @@ var errMissingRequiredAttr = errors.New("missing required attribute in DB record
|
|||
// - Continent: R.Continent().String().
|
||||
//
|
||||
// UN-LOCODE attribute remains untouched.
|
||||
func (v *Validator) VerifyAndUpdate(_ context.Context, n *netmap.NodeInfo) error {
|
||||
func (v *Validator) VerifyAndUpdate(n *netmap.NodeInfo) error {
|
||||
attrLocode := n.LOCODE()
|
||||
if attrLocode == "" {
|
||||
return nil
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package locode_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
@ -93,7 +92,7 @@ func TestValidator_VerifyAndUpdate(t *testing.T) {
|
|||
t.Run("w/o locode", func(t *testing.T) {
|
||||
n := nodeInfoWithSomeAttrs()
|
||||
|
||||
err := validator.VerifyAndUpdate(context.Background(), n)
|
||||
err := validator.VerifyAndUpdate(n)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
|
@ -103,7 +102,7 @@ func TestValidator_VerifyAndUpdate(t *testing.T) {
|
|||
|
||||
addLocodeAttrValue(n, "WRONG LOCODE")
|
||||
|
||||
err := validator.VerifyAndUpdate(context.Background(), n)
|
||||
err := validator.VerifyAndUpdate(n)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -112,7 +111,7 @@ func TestValidator_VerifyAndUpdate(t *testing.T) {
|
|||
|
||||
addLocodeAttr(n, locodestd.LOCODE{"RU", "SPB"})
|
||||
|
||||
err := validator.VerifyAndUpdate(context.Background(), n)
|
||||
err := validator.VerifyAndUpdate(n)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
|
@ -120,7 +119,7 @@ func TestValidator_VerifyAndUpdate(t *testing.T) {
|
|||
|
||||
addLocodeAttr(n, r.LOCODE)
|
||||
|
||||
err := validator.VerifyAndUpdate(context.Background(), n)
|
||||
err := validator.VerifyAndUpdate(n)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, rec.CountryCode().String(), n.Attribute("CountryCode"))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package maddress
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
||||
|
@ -9,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
// VerifyAndUpdate calls network.VerifyAddress.
|
||||
func (v *Validator) VerifyAndUpdate(_ context.Context, n *netmap.NodeInfo) error {
|
||||
func (v *Validator) VerifyAndUpdate(n *netmap.NodeInfo) error {
|
||||
err := network.VerifyMultiAddress(*n)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not verify multiaddress: %w", err)
|
||||
|
|
|
@ -7,7 +7,6 @@ map candidates.
|
|||
package state
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
|
@ -24,7 +23,7 @@ type NetworkSettings interface {
|
|||
// no error if allowed;
|
||||
// ErrMaintenanceModeDisallowed if disallowed;
|
||||
// other error if there are any problems with the check.
|
||||
MaintenanceModeAllowed(ctx context.Context) error
|
||||
MaintenanceModeAllowed() error
|
||||
}
|
||||
|
||||
// NetMapCandidateValidator represents tool which checks state of nodes which
|
||||
|
@ -56,13 +55,13 @@ func (x *NetMapCandidateValidator) SetNetworkSettings(netSettings NetworkSetting
|
|||
// MUST NOT be called before SetNetworkSettings.
|
||||
//
|
||||
// See also netmap.NodeInfo.IsOnline/SetOnline and other similar methods.
|
||||
func (x *NetMapCandidateValidator) VerifyAndUpdate(ctx context.Context, node *netmap.NodeInfo) error {
|
||||
func (x *NetMapCandidateValidator) VerifyAndUpdate(node *netmap.NodeInfo) error {
|
||||
if node.Status().IsOnline() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.Status().IsMaintenance() {
|
||||
return x.netSettings.MaintenanceModeAllowed(ctx)
|
||||
return x.netSettings.MaintenanceModeAllowed()
|
||||
}
|
||||
|
||||
return errors.New("invalid status: MUST be either ONLINE or MAINTENANCE")
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package state_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/netmap/nodevalidation/state"
|
||||
|
@ -14,7 +13,7 @@ type testNetworkSettings struct {
|
|||
disallowed bool
|
||||
}
|
||||
|
||||
func (x testNetworkSettings) MaintenanceModeAllowed(context.Context) error {
|
||||
func (x testNetworkSettings) MaintenanceModeAllowed() error {
|
||||
if x.disallowed {
|
||||
return state.ErrMaintenanceModeDisallowed
|
||||
}
|
||||
|
@ -82,7 +81,7 @@ func TestValidator_VerifyAndUpdate(t *testing.T) {
|
|||
testCase.validatorPreparer(&v)
|
||||
}
|
||||
|
||||
err := v.VerifyAndUpdate(context.Background(), &node)
|
||||
err := v.VerifyAndUpdate(&node)
|
||||
|
||||
if testCase.valid {
|
||||
require.NoError(t, err, testCase.name)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package nodevalidation
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring/processors/netmap"
|
||||
apinetmap "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
)
|
||||
|
@ -28,9 +26,9 @@ func New(validators ...netmap.NodeValidator) *CompositeValidator {
|
|||
// VerifyAndUpdate passes apinetmap.NodeInfo to wrapped validators.
|
||||
//
|
||||
// If error appears, returns it immediately.
|
||||
func (c *CompositeValidator) VerifyAndUpdate(ctx context.Context, ni *apinetmap.NodeInfo) error {
|
||||
func (c *CompositeValidator) VerifyAndUpdate(ni *apinetmap.NodeInfo) error {
|
||||
for _, v := range c.validators {
|
||||
if err := v.VerifyAndUpdate(ctx, ni); err != nil {
|
||||
if err := v.VerifyAndUpdate(ni); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
func (np *Processor) processNewEpoch(ctx context.Context, ev netmapEvent.NewEpoch) bool {
|
||||
epoch := ev.EpochNumber()
|
||||
|
||||
epochDuration, err := np.netmapClient.EpochDuration(ctx)
|
||||
epochDuration, err := np.netmapClient.EpochDuration()
|
||||
if err != nil {
|
||||
np.log.Warn(ctx, logs.NetmapCantGetEpochDuration,
|
||||
zap.Error(err))
|
||||
|
@ -37,7 +37,7 @@ func (np *Processor) processNewEpoch(ctx context.Context, ev netmapEvent.NewEpoc
|
|||
}
|
||||
|
||||
// get new netmap snapshot
|
||||
networkMap, err := np.netmapClient.NetMap(ctx)
|
||||
networkMap, err := np.netmapClient.NetMap()
|
||||
if err != nil {
|
||||
np.log.Warn(ctx, logs.NetmapCantGetNetmapSnapshotToPerformCleanup,
|
||||
zap.Error(err))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue