[#1454] Upgrade NeoFS SDK Go module with new IDs
Core changes: * avoid package-colliding variable naming * avoid using pointers to IDs where unnecessary * avoid using `idSDK` import alias pattern * use `EncodeToString` for protocol string calculation and `String` for printing Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
cc6209e8a0
commit
1c30414a6c
218 changed files with 2091 additions and 2517 deletions
|
@ -14,8 +14,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/version"
|
"github.com/nspcc-dev/neofs-sdk-go/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -77,12 +76,12 @@ type PutContainerPrm struct {
|
||||||
|
|
||||||
// PutContainerRes groups the resulting values of PutContainer operation.
|
// PutContainerRes groups the resulting values of PutContainer operation.
|
||||||
type PutContainerRes struct {
|
type PutContainerRes struct {
|
||||||
cliRes *client.ResContainerPut
|
cnr cid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns identifier of the created container.
|
// ID returns identifier of the created container.
|
||||||
func (x PutContainerRes) ID() *cid.ID {
|
func (x PutContainerRes) ID() cid.ID {
|
||||||
return x.cliRes.ID()
|
return x.cnr
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutContainer sends a request to save the container in NeoFS.
|
// PutContainer sends a request to save the container in NeoFS.
|
||||||
|
@ -94,7 +93,15 @@ func (x PutContainerRes) ID() *cid.ID {
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func PutContainer(prm PutContainerPrm) (res PutContainerRes, err error) {
|
func PutContainer(prm PutContainerPrm) (res PutContainerRes, err error) {
|
||||||
res.cliRes, err = prm.cli.ContainerPut(context.Background(), prm.PrmContainerPut)
|
cliRes, err := prm.cli.ContainerPut(context.Background(), prm.PrmContainerPut)
|
||||||
|
if err == nil {
|
||||||
|
cnr := cliRes.ID()
|
||||||
|
if cnr == nil {
|
||||||
|
err = errors.New("missing container ID in response")
|
||||||
|
} else {
|
||||||
|
res.cnr = *cnr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -306,11 +313,11 @@ func (x *PutObjectPrm) SetPayloadReader(rdr io.Reader) {
|
||||||
|
|
||||||
// PutObjectRes groups the resulting values of PutObject operation.
|
// PutObjectRes groups the resulting values of PutObject operation.
|
||||||
type PutObjectRes struct {
|
type PutObjectRes struct {
|
||||||
id *oidSDK.ID
|
id oid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns identifier of the created object.
|
// ID returns identifier of the created object.
|
||||||
func (x PutObjectRes) ID() *oidSDK.ID {
|
func (x PutObjectRes) ID() oid.ID {
|
||||||
return x.id
|
return x.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,20 +389,18 @@ func PutObject(prm PutObjectPrm) (*PutObjectRes, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := wrt.Close()
|
cliRes, err := wrt.Close()
|
||||||
if err != nil { // here err already carries both status and client errors
|
if err != nil { // here err already carries both status and client errors
|
||||||
return nil, fmt.Errorf("client failure: %w", err)
|
return nil, fmt.Errorf("client failure: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var id oidSDK.ID
|
var res PutObjectRes
|
||||||
|
|
||||||
if !res.ReadStoredObjectID(&id) {
|
if !cliRes.ReadStoredObjectID(&res.id) {
|
||||||
return nil, errors.New("missing ID of the stored object")
|
return nil, errors.New("missing ID of the stored object")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PutObjectRes{
|
return &res, nil
|
||||||
id: &id,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteObjectPrm groups parameters of DeleteObject operation.
|
// DeleteObjectPrm groups parameters of DeleteObject operation.
|
||||||
|
@ -406,12 +411,12 @@ type DeleteObjectPrm struct {
|
||||||
|
|
||||||
// DeleteObjectRes groups the resulting values of DeleteObject operation.
|
// DeleteObjectRes groups the resulting values of DeleteObject operation.
|
||||||
type DeleteObjectRes struct {
|
type DeleteObjectRes struct {
|
||||||
addrTombstone *addressSDK.Address
|
tomb oid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// TombstoneAddress returns the address of the created object with tombstone.
|
// Tombstone returns the ID of the created object with tombstone.
|
||||||
func (x DeleteObjectRes) TombstoneAddress() *addressSDK.Address {
|
func (x DeleteObjectRes) Tombstone() oid.ID {
|
||||||
return x.addrTombstone
|
return x.tomb
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteObject marks an object to be removed from NeoFS through tombstone placement.
|
// DeleteObject marks an object to be removed from NeoFS through tombstone placement.
|
||||||
|
@ -419,15 +424,8 @@ func (x DeleteObjectRes) TombstoneAddress() *addressSDK.Address {
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func DeleteObject(prm DeleteObjectPrm) (*DeleteObjectRes, error) {
|
func DeleteObject(prm DeleteObjectPrm) (*DeleteObjectRes, error) {
|
||||||
var delPrm client.PrmObjectDelete
|
var delPrm client.PrmObjectDelete
|
||||||
|
delPrm.FromContainer(prm.objAddr.Container())
|
||||||
cnr, ok := prm.objAddr.ContainerID()
|
delPrm.ByID(prm.objAddr.Object())
|
||||||
if ok {
|
|
||||||
delPrm.FromContainer(cnr)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
delPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if prm.sessionToken != nil {
|
if prm.sessionToken != nil {
|
||||||
delPrm.WithinSession(*prm.sessionToken)
|
delPrm.WithinSession(*prm.sessionToken)
|
||||||
|
@ -444,18 +442,14 @@ func DeleteObject(prm DeleteObjectPrm) (*DeleteObjectRes, error) {
|
||||||
return nil, fmt.Errorf("remove object via client: %w", err)
|
return nil, fmt.Errorf("remove object via client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var id oidSDK.ID
|
var id oid.ID
|
||||||
|
|
||||||
if !cliRes.ReadTombstoneID(&id) {
|
if !cliRes.ReadTombstoneID(&id) {
|
||||||
return nil, errors.New("object removed but tombstone ID is missing")
|
return nil, errors.New("object removed but tombstone ID is missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
var addr addressSDK.Address
|
|
||||||
addr.SetObjectID(id)
|
|
||||||
addr.SetContainerID(cnr)
|
|
||||||
|
|
||||||
return &DeleteObjectRes{
|
return &DeleteObjectRes{
|
||||||
addrTombstone: &addr,
|
tomb: id,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,14 +486,8 @@ func (x GetObjectRes) Header() *object.Object {
|
||||||
// For raw reading, returns *object.SplitInfoError error if object is virtual.
|
// For raw reading, returns *object.SplitInfoError error if object is virtual.
|
||||||
func GetObject(prm GetObjectPrm) (*GetObjectRes, error) {
|
func GetObject(prm GetObjectPrm) (*GetObjectRes, error) {
|
||||||
var getPrm client.PrmObjectGet
|
var getPrm client.PrmObjectGet
|
||||||
|
getPrm.FromContainer(prm.objAddr.Container())
|
||||||
if id, ok := prm.objAddr.ContainerID(); ok {
|
getPrm.ByID(prm.objAddr.Object())
|
||||||
getPrm.FromContainer(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
getPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if prm.sessionToken != nil {
|
if prm.sessionToken != nil {
|
||||||
getPrm.WithinSession(*prm.sessionToken)
|
getPrm.WithinSession(*prm.sessionToken)
|
||||||
|
@ -574,14 +562,8 @@ func (x HeadObjectRes) Header() *object.Object {
|
||||||
// For raw reading, returns *object.SplitInfoError error if object is virtual.
|
// For raw reading, returns *object.SplitInfoError error if object is virtual.
|
||||||
func HeadObject(prm HeadObjectPrm) (*HeadObjectRes, error) {
|
func HeadObject(prm HeadObjectPrm) (*HeadObjectRes, error) {
|
||||||
var cliPrm client.PrmObjectHead
|
var cliPrm client.PrmObjectHead
|
||||||
|
cliPrm.FromContainer(prm.objAddr.Container())
|
||||||
if id, ok := prm.objAddr.ContainerID(); ok {
|
cliPrm.ByID(prm.objAddr.Object())
|
||||||
cliPrm.FromContainer(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
cliPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if prm.sessionToken != nil {
|
if prm.sessionToken != nil {
|
||||||
cliPrm.WithinSession(*prm.sessionToken)
|
cliPrm.WithinSession(*prm.sessionToken)
|
||||||
|
@ -632,11 +614,11 @@ func (x *SearchObjectsPrm) SetFilters(filters object.SearchFilters) {
|
||||||
|
|
||||||
// SearchObjectsRes groups the resulting values of SearchObjects operation.
|
// SearchObjectsRes groups the resulting values of SearchObjects operation.
|
||||||
type SearchObjectsRes struct {
|
type SearchObjectsRes struct {
|
||||||
ids []oidSDK.ID
|
ids []oid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDList returns identifiers of the matched objects.
|
// IDList returns identifiers of the matched objects.
|
||||||
func (x SearchObjectsRes) IDList() []oidSDK.ID {
|
func (x SearchObjectsRes) IDList() []oid.ID {
|
||||||
return x.ids
|
return x.ids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,11 +627,7 @@ func (x SearchObjectsRes) IDList() []oidSDK.ID {
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func SearchObjects(prm SearchObjectsPrm) (*SearchObjectsRes, error) {
|
func SearchObjects(prm SearchObjectsPrm) (*SearchObjectsRes, error) {
|
||||||
var cliPrm client.PrmObjectSearch
|
var cliPrm client.PrmObjectSearch
|
||||||
|
cliPrm.InContainer(prm.cnrID)
|
||||||
if prm.cnrID != nil {
|
|
||||||
cliPrm.InContainer(*prm.cnrID)
|
|
||||||
}
|
|
||||||
|
|
||||||
cliPrm.SetFilters(prm.filters)
|
cliPrm.SetFilters(prm.filters)
|
||||||
|
|
||||||
if prm.sessionToken != nil {
|
if prm.sessionToken != nil {
|
||||||
|
@ -671,8 +649,8 @@ func SearchObjects(prm SearchObjectsPrm) (*SearchObjectsRes, error) {
|
||||||
return nil, fmt.Errorf("init object search: %w", err)
|
return nil, fmt.Errorf("init object search: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]oidSDK.ID, 10)
|
buf := make([]oid.ID, 10)
|
||||||
var list []oidSDK.ID
|
var list []oid.ID
|
||||||
var n int
|
var n int
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
|
@ -739,14 +717,8 @@ func (x HashPayloadRangesRes) HashList() [][]byte {
|
||||||
// Returns an error if number of received hashes differs with the number of requested ranges.
|
// Returns an error if number of received hashes differs with the number of requested ranges.
|
||||||
func HashPayloadRanges(prm HashPayloadRangesPrm) (*HashPayloadRangesRes, error) {
|
func HashPayloadRanges(prm HashPayloadRangesPrm) (*HashPayloadRangesRes, error) {
|
||||||
var cliPrm client.PrmObjectHash
|
var cliPrm client.PrmObjectHash
|
||||||
|
cliPrm.FromContainer(prm.objAddr.Container())
|
||||||
if id, ok := prm.objAddr.ContainerID(); ok {
|
cliPrm.ByID(prm.objAddr.Object())
|
||||||
cliPrm.FromContainer(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
cliPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if prm.local {
|
if prm.local {
|
||||||
cliPrm.MarkLocal()
|
cliPrm.MarkLocal()
|
||||||
|
@ -813,14 +785,8 @@ type PayloadRangeRes struct{}
|
||||||
// For raw reading, returns *object.SplitInfoError error if object is virtual.
|
// For raw reading, returns *object.SplitInfoError error if object is virtual.
|
||||||
func PayloadRange(prm PayloadRangePrm) (*PayloadRangeRes, error) {
|
func PayloadRange(prm PayloadRangePrm) (*PayloadRangeRes, error) {
|
||||||
var cliPrm client.PrmObjectRange
|
var cliPrm client.PrmObjectRange
|
||||||
|
cliPrm.FromContainer(prm.objAddr.Container())
|
||||||
if id, ok := prm.objAddr.ContainerID(); ok {
|
cliPrm.ByID(prm.objAddr.Object())
|
||||||
cliPrm.FromContainer(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
cliPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if prm.sessionToken != nil {
|
if prm.sessionToken != nil {
|
||||||
cliPrm.WithinSession(*prm.sessionToken)
|
cliPrm.WithinSession(*prm.sessionToken)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/client"
|
"github.com/nspcc-dev/neofs-sdk-go/client"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,11 +22,11 @@ func (x *commonPrm) SetClient(cli *client.Client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type containerIDPrm struct {
|
type containerIDPrm struct {
|
||||||
cnrID *cid.ID
|
cnrID cid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContainerID sets the container identifier.
|
// SetContainerID sets the container identifier.
|
||||||
func (x *containerIDPrm) SetContainerID(id *cid.ID) {
|
func (x *containerIDPrm) SetContainerID(id cid.ID) {
|
||||||
x.cnrID = id
|
x.cnrID = id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,10 +40,10 @@ func (x *bearerTokenPrm) SetBearerToken(tok *bearer.Token) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type objectAddressPrm struct {
|
type objectAddressPrm struct {
|
||||||
objAddr *addressSDK.Address
|
objAddr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *objectAddressPrm) SetAddress(addr *addressSDK.Address) {
|
func (x *objectAddressPrm) SetAddress(addr oid.Address) {
|
||||||
x.objAddr = addr
|
x.objAddr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||||
|
@ -33,13 +34,24 @@ func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token {
|
||||||
return &tok
|
return &tok
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadSessionToken reads session token as JSON file with session token
|
// ReadSessionToken calls ReadSessionTokenErr and exists on error.
|
||||||
// from path provided in a specified flag.
|
|
||||||
func ReadSessionToken(cmd *cobra.Command, dst json.Unmarshaler, fPath string) {
|
func ReadSessionToken(cmd *cobra.Command, dst json.Unmarshaler, fPath string) {
|
||||||
|
ExitOnErr(cmd, "", ReadSessionTokenErr(dst, fPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadSessionTokenErr reads session token as JSON file with session token
|
||||||
|
// from path provided in a specified flag.
|
||||||
|
func ReadSessionTokenErr(dst json.Unmarshaler, fPath string) error {
|
||||||
// try to read session token from file
|
// try to read session token from file
|
||||||
data, err := os.ReadFile(fPath)
|
data, err := os.ReadFile(fPath)
|
||||||
ExitOnErr(cmd, "could not open file with session token: %w", err)
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not open file with session token <%s>: %w", fPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
err = dst.UnmarshalJSON(data)
|
err = dst.UnmarshalJSON(data)
|
||||||
ExitOnErr(cmd, "could not unmarshal session token from file: %w", err)
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not unmarshal session token from file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,22 +24,22 @@ var accountingBalanceCmd = &cobra.Command{
|
||||||
Short: "Get internal balance of NeoFS account",
|
Short: "Get internal balance of NeoFS account",
|
||||||
Long: `Get internal balance of NeoFS account`,
|
Long: `Get internal balance of NeoFS account`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
var oid user.ID
|
var idUser user.ID
|
||||||
|
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
balanceOwner, _ := cmd.Flags().GetString(ownerFlag)
|
balanceOwner, _ := cmd.Flags().GetString(ownerFlag)
|
||||||
if balanceOwner == "" {
|
if balanceOwner == "" {
|
||||||
user.IDFromKey(&oid, pk.PublicKey)
|
user.IDFromKey(&idUser, pk.PublicKey)
|
||||||
} else {
|
} else {
|
||||||
common.ExitOnErr(cmd, "can't decode owner ID wallet address: %w", oid.DecodeString(balanceOwner))
|
common.ExitOnErr(cmd, "can't decode owner ID wallet address: %w", idUser.DecodeString(balanceOwner))
|
||||||
}
|
}
|
||||||
|
|
||||||
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
|
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
|
||||||
|
|
||||||
var prm internalclient.BalanceOfPrm
|
var prm internalclient.BalanceOfPrm
|
||||||
prm.SetClient(cli)
|
prm.SetClient(cli)
|
||||||
prm.SetAccount(oid)
|
prm.SetAccount(idUser)
|
||||||
|
|
||||||
res, err := internalclient.BalanceOf(prm)
|
res, err := internalclient.BalanceOf(prm)
|
||||||
common.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/policy"
|
"github.com/nspcc-dev/neofs-sdk-go/policy"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
|
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
|
||||||
|
@ -205,7 +204,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
if containerAwait {
|
if containerAwait {
|
||||||
cmd.Println("awaiting...")
|
cmd.Println("awaiting...")
|
||||||
|
|
||||||
getPrm.SetContainer(*id)
|
getPrm.SetContainer(id)
|
||||||
|
|
||||||
for i := 0; i < awaitTimeout; i++ {
|
for i := 0; i < awaitTimeout; i++ {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
@ -288,11 +287,9 @@ var listContainerObjectsCmd = &cobra.Command{
|
||||||
|
|
||||||
var prm internalclient.SearchObjectsPrm
|
var prm internalclient.SearchObjectsPrm
|
||||||
|
|
||||||
sessionObjectCtxAddress := addressSDK.NewAddress()
|
prepareSessionPrm(cmd, *id, nil, &prm)
|
||||||
sessionObjectCtxAddress.SetContainerID(*id)
|
|
||||||
prepareSessionPrm(cmd, sessionObjectCtxAddress, &prm)
|
|
||||||
prepareObjectPrm(cmd, &prm)
|
prepareObjectPrm(cmd, &prm)
|
||||||
prm.SetContainerID(id)
|
prm.SetContainerID(*id)
|
||||||
prm.SetFilters(*filters)
|
prm.SetFilters(*filters)
|
||||||
|
|
||||||
res, err := internalclient.SearchObjects(prm)
|
res, err := internalclient.SearchObjects(prm)
|
||||||
|
@ -301,7 +298,7 @@ var listContainerObjectsCmd = &cobra.Command{
|
||||||
objectIDs := res.IDList()
|
objectIDs := res.IDList()
|
||||||
|
|
||||||
for i := range objectIDs {
|
for i := range objectIDs {
|
||||||
cmd.Println(objectIDs[i].String())
|
cmd.Println(objectIDs[i])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -603,7 +600,7 @@ func init() {
|
||||||
|
|
||||||
func prettyPrintContainerList(cmd *cobra.Command, list []cid.ID) {
|
func prettyPrintContainerList(cmd *cobra.Command, list []cid.ID) {
|
||||||
for i := range list {
|
for i := range list {
|
||||||
cmd.Println(list[i].String())
|
cmd.Println(list[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/services/control"
|
"github.com/nspcc-dev/neofs-node/pkg/services/control"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,20 +19,10 @@ var dropObjectsCmd = &cobra.Command{
|
||||||
pk := key.Get(cmd)
|
pk := key.Get(cmd)
|
||||||
|
|
||||||
dropObjectsList, _ := cmd.Flags().GetStringSlice(dropObjectsFlag)
|
dropObjectsList, _ := cmd.Flags().GetStringSlice(dropObjectsFlag)
|
||||||
binAddrList := make([][]byte, 0, len(dropObjectsList))
|
binAddrList := make([][]byte, len(dropObjectsList))
|
||||||
|
|
||||||
for i := range dropObjectsList {
|
for i := range dropObjectsList {
|
||||||
a := addressSDK.NewAddress()
|
binAddrList[i] = []byte(dropObjectsList[i])
|
||||||
|
|
||||||
err := a.Parse(dropObjectsList[i])
|
|
||||||
if err != nil {
|
|
||||||
common.ExitOnErr(cmd, "", fmt.Errorf("could not parse address #%d: %w", i, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
binAddr, err := a.Marshal()
|
|
||||||
common.ExitOnErr(cmd, "could not marshal the address: %w", err)
|
|
||||||
|
|
||||||
binAddrList = append(binAddrList, binAddr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body := new(control.DropObjectsRequest_Body)
|
body := new(control.DropObjectsRequest_Body)
|
||||||
|
|
|
@ -24,16 +24,13 @@ func verifyResponse(cmd *cobra.Command,
|
||||||
GetSign() []byte
|
GetSign() []byte
|
||||||
},
|
},
|
||||||
body interface {
|
body interface {
|
||||||
StableMarshal([]byte) ([]byte, error)
|
StableMarshal([]byte) []byte
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if sigControl == nil {
|
if sigControl == nil {
|
||||||
common.ExitOnErr(cmd, "", errors.New("missing response signature"))
|
common.ExitOnErr(cmd, "", errors.New("missing response signature"))
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyData, err := body.StableMarshal(nil)
|
|
||||||
common.ExitOnErr(cmd, "marshal response body: %w", err)
|
|
||||||
|
|
||||||
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
|
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
|
||||||
var sigV2 refs.Signature
|
var sigV2 refs.Signature
|
||||||
sigV2.SetScheme(refs.ECDSA_SHA512)
|
sigV2.SetScheme(refs.ECDSA_SHA512)
|
||||||
|
@ -43,7 +40,7 @@ func verifyResponse(cmd *cobra.Command,
|
||||||
var sig neofscrypto.Signature
|
var sig neofscrypto.Signature
|
||||||
sig.ReadFromV2(sigV2)
|
sig.ReadFromV2(sigV2)
|
||||||
|
|
||||||
if !sig.Verify(bodyData) {
|
if !sig.Verify(body.StableMarshal(nil)) {
|
||||||
common.ExitOnErr(cmd, "", errors.New("invalid response signature"))
|
common.ExitOnErr(cmd, "", errors.New("invalid response signature"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common"
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
|
||||||
objectcore "github.com/nspcc-dev/neofs-node/pkg/core/object"
|
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
|
@ -51,7 +50,7 @@ var cmdObjectLock = &cobra.Command{
|
||||||
|
|
||||||
var prm internalclient.PutObjectPrm
|
var prm internalclient.PutObjectPrm
|
||||||
|
|
||||||
prepareSessionPrmWithOwner(cmd, objectcore.AddressOf(obj), key, idOwner, &prm)
|
prepareSessionPrmWithOwner(cmd, cnr, nil, key, *idOwner, &prm)
|
||||||
prepareObjectPrm(cmd, &prm)
|
prepareObjectPrm(cmd, &prm)
|
||||||
prm.SetHeader(obj)
|
prm.SetHeader(obj)
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/checksum"
|
"github.com/nspcc-dev/neofs-sdk-go/checksum"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -317,24 +316,25 @@ type clientKeySession interface {
|
||||||
SetSessionToken(*session.Object)
|
SetSessionToken(*session.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareSessionPrm(cmd *cobra.Command, addr *addressSDK.Address, prms ...clientKeySession) {
|
func prepareSessionPrm(cmd *cobra.Command, cnr cid.ID, obj *oid.ID, prms ...clientKeySession) {
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
prepareSessionPrmWithKey(cmd, addr, pk, prms...)
|
prepareSessionPrmWithKey(cmd, cnr, obj, pk, prms...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareSessionPrmWithKey(cmd *cobra.Command, addr *addressSDK.Address, key *ecdsa.PrivateKey, prms ...clientKeySession) {
|
func prepareSessionPrmWithKey(cmd *cobra.Command, cnr cid.ID, obj *oid.ID, key *ecdsa.PrivateKey, prms ...clientKeySession) {
|
||||||
ownerID, err := getOwnerID(key)
|
ownerID, err := getOwnerID(key)
|
||||||
common.ExitOnErr(cmd, "owner ID from key: %w", err)
|
common.ExitOnErr(cmd, "owner ID from key: %w", err)
|
||||||
|
|
||||||
prepareSessionPrmWithOwner(cmd, addr, key, ownerID, prms...)
|
prepareSessionPrmWithOwner(cmd, cnr, obj, key, *ownerID, prms...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareSessionPrmWithOwner(
|
func prepareSessionPrmWithOwner(
|
||||||
cmd *cobra.Command,
|
cmd *cobra.Command,
|
||||||
addr *addressSDK.Address,
|
cnr cid.ID,
|
||||||
|
obj *oid.ID,
|
||||||
key *ecdsa.PrivateKey,
|
key *ecdsa.PrivateKey,
|
||||||
ownerID *user.ID,
|
ownerID user.ID,
|
||||||
prms ...clientKeySession,
|
prms ...clientKeySession,
|
||||||
) {
|
) {
|
||||||
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
||||||
|
@ -373,7 +373,11 @@ func prepareSessionPrmWithOwner(
|
||||||
panic("invalid client parameter type")
|
panic("invalid client parameter type")
|
||||||
}
|
}
|
||||||
|
|
||||||
tok.ApplyTo(*addr)
|
tok.BindContainer(cnr)
|
||||||
|
|
||||||
|
if obj != nil {
|
||||||
|
tok.LimitByObject(*obj)
|
||||||
|
}
|
||||||
|
|
||||||
err := tok.Sign(*key)
|
err := tok.Sign(*key)
|
||||||
common.ExitOnErr(cmd, "session token signing: %w", err)
|
common.ExitOnErr(cmd, "session token signing: %w", err)
|
||||||
|
@ -413,8 +417,9 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
ownerID, err := getOwnerID(pk)
|
ownerID, err := getOwnerID(pk)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
cnr, err := getCID(cmd)
|
|
||||||
common.ExitOnErr(cmd, "", err)
|
var cnr cid.ID
|
||||||
|
common.ExitOnErr(cmd, "", readCID(cmd, &cnr))
|
||||||
|
|
||||||
filename := cmd.Flag("file").Value.String()
|
filename := cmd.Flag("file").Value.String()
|
||||||
f, err := os.OpenFile(filename, os.O_RDONLY, os.ModePerm)
|
f, err := os.OpenFile(filename, os.O_RDONLY, os.ModePerm)
|
||||||
|
@ -447,7 +452,7 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
obj.SetContainerID(*cnr)
|
obj.SetContainerID(cnr)
|
||||||
obj.SetOwnerID(ownerID)
|
obj.SetOwnerID(ownerID)
|
||||||
obj.SetAttributes(attrs...)
|
obj.SetAttributes(attrs...)
|
||||||
|
|
||||||
|
@ -460,9 +465,7 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var prm internalclient.PutObjectPrm
|
var prm internalclient.PutObjectPrm
|
||||||
|
|
||||||
sessionObjectCtxAddress := addressSDK.NewAddress()
|
prepareSessionPrmWithOwner(cmd, cnr, nil, pk, *ownerID, &prm)
|
||||||
sessionObjectCtxAddress.SetContainerID(*cnr)
|
|
||||||
prepareSessionPrmWithOwner(cmd, sessionObjectCtxAddress, pk, ownerID, &prm)
|
|
||||||
prepareObjectPrm(cmd, &prm)
|
prepareObjectPrm(cmd, &prm)
|
||||||
prm.SetHeader(obj)
|
prm.SetHeader(obj)
|
||||||
|
|
||||||
|
@ -495,44 +498,37 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteObject(cmd *cobra.Command, _ []string) {
|
func deleteObject(cmd *cobra.Command, _ []string) {
|
||||||
objAddr, err := getObjectAddress(cmd)
|
var cnr cid.ID
|
||||||
|
var obj oid.ID
|
||||||
|
|
||||||
|
err := readObjectAddress(cmd, &cnr, &obj)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
var prm internalclient.DeleteObjectPrm
|
var prm internalclient.DeleteObjectPrm
|
||||||
|
|
||||||
prepareSessionPrm(cmd, objAddr, &prm)
|
prepareSessionPrm(cmd, cnr, &obj, &prm)
|
||||||
prepareObjectPrm(cmd, &prm)
|
prepareObjectPrm(cmd, &prm)
|
||||||
prm.SetAddress(objAddr)
|
|
||||||
|
var addr oid.Address
|
||||||
|
addr.SetContainer(cnr)
|
||||||
|
addr.SetObject(obj)
|
||||||
|
|
||||||
|
prm.SetAddress(addr)
|
||||||
|
|
||||||
res, err := internalclient.DeleteObject(prm)
|
res, err := internalclient.DeleteObject(prm)
|
||||||
common.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
tombstoneAddr := res.TombstoneAddress()
|
tomb := res.Tombstone()
|
||||||
|
|
||||||
cmd.Println("Object removed successfully.")
|
cmd.Println("Object removed successfully.")
|
||||||
|
cmd.Printf(" ID: %s\n CID: %s\n", tomb, cnr)
|
||||||
const strEmpty = "<empty>"
|
|
||||||
var strID, strCnr string
|
|
||||||
|
|
||||||
id, ok := tombstoneAddr.ObjectID()
|
|
||||||
if ok {
|
|
||||||
strID = id.String()
|
|
||||||
} else {
|
|
||||||
strID = strEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
cnr, ok := tombstoneAddr.ContainerID()
|
|
||||||
if ok {
|
|
||||||
strCnr = cnr.String()
|
|
||||||
} else {
|
|
||||||
strCnr = strEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Printf(" ID: %s\n CID: %s\n", strID, strCnr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getObject(cmd *cobra.Command, _ []string) {
|
func getObject(cmd *cobra.Command, _ []string) {
|
||||||
objAddr, err := getObjectAddress(cmd)
|
var cnr cid.ID
|
||||||
|
var obj oid.ID
|
||||||
|
|
||||||
|
err := readObjectAddress(cmd, &cnr, &obj)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
var out io.Writer
|
var out io.Writer
|
||||||
|
@ -552,8 +548,13 @@ func getObject(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var prm internalclient.GetObjectPrm
|
var prm internalclient.GetObjectPrm
|
||||||
|
|
||||||
prepareSessionPrm(cmd, objAddr, &prm)
|
prepareSessionPrm(cmd, cnr, &obj, &prm)
|
||||||
prepareObjectPrmRaw(cmd, &prm)
|
prepareObjectPrmRaw(cmd, &prm)
|
||||||
|
|
||||||
|
var objAddr oid.Address
|
||||||
|
objAddr.SetContainer(cnr)
|
||||||
|
objAddr.SetObject(obj)
|
||||||
|
|
||||||
prm.SetAddress(objAddr)
|
prm.SetAddress(objAddr)
|
||||||
|
|
||||||
var p *pb.ProgressBar
|
var p *pb.ProgressBar
|
||||||
|
@ -598,15 +599,23 @@ func getObject(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getObjectHeader(cmd *cobra.Command, _ []string) {
|
func getObjectHeader(cmd *cobra.Command, _ []string) {
|
||||||
objAddr, err := getObjectAddress(cmd)
|
var cnr cid.ID
|
||||||
|
var obj oid.ID
|
||||||
|
|
||||||
|
err := readObjectAddress(cmd, &cnr, &obj)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
mainOnly, _ := cmd.Flags().GetBool("main-only")
|
mainOnly, _ := cmd.Flags().GetBool("main-only")
|
||||||
|
|
||||||
var prm internalclient.HeadObjectPrm
|
var prm internalclient.HeadObjectPrm
|
||||||
|
|
||||||
prepareSessionPrm(cmd, objAddr, &prm)
|
prepareSessionPrm(cmd, cnr, &obj, &prm)
|
||||||
prepareObjectPrmRaw(cmd, &prm)
|
prepareObjectPrmRaw(cmd, &prm)
|
||||||
|
|
||||||
|
var objAddr oid.Address
|
||||||
|
objAddr.SetContainer(cnr)
|
||||||
|
objAddr.SetObject(obj)
|
||||||
|
|
||||||
prm.SetAddress(objAddr)
|
prm.SetAddress(objAddr)
|
||||||
prm.SetMainOnlyFlag(mainOnly)
|
prm.SetMainOnlyFlag(mainOnly)
|
||||||
|
|
||||||
|
@ -624,7 +633,9 @@ func getObjectHeader(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchObject(cmd *cobra.Command, _ []string) {
|
func searchObject(cmd *cobra.Command, _ []string) {
|
||||||
cnr, err := getCID(cmd)
|
var cnr cid.ID
|
||||||
|
|
||||||
|
err := readCID(cmd, &cnr)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
sf, err := parseSearchFilters(cmd)
|
sf, err := parseSearchFilters(cmd)
|
||||||
|
@ -632,9 +643,7 @@ func searchObject(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var prm internalclient.SearchObjectsPrm
|
var prm internalclient.SearchObjectsPrm
|
||||||
|
|
||||||
sessionObjectCtxAddress := addressSDK.NewAddress()
|
prepareSessionPrm(cmd, cnr, nil, &prm)
|
||||||
sessionObjectCtxAddress.SetContainerID(*cnr)
|
|
||||||
prepareSessionPrm(cmd, sessionObjectCtxAddress, &prm)
|
|
||||||
prepareObjectPrm(cmd, &prm)
|
prepareObjectPrm(cmd, &prm)
|
||||||
prm.SetContainerID(cnr)
|
prm.SetContainerID(cnr)
|
||||||
prm.SetFilters(sf)
|
prm.SetFilters(sf)
|
||||||
|
@ -646,12 +655,15 @@ func searchObject(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
cmd.Printf("Found %d objects.\n", len(ids))
|
cmd.Printf("Found %d objects.\n", len(ids))
|
||||||
for i := range ids {
|
for i := range ids {
|
||||||
cmd.Println(ids[i].String())
|
cmd.Println(ids[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getObjectHash(cmd *cobra.Command, _ []string) {
|
func getObjectHash(cmd *cobra.Command, _ []string) {
|
||||||
objAddr, err := getObjectAddress(cmd)
|
var cnr cid.ID
|
||||||
|
var obj oid.ID
|
||||||
|
|
||||||
|
err := readObjectAddress(cmd, &cnr, &obj)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
ranges, err := getRangeList(cmd)
|
ranges, err := getRangeList(cmd)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
@ -677,9 +689,13 @@ func getObjectHash(cmd *cobra.Command, _ []string) {
|
||||||
objPrms = append(objPrms, &headPrm)
|
objPrms = append(objPrms, &headPrm)
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareSessionPrm(cmd, objAddr, sesPrms...)
|
prepareSessionPrm(cmd, cnr, &obj, sesPrms...)
|
||||||
prepareObjectPrm(cmd, objPrms...)
|
prepareObjectPrm(cmd, objPrms...)
|
||||||
|
|
||||||
|
var objAddr oid.Address
|
||||||
|
objAddr.SetContainer(cnr)
|
||||||
|
objAddr.SetObject(obj)
|
||||||
|
|
||||||
tz := typ == hashTz
|
tz := typ == hashTz
|
||||||
|
|
||||||
if fullHash {
|
if fullHash {
|
||||||
|
@ -792,10 +808,10 @@ func parseSearchFilters(cmd *cobra.Command) (object.SearchFilters, error) {
|
||||||
fs.AddPhyFilter()
|
fs.AddPhyFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
oid, _ := cmd.Flags().GetString(searchOIDFlag)
|
strObj, _ := cmd.Flags().GetString(searchOIDFlag)
|
||||||
if oid != "" {
|
if strObj != "" {
|
||||||
var id oidSDK.ID
|
var id oid.ID
|
||||||
if err := id.DecodeString(oid); err != nil {
|
if err := id.DecodeString(strObj); err != nil {
|
||||||
return nil, fmt.Errorf("could not parse object ID: %w", err)
|
return nil, fmt.Errorf("could not parse object ID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,42 +895,36 @@ func parseObjectNotifications(cmd *cobra.Command) (*object.NotificationInfo, err
|
||||||
return ni, nil
|
return ni, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCID(cmd *cobra.Command) (*cid.ID, error) {
|
func readCID(cmd *cobra.Command, cnr *cid.ID) error {
|
||||||
var id cid.ID
|
err := cnr.DecodeString(cmd.Flag("cid").Value.String())
|
||||||
|
|
||||||
err := id.DecodeString(cmd.Flag("cid").Value.String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse container ID: %w", err)
|
return fmt.Errorf("decode container ID string: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &id, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOID(cmd *cobra.Command) (*oidSDK.ID, error) {
|
func readOID(cmd *cobra.Command, obj *oid.ID) error {
|
||||||
var oid oidSDK.ID
|
err := obj.DecodeString(cmd.Flag("oid").Value.String())
|
||||||
|
|
||||||
err := oid.DecodeString(cmd.Flag("oid").Value.String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse object ID: %w", err)
|
return fmt.Errorf("decode container ID string: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &oid, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getObjectAddress(cmd *cobra.Command) (*addressSDK.Address, error) {
|
func readObjectAddress(cmd *cobra.Command, cnr *cid.ID, obj *oid.ID) error {
|
||||||
cnr, err := getCID(cmd)
|
err := readCID(cmd, cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
|
||||||
oid, err := getOID(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
objAddr := addressSDK.NewAddress()
|
err = readOID(cmd, obj)
|
||||||
objAddr.SetContainerID(*cnr)
|
if err != nil {
|
||||||
objAddr.SetObjectID(*oid)
|
return err
|
||||||
return objAddr, nil
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRangeList(cmd *cobra.Command) ([]*object.Range, error) {
|
func getRangeList(cmd *cobra.Command) ([]*object.Range, error) {
|
||||||
|
@ -988,7 +998,7 @@ func printChecksum(cmd *cobra.Command, name string, recv func() (checksum.Checks
|
||||||
cmd.Printf("%s: %s\n", name, strVal)
|
cmd.Printf("%s: %s\n", name, strVal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printObjectID(cmd *cobra.Command, recv func() (oidSDK.ID, bool)) {
|
func printObjectID(cmd *cobra.Command, recv func() (oid.ID, bool)) {
|
||||||
var strID string
|
var strID string
|
||||||
|
|
||||||
id, ok := recv()
|
id, ok := recv()
|
||||||
|
@ -1044,8 +1054,8 @@ func printSplitHeader(cmd *cobra.Command, obj *object.Object) error {
|
||||||
cmd.Printf("Split ID: %s\n", splitID)
|
cmd.Printf("Split ID: %s\n", splitID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if oid, ok := obj.ParentID(); ok {
|
if par, ok := obj.ParentID(); ok {
|
||||||
cmd.Printf("Split ParentID: %s\n", oid)
|
cmd.Printf("Split ParentID: %s\n", par)
|
||||||
}
|
}
|
||||||
|
|
||||||
if prev, ok := obj.PreviousID(); ok {
|
if prev, ok := obj.PreviousID(); ok {
|
||||||
|
@ -1053,7 +1063,7 @@ func printSplitHeader(cmd *cobra.Command, obj *object.Object) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, child := range obj.Children() {
|
for _, child := range obj.Children() {
|
||||||
cmd.Printf("Split ChildID: %s\n", child.String())
|
cmd.Printf("Split ChildID: %s\n", child)
|
||||||
}
|
}
|
||||||
|
|
||||||
if signature := obj.Signature(); signature != nil {
|
if signature := obj.Signature(); signature != nil {
|
||||||
|
@ -1099,8 +1109,10 @@ func marshalHeader(cmd *cobra.Command, hdr *object.Object) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getObjectRange(cmd *cobra.Command, _ []string) {
|
func getObjectRange(cmd *cobra.Command, _ []string) {
|
||||||
objAddr, err := getObjectAddress(cmd)
|
var cnr cid.ID
|
||||||
common.ExitOnErr(cmd, "", err)
|
var obj oid.ID
|
||||||
|
|
||||||
|
common.ExitOnErr(cmd, "", readObjectAddress(cmd, &cnr, &obj))
|
||||||
|
|
||||||
ranges, err := getRangeList(cmd)
|
ranges, err := getRangeList(cmd)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
@ -1127,9 +1139,14 @@ func getObjectRange(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var prm internalclient.PayloadRangePrm
|
var prm internalclient.PayloadRangePrm
|
||||||
|
|
||||||
prepareSessionPrm(cmd, objAddr, &prm)
|
prepareSessionPrm(cmd, cnr, &obj, &prm)
|
||||||
prepareObjectPrmRaw(cmd, &prm)
|
prepareObjectPrmRaw(cmd, &prm)
|
||||||
prm.SetAddress(objAddr)
|
|
||||||
|
var addr oid.Address
|
||||||
|
addr.SetContainer(cnr)
|
||||||
|
addr.SetObject(obj)
|
||||||
|
|
||||||
|
prm.SetAddress(addr)
|
||||||
prm.SetRange(ranges[0])
|
prm.SetRange(ranges[0])
|
||||||
prm.SetPayloadWriter(out)
|
prm.SetPayloadWriter(out)
|
||||||
|
|
||||||
|
@ -1183,10 +1200,10 @@ func marshalSplitInfo(cmd *cobra.Command, info *object.SplitInfo) ([]byte, error
|
||||||
b.WriteString("Split ID: " + splitID.String() + "\n")
|
b.WriteString("Split ID: " + splitID.String() + "\n")
|
||||||
}
|
}
|
||||||
if link, ok := info.Link(); ok {
|
if link, ok := info.Link(); ok {
|
||||||
b.WriteString("Linking object: " + link.String() + "\n")
|
b.WriteString(fmt.Sprintf("Linking object: %s\n", link))
|
||||||
}
|
}
|
||||||
if last, ok := info.LastPart(); ok {
|
if last, ok := info.LastPart(); ok {
|
||||||
b.WriteString("Last object: " + last.String() + "\n")
|
b.WriteString(fmt.Sprintf("Last object: %s\n", last))
|
||||||
}
|
}
|
||||||
return b.Bytes(), nil
|
return b.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
|
||||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/storagegroup"
|
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/storagegroup"
|
||||||
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
||||||
storagegroupAPI "github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
storagegroupAPI "github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -141,12 +141,15 @@ func init() {
|
||||||
type sgHeadReceiver struct {
|
type sgHeadReceiver struct {
|
||||||
cmd *cobra.Command
|
cmd *cobra.Command
|
||||||
key *ecdsa.PrivateKey
|
key *ecdsa.PrivateKey
|
||||||
ownerID *user.ID
|
ownerID user.ID
|
||||||
prm internalclient.HeadObjectPrm
|
prm internalclient.HeadObjectPrm
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c sgHeadReceiver) Head(addr *addressSDK.Address) (interface{}, error) {
|
func (c sgHeadReceiver) Head(addr oid.Address) (interface{}, error) {
|
||||||
prepareSessionPrmWithOwner(c.cmd, addr, c.key, c.ownerID, &c.prm)
|
obj := addr.Object()
|
||||||
|
|
||||||
|
prepareSessionPrmWithOwner(c.cmd, addr.Container(), &obj, c.key, c.ownerID, &c.prm)
|
||||||
|
|
||||||
c.prm.SetAddress(addr)
|
c.prm.SetAddress(addr)
|
||||||
|
|
||||||
res, err := internalclient.HeadObject(c.prm)
|
res, err := internalclient.HeadObject(c.prm)
|
||||||
|
@ -169,10 +172,12 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
ownerID, err := getOwnerID(pk)
|
ownerID, err := getOwnerID(pk)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
cnr, err := getCID(cmd)
|
var cnr cid.ID
|
||||||
|
|
||||||
|
err = readCID(cmd, &cnr)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
members := make([]oidSDK.ID, len(sgMembers))
|
members := make([]oid.ID, len(sgMembers))
|
||||||
|
|
||||||
for i := range sgMembers {
|
for i := range sgMembers {
|
||||||
err = members[i].DecodeString(sgMembers[i])
|
err = members[i].DecodeString(sgMembers[i])
|
||||||
|
@ -184,9 +189,7 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
putPrm internalclient.PutObjectPrm
|
putPrm internalclient.PutObjectPrm
|
||||||
)
|
)
|
||||||
|
|
||||||
sessionObjectCtxAddress := addressSDK.NewAddress()
|
prepareSessionPrmWithOwner(cmd, cnr, nil, pk, *ownerID, &putPrm)
|
||||||
sessionObjectCtxAddress.SetContainerID(*cnr)
|
|
||||||
prepareSessionPrmWithOwner(cmd, sessionObjectCtxAddress, pk, ownerID, &putPrm)
|
|
||||||
prepareObjectPrm(cmd, &headPrm, &putPrm)
|
prepareObjectPrm(cmd, &headPrm, &putPrm)
|
||||||
|
|
||||||
headPrm.SetRawFlag(true)
|
headPrm.SetRawFlag(true)
|
||||||
|
@ -194,7 +197,7 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
sg, err := storagegroup.CollectMembers(sgHeadReceiver{
|
sg, err := storagegroup.CollectMembers(sgHeadReceiver{
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
key: pk,
|
key: pk,
|
||||||
ownerID: ownerID,
|
ownerID: *ownerID,
|
||||||
prm: headPrm,
|
prm: headPrm,
|
||||||
}, cnr, members)
|
}, cnr, members)
|
||||||
common.ExitOnErr(cmd, "could not collect storage group members: %w", err)
|
common.ExitOnErr(cmd, "could not collect storage group members: %w", err)
|
||||||
|
@ -203,7 +206,7 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
common.ExitOnErr(cmd, "could not marshal storage group: %w", err)
|
common.ExitOnErr(cmd, "could not marshal storage group: %w", err)
|
||||||
|
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
obj.SetContainerID(*cnr)
|
obj.SetContainerID(cnr)
|
||||||
obj.SetOwnerID(ownerID)
|
obj.SetOwnerID(ownerID)
|
||||||
obj.SetType(object.TypeStorageGroup)
|
obj.SetType(object.TypeStorageGroup)
|
||||||
|
|
||||||
|
@ -217,32 +220,34 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
cmd.Printf(" ID: %s\n CID: %s\n", res.ID(), cnr)
|
cmd.Printf(" ID: %s\n CID: %s\n", res.ID(), cnr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSGID() (*oidSDK.ID, error) {
|
func getSGID() (*oid.ID, error) {
|
||||||
var oid oidSDK.ID
|
var obj oid.ID
|
||||||
err := oid.DecodeString(sgID)
|
err := obj.DecodeString(sgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse storage group ID: %w", err)
|
return nil, fmt.Errorf("could not parse storage group ID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &oid, nil
|
return &obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSG(cmd *cobra.Command, _ []string) {
|
func getSG(cmd *cobra.Command, _ []string) {
|
||||||
cnr, err := getCID(cmd)
|
var cnr cid.ID
|
||||||
|
|
||||||
|
err := readCID(cmd, &cnr)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
id, err := getSGID()
|
id, err := getSGID()
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
addr := addressSDK.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetContainerID(*cnr)
|
addr.SetContainer(cnr)
|
||||||
addr.SetObjectID(*id)
|
addr.SetObject(*id)
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
|
|
||||||
var prm internalclient.GetObjectPrm
|
var prm internalclient.GetObjectPrm
|
||||||
|
|
||||||
prepareSessionPrm(cmd, addr, &prm)
|
prepareSessionPrm(cmd, cnr, id, &prm)
|
||||||
prepareObjectPrmRaw(cmd, &prm)
|
prepareObjectPrmRaw(cmd, &prm)
|
||||||
prm.SetAddress(addr)
|
prm.SetAddress(addr)
|
||||||
prm.SetPayloadWriter(buf)
|
prm.SetPayloadWriter(buf)
|
||||||
|
@ -263,20 +268,20 @@ func getSG(cmd *cobra.Command, _ []string) {
|
||||||
cmd.Println("Members:")
|
cmd.Println("Members:")
|
||||||
|
|
||||||
for i := range members {
|
for i := range members {
|
||||||
cmd.Printf("\t%s\n", members[i].String())
|
cmd.Printf("\t%s\n", members[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func listSG(cmd *cobra.Command, _ []string) {
|
func listSG(cmd *cobra.Command, _ []string) {
|
||||||
cnr, err := getCID(cmd)
|
var cnr cid.ID
|
||||||
|
|
||||||
|
err := readCID(cmd, &cnr)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
var prm internalclient.SearchObjectsPrm
|
var prm internalclient.SearchObjectsPrm
|
||||||
|
|
||||||
sessionObjectCtxAddress := addressSDK.NewAddress()
|
prepareSessionPrm(cmd, cnr, nil, &prm)
|
||||||
sessionObjectCtxAddress.SetContainerID(*cnr)
|
|
||||||
prepareSessionPrm(cmd, sessionObjectCtxAddress, &prm)
|
|
||||||
prepareObjectPrm(cmd, &prm)
|
prepareObjectPrm(cmd, &prm)
|
||||||
prm.SetContainerID(cnr)
|
prm.SetContainerID(cnr)
|
||||||
prm.SetFilters(storagegroup.SearchQuery())
|
prm.SetFilters(storagegroup.SearchQuery())
|
||||||
|
@ -289,41 +294,34 @@ func listSG(cmd *cobra.Command, _ []string) {
|
||||||
cmd.Printf("Found %d storage groups.\n", len(ids))
|
cmd.Printf("Found %d storage groups.\n", len(ids))
|
||||||
|
|
||||||
for i := range ids {
|
for i := range ids {
|
||||||
cmd.Println(ids[i].String())
|
cmd.Println(ids[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func delSG(cmd *cobra.Command, _ []string) {
|
func delSG(cmd *cobra.Command, _ []string) {
|
||||||
cnr, err := getCID(cmd)
|
var cnr cid.ID
|
||||||
|
|
||||||
|
err := readCID(cmd, &cnr)
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
id, err := getSGID()
|
id, err := getSGID()
|
||||||
common.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
addr := addressSDK.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetContainerID(*cnr)
|
addr.SetContainer(cnr)
|
||||||
addr.SetObjectID(*id)
|
addr.SetObject(*id)
|
||||||
|
|
||||||
var prm internalclient.DeleteObjectPrm
|
var prm internalclient.DeleteObjectPrm
|
||||||
|
|
||||||
prepareSessionPrm(cmd, addr, &prm)
|
prepareSessionPrm(cmd, cnr, id, &prm)
|
||||||
prepareObjectPrm(cmd, &prm)
|
prepareObjectPrm(cmd, &prm)
|
||||||
prm.SetAddress(addr)
|
prm.SetAddress(addr)
|
||||||
|
|
||||||
res, err := internalclient.DeleteObject(prm)
|
res, err := internalclient.DeleteObject(prm)
|
||||||
common.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
tombstone := res.TombstoneAddress()
|
tomb := res.Tombstone()
|
||||||
|
|
||||||
var strID string
|
|
||||||
|
|
||||||
idTomb, ok := tombstone.ObjectID()
|
|
||||||
if ok {
|
|
||||||
strID = idTomb.String()
|
|
||||||
} else {
|
|
||||||
strID = "<empty>"
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Println("Storage group removed successfully.")
|
cmd.Println("Storage group removed successfully.")
|
||||||
cmd.Printf(" Tombstone: %s\n", strID)
|
cmd.Printf(" Tombstone: %s\n", tomb)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/writecache"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/writecache"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -57,8 +56,9 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func objectInspectCmd(cmd *cobra.Command, _ []string) {
|
func objectInspectCmd(cmd *cobra.Command, _ []string) {
|
||||||
addr := addressSDK.NewAddress()
|
var addr oid.Address
|
||||||
err := addr.Parse(vAddress)
|
|
||||||
|
err := addr.DecodeString(vAddress)
|
||||||
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
|
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
|
||||||
|
|
||||||
if vOut == "" && !vHeader {
|
if vOut == "" && !vHeader {
|
||||||
|
@ -72,7 +72,7 @@ func objectInspectCmd(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
data, err := writecache.Get(db, []byte(addr.String()))
|
data, err := writecache.Get(db, []byte(vAddress))
|
||||||
common.ExitOnErr(cmd, common.Errf("could not fetch object: %w", err))
|
common.ExitOnErr(cmd, common.Errf("could not fetch object: %w", err))
|
||||||
printObjectInfo(cmd, data)
|
printObjectInfo(cmd, data)
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package cmdlist
|
package cmdlist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal"
|
common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/writecache"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/writecache"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,8 +41,8 @@ var Command = &cobra.Command{
|
||||||
// other targets can be supported
|
// other targets can be supported
|
||||||
w := cmd.OutOrStderr()
|
w := cmd.OutOrStderr()
|
||||||
|
|
||||||
wAddr := func(addr *addressSDK.Address) error {
|
wAddr := func(addr oid.Address) error {
|
||||||
_, err := io.WriteString(w, addr.String()+"\n")
|
_, err := io.WriteString(w, fmt.Sprintf("%s\n", addr))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ func newCachedContainerStorage(v container.Source) *ttlContainerStorage {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.Get(&id)
|
return v.Get(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
return (*ttlContainerStorage)(lruCnrCache)
|
return (*ttlContainerStorage)(lruCnrCache)
|
||||||
|
@ -149,8 +149,8 @@ func newCachedContainerStorage(v container.Source) *ttlContainerStorage {
|
||||||
|
|
||||||
// Get returns container value from the cache. If value is missing in the cache
|
// 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.
|
// or expired, then it returns value from side chain and updates the cache.
|
||||||
func (s *ttlContainerStorage) Get(cid *cid.ID) (*containerSDK.Container, error) {
|
func (s *ttlContainerStorage) Get(cnr cid.ID) (*containerSDK.Container, error) {
|
||||||
val, err := (*ttlNetCache)(s).get(cid.String())
|
val, err := (*ttlNetCache)(s).get(cnr.EncodeToString())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ func newCachedEACLStorage(v eacl.Source) *ttlEACLStorage {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.GetEACL(&id)
|
return v.GetEACL(id)
|
||||||
})
|
})
|
||||||
|
|
||||||
return (*ttlEACLStorage)(lruCnrCache)
|
return (*ttlEACLStorage)(lruCnrCache)
|
||||||
|
@ -182,8 +182,8 @@ func newCachedEACLStorage(v eacl.Source) *ttlEACLStorage {
|
||||||
|
|
||||||
// GetEACL returns eACL value from the cache. If value is missing in the cache
|
// GetEACL returns eACL value from the cache. If value is missing in the cache
|
||||||
// or expired, then it returns value from side chain and updates cache.
|
// or expired, then it returns value from side chain and updates cache.
|
||||||
func (s *ttlEACLStorage) GetEACL(cid *cid.ID) (*eaclSDK.Table, error) {
|
func (s *ttlEACLStorage) GetEACL(cnr cid.ID) (*eaclSDK.Table, error) {
|
||||||
val, err := (*ttlNetCache)(s).get(cid.String())
|
val, err := (*ttlNetCache)(s).get(cnr.EncodeToString())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -192,8 +192,8 @@ func (s *ttlEACLStorage) GetEACL(cid *cid.ID) (*eaclSDK.Table, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidateEACL removes cached eACL value.
|
// InvalidateEACL removes cached eACL value.
|
||||||
func (s *ttlEACLStorage) InvalidateEACL(cid *cid.ID) {
|
func (s *ttlEACLStorage) InvalidateEACL(cnr cid.ID) {
|
||||||
(*ttlNetCache)(s).remove(cid.String())
|
(*ttlNetCache)(s).remove(cnr.EncodeToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
type lruNetmapSource struct {
|
type lruNetmapSource struct {
|
||||||
|
@ -270,11 +270,11 @@ func newCachedContainerLister(c *cntClient.Client) *ttlContainerLister {
|
||||||
// List returns list of container IDs from the cache. If list is missing in the
|
// List returns list of container IDs from the cache. If list is missing in the
|
||||||
// cache or expired, then it returns container IDs from side chain and updates
|
// cache or expired, then it returns container IDs from side chain and updates
|
||||||
// the cache.
|
// the cache.
|
||||||
func (s *ttlContainerLister) List(id *user.ID) ([]*cid.ID, error) {
|
func (s *ttlContainerLister) List(id *user.ID) ([]cid.ID, error) {
|
||||||
var str string
|
var str string
|
||||||
|
|
||||||
if id != nil {
|
if id != nil {
|
||||||
str = id.String()
|
str = id.EncodeToString()
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err := (*ttlNetCache)(s).get(str)
|
val, err := (*ttlNetCache)(s).get(str)
|
||||||
|
@ -282,12 +282,12 @@ func (s *ttlContainerLister) List(id *user.ID) ([]*cid.ID, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return val.([]*cid.ID), nil
|
return val.([]cid.ID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidateContainerList removes cached list of container IDs.
|
// InvalidateContainerList removes cached list of container IDs.
|
||||||
func (s *ttlContainerLister) InvalidateContainerList(id *user.ID) {
|
func (s *ttlContainerLister) InvalidateContainerList(id user.ID) {
|
||||||
(*ttlNetCache)(s).remove(id.String())
|
(*ttlNetCache)(s).remove(id.EncodeToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
type cachedIRFetcher ttlNetCache
|
type cachedIRFetcher ttlNetCache
|
||||||
|
|
|
@ -54,7 +54,7 @@ import (
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
const addressSize = 72 // 32 bytes oid, 32 bytes cid, 8 bytes protobuf encoding
|
const addressSize = 72 // 32 bytes object ID, 32 bytes container ID, 8 bytes protobuf encoding
|
||||||
|
|
||||||
const maxMsgSize = 4 << 20 // transport msg limit 4 MiB
|
const maxMsgSize = 4 << 20 // transport msg limit 4 MiB
|
||||||
|
|
||||||
|
|
|
@ -329,8 +329,8 @@ type loadPlacementBuilder struct {
|
||||||
cnrSrc containerCore.Source
|
cnrSrc containerCore.Source
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loadPlacementBuilder) BuildPlacement(epoch uint64, cid *cid.ID) ([]netmap.Nodes, error) {
|
func (l *loadPlacementBuilder) BuildPlacement(epoch uint64, cnr cid.ID) ([]netmap.Nodes, error) {
|
||||||
cnrNodes, nm, err := l.buildPlacement(epoch, cid)
|
cnrNodes, nm, err := l.buildPlacement(epoch, cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ func (l *loadPlacementBuilder) BuildPlacement(epoch uint64, cid *cid.ID) ([]netm
|
||||||
return placement, nil
|
return placement, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loadPlacementBuilder) buildPlacement(epoch uint64, idCnr *cid.ID) (netmap.ContainerNodes, *netmap.Netmap, error) {
|
func (l *loadPlacementBuilder) buildPlacement(epoch uint64, idCnr cid.ID) (netmap.ContainerNodes, *netmap.Netmap, error) {
|
||||||
cnr, err := l.cnrSrc.Get(idCnr)
|
cnr, err := l.cnrSrc.Get(idCnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -400,7 +400,7 @@ func (d *localStorageLoad) Iterate(f loadcontroller.UsedSpaceFilter, h loadcontr
|
||||||
)
|
)
|
||||||
|
|
||||||
a := containerSDK.NewAnnouncement()
|
a := containerSDK.NewAnnouncement()
|
||||||
a.SetContainerID(*idList[i])
|
a.SetContainerID(idList[i])
|
||||||
a.SetUsedSpace(sz)
|
a.SetUsedSpace(sz)
|
||||||
|
|
||||||
if f != nil && !f(*a) {
|
if f != nil && !f(*a) {
|
||||||
|
@ -506,8 +506,8 @@ func (*containerOnlyKeyRemoteServerInfo) NumberOfAddresses() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *loadPlacementBuilder) isNodeFromContainerKey(epoch uint64, cid *cid.ID, key []byte) (bool, error) {
|
func (l *loadPlacementBuilder) isNodeFromContainerKey(epoch uint64, cnr cid.ID, key []byte) (bool, error) {
|
||||||
cnrNodes, _, err := l.buildPlacement(epoch, cid)
|
cnrNodes, _, err := l.buildPlacement(epoch, cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -530,7 +530,7 @@ func (c *usedSpaceService) processLoadValue(_ context.Context, a containerSDK.Us
|
||||||
return errors.New("missing container ID in load announcement")
|
return errors.New("missing container ID in load announcement")
|
||||||
}
|
}
|
||||||
|
|
||||||
fromCnr, err := c.loadPlacementBuilder.isNodeFromContainerKey(a.Epoch(), &cnr, route[0].PublicKey())
|
fromCnr, err := c.loadPlacementBuilder.isNodeFromContainerKey(a.Epoch(), cnr, route[0].PublicKey())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not verify that the sender belongs to the container: %w", err)
|
return fmt.Errorf("could not verify that the sender belongs to the container: %w", err)
|
||||||
} else if !fromCnr {
|
} else if !fromCnr {
|
||||||
|
@ -557,19 +557,19 @@ type morphContainerReader struct {
|
||||||
get containerCore.Source
|
get containerCore.Source
|
||||||
|
|
||||||
lister interface {
|
lister interface {
|
||||||
List(*user.ID) ([]*cid.ID, error)
|
List(*user.ID) ([]cid.ID, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *morphContainerReader) Get(id *cid.ID) (*containerSDK.Container, error) {
|
func (x *morphContainerReader) Get(id cid.ID) (*containerSDK.Container, error) {
|
||||||
return x.get.Get(id)
|
return x.get.Get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *morphContainerReader) GetEACL(id *cid.ID) (*eaclSDK.Table, error) {
|
func (x *morphContainerReader) GetEACL(id cid.ID) (*eaclSDK.Table, error) {
|
||||||
return x.eacl.GetEACL(id)
|
return x.eacl.GetEACL(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *morphContainerReader) List(id *user.ID) ([]*cid.ID, error) {
|
func (x *morphContainerReader) List(id *user.ID) ([]cid.ID, error) {
|
||||||
return x.lister.List(id)
|
return x.lister.List(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,8 +587,13 @@ func (m morphContainerWriter) Put(cnr *containerSDK.Container) (*cid.ID, error)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idOwner := cnr.OwnerID()
|
||||||
|
if idOwner == nil {
|
||||||
|
return nil, errors.New("missing container owner")
|
||||||
|
}
|
||||||
|
|
||||||
if m.cacheEnabled {
|
if m.cacheEnabled {
|
||||||
m.lists.InvalidateContainerList(cnr.OwnerID())
|
m.lists.InvalidateContainerList(*idOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
return containerID, nil
|
return containerID, nil
|
||||||
|
@ -606,7 +611,7 @@ func (m morphContainerWriter) PutEACL(table *eaclSDK.Table) error {
|
||||||
|
|
||||||
if m.cacheEnabled {
|
if m.cacheEnabled {
|
||||||
id, _ := table.CID()
|
id, _ := table.CID()
|
||||||
m.eacls.InvalidateEACL(&id)
|
m.eacls.InvalidateEACL(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/services/control"
|
"github.com/nspcc-dev/neofs-node/pkg/services/control"
|
||||||
controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server"
|
controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ func initControlService(c *cfg) {
|
||||||
controlSvc.WithHealthChecker(c),
|
controlSvc.WithHealthChecker(c),
|
||||||
controlSvc.WithNetMapSource(c.netMapSource),
|
controlSvc.WithNetMapSource(c.netMapSource),
|
||||||
controlSvc.WithNodeState(c),
|
controlSvc.WithNodeState(c),
|
||||||
controlSvc.WithDeletedObjectHandler(func(addrList []*addressSDK.Address) error {
|
controlSvc.WithDeletedObjectHandler(func(addrList []oid.Address) error {
|
||||||
prm := new(engine.DeletePrm).WithAddresses(addrList...)
|
prm := new(engine.DeletePrm).WithAddresses(addrList...)
|
||||||
|
|
||||||
_, err := c.cfgObject.cfgLocalStorage.localStorage.Delete(prm)
|
_, err := c.cfgObject.cfgLocalStorage.localStorage.Delete(prm)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/services/notificator"
|
"github.com/nspcc-dev/neofs-node/pkg/services/notificator"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/services/notificator/nats"
|
"github.com/nspcc-dev/neofs-node/pkg/services/notificator/nats"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ type notificationSource struct {
|
||||||
defaultTopic string
|
defaultTopic string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notificationSource) Iterate(epoch uint64, handler func(topic string, addr *addressSDK.Address)) {
|
func (n *notificationSource) Iterate(epoch uint64, handler func(topic string, addr oid.Address)) {
|
||||||
log := n.l.With(zap.Uint64("epoch", epoch))
|
log := n.l.With(zap.Uint64("epoch", epoch))
|
||||||
|
|
||||||
listRes, err := n.e.ListContainers(engine.ListContainersPrm{})
|
listRes, err := n.e.ListContainers(engine.ListContainersPrm{})
|
||||||
|
@ -64,8 +64,8 @@ func (n *notificationSource) Iterate(epoch uint64, handler func(topic string, ad
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notificationSource) processAddress(
|
func (n *notificationSource) processAddress(
|
||||||
a *addressSDK.Address,
|
a oid.Address,
|
||||||
h func(topic string, addr *addressSDK.Address),
|
h func(topic string, addr oid.Address),
|
||||||
) error {
|
) error {
|
||||||
prm := new(engine.HeadPrm)
|
prm := new(engine.HeadPrm)
|
||||||
prm.WithAddress(a)
|
prm.WithAddress(a)
|
||||||
|
@ -96,7 +96,7 @@ type notificationWriter struct {
|
||||||
w *nats.Writer
|
w *nats.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n notificationWriter) Notify(topic string, address *addressSDK.Address) {
|
func (n notificationWriter) Notify(topic string, address oid.Address) {
|
||||||
if err := n.w.Notify(topic, address); err != nil {
|
if err := n.w.Notify(topic, address); err != nil {
|
||||||
n.l.Warn("could not write object notification",
|
n.l.Warn("could not write object notification",
|
||||||
zap.Stringer("address", address),
|
zap.Stringer("address", address),
|
||||||
|
|
|
@ -42,7 +42,7 @@ import (
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -102,7 +102,7 @@ type localObjectInhumer struct {
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *localObjectInhumer) DeleteObjects(ts *addressSDK.Address, addr ...*addressSDK.Address) error {
|
func (r *localObjectInhumer) DeleteObjects(ts oid.Address, addr ...oid.Address) error {
|
||||||
prm := new(engine.InhumePrm)
|
prm := new(engine.InhumePrm)
|
||||||
prm.WithTarget(ts, addr...)
|
prm.WithTarget(ts, addr...)
|
||||||
|
|
||||||
|
@ -124,8 +124,8 @@ func (i *delNetInfo) TombstoneLifetime() (uint64, error) {
|
||||||
// returns node owner ID calculated from configured private key.
|
// returns node owner ID calculated from configured private key.
|
||||||
//
|
//
|
||||||
// Implements method needed for Object.Delete service.
|
// Implements method needed for Object.Delete service.
|
||||||
func (i *delNetInfo) LocalNodeID() *user.ID {
|
func (i *delNetInfo) LocalNodeID() user.ID {
|
||||||
return &i.cfg.ownerIDFromKey
|
return i.cfg.ownerIDFromKey
|
||||||
}
|
}
|
||||||
|
|
||||||
type innerRingFetcherWithNotary struct {
|
type innerRingFetcherWithNotary struct {
|
||||||
|
@ -234,7 +234,7 @@ func initObjectService(c *cfg) {
|
||||||
policerconfig.HeadTimeout(c.appCfg),
|
policerconfig.HeadTimeout(c.appCfg),
|
||||||
),
|
),
|
||||||
policer.WithReplicator(repl),
|
policer.WithReplicator(repl),
|
||||||
policer.WithRedundantCopyCallback(func(addr *addressSDK.Address) {
|
policer.WithRedundantCopyCallback(func(addr oid.Address) {
|
||||||
_, err := ls.Inhume(new(engine.InhumePrm).MarkAsGarbage(addr))
|
_, err := ls.Inhume(new(engine.InhumePrm).MarkAsGarbage(addr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.log.Warn("could not inhume mark redundant copy as garbage",
|
c.log.Warn("could not inhume mark redundant copy as garbage",
|
||||||
|
@ -412,8 +412,8 @@ func (s *signedEACLTable) SignedDataSize() int {
|
||||||
return (*eaclSDK.Table)(s).ToV2().StableSize()
|
return (*eaclSDK.Table)(s).ToV2().StableSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *morphEACLFetcher) GetEACL(cid *cid.ID) (*eaclSDK.Table, error) {
|
func (s *morphEACLFetcher) GetEACL(cnr cid.ID) (*eaclSDK.Table, error) {
|
||||||
table, err := s.w.GetEACL(cid)
|
table, err := s.w.GetEACL(cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
|
|
||||||
type sessionStorage interface {
|
type sessionStorage interface {
|
||||||
Create(ctx context.Context, body *session.CreateRequestBody) (*session.CreateResponseBody, error)
|
Create(ctx context.Context, body *session.CreateRequestBody) (*session.CreateResponseBody, error)
|
||||||
Get(ownerID *user.ID, tokenID []byte) *storage.PrivateToken
|
Get(ownerID user.ID, tokenID []byte) *storage.PrivateToken
|
||||||
RemoveOld(epoch uint64)
|
RemoveOld(epoch uint64)
|
||||||
|
|
||||||
Close() error
|
Close() error
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -17,9 +17,9 @@ require (
|
||||||
github.com/nspcc-dev/hrw v1.0.9
|
github.com/nspcc-dev/hrw v1.0.9
|
||||||
github.com/nspcc-dev/neo-go v0.98.3
|
github.com/nspcc-dev/neo-go v0.98.3
|
||||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af // indirect
|
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220321144137-d5a9af5860af // indirect
|
||||||
github.com/nspcc-dev/neofs-api-go/v2 v2.12.1
|
github.com/nspcc-dev/neofs-api-go/v2 v2.12.2-0.20220530190258-c82dcf7e1610
|
||||||
github.com/nspcc-dev/neofs-contract v0.15.1
|
github.com/nspcc-dev/neofs-contract v0.15.1
|
||||||
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220526065457-bef4618cd6b9
|
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220531091404-82d762f536a3
|
||||||
github.com/nspcc-dev/tzhash v1.5.2
|
github.com/nspcc-dev/tzhash v1.5.2
|
||||||
github.com/panjf2000/ants/v2 v2.4.0
|
github.com/panjf2000/ants/v2 v2.4.0
|
||||||
github.com/paulmach/orb v0.2.2
|
github.com/paulmach/orb v0.2.2
|
||||||
|
|
BIN
go.sum
BIN
go.sum
Binary file not shown.
|
@ -8,7 +8,7 @@ import (
|
||||||
// RemovalWitness groups the information required
|
// RemovalWitness groups the information required
|
||||||
// to prove and verify the removal of a container.
|
// to prove and verify the removal of a container.
|
||||||
type RemovalWitness struct {
|
type RemovalWitness struct {
|
||||||
cid *cid.ID
|
cnr cid.ID
|
||||||
|
|
||||||
sig []byte
|
sig []byte
|
||||||
|
|
||||||
|
@ -17,14 +17,14 @@ type RemovalWitness struct {
|
||||||
|
|
||||||
// ContainerID returns the identifier of the container
|
// ContainerID returns the identifier of the container
|
||||||
// to be removed.
|
// to be removed.
|
||||||
func (x RemovalWitness) ContainerID() *cid.ID {
|
func (x RemovalWitness) ContainerID() cid.ID {
|
||||||
return x.cid
|
return x.cnr
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContainerID sets the identifier of the container
|
// SetContainerID sets the identifier of the container
|
||||||
// to be removed.
|
// to be removed.
|
||||||
func (x *RemovalWitness) SetContainerID(id *cid.ID) {
|
func (x *RemovalWitness) SetContainerID(id cid.ID) {
|
||||||
x.cid = id
|
x.cnr = id
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signature returns the signature of the container identifier.
|
// Signature returns the signature of the container identifier.
|
||||||
|
|
|
@ -27,10 +27,10 @@ func TestCheckFormat(t *testing.T) {
|
||||||
|
|
||||||
require.Error(t, CheckFormat(c))
|
require.Error(t, CheckFormat(c))
|
||||||
|
|
||||||
var oid user.ID
|
var idUser user.ID
|
||||||
user.IDFromKey(&oid, test.DecodeKey(-1).PublicKey)
|
user.IDFromKey(&idUser, test.DecodeKey(-1).PublicKey)
|
||||||
|
|
||||||
c.SetOwnerID(&oid)
|
c.SetOwnerID(&idUser)
|
||||||
|
|
||||||
// set incorrect nonce
|
// set incorrect nonce
|
||||||
cV2 := c.ToV2()
|
cV2 := c.ToV2()
|
||||||
|
|
|
@ -19,7 +19,7 @@ type Source interface {
|
||||||
//
|
//
|
||||||
// Implementations must not retain the container pointer and modify
|
// Implementations must not retain the container pointer and modify
|
||||||
// the container through it.
|
// the container through it.
|
||||||
Get(*cid.ID) (*container.Container, error)
|
Get(cid.ID) (*container.Container, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrNotFound checks if the error returned by Source.Get corresponds
|
// IsErrNotFound checks if the error returned by Source.Get corresponds
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
|
@ -40,7 +39,7 @@ type DeleteHandler interface {
|
||||||
//
|
//
|
||||||
// Returns apistatus.LockNonRegularObject if at least one object
|
// Returns apistatus.LockNonRegularObject if at least one object
|
||||||
// is locked.
|
// is locked.
|
||||||
DeleteObjects(*addressSDK.Address, ...*addressSDK.Address) error
|
DeleteObjects(oid.Address, ...oid.Address) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locker is an object lock storage interface.
|
// Locker is an object lock storage interface.
|
||||||
|
@ -100,6 +99,10 @@ func (v *FormatValidator) Validate(obj *object.Object, unprepared bool) error {
|
||||||
return errNilCID
|
return errNilCID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := v.checkOwner(obj); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := v.checkAttributes(obj); err != nil {
|
if err := v.checkAttributes(obj); err != nil {
|
||||||
return fmt.Errorf("invalid attributes: %w", err)
|
return fmt.Errorf("invalid attributes: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -149,7 +152,7 @@ func (v *FormatValidator) validateSignatureKey(obj *object.Object) error {
|
||||||
token := obj.SessionToken()
|
token := obj.SessionToken()
|
||||||
|
|
||||||
if token == nil || !token.AssertAuthKey(&key) {
|
if token == nil || !token.AssertAuthKey(&key) {
|
||||||
return v.checkOwnerKey(obj.OwnerID(), key)
|
return v.checkOwnerKey(*obj.OwnerID(), key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: #1159 perform token verification
|
// FIXME: #1159 perform token verification
|
||||||
|
@ -157,7 +160,7 @@ func (v *FormatValidator) validateSignatureKey(obj *object.Object) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FormatValidator) checkOwnerKey(id *user.ID, key neofsecdsa.PublicKey) error {
|
func (v *FormatValidator) checkOwnerKey(id user.ID, key neofsecdsa.PublicKey) error {
|
||||||
var id2 user.ID
|
var id2 user.ID
|
||||||
user.IDFromKey(&id2, (ecdsa.PublicKey)(key))
|
user.IDFromKey(&id2, (ecdsa.PublicKey)(key))
|
||||||
|
|
||||||
|
@ -201,14 +204,11 @@ func (v *FormatValidator) ValidateContent(o *object.Object) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
idList := tombstone.Members()
|
idList := tombstone.Members()
|
||||||
addrList := make([]*addressSDK.Address, 0, len(idList))
|
addrList := make([]oid.Address, len(idList))
|
||||||
|
|
||||||
for i := range idList {
|
for i := range idList {
|
||||||
a := addressSDK.NewAddress()
|
addrList[i].SetContainer(cnr)
|
||||||
a.SetContainerID(cnr)
|
addrList[i].SetObject(idList[i])
|
||||||
a.SetObjectID(idList[i])
|
|
||||||
|
|
||||||
addrList = append(addrList, a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.deleteHandler != nil {
|
if v.deleteHandler != nil {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
||||||
|
@ -117,7 +117,7 @@ func TestFormatValidator_Validate(t *testing.T) {
|
||||||
require.Error(t, v.ValidateContent(obj)) // no tombstone content
|
require.Error(t, v.ValidateContent(obj)) // no tombstone content
|
||||||
|
|
||||||
content := object.NewTombstone()
|
content := object.NewTombstone()
|
||||||
content.SetMembers([]oidSDK.ID{oidtest.ID()})
|
content.SetMembers([]oid.ID{oidtest.ID()})
|
||||||
|
|
||||||
data, err := content.Marshal()
|
data, err := content.Marshal()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -126,7 +126,7 @@ func TestFormatValidator_Validate(t *testing.T) {
|
||||||
|
|
||||||
require.Error(t, v.ValidateContent(obj)) // no members in tombstone
|
require.Error(t, v.ValidateContent(obj)) // no members in tombstone
|
||||||
|
|
||||||
content.SetMembers([]oidSDK.ID{oidtest.ID()})
|
content.SetMembers([]oid.ID{oidtest.ID()})
|
||||||
|
|
||||||
data, err = content.Marshal()
|
data, err = content.Marshal()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -167,7 +167,7 @@ func TestFormatValidator_Validate(t *testing.T) {
|
||||||
|
|
||||||
require.Error(t, v.ValidateContent(obj))
|
require.Error(t, v.ValidateContent(obj))
|
||||||
|
|
||||||
content.SetMembers([]oidSDK.ID{oidtest.ID()})
|
content.SetMembers([]oid.ID{oidtest.ID()})
|
||||||
|
|
||||||
data, err = content.Marshal()
|
data, err = content.Marshal()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -2,26 +2,22 @@ package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddressOf returns the address of the object.
|
// AddressOf returns the address of the object.
|
||||||
func AddressOf(obj *object.Object) *addressSDK.Address {
|
func AddressOf(obj *object.Object) oid.Address {
|
||||||
if obj != nil {
|
var addr oid.Address
|
||||||
addr := addressSDK.NewAddress()
|
|
||||||
|
|
||||||
id, ok := obj.ID()
|
id, ok := obj.ID()
|
||||||
if ok {
|
if ok {
|
||||||
addr.SetObjectID(id)
|
addr.SetObject(id)
|
||||||
}
|
|
||||||
|
|
||||||
cnr, ok := obj.ContainerID()
|
|
||||||
if ok {
|
|
||||||
addr.SetContainerID(cnr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return addr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
cnr, ok := obj.ContainerID()
|
||||||
|
if ok {
|
||||||
|
addr.SetContainer(cnr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,11 +37,11 @@ func (x *Client) SetPrivateKey(key *ecdsa.PrivateKey) {
|
||||||
type SearchSGPrm struct {
|
type SearchSGPrm struct {
|
||||||
contextPrm
|
contextPrm
|
||||||
|
|
||||||
cnrID *cid.ID
|
cnrID cid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContainerID sets the ID of the container to search for storage groups.
|
// SetContainerID sets the ID of the container to search for storage groups.
|
||||||
func (x *SearchSGPrm) SetContainerID(id *cid.ID) {
|
func (x *SearchSGPrm) SetContainerID(id cid.ID) {
|
||||||
x.cnrID = id
|
x.cnrID = id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +62,7 @@ var sgFilter = storagegroup.SearchQuery()
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func (x Client) SearchSG(prm SearchSGPrm) (*SearchSGRes, error) {
|
func (x Client) SearchSG(prm SearchSGPrm) (*SearchSGRes, error) {
|
||||||
var cliPrm client.PrmObjectSearch
|
var cliPrm client.PrmObjectSearch
|
||||||
|
cliPrm.InContainer(prm.cnrID)
|
||||||
cliPrm.InContainer(*prm.cnrID)
|
|
||||||
cliPrm.SetFilters(sgFilter)
|
cliPrm.SetFilters(sgFilter)
|
||||||
|
|
||||||
rdr, err := x.c.ObjectSearchInit(prm.ctx, cliPrm)
|
rdr, err := x.c.ObjectSearchInit(prm.ctx, cliPrm)
|
||||||
|
@ -124,14 +122,8 @@ func (x GetObjectRes) Object() *object.Object {
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func (x Client) GetObject(prm GetObjectPrm) (*GetObjectRes, error) {
|
func (x Client) GetObject(prm GetObjectPrm) (*GetObjectRes, error) {
|
||||||
var cliPrm client.PrmObjectGet
|
var cliPrm client.PrmObjectGet
|
||||||
|
cliPrm.FromContainer(prm.objAddr.Container())
|
||||||
if id, ok := prm.objAddr.ContainerID(); ok {
|
cliPrm.ByID(prm.objAddr.Object())
|
||||||
cliPrm.FromContainer(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
cliPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
rdr, err := x.c.ObjectGetInit(prm.ctx, cliPrm)
|
rdr, err := x.c.ObjectGetInit(prm.ctx, cliPrm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -210,13 +202,8 @@ func (x Client) HeadObject(prm HeadObjectPrm) (*HeadObjectRes, error) {
|
||||||
cliPrm.MarkLocal()
|
cliPrm.MarkLocal()
|
||||||
}
|
}
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ContainerID(); ok {
|
cliPrm.FromContainer(prm.objAddr.Container())
|
||||||
cliPrm.FromContainer(id)
|
cliPrm.ByID(prm.objAddr.Object())
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
cliPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
cliRes, err := x.c.ObjectHead(prm.ctx, cliPrm)
|
cliRes, err := x.c.ObjectHead(prm.ctx, cliPrm)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -242,7 +229,7 @@ func (x Client) HeadObject(prm HeadObjectPrm) (*HeadObjectRes, error) {
|
||||||
// GetObjectPayload reads an object by address from NeoFS via Client and returns its payload.
|
// GetObjectPayload reads an object by address from NeoFS via Client and returns its payload.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func GetObjectPayload(ctx context.Context, c Client, addr *addressSDK.Address) ([]byte, error) {
|
func GetObjectPayload(ctx context.Context, c Client, addr oid.Address) ([]byte, error) {
|
||||||
var prm GetObjectPrm
|
var prm GetObjectPrm
|
||||||
|
|
||||||
prm.SetContext(ctx)
|
prm.SetContext(ctx)
|
||||||
|
@ -256,7 +243,7 @@ func GetObjectPayload(ctx context.Context, c Client, addr *addressSDK.Address) (
|
||||||
return obj.Object().Payload(), nil
|
return obj.Object().Payload(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func headObject(ctx context.Context, c Client, addr *addressSDK.Address, raw bool, ttl uint32) (*object.Object, error) {
|
func headObject(ctx context.Context, c Client, addr oid.Address, raw bool, ttl uint32) (*object.Object, error) {
|
||||||
var prm HeadObjectPrm
|
var prm HeadObjectPrm
|
||||||
|
|
||||||
prm.SetContext(ctx)
|
prm.SetContext(ctx)
|
||||||
|
@ -276,13 +263,13 @@ func headObject(ctx context.Context, c Client, addr *addressSDK.Address, raw boo
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawObjectHeaderLocally reads the raw short object header from the server's local storage by address via Client.
|
// GetRawObjectHeaderLocally reads the raw short object header from the server's local storage by address via Client.
|
||||||
func GetRawObjectHeaderLocally(ctx context.Context, c Client, addr *addressSDK.Address) (*object.Object, error) {
|
func GetRawObjectHeaderLocally(ctx context.Context, c Client, addr oid.Address) (*object.Object, error) {
|
||||||
return headObject(ctx, c, addr, true, 1)
|
return headObject(ctx, c, addr, true, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectHeaderFromContainer reads the short object header by address via Client with TTL = 10
|
// GetObjectHeaderFromContainer reads the short object header by address via Client with TTL = 10
|
||||||
// for deep traversal of the container.
|
// for deep traversal of the container.
|
||||||
func GetObjectHeaderFromContainer(ctx context.Context, c Client, addr *addressSDK.Address) (*object.Object, error) {
|
func GetObjectHeaderFromContainer(ctx context.Context, c Client, addr oid.Address) (*object.Object, error) {
|
||||||
return headObject(ctx, c, addr, false, 10)
|
return headObject(ctx, c, addr, false, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,15 +301,8 @@ func (x HashPayloadRangeRes) Hash() []byte {
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func (x Client) HashPayloadRange(prm HashPayloadRangePrm) (res HashPayloadRangeRes, err error) {
|
func (x Client) HashPayloadRange(prm HashPayloadRangePrm) (res HashPayloadRangeRes, err error) {
|
||||||
var cliPrm client.PrmObjectHash
|
var cliPrm client.PrmObjectHash
|
||||||
|
cliPrm.FromContainer(prm.objAddr.Container())
|
||||||
if id, ok := prm.objAddr.ContainerID(); ok {
|
cliPrm.ByID(prm.objAddr.Object())
|
||||||
cliPrm.FromContainer(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id, ok := prm.objAddr.ObjectID(); ok {
|
|
||||||
cliPrm.ByID(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
cliPrm.SetRangeList(prm.rng.GetOffset(), prm.rng.GetLength())
|
cliPrm.SetRangeList(prm.rng.GetOffset(), prm.rng.GetLength())
|
||||||
cliPrm.TillichZemorAlgo()
|
cliPrm.TillichZemorAlgo()
|
||||||
|
|
||||||
|
@ -349,7 +329,7 @@ func (x Client) HashPayloadRange(prm HashPayloadRangePrm) (res HashPayloadRangeR
|
||||||
// from the remote server's local storage via Client.
|
// from the remote server's local storage via Client.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func HashObjectRange(ctx context.Context, c Client, addr *addressSDK.Address, rng *object.Range) ([]byte, error) {
|
func HashObjectRange(ctx context.Context, c Client, addr oid.Address, rng *object.Range) ([]byte, error) {
|
||||||
var prm HashPayloadRangePrm
|
var prm HashPayloadRangePrm
|
||||||
|
|
||||||
prm.SetContext(ctx)
|
prm.SetContext(ctx)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package neofsapiclient
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type contextPrm struct {
|
type contextPrm struct {
|
||||||
|
@ -16,11 +16,11 @@ func (x *contextPrm) SetContext(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type objectAddressPrm struct {
|
type objectAddressPrm struct {
|
||||||
objAddr *addressSDK.Address
|
objAddr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAddress sets address of the object.
|
// SetAddress sets address of the object.
|
||||||
func (x *objectAddressPrm) SetAddress(addr *addressSDK.Address) {
|
func (x *objectAddressPrm) SetAddress(addr oid.Address) {
|
||||||
x.objAddr = addr
|
x.objAddr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util/rand"
|
"github.com/nspcc-dev/neofs-node/pkg/util/rand"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,8 +110,8 @@ func (ap *Processor) processStartAudit(epoch uint64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ap *Processor) findStorageGroups(cid *cid.ID, shuffled netmap.Nodes) []oidSDK.ID {
|
func (ap *Processor) findStorageGroups(cnr cid.ID, shuffled netmap.Nodes) []oid.ID {
|
||||||
var sg []oidSDK.ID
|
var sg []oid.ID
|
||||||
|
|
||||||
ln := len(shuffled)
|
ln := len(shuffled)
|
||||||
|
|
||||||
|
@ -120,11 +120,11 @@ func (ap *Processor) findStorageGroups(cid *cid.ID, shuffled netmap.Nodes) []oid
|
||||||
prm SearchSGPrm
|
prm SearchSGPrm
|
||||||
)
|
)
|
||||||
|
|
||||||
prm.id = cid
|
prm.id = cnr
|
||||||
|
|
||||||
for i := range shuffled { // consider iterating over some part of container
|
for i := range shuffled { // consider iterating over some part of container
|
||||||
log := ap.log.With(
|
log := ap.log.With(
|
||||||
zap.Stringer("cid", cid),
|
zap.Stringer("cid", cnr),
|
||||||
zap.String("key", hex.EncodeToString(shuffled[0].PublicKey())),
|
zap.String("key", hex.EncodeToString(shuffled[0].PublicKey())),
|
||||||
zap.Int("try", i),
|
zap.Int("try", i),
|
||||||
zap.Int("total_tries", ln),
|
zap.Int("total_tries", ln),
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/services/audit"
|
"github.com/nspcc-dev/neofs-node/pkg/services/audit"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -67,7 +67,7 @@ type (
|
||||||
type SearchSGPrm struct {
|
type SearchSGPrm struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
id *cid.ID
|
id cid.ID
|
||||||
|
|
||||||
info client.NodeInfo
|
info client.NodeInfo
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func (x SearchSGPrm) Context() context.Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CID returns the identifier of the container to search SG in.
|
// CID returns the identifier of the container to search SG in.
|
||||||
func (x SearchSGPrm) CID() *cid.ID {
|
func (x SearchSGPrm) CID() cid.ID {
|
||||||
return x.id
|
return x.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,11 +89,11 @@ func (x SearchSGPrm) NodeInfo() client.NodeInfo {
|
||||||
|
|
||||||
// SearchSGDst groups the target values which Processor expects from SG searching to process.
|
// SearchSGDst groups the target values which Processor expects from SG searching to process.
|
||||||
type SearchSGDst struct {
|
type SearchSGDst struct {
|
||||||
ids []oidSDK.ID
|
ids []oid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteIDList writes a list of identifiers of storage group objects stored in the container.
|
// WriteIDList writes a list of identifiers of storage group objects stored in the container.
|
||||||
func (x *SearchSGDst) WriteIDList(ids []oidSDK.ID) {
|
func (x *SearchSGDst) WriteIDList(ids []oid.ID) {
|
||||||
x.ids = ids
|
x.ids = ids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
var ErrInvalidIRNode = errors.New("node is not in the inner ring list")
|
var ErrInvalidIRNode = errors.New("node is not in the inner ring list")
|
||||||
|
|
||||||
func (ap *Processor) selectContainersToAudit(epoch uint64) ([]*cid.ID, error) {
|
func (ap *Processor) selectContainersToAudit(epoch uint64) ([]cid.ID, error) {
|
||||||
containers, err := ap.containerClient.List(nil)
|
containers, err := ap.containerClient.List(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get list of containers to start audit: %w", err)
|
return nil, fmt.Errorf("can't get list of containers to start audit: %w", err)
|
||||||
|
@ -25,7 +25,7 @@ func (ap *Processor) selectContainersToAudit(epoch uint64) ([]*cid.ID, error) {
|
||||||
)
|
)
|
||||||
|
|
||||||
sort.Slice(containers, func(i, j int) bool {
|
sort.Slice(containers, func(i, j int) bool {
|
||||||
return strings.Compare(containers[i].String(), containers[j].String()) < 0
|
return strings.Compare(containers[i].EncodeToString(), containers[j].EncodeToString()) < 0
|
||||||
})
|
})
|
||||||
|
|
||||||
ind := ap.irList.InnerRingIndex()
|
ind := ap.irList.InnerRingIndex()
|
||||||
|
@ -38,7 +38,7 @@ func (ap *Processor) selectContainersToAudit(epoch uint64) ([]*cid.ID, error) {
|
||||||
return Select(containers, epoch, uint64(ind), uint64(irSize)), nil
|
return Select(containers, epoch, uint64(ind), uint64(irSize)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Select(ids []*cid.ID, epoch, index, size uint64) []*cid.ID {
|
func Select(ids []cid.ID, epoch, index, size uint64) []cid.ID {
|
||||||
if index >= size {
|
if index >= size {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,10 @@ func TestSelect(t *testing.T) {
|
||||||
require.Equal(t, len(cids)/irSize, len(s))
|
require.Equal(t, len(cids)/irSize, len(s))
|
||||||
|
|
||||||
for _, id := range s {
|
for _, id := range s {
|
||||||
n, ok := m[id.String()]
|
n, ok := m[id.EncodeToString()]
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, 0, n)
|
require.Equal(t, 0, n)
|
||||||
m[id.String()] = 1
|
m[id.EncodeToString()] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ func TestSelect(t *testing.T) {
|
||||||
s := audit.Select(cids, 0, uint64(i), irSize)
|
s := audit.Select(cids, 0, uint64(i), irSize)
|
||||||
|
|
||||||
for _, id := range s {
|
for _, id := range s {
|
||||||
n, ok := m[id.String()]
|
n, ok := m[id.EncodeToString()]
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, 0, n)
|
require.Equal(t, 0, n)
|
||||||
m[id.String()] = 1
|
m[id.EncodeToString()] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +64,10 @@ func TestSelect(t *testing.T) {
|
||||||
s := audit.Select(cids, uint64(i), 0, irSize)
|
s := audit.Select(cids, uint64(i), 0, irSize)
|
||||||
|
|
||||||
for _, id := range s {
|
for _, id := range s {
|
||||||
n, ok := m[id.String()]
|
n, ok := m[id.EncodeToString()]
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, 0, n)
|
require.Equal(t, 0, n)
|
||||||
m[id.String()] = 1
|
m[id.EncodeToString()] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,22 +75,21 @@ func TestSelect(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateContainers(n int) []*cid.ID {
|
func generateContainers(n int) []cid.ID {
|
||||||
result := make([]*cid.ID, 0, n)
|
result := make([]cid.ID, n)
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
v := cidtest.ID()
|
result[i] = cidtest.ID()
|
||||||
result = append(result, &v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func hitMap(ids []*cid.ID) map[string]int {
|
func hitMap(ids []cid.ID) map[string]int {
|
||||||
result := make(map[string]int, len(ids))
|
result := make(map[string]int, len(ids))
|
||||||
|
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
result[id.String()] = 0
|
result[id.EncodeToString()] = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -115,7 +115,7 @@ func (cp *Processor) verifySignature(v signatureVerificationData) error {
|
||||||
|
|
||||||
if verificationKeys == nil {
|
if verificationKeys == nil {
|
||||||
var prm neofsid.AccountKeysPrm
|
var prm neofsid.AccountKeysPrm
|
||||||
prm.SetID(&v.ownerContainer)
|
prm.SetID(v.ownerContainer)
|
||||||
|
|
||||||
ownerKeys, err := cp.idClient.AccountKeys(prm)
|
ownerKeys, err := cp.idClient.AccountKeys(prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -154,17 +154,17 @@ func (cp *Processor) processContainerDelete(delete *containerEvent.Delete) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
||||||
binCID := e.ContainerID()
|
binCnr := e.ContainerID()
|
||||||
|
|
||||||
var idCnr cid.ID
|
var idCnr cid.ID
|
||||||
|
|
||||||
err := idCnr.Decode(binCID)
|
err := idCnr.Decode(binCnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid container ID: %w", err)
|
return fmt.Errorf("invalid container ID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// receive owner of the related container
|
// receive owner of the related container
|
||||||
cnr, err := cp.cnrClient.Get(binCID)
|
cnr, err := cp.cnrClient.Get(binCnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not receive the container: %w", err)
|
return fmt.Errorf("could not receive the container: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
||||||
idContainer: idCnr,
|
idContainer: idCnr,
|
||||||
binTokenSession: e.SessionToken(),
|
binTokenSession: e.SessionToken(),
|
||||||
signature: e.Signature(),
|
signature: e.Signature(),
|
||||||
signedData: binCID,
|
signedData: binCnr,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("auth container removal: %w", err)
|
return fmt.Errorf("auth container removal: %w", err)
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (cp *Processor) checkSetEACL(e container.SetEACL) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// receive owner of the related container
|
// receive owner of the related container
|
||||||
cnr, err := cntClient.Get(cp.cnrClient, &idCnr)
|
cnr, err := cntClient.Get(cp.cnrClient, idCnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not receive the container: %w", err)
|
return fmt.Errorf("could not receive the container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
|
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/audit"
|
"github.com/nspcc-dev/neofs-sdk-go/audit"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -152,7 +151,7 @@ func (c *Calculator) readContainerInfo(ctx *singleResultCtx) bool {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
ctx.cnrInfo, err = c.prm.ContainerStorage.ContainerInfo(&cnr)
|
ctx.cnrInfo, err = c.prm.ContainerStorage.ContainerInfo(cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.log.Error("could not get container info",
|
ctx.log.Error("could not get container info",
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
|
@ -217,11 +216,11 @@ func (c *Calculator) sumSGSizes(ctx *singleResultCtx) bool {
|
||||||
sumPassSGSize := uint64(0)
|
sumPassSGSize := uint64(0)
|
||||||
fail := false
|
fail := false
|
||||||
|
|
||||||
addr := addressSDK.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetContainerID(*ctx.containerID())
|
addr.SetContainer(ctx.containerID())
|
||||||
|
|
||||||
ctx.auditResult.IteratePassedStorageGroups(func(id oid.ID) bool {
|
ctx.auditResult.IteratePassedStorageGroups(func(id oid.ID) bool {
|
||||||
addr.SetObjectID(id)
|
addr.SetObject(id)
|
||||||
|
|
||||||
sgInfo, err := c.prm.SGStorage.SGInfo(addr)
|
sgInfo, err := c.prm.SGStorage.SGInfo(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -285,7 +284,7 @@ func (c *Calculator) fillTransferTable(ctx *singleResultCtx) bool {
|
||||||
|
|
||||||
ctx.txTable.Transfer(&common.TransferTx{
|
ctx.txTable.Transfer(&common.TransferTx{
|
||||||
From: cnrOwner,
|
From: cnrOwner,
|
||||||
To: ownerID,
|
To: *ownerID,
|
||||||
Amount: fee,
|
Amount: fee,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -303,16 +302,16 @@ func (c *Calculator) fillTransferTable(ctx *singleResultCtx) bool {
|
||||||
|
|
||||||
ctx.txTable.Transfer(&common.TransferTx{
|
ctx.txTable.Transfer(&common.TransferTx{
|
||||||
From: cnrOwner,
|
From: cnrOwner,
|
||||||
To: auditIR,
|
To: *auditIR,
|
||||||
Amount: ctx.auditFee,
|
Amount: ctx.auditFee,
|
||||||
})
|
})
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *singleResultCtx) containerID() *cid.ID {
|
func (c *singleResultCtx) containerID() cid.ID {
|
||||||
cnr, _ := c.auditResult.Container()
|
cnr, _ := c.auditResult.Container()
|
||||||
return &cnr
|
return cnr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *singleResultCtx) auditEpoch() uint64 {
|
func (c *singleResultCtx) auditEpoch() uint64 {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package audit
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement/common"
|
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement/common"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/audit"
|
"github.com/nspcc-dev/neofs-sdk-go/audit"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CalculatorPrm groups the parameters of Calculator's constructor.
|
// CalculatorPrm groups the parameters of Calculator's constructor.
|
||||||
|
@ -39,7 +39,7 @@ type SGInfo interface {
|
||||||
// SGStorage is an interface of storage of the storage groups.
|
// SGStorage is an interface of storage of the storage groups.
|
||||||
type SGStorage interface {
|
type SGStorage interface {
|
||||||
// Must return information about the storage group by address.
|
// Must return information about the storage group by address.
|
||||||
SGInfo(*addressSDK.Address) (SGInfo, error)
|
SGInfo(oid.Address) (SGInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeeFetcher wraps AuditFee method that returns audit fee price from
|
// FeeFetcher wraps AuditFee method that returns audit fee price from
|
||||||
|
|
|
@ -41,7 +41,8 @@ func (inc *IncomeSettlementContext) Collect() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
inc.log.Warn("can't fetch container info",
|
inc.log.Warn("can't fetch container info",
|
||||||
zap.Uint64("epoch", inc.epoch),
|
zap.Uint64("epoch", inc.epoch),
|
||||||
zap.Stringer("container_id", cnrEstimations[i].ContainerID))
|
zap.Stringer("container_id", cnrEstimations[i].ContainerID),
|
||||||
|
)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -50,7 +51,8 @@ func (inc *IncomeSettlementContext) Collect() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
inc.log.Debug("can't fetch container info",
|
inc.log.Debug("can't fetch container info",
|
||||||
zap.Uint64("epoch", inc.epoch),
|
zap.Uint64("epoch", inc.epoch),
|
||||||
zap.Stringer("container_id", cnrEstimations[i].ContainerID))
|
zap.Stringer("container_id", cnrEstimations[i].ContainerID),
|
||||||
|
)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -65,7 +67,7 @@ func (inc *IncomeSettlementContext) Collect() {
|
||||||
|
|
||||||
txTable.Transfer(&common.TransferTx{
|
txTable.Transfer(&common.TransferTx{
|
||||||
From: owner.Owner(),
|
From: owner.Owner(),
|
||||||
To: &inc.bankOwner,
|
To: inc.bankOwner,
|
||||||
Amount: total,
|
Amount: total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ type (
|
||||||
|
|
||||||
// BalanceFetcher uses NEP-17 compatible balance contract
|
// BalanceFetcher uses NEP-17 compatible balance contract
|
||||||
BalanceFetcher interface {
|
BalanceFetcher interface {
|
||||||
Balance(id *user.ID) (*big.Int, error)
|
Balance(id user.ID) (*big.Int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
IncomeSettlementContext struct {
|
IncomeSettlementContext struct {
|
||||||
|
|
|
@ -14,7 +14,7 @@ func (inc *IncomeSettlementContext) Distribute() {
|
||||||
|
|
||||||
txTable := common.NewTransferTable()
|
txTable := common.NewTransferTable()
|
||||||
|
|
||||||
bankBalance, err := inc.balances.Balance(&inc.bankOwner)
|
bankBalance, err := inc.balances.Balance(inc.bankOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
inc.log.Error("can't fetch balance of banking account",
|
inc.log.Error("can't fetch balance of banking account",
|
||||||
zap.String("error", err.Error()))
|
zap.String("error", err.Error()))
|
||||||
|
@ -35,8 +35,8 @@ func (inc *IncomeSettlementContext) Distribute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
txTable.Transfer(&common.TransferTx{
|
txTable.Transfer(&common.TransferTx{
|
||||||
From: &inc.bankOwner,
|
From: inc.bankOwner,
|
||||||
To: nodeOwner,
|
To: *nodeOwner,
|
||||||
Amount: normalizedValue(n, total, bankBalance),
|
Amount: normalizedValue(n, total, bankBalance),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,21 +21,21 @@ type NodeInfo interface {
|
||||||
// necessary for calculating audit fee.
|
// necessary for calculating audit fee.
|
||||||
type ContainerInfo interface {
|
type ContainerInfo interface {
|
||||||
// Must return identifier of the container owner.
|
// Must return identifier of the container owner.
|
||||||
Owner() *user.ID
|
Owner() user.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStorage is an interface of
|
// ContainerStorage is an interface of
|
||||||
// storage of the NeoFS containers.
|
// storage of the NeoFS containers.
|
||||||
type ContainerStorage interface {
|
type ContainerStorage interface {
|
||||||
// Must return information about the container by ID.
|
// Must return information about the container by ID.
|
||||||
ContainerInfo(*cid.ID) (ContainerInfo, error)
|
ContainerInfo(cid.ID) (ContainerInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PlacementCalculator is a component interface
|
// PlacementCalculator is a component interface
|
||||||
// that builds placement vectors.
|
// that builds placement vectors.
|
||||||
type PlacementCalculator interface {
|
type PlacementCalculator interface {
|
||||||
// Must return information about the nodes from container cid of the epoch e.
|
// Must return information about the nodes from container by its ID of the given epoch.
|
||||||
ContainerNodes(e uint64, cid *cid.ID) ([]NodeInfo, error)
|
ContainerNodes(uint64, cid.ID) ([]NodeInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountStorage is an network member accounts interface.
|
// AccountStorage is an network member accounts interface.
|
||||||
|
@ -50,5 +50,5 @@ type Exchanger interface {
|
||||||
// Must transfer amount of GASe-12 from sender to recipient.
|
// Must transfer amount of GASe-12 from sender to recipient.
|
||||||
//
|
//
|
||||||
// Amount must be positive.
|
// Amount must be positive.
|
||||||
Transfer(sender, recipient *user.ID, amount *big.Int, details []byte)
|
Transfer(sender, recipient user.ID, amount *big.Int, details []byte)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ type TransferTable struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransferTx struct {
|
type TransferTx struct {
|
||||||
From, To *user.ID
|
From, To user.ID
|
||||||
|
|
||||||
Amount *big.Int
|
Amount *big.Int
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ func NewTransferTable() *TransferTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TransferTable) Transfer(tx *TransferTx) {
|
func (t *TransferTable) Transfer(tx *TransferTx) {
|
||||||
if tx.From.Equals(*tx.To) {
|
if tx.From.Equals(tx.To) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
from, to := tx.From.String(), tx.To.String()
|
from, to := tx.From.EncodeToString(), tx.To.EncodeToString()
|
||||||
|
|
||||||
m, ok := t.txs[from]
|
m, ok := t.txs[from]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package innerring
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -16,8 +15,7 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -63,19 +61,16 @@ func (c *ClientCache) Get(info clientcore.NodeInfo) (clientcore.Client, error) {
|
||||||
// Returns storage groups structure from received object.
|
// Returns storage groups structure from received object.
|
||||||
//
|
//
|
||||||
// Returns an error of type apistatus.ObjectNotFound if storage group is missing.
|
// Returns an error of type apistatus.ObjectNotFound if storage group is missing.
|
||||||
func (c *ClientCache) GetSG(task *audit.Task, id *oidSDK.ID) (*storagegroup.StorageGroup, error) {
|
func (c *ClientCache) GetSG(task *audit.Task, id oid.ID) (*storagegroup.StorageGroup, error) {
|
||||||
sgAddress := new(addressSDK.Address)
|
var sgAddress oid.Address
|
||||||
sgAddress.SetContainerID(*task.ContainerID())
|
sgAddress.SetContainer(task.ContainerID())
|
||||||
sgAddress.SetObjectID(*id)
|
sgAddress.SetObject(id)
|
||||||
|
|
||||||
return c.getSG(task.AuditContext(), sgAddress, task.NetworkMap(), task.ContainerNodes())
|
return c.getSG(task.AuditContext(), sgAddress, task.NetworkMap(), task.ContainerNodes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientCache) getSG(ctx context.Context, addr *addressSDK.Address, nm *netmap.Netmap, cn netmap.ContainerNodes) (*storagegroup.StorageGroup, error) {
|
func (c *ClientCache) getSG(ctx context.Context, addr oid.Address, nm *netmap.Netmap, cn netmap.ContainerNodes) (*storagegroup.StorageGroup, error) {
|
||||||
obj, ok := addr.ObjectID()
|
obj := addr.Object()
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("missing object ID in object address")
|
|
||||||
}
|
|
||||||
|
|
||||||
nodes, err := placement.BuildObjectPlacement(nm, cn, &obj)
|
nodes, err := placement.BuildObjectPlacement(nm, cn, &obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -129,10 +124,10 @@ func (c *ClientCache) getSG(ctx context.Context, addr *addressSDK.Address, nm *n
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeader requests node from the container under audit to return object header by id.
|
// GetHeader requests node from the container under audit to return object header by id.
|
||||||
func (c *ClientCache) GetHeader(task *audit.Task, node *netmap.Node, id *oidSDK.ID, relay bool) (*object.Object, error) {
|
func (c *ClientCache) GetHeader(task *audit.Task, node *netmap.Node, id oid.ID, relay bool) (*object.Object, error) {
|
||||||
objAddress := new(addressSDK.Address)
|
var objAddress oid.Address
|
||||||
objAddress.SetContainerID(*task.ContainerID())
|
objAddress.SetContainer(task.ContainerID())
|
||||||
objAddress.SetObjectID(*id)
|
objAddress.SetObject(id)
|
||||||
|
|
||||||
var info clientcore.NodeInfo
|
var info clientcore.NodeInfo
|
||||||
|
|
||||||
|
@ -167,10 +162,10 @@ func (c *ClientCache) GetHeader(task *audit.Task, node *netmap.Node, id *oidSDK.
|
||||||
|
|
||||||
// GetRangeHash requests node from the container under audit to return Tillich-Zemor hash of the
|
// GetRangeHash requests node from the container under audit to return Tillich-Zemor hash of the
|
||||||
// payload range of the object with specified identifier.
|
// payload range of the object with specified identifier.
|
||||||
func (c *ClientCache) GetRangeHash(task *audit.Task, node *netmap.Node, id *oidSDK.ID, rng *object.Range) ([]byte, error) {
|
func (c *ClientCache) GetRangeHash(task *audit.Task, node *netmap.Node, id oid.ID, rng *object.Range) ([]byte, error) {
|
||||||
objAddress := new(addressSDK.Address)
|
var objAddress oid.Address
|
||||||
objAddress.SetContainerID(*task.ContainerID())
|
objAddress.SetContainer(task.ContainerID())
|
||||||
objAddress.SetObjectID(*id)
|
objAddress.SetObject(id)
|
||||||
|
|
||||||
var info clientcore.NodeInfo
|
var info clientcore.NodeInfo
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
@ -24,7 +23,7 @@ import (
|
||||||
containerAPI "github.com/nspcc-dev/neofs-sdk-go/container"
|
containerAPI "github.com/nspcc-dev/neofs-sdk-go/container"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
netmapAPI "github.com/nspcc-dev/neofs-sdk-go/netmap"
|
netmapAPI "github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
"github.com/nspcc-dev/neofs-sdk-go/storagegroup"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -93,8 +92,8 @@ func (n nodeInfoWrapper) Price() *big.Int {
|
||||||
return big.NewInt(int64(n.ni.Price))
|
return big.NewInt(int64(n.ni.Price))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *containerWrapper) Owner() *user.ID {
|
func (c *containerWrapper) Owner() user.ID {
|
||||||
return (*containerAPI.Container)(c).OwnerID()
|
return *(*containerAPI.Container)(c).OwnerID()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s settlementDeps) AuditResultsForEpoch(epoch uint64) ([]*auditAPI.Result, error) {
|
func (s settlementDeps) AuditResultsForEpoch(epoch uint64) ([]*auditAPI.Result, error) {
|
||||||
|
@ -117,7 +116,7 @@ func (s settlementDeps) AuditResultsForEpoch(epoch uint64) ([]*auditAPI.Result,
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s settlementDeps) ContainerInfo(cid *cid.ID) (common.ContainerInfo, error) {
|
func (s settlementDeps) ContainerInfo(cid cid.ID) (common.ContainerInfo, error) {
|
||||||
cnr, err := s.cnrSrc.Get(cid)
|
cnr, err := s.cnrSrc.Get(cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not get container from storage: %w", err)
|
return nil, fmt.Errorf("could not get container from storage: %w", err)
|
||||||
|
@ -126,7 +125,7 @@ func (s settlementDeps) ContainerInfo(cid *cid.ID) (common.ContainerInfo, error)
|
||||||
return (*containerWrapper)(cnr), nil
|
return (*containerWrapper)(cnr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s settlementDeps) buildContainer(e uint64, cid *cid.ID) (netmapAPI.ContainerNodes, *netmapAPI.Netmap, error) {
|
func (s settlementDeps) buildContainer(e uint64, cid cid.ID) (netmapAPI.ContainerNodes, *netmapAPI.Netmap, error) {
|
||||||
var (
|
var (
|
||||||
nm *netmapAPI.Netmap
|
nm *netmapAPI.Netmap
|
||||||
err error
|
err error
|
||||||
|
@ -161,7 +160,7 @@ func (s settlementDeps) buildContainer(e uint64, cid *cid.ID) (netmapAPI.Contain
|
||||||
return cn, nm, nil
|
return cn, nm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s settlementDeps) ContainerNodes(e uint64, cid *cid.ID) ([]common.NodeInfo, error) {
|
func (s settlementDeps) ContainerNodes(e uint64, cid cid.ID) ([]common.NodeInfo, error) {
|
||||||
cn, _, err := s.buildContainer(e, cid)
|
cn, _, err := s.buildContainer(e, cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -182,13 +181,10 @@ func (s settlementDeps) ContainerNodes(e uint64, cid *cid.ID) ([]common.NodeInfo
|
||||||
// SGInfo returns audit.SGInfo by object address.
|
// SGInfo returns audit.SGInfo by object address.
|
||||||
//
|
//
|
||||||
// Returns an error of type apistatus.ObjectNotFound if storage group is missing.
|
// Returns an error of type apistatus.ObjectNotFound if storage group is missing.
|
||||||
func (s settlementDeps) SGInfo(addr *addressSDK.Address) (audit.SGInfo, error) {
|
func (s settlementDeps) SGInfo(addr oid.Address) (audit.SGInfo, error) {
|
||||||
cnr, ok := addr.ContainerID()
|
cnr := addr.Container()
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("missing container in object address")
|
|
||||||
}
|
|
||||||
|
|
||||||
cn, nm, err := s.buildContainer(0, &cnr)
|
cn, nm, err := s.buildContainer(0, cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -213,7 +209,7 @@ func (s settlementDeps) ResolveKey(ni common.NodeInfo) (*user.ID, error) {
|
||||||
return &id, nil
|
return &id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s settlementDeps) Transfer(sender, recipient *user.ID, amount *big.Int, details []byte) {
|
func (s settlementDeps) Transfer(sender, recipient user.ID, amount *big.Int, details []byte) {
|
||||||
if s.settlementCtx == "" {
|
if s.settlementCtx == "" {
|
||||||
panic("unknown settlement deps context")
|
panic("unknown settlement deps context")
|
||||||
}
|
}
|
||||||
|
@ -278,7 +274,7 @@ func (b basicIncomeSettlementDeps) Estimations(epoch uint64) ([]*containerClient
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b basicIncomeSettlementDeps) Balance(id *user.ID) (*big.Int, error) {
|
func (b basicIncomeSettlementDeps) Balance(id user.ID) (*big.Int, error) {
|
||||||
return b.balanceClient.BalanceOf(id)
|
return b.balanceClient.BalanceOf(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,12 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util/logger/test"
|
"github.com/nspcc-dev/neofs-node/pkg/util/logger/test"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testPutGet(t *testing.T, blz *Blobovnicza, addr *addressSDK.Address, sz uint64, assertErrPut, assertErrGet func(error) bool) *addressSDK.Address {
|
func testPutGet(t *testing.T, blz *Blobovnicza, addr oid.Address, sz uint64, assertErrPut, assertErrGet func(error) bool) oid.Address {
|
||||||
// create binary object
|
// create binary object
|
||||||
data := make([]byte, sz)
|
data := make([]byte, sz)
|
||||||
rand.Read(data)
|
rand.Read(data)
|
||||||
|
@ -28,16 +28,14 @@ func testPutGet(t *testing.T, blz *Blobovnicza, addr *addressSDK.Address, sz uin
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if assertErrPut != nil {
|
if assertErrGet != nil {
|
||||||
return nil
|
testGet(t, blz, addr, data, assertErrGet)
|
||||||
}
|
}
|
||||||
|
|
||||||
testGet(t, blz, addr, data, assertErrGet)
|
|
||||||
|
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGet(t *testing.T, blz *Blobovnicza, addr *addressSDK.Address, expObj []byte, assertErr func(error) bool) {
|
func testGet(t *testing.T, blz *Blobovnicza, addr oid.Address, expObj []byte, assertErr func(error) bool) {
|
||||||
pGet := new(GetPrm)
|
pGet := new(GetPrm)
|
||||||
pGet.SetAddress(addr)
|
pGet.SetAddress(addr)
|
||||||
|
|
||||||
|
@ -79,12 +77,12 @@ func TestBlobovnicza(t *testing.T) {
|
||||||
require.NoError(t, blz.Init())
|
require.NoError(t, blz.Init())
|
||||||
|
|
||||||
// try to read non-existent address
|
// try to read non-existent address
|
||||||
testGet(t, blz, objecttest.Address(), nil, IsErrNotFound)
|
testGet(t, blz, oidtest.Address(), nil, IsErrNotFound)
|
||||||
|
|
||||||
filled := uint64(15 * 1 << 10)
|
filled := uint64(15 * 1 << 10)
|
||||||
|
|
||||||
// test object 15KB
|
// test object 15KB
|
||||||
addr := testPutGet(t, blz, objecttest.Address(), filled, nil, nil)
|
addr := testPutGet(t, blz, oidtest.Address(), filled, nil, nil)
|
||||||
|
|
||||||
// remove the object
|
// remove the object
|
||||||
dPrm := new(DeletePrm)
|
dPrm := new(DeletePrm)
|
||||||
|
@ -98,11 +96,11 @@ func TestBlobovnicza(t *testing.T) {
|
||||||
|
|
||||||
// fill Blobovnicza fully
|
// fill Blobovnicza fully
|
||||||
for ; filled < sizeLim; filled += objSizeLim {
|
for ; filled < sizeLim; filled += objSizeLim {
|
||||||
testPutGet(t, blz, objecttest.Address(), objSizeLim, nil, nil)
|
testPutGet(t, blz, oidtest.Address(), objSizeLim, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// from now objects should not be saved
|
// from now objects should not be saved
|
||||||
testPutGet(t, blz, objecttest.Address(), 1024, func(err error) bool {
|
testPutGet(t, blz, oidtest.Address(), 1024, func(err error) bool {
|
||||||
return errors.Is(err, ErrFull)
|
return errors.Is(err, ErrFull)
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
|
@ -142,7 +140,7 @@ func TestIterateObjects(t *testing.T) {
|
||||||
var putPrm PutPrm
|
var putPrm PutPrm
|
||||||
|
|
||||||
for _, v := range mObjs {
|
for _, v := range mObjs {
|
||||||
putPrm.SetAddress(objecttest.Address())
|
putPrm.SetAddress(oidtest.Address())
|
||||||
putPrm.SetMarshaledObject(v)
|
putPrm.SetMarshaledObject(v)
|
||||||
|
|
||||||
_, err := blz.Put(&putPrm)
|
_, err := blz.Put(&putPrm)
|
||||||
|
|
|
@ -2,14 +2,14 @@ package blobovnicza
|
||||||
|
|
||||||
import (
|
import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeletePrm groups the parameters of Delete operation.
|
// DeletePrm groups the parameters of Delete operation.
|
||||||
type DeletePrm struct {
|
type DeletePrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRes groups the resulting values of Delete operation.
|
// DeleteRes groups the resulting values of Delete operation.
|
||||||
|
@ -17,7 +17,7 @@ type DeleteRes struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAddress sets the address of the requested object.
|
// SetAddress sets the address of the requested object.
|
||||||
func (p *DeletePrm) SetAddress(addr *addressSDK.Address) {
|
func (p *DeletePrm) SetAddress(addr oid.Address) {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@ package blobovnicza
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetPrm groups the parameters of Get operation.
|
// GetPrm groups the parameters of Get operation.
|
||||||
type GetPrm struct {
|
type GetPrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRes groups the resulting values of Get operation.
|
// GetRes groups the resulting values of Get operation.
|
||||||
|
@ -19,7 +19,7 @@ type GetRes struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAddress sets the address of the requested object.
|
// SetAddress sets the address of the requested object.
|
||||||
func (p *GetPrm) SetAddress(addr *addressSDK.Address) {
|
func (p *GetPrm) SetAddress(addr oid.Address) {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package blobovnicza
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func max(a, b uint64) uint64 {
|
||||||
|
|
||||||
// IterationElement represents a unit of elements through which Iterate operation passes.
|
// IterationElement represents a unit of elements through which Iterate operation passes.
|
||||||
type IterationElement struct {
|
type IterationElement struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
|
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func (x IterationElement) ObjectData() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address returns address of the stored object.
|
// Address returns address of the stored object.
|
||||||
func (x IterationElement) Address() *addressSDK.Address {
|
func (x IterationElement) Address() oid.Address {
|
||||||
return x.addr
|
return x.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,11 +124,7 @@ func (b *Blobovnicza) Iterate(prm IteratePrm) (*IterateRes, error) {
|
||||||
return tx.ForEach(func(name []byte, buck *bbolt.Bucket) error {
|
return tx.ForEach(func(name []byte, buck *bbolt.Bucket) error {
|
||||||
return buck.ForEach(func(k, v []byte) error {
|
return buck.ForEach(func(k, v []byte) error {
|
||||||
if prm.decodeAddresses {
|
if prm.decodeAddresses {
|
||||||
if elem.addr == nil {
|
if err := addressFromKey(&elem.addr, k); err != nil {
|
||||||
elem.addr = addressSDK.NewAddress()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := addressFromKey(elem.addr, k); err != nil {
|
|
||||||
if prm.ignoreErrors {
|
if prm.ignoreErrors {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -164,7 +160,7 @@ func IterateObjects(blz *Blobovnicza, f func([]byte) error) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// IterateAddresses is a helper function which iterates over Blobovnicza and passes addresses of the objects to f.
|
// IterateAddresses is a helper function which iterates over Blobovnicza and passes addresses of the objects to f.
|
||||||
func IterateAddresses(blz *Blobovnicza, f func(*addressSDK.Address) error) error {
|
func IterateAddresses(blz *Blobovnicza, f func(oid.Address) error) error {
|
||||||
var prm IteratePrm
|
var prm IteratePrm
|
||||||
|
|
||||||
prm.DecodeAddresses()
|
prm.DecodeAddresses()
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -18,7 +18,7 @@ func TestBlobovniczaIterate(t *testing.T) {
|
||||||
require.NoError(t, b.Init())
|
require.NoError(t, b.Init())
|
||||||
|
|
||||||
data := [][]byte{{0, 1, 2, 3}, {5, 6, 7, 8}}
|
data := [][]byte{{0, 1, 2, 3}, {5, 6, 7, 8}}
|
||||||
addr := objecttest.Address()
|
addr := oidtest.Address()
|
||||||
_, err := b.Put(&PutPrm{addr: addr, objData: data[0]})
|
_, err := b.Put(&PutPrm{addr: addr, objData: data[0]})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PutPrm groups the parameters of Put operation.
|
// PutPrm groups the parameters of Put operation.
|
||||||
type PutPrm struct {
|
type PutPrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
|
|
||||||
objData []byte
|
objData []byte
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,8 @@ type PutRes struct {
|
||||||
// object to a filled blobovnicza.
|
// object to a filled blobovnicza.
|
||||||
var ErrFull = errors.New("blobovnicza is full")
|
var ErrFull = errors.New("blobovnicza is full")
|
||||||
|
|
||||||
var errNilAddress = errors.New("object address is nil")
|
|
||||||
|
|
||||||
// SetAddress sets the address of the saving object.
|
// SetAddress sets the address of the saving object.
|
||||||
func (p *PutPrm) SetAddress(addr *addressSDK.Address) {
|
func (p *PutPrm) SetAddress(addr oid.Address) {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,14 +48,9 @@ func (p *PutPrm) SetMarshaledObject(data []byte) {
|
||||||
//
|
//
|
||||||
// Should not be called in read-only configuration.
|
// Should not be called in read-only configuration.
|
||||||
func (b *Blobovnicza) Put(prm *PutPrm) (*PutRes, error) {
|
func (b *Blobovnicza) Put(prm *PutPrm) (*PutRes, error) {
|
||||||
addr := prm.addr
|
|
||||||
if addr == nil {
|
|
||||||
return nil, errNilAddress
|
|
||||||
}
|
|
||||||
|
|
||||||
sz := uint64(len(prm.objData))
|
sz := uint64(len(prm.objData))
|
||||||
bucketName := bucketForSize(sz)
|
bucketName := bucketForSize(sz)
|
||||||
key := addressKey(addr)
|
key := addressKey(prm.addr)
|
||||||
|
|
||||||
err := b.boltDB.Batch(func(tx *bbolt.Tx) error {
|
err := b.boltDB.Batch(func(tx *bbolt.Tx) error {
|
||||||
if b.full() {
|
if b.full() {
|
||||||
|
@ -86,10 +79,10 @@ func (b *Blobovnicza) Put(prm *PutPrm) (*PutRes, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func addressKey(addr *addressSDK.Address) []byte {
|
func addressKey(addr oid.Address) []byte {
|
||||||
return []byte(addr.String())
|
return []byte(addr.EncodeToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
func addressFromKey(dst *addressSDK.Address, data []byte) error {
|
func addressFromKey(dst *oid.Address, data []byte) error {
|
||||||
return dst.Parse(string(data))
|
return dst.DecodeString(string(data))
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ func indexSlice(number uint64) []uint64 {
|
||||||
// save object in the maximum weight blobobnicza.
|
// save object in the maximum weight blobobnicza.
|
||||||
//
|
//
|
||||||
// returns error if could not save object in any blobovnicza.
|
// returns error if could not save object in any blobovnicza.
|
||||||
func (b *blobovniczas) put(addr *addressSDK.Address, data []byte) (*blobovnicza.ID, error) {
|
func (b *blobovniczas) put(addr oid.Address, data []byte) (*blobovnicza.ID, error) {
|
||||||
prm := new(blobovnicza.PutPrm)
|
prm := new(blobovnicza.PutPrm)
|
||||||
prm.SetAddress(addr)
|
prm.SetAddress(addr)
|
||||||
prm.SetMarshaledObject(data)
|
prm.SetMarshaledObject(data)
|
||||||
|
@ -220,7 +220,7 @@ func (b *blobovniczas) get(prm *GetSmallPrm) (res *GetSmallRes, err error) {
|
||||||
|
|
||||||
activeCache := make(map[string]struct{})
|
activeCache := make(map[string]struct{})
|
||||||
|
|
||||||
err = b.iterateSortedLeaves(prm.addr, func(p string) (bool, error) {
|
err = b.iterateSortedLeaves(&prm.addr, func(p string) (bool, error) {
|
||||||
dirPath := filepath.Dir(p)
|
dirPath := filepath.Dir(p)
|
||||||
|
|
||||||
_, ok := activeCache[dirPath]
|
_, ok := activeCache[dirPath]
|
||||||
|
@ -270,7 +270,7 @@ func (b *blobovniczas) delete(prm *DeleteSmallPrm) (res *DeleteSmallRes, err err
|
||||||
|
|
||||||
activeCache := make(map[string]struct{})
|
activeCache := make(map[string]struct{})
|
||||||
|
|
||||||
err = b.iterateSortedLeaves(prm.addr, func(p string) (bool, error) {
|
err = b.iterateSortedLeaves(&prm.addr, func(p string) (bool, error) {
|
||||||
dirPath := filepath.Dir(p)
|
dirPath := filepath.Dir(p)
|
||||||
|
|
||||||
// don't process active blobovnicza of the level twice
|
// don't process active blobovnicza of the level twice
|
||||||
|
@ -322,7 +322,7 @@ func (b *blobovniczas) getRange(prm *GetRangeSmallPrm) (res *GetRangeSmallRes, e
|
||||||
|
|
||||||
activeCache := make(map[string]struct{})
|
activeCache := make(map[string]struct{})
|
||||||
|
|
||||||
err = b.iterateSortedLeaves(prm.addr, func(p string) (bool, error) {
|
err = b.iterateSortedLeaves(&prm.addr, func(p string) (bool, error) {
|
||||||
dirPath := filepath.Dir(p)
|
dirPath := filepath.Dir(p)
|
||||||
|
|
||||||
_, ok := activeCache[dirPath]
|
_, ok := activeCache[dirPath]
|
||||||
|
@ -665,7 +665,7 @@ func (b *blobovniczas) iterateBlobovniczas(ignoreErrors bool, f func(string, *bl
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterator over the paths of blobovniczas sorted by weight.
|
// iterator over the paths of blobovniczas sorted by weight.
|
||||||
func (b *blobovniczas) iterateSortedLeaves(addr *addressSDK.Address, f func(string) (bool, error)) error {
|
func (b *blobovniczas) iterateSortedLeaves(addr *oid.Address, f func(string) (bool, error)) error {
|
||||||
_, err := b.iterateSorted(
|
_, err := b.iterateSorted(
|
||||||
addr,
|
addr,
|
||||||
make([]string, 0, b.blzShallowDepth),
|
make([]string, 0, b.blzShallowDepth),
|
||||||
|
@ -677,14 +677,14 @@ func (b *blobovniczas) iterateSortedLeaves(addr *addressSDK.Address, f func(stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterator over directories with blobovniczas sorted by weight.
|
// iterator over directories with blobovniczas sorted by weight.
|
||||||
func (b *blobovniczas) iterateDeepest(addr *addressSDK.Address, f func(string) (bool, error)) error {
|
func (b *blobovniczas) iterateDeepest(addr oid.Address, f func(string) (bool, error)) error {
|
||||||
depth := b.blzShallowDepth
|
depth := b.blzShallowDepth
|
||||||
if depth > 0 {
|
if depth > 0 {
|
||||||
depth--
|
depth--
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := b.iterateSorted(
|
_, err := b.iterateSorted(
|
||||||
addr,
|
&addr,
|
||||||
make([]string, 0, depth),
|
make([]string, 0, depth),
|
||||||
depth,
|
depth,
|
||||||
func(p []string) (bool, error) { return f(filepath.Join(p...)) },
|
func(p []string) (bool, error) { return f(filepath.Join(p...)) },
|
||||||
|
@ -694,7 +694,7 @@ func (b *blobovniczas) iterateDeepest(addr *addressSDK.Address, f func(string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterator over particular level of directories.
|
// iterator over particular level of directories.
|
||||||
func (b *blobovniczas) iterateSorted(addr *addressSDK.Address, curPath []string, execDepth uint64, f func([]string) (bool, error)) (bool, error) {
|
func (b *blobovniczas) iterateSorted(addr *oid.Address, curPath []string, execDepth uint64, f func([]string) (bool, error)) (bool, error) {
|
||||||
indices := indexSlice(b.blzShallowWidth)
|
indices := indexSlice(b.blzShallowWidth)
|
||||||
|
|
||||||
hrw.SortSliceByValue(indices, addressHash(addr, filepath.Join(curPath...)))
|
hrw.SortSliceByValue(indices, addressHash(addr, filepath.Join(curPath...)))
|
||||||
|
@ -934,11 +934,11 @@ func (b *blobovniczas) openBlobovnicza(p string) (*blobovnicza.Blobovnicza, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns hash of the object address.
|
// returns hash of the object address.
|
||||||
func addressHash(addr *addressSDK.Address, path string) uint64 {
|
func addressHash(addr *oid.Address, path string) uint64 {
|
||||||
var a string
|
var a string
|
||||||
|
|
||||||
if addr != nil {
|
if addr != nil {
|
||||||
a = addr.String()
|
a = addr.EncodeToString()
|
||||||
}
|
}
|
||||||
|
|
||||||
return hrw.Hash([]byte(a + path))
|
return hrw.Hash([]byte(a + path))
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -63,7 +63,7 @@ func TestBlobovniczas(t *testing.T) {
|
||||||
|
|
||||||
objSz := uint64(szLim / 2)
|
objSz := uint64(szLim / 2)
|
||||||
|
|
||||||
addrList := make([]*addressSDK.Address, 0)
|
addrList := make([]oid.Address, 0)
|
||||||
minFitObjNum := width * depth * szLim / objSz
|
minFitObjNum := width * depth * szLim / objSz
|
||||||
|
|
||||||
for i := uint64(0); i < minFitObjNum; i++ {
|
for i := uint64(0); i < minFitObjNum; i++ {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func (b *BlobStor) Exists(prm *ExistsPrm) (*ExistsRes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if object is presented in shallow dir.
|
// checks if object is presented in shallow dir.
|
||||||
func (b *BlobStor) existsBig(addr *addressSDK.Address) (bool, error) {
|
func (b *BlobStor) existsBig(addr oid.Address) (bool, error) {
|
||||||
_, err := b.fsTree.Exists(addr)
|
_, err := b.fsTree.Exists(addr)
|
||||||
if errors.Is(err, fstree.ErrFileNotFound) {
|
if errors.Is(err, fstree.ErrFileNotFound) {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -74,18 +74,18 @@ func (b *BlobStor) existsBig(addr *addressSDK.Address) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// existsSmall checks if object is presented in blobovnicza.
|
// existsSmall checks if object is presented in blobovnicza.
|
||||||
func (b *BlobStor) existsSmall(addr *addressSDK.Address) (bool, error) {
|
func (b *BlobStor) existsSmall(addr oid.Address) (bool, error) {
|
||||||
return b.blobovniczas.existsSmall(addr)
|
return b.blobovniczas.existsSmall(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *blobovniczas) existsSmall(addr *addressSDK.Address) (bool, error) {
|
func (b *blobovniczas) existsSmall(addr oid.Address) (bool, error) {
|
||||||
activeCache := make(map[string]struct{})
|
activeCache := make(map[string]struct{})
|
||||||
|
|
||||||
prm := new(blobovnicza.GetPrm)
|
prm := new(blobovnicza.GetPrm)
|
||||||
prm.SetAddress(addr)
|
prm.SetAddress(addr)
|
||||||
|
|
||||||
var found bool
|
var found bool
|
||||||
err := b.iterateSortedLeaves(addr, func(p string) (bool, error) {
|
err := b.iterateSortedLeaves(&addr, func(p string) (bool, error) {
|
||||||
dirPath := filepath.Dir(p)
|
dirPath := filepath.Dir(p)
|
||||||
|
|
||||||
_, ok := activeCache[dirPath]
|
_, ok := activeCache[dirPath]
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
objectCore "github.com/nspcc-dev/neofs-node/pkg/core/object"
|
objectCore "github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func TestExists(t *testing.T) {
|
||||||
require.True(t, res.Exists())
|
require.True(t, res.Exists())
|
||||||
}
|
}
|
||||||
|
|
||||||
prm.SetAddress(objecttest.Address())
|
prm.SetAddress(oidtest.Address())
|
||||||
res, err := b.Exists(prm)
|
res, err := b.Exists(prm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, res.Exists())
|
require.False(t, res.Exists())
|
||||||
|
|
|
@ -11,8 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util"
|
"github.com/nspcc-dev/neofs-node/pkg/util"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FSTree represents an object storage as a filesystem tree.
|
// FSTree represents an object storage as a filesystem tree.
|
||||||
|
@ -42,44 +41,41 @@ const (
|
||||||
// ErrFileNotFound is returned when file is missing.
|
// ErrFileNotFound is returned when file is missing.
|
||||||
var ErrFileNotFound = errors.New("file not found")
|
var ErrFileNotFound = errors.New("file not found")
|
||||||
|
|
||||||
func stringifyAddress(addr *addressSDK.Address) string {
|
func stringifyAddress(addr oid.Address) string {
|
||||||
id, _ := addr.ObjectID()
|
return addr.Object().EncodeToString() + "." + addr.Container().EncodeToString()
|
||||||
cnr, _ := addr.ContainerID()
|
|
||||||
|
|
||||||
return id.EncodeToString() + "." + cnr.EncodeToString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addressFromString(s string) (*addressSDK.Address, error) {
|
func addressFromString(s string) (*oid.Address, error) {
|
||||||
ss := strings.SplitN(s, ".", 2)
|
ss := strings.SplitN(s, ".", 2)
|
||||||
if len(ss) != 2 {
|
if len(ss) != 2 {
|
||||||
return nil, errors.New("invalid address")
|
return nil, errors.New("invalid address")
|
||||||
}
|
}
|
||||||
|
|
||||||
var oid oidSDK.ID
|
var obj oid.ID
|
||||||
if err := oid.DecodeString(ss[0]); err != nil {
|
if err := obj.DecodeString(ss[0]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var id cid.ID
|
var cnr cid.ID
|
||||||
if err := id.DecodeString(ss[1]); err != nil {
|
if err := cnr.DecodeString(ss[1]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := addressSDK.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetObjectID(oid)
|
addr.SetObject(obj)
|
||||||
addr.SetContainerID(id)
|
addr.SetContainer(cnr)
|
||||||
|
|
||||||
return addr, nil
|
return &addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IterationPrm contains iteraction parameters.
|
// IterationPrm contains iteraction parameters.
|
||||||
type IterationPrm struct {
|
type IterationPrm struct {
|
||||||
handler func(addr *addressSDK.Address, data []byte) error
|
handler func(addr oid.Address, data []byte) error
|
||||||
ignoreErrors bool
|
ignoreErrors bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithHandler sets a function to call on each object.
|
// WithHandler sets a function to call on each object.
|
||||||
func (p *IterationPrm) WithHandler(f func(addr *addressSDK.Address, data []byte) error) *IterationPrm {
|
func (p *IterationPrm) WithHandler(f func(addr oid.Address, data []byte) error) *IterationPrm {
|
||||||
p.handler = f
|
p.handler = f
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
@ -138,7 +134,7 @@ func (t *FSTree) iterate(depth int, curPath []string, prm *IterationPrm) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := prm.handler(addr, data); err != nil {
|
if err := prm.handler(*addr, data); err != nil {
|
||||||
// Error occurred in handler, outside of our scope, needs to be reported.
|
// Error occurred in handler, outside of our scope, needs to be reported.
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -147,7 +143,7 @@ func (t *FSTree) iterate(depth int, curPath []string, prm *IterationPrm) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *FSTree) treePath(addr *addressSDK.Address) string {
|
func (t *FSTree) treePath(addr oid.Address) string {
|
||||||
sAddr := stringifyAddress(addr)
|
sAddr := stringifyAddress(addr)
|
||||||
|
|
||||||
dirs := make([]string, 0, t.Depth+1+1) // 1 for root, 1 for file
|
dirs := make([]string, 0, t.Depth+1+1) // 1 for root, 1 for file
|
||||||
|
@ -164,7 +160,7 @@ func (t *FSTree) treePath(addr *addressSDK.Address) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes the object with the specified address from the storage.
|
// Delete removes the object with the specified address from the storage.
|
||||||
func (t *FSTree) Delete(addr *addressSDK.Address) error {
|
func (t *FSTree) Delete(addr oid.Address) error {
|
||||||
p, err := t.Exists(addr)
|
p, err := t.Exists(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -175,7 +171,7 @@ func (t *FSTree) Delete(addr *addressSDK.Address) error {
|
||||||
|
|
||||||
// Exists returns the path to the file with object contents if it exists in the storage
|
// Exists returns the path to the file with object contents if it exists in the storage
|
||||||
// and an error otherwise.
|
// and an error otherwise.
|
||||||
func (t *FSTree) Exists(addr *addressSDK.Address) (string, error) {
|
func (t *FSTree) Exists(addr oid.Address) (string, error) {
|
||||||
p := t.treePath(addr)
|
p := t.treePath(addr)
|
||||||
|
|
||||||
_, err := os.Stat(p)
|
_, err := os.Stat(p)
|
||||||
|
@ -187,7 +183,7 @@ func (t *FSTree) Exists(addr *addressSDK.Address) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put puts an object in the storage.
|
// Put puts an object in the storage.
|
||||||
func (t *FSTree) Put(addr *addressSDK.Address, data []byte) error {
|
func (t *FSTree) Put(addr oid.Address, data []byte) error {
|
||||||
p := t.treePath(addr)
|
p := t.treePath(addr)
|
||||||
|
|
||||||
if err := util.MkdirAllX(filepath.Dir(p), t.Permissions); err != nil {
|
if err := util.MkdirAllX(filepath.Dir(p), t.Permissions); err != nil {
|
||||||
|
@ -198,7 +194,7 @@ func (t *FSTree) Put(addr *addressSDK.Address, data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutStream puts executes handler on a file opened for write.
|
// PutStream puts executes handler on a file opened for write.
|
||||||
func (t *FSTree) PutStream(addr *addressSDK.Address, handler func(*os.File) error) error {
|
func (t *FSTree) PutStream(addr oid.Address, handler func(*os.File) error) error {
|
||||||
p := t.treePath(addr)
|
p := t.treePath(addr)
|
||||||
|
|
||||||
if err := util.MkdirAllX(filepath.Dir(p), t.Permissions); err != nil {
|
if err := util.MkdirAllX(filepath.Dir(p), t.Permissions); err != nil {
|
||||||
|
@ -215,7 +211,7 @@ func (t *FSTree) PutStream(addr *addressSDK.Address, handler func(*os.File) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns an object from the storage by address.
|
// Get returns an object from the storage by address.
|
||||||
func (t *FSTree) Get(addr *addressSDK.Address) ([]byte, error) {
|
func (t *FSTree) Get(addr oid.Address) ([]byte, error) {
|
||||||
p := t.treePath(addr)
|
p := t.treePath(addr)
|
||||||
|
|
||||||
if _, err := os.Stat(p); os.IsNotExist(err) {
|
if _, err := os.Stat(p); os.IsNotExist(err) {
|
||||||
|
|
|
@ -8,17 +8,17 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util"
|
"github.com/nspcc-dev/neofs-node/pkg/util"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAddressToString(t *testing.T) {
|
func TestAddressToString(t *testing.T) {
|
||||||
addr := objecttest.Address()
|
addr := oidtest.Address()
|
||||||
s := stringifyAddress(addr)
|
s := stringifyAddress(addr)
|
||||||
actual, err := addressFromString(s)
|
actual, err := addressFromString(s)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, addr, actual)
|
require.Equal(t, addr, *actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFSTree(t *testing.T) {
|
func TestFSTree(t *testing.T) {
|
||||||
|
@ -36,28 +36,28 @@ func TestFSTree(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const count = 3
|
const count = 3
|
||||||
var addrs []*addressSDK.Address
|
var addrs []oid.Address
|
||||||
|
|
||||||
store := map[string][]byte{}
|
store := map[string][]byte{}
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
a := objecttest.Address()
|
a := oidtest.Address()
|
||||||
addrs = append(addrs, a)
|
addrs = append(addrs, a)
|
||||||
|
|
||||||
data := make([]byte, 10)
|
data := make([]byte, 10)
|
||||||
_, _ = rand.Read(data[:])
|
_, _ = rand.Read(data[:])
|
||||||
require.NoError(t, fs.Put(a, data))
|
require.NoError(t, fs.Put(a, data))
|
||||||
store[a.String()] = data
|
store[a.EncodeToString()] = data
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("get", func(t *testing.T) {
|
t.Run("get", func(t *testing.T) {
|
||||||
for _, a := range addrs {
|
for _, a := range addrs {
|
||||||
actual, err := fs.Get(a)
|
actual, err := fs.Get(a)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, store[a.String()], actual)
|
require.Equal(t, store[a.EncodeToString()], actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := fs.Get(objecttest.Address())
|
_, err := fs.Get(oidtest.Address())
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -67,16 +67,16 @@ func TestFSTree(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := fs.Exists(objecttest.Address())
|
_, err := fs.Exists(oidtest.Address())
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("iterate", func(t *testing.T) {
|
t.Run("iterate", func(t *testing.T) {
|
||||||
n := 0
|
n := 0
|
||||||
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr *addressSDK.Address, data []byte) error {
|
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr oid.Address, data []byte) error {
|
||||||
n++
|
n++
|
||||||
expected, ok := store[addr.String()]
|
expected, ok := store[addr.EncodeToString()]
|
||||||
require.True(t, ok, "object %s was not found", addr.String())
|
require.True(t, ok, "object %s was not found", addr.EncodeToString())
|
||||||
require.Equal(t, data, expected)
|
require.Equal(t, data, expected)
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
@ -87,7 +87,7 @@ func TestFSTree(t *testing.T) {
|
||||||
t.Run("leave early", func(t *testing.T) {
|
t.Run("leave early", func(t *testing.T) {
|
||||||
n := 0
|
n := 0
|
||||||
errStop := errors.New("stop")
|
errStop := errors.New("stop")
|
||||||
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr *addressSDK.Address, data []byte) error {
|
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr oid.Address, data []byte) error {
|
||||||
if n++; n == count-1 {
|
if n++; n == count-1 {
|
||||||
return errStop
|
return errStop
|
||||||
}
|
}
|
||||||
|
@ -105,16 +105,16 @@ func TestFSTree(t *testing.T) {
|
||||||
require.NoError(t, os.Mkdir(filepath.Join(fs.RootPath, "ZZ"), 0))
|
require.NoError(t, os.Mkdir(filepath.Join(fs.RootPath, "ZZ"), 0))
|
||||||
|
|
||||||
// Unreadable file.
|
// Unreadable file.
|
||||||
p := fs.treePath(objecttest.Address())
|
p := fs.treePath(oidtest.Address())
|
||||||
require.NoError(t, util.MkdirAllX(filepath.Dir(p), fs.Permissions))
|
require.NoError(t, util.MkdirAllX(filepath.Dir(p), fs.Permissions))
|
||||||
require.NoError(t, os.WriteFile(p, []byte{1, 2, 3}, 0))
|
require.NoError(t, os.WriteFile(p, []byte{1, 2, 3}, 0))
|
||||||
|
|
||||||
// Invalid address.
|
// Invalid address.
|
||||||
p = fs.treePath(objecttest.Address()) + ".invalid"
|
p = fs.treePath(oidtest.Address()) + ".invalid"
|
||||||
require.NoError(t, util.MkdirAllX(filepath.Dir(p), fs.Permissions))
|
require.NoError(t, util.MkdirAllX(filepath.Dir(p), fs.Permissions))
|
||||||
require.NoError(t, os.WriteFile(p, []byte{1, 2, 3}, fs.Permissions))
|
require.NoError(t, os.WriteFile(p, []byte{1, 2, 3}, fs.Permissions))
|
||||||
|
|
||||||
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr *addressSDK.Address, data []byte) error {
|
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr oid.Address, data []byte) error {
|
||||||
n++
|
n++
|
||||||
return nil
|
return nil
|
||||||
}).WithIgnoreErrors(true))
|
}).WithIgnoreErrors(true))
|
||||||
|
@ -124,7 +124,7 @@ func TestFSTree(t *testing.T) {
|
||||||
t.Run("error from handler is returned", func(t *testing.T) {
|
t.Run("error from handler is returned", func(t *testing.T) {
|
||||||
expectedErr := errors.New("expected error")
|
expectedErr := errors.New("expected error")
|
||||||
n := 0
|
n := 0
|
||||||
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr *addressSDK.Address, data []byte) error {
|
err := fs.Iterate(new(IterationPrm).WithHandler(func(addr oid.Address, data []byte) error {
|
||||||
n++
|
n++
|
||||||
if n == count/2 { // process some iterations
|
if n == count/2 { // process some iterations
|
||||||
return expectedErr
|
return expectedErr
|
||||||
|
@ -146,6 +146,6 @@ func TestFSTree(t *testing.T) {
|
||||||
_, err = fs.Exists(addrs[1])
|
_, err = fs.Exists(addrs[1])
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Error(t, fs.Delete(objecttest.Address()))
|
require.Error(t, fs.Delete(oidtest.Address()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IterationElement represents a unit of elements through which Iterate operation passes.
|
// IterationElement represents a unit of elements through which Iterate operation passes.
|
||||||
|
@ -88,7 +88,7 @@ func (b *BlobStor) Iterate(prm IteratePrm) (*IterateRes, error) {
|
||||||
|
|
||||||
elem.blzID = nil
|
elem.blzID = nil
|
||||||
|
|
||||||
err = b.fsTree.Iterate(new(fstree.IterationPrm).WithHandler(func(_ *addressSDK.Address, data []byte) error {
|
err = b.fsTree.Iterate(new(fstree.IterationPrm).WithHandler(func(_ oid.Address, data []byte) error {
|
||||||
// decompress the data
|
// decompress the data
|
||||||
elem.data, err = b.decompressor(data)
|
elem.data, err = b.decompressor(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"github.com/klauspost/compress/zstd"
|
"github.com/klauspost/compress/zstd"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func TestIterateObjects(t *testing.T) {
|
||||||
|
|
||||||
type addrData struct {
|
type addrData struct {
|
||||||
big bool
|
big bool
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ func TestIterateObjects(t *testing.T) {
|
||||||
data := make([]byte, sz)
|
data := make([]byte, sz)
|
||||||
binary.BigEndian.PutUint64(data, i)
|
binary.BigEndian.PutUint64(data, i)
|
||||||
|
|
||||||
addr := objecttest.Address()
|
addr := oidtest.Address()
|
||||||
|
|
||||||
mObjs[string(data)] = addrData{
|
mObjs[string(data)] = addrData{
|
||||||
big: big,
|
big: big,
|
||||||
|
@ -114,15 +114,13 @@ func TestIterate_IgnoreErrors(t *testing.T) {
|
||||||
require.NoError(t, bs.Open())
|
require.NoError(t, bs.Open())
|
||||||
require.NoError(t, bs.Init())
|
require.NoError(t, bs.Init())
|
||||||
|
|
||||||
addrs := make([]*addressSDK.Address, objCount)
|
addrs := make([]oid.Address, objCount)
|
||||||
for i := range addrs {
|
for i := range addrs {
|
||||||
addrs[i] = objecttest.Address()
|
addrs[i] = oidtest.Address()
|
||||||
id, _ := addrs[i].ObjectID()
|
|
||||||
cnr, _ := addrs[i].ContainerID()
|
|
||||||
|
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
obj.SetContainerID(cnr)
|
obj.SetContainerID(addrs[i].Container())
|
||||||
obj.SetID(id)
|
obj.SetID(addrs[i].Object())
|
||||||
obj.SetPayload(make([]byte, smallSize<<(i%2)))
|
obj.SetPayload(make([]byte, smallSize<<(i%2)))
|
||||||
|
|
||||||
objData, err := obj.Marshal()
|
objData, err := obj.Marshal()
|
||||||
|
@ -142,9 +140,9 @@ func TestIterate_IgnoreErrors(t *testing.T) {
|
||||||
rawData[i] ^= 0xFF
|
rawData[i] ^= 0xFF
|
||||||
}
|
}
|
||||||
// Will be put uncompressed but fetched as compressed because of magic.
|
// Will be put uncompressed but fetched as compressed because of magic.
|
||||||
_, err = bs.PutRaw(objecttest.Address(), rawData, false)
|
_, err = bs.PutRaw(oidtest.Address(), rawData, false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, bs.fsTree.Put(objecttest.Address(), rawData))
|
require.NoError(t, bs.fsTree.Put(oidtest.Address(), rawData))
|
||||||
|
|
||||||
require.NoError(t, bs.Close())
|
require.NoError(t, bs.Close())
|
||||||
|
|
||||||
|
@ -178,7 +176,7 @@ func TestIterate_IgnoreErrors(t *testing.T) {
|
||||||
prm.IgnoreErrors()
|
prm.IgnoreErrors()
|
||||||
|
|
||||||
t.Run("skip invalid objects", func(t *testing.T) {
|
t.Run("skip invalid objects", func(t *testing.T) {
|
||||||
actual := make([]*addressSDK.Address, 0, len(addrs))
|
actual := make([]oid.Address, 0, len(addrs))
|
||||||
prm.SetIterationHandler(func(e IterationElement) error {
|
prm.SetIterationHandler(func(e IterationElement) error {
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
err := obj.Unmarshal(e.data)
|
err := obj.Unmarshal(e.data)
|
||||||
|
@ -186,11 +184,11 @@ func TestIterate_IgnoreErrors(t *testing.T) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := addressSDK.NewAddress()
|
var addr oid.Address
|
||||||
cnr, _ := obj.ContainerID()
|
cnr, _ := obj.ContainerID()
|
||||||
addr.SetContainerID(cnr)
|
addr.SetContainer(cnr)
|
||||||
id, _ := obj.ID()
|
id, _ := obj.ID()
|
||||||
addr.SetObjectID(id)
|
addr.SetObject(id)
|
||||||
actual = append(actual, addr)
|
actual = append(actual, addr)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PutPrm groups the parameters of Put operation.
|
// PutPrm groups the parameters of Put operation.
|
||||||
|
@ -72,7 +72,7 @@ func (b *BlobStor) NeedsCompression(obj *objectSDK.Object) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutRaw saves an already marshaled object in BLOB storage.
|
// PutRaw saves an already marshaled object in BLOB storage.
|
||||||
func (b *BlobStor) PutRaw(addr *addressSDK.Address, data []byte, compress bool) (*PutRes, error) {
|
func (b *BlobStor) PutRaw(addr oid.Address, data []byte, compress bool) (*PutRes, error) {
|
||||||
big := b.isBig(data)
|
big := b.isBig(data)
|
||||||
|
|
||||||
if big {
|
if big {
|
||||||
|
|
|
@ -3,15 +3,15 @@ package blobstor
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type address struct {
|
type address struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAddress sets the address of the requested object.
|
// SetAddress sets the address of the requested object.
|
||||||
func (a *address) SetAddress(addr *addressSDK.Address) {
|
func (a *address) SetAddress(addr oid.Address) {
|
||||||
a.addr = addr
|
a.addr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
// ContainerSizePrm groups parameters of ContainerSize operation.
|
// ContainerSizePrm groups parameters of ContainerSize operation.
|
||||||
type ContainerSizePrm struct {
|
type ContainerSizePrm struct {
|
||||||
cid *cid.ID
|
cnr cid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerSizeRes resulting values of ContainerSize operation.
|
// ContainerSizeRes resulting values of ContainerSize operation.
|
||||||
|
@ -21,12 +21,12 @@ type ListContainersPrm struct{}
|
||||||
|
|
||||||
// ListContainersRes groups the resulting values of ListContainers operation.
|
// ListContainersRes groups the resulting values of ListContainers operation.
|
||||||
type ListContainersRes struct {
|
type ListContainersRes struct {
|
||||||
containers []*cid.ID
|
containers []cid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContainerID sets the identifier of the container to estimate the size.
|
// SetContainerID sets the identifier of the container to estimate the size.
|
||||||
func (p *ContainerSizePrm) SetContainerID(cid *cid.ID) {
|
func (p *ContainerSizePrm) SetContainerID(cnr cid.ID) {
|
||||||
p.cid = cid
|
p.cnr = cnr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns calculated estimation of the container size.
|
// Size returns calculated estimation of the container size.
|
||||||
|
@ -35,7 +35,7 @@ func (r ContainerSizeRes) Size() uint64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Containers returns a list of identifiers of the containers in which local objects are stored.
|
// Containers returns a list of identifiers of the containers in which local objects are stored.
|
||||||
func (r ListContainersRes) Containers() []*cid.ID {
|
func (r ListContainersRes) Containers() []cid.ID {
|
||||||
return r.containers
|
return r.containers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func (e *StorageEngine) ContainerSize(prm ContainerSizePrm) (res *ContainerSizeR
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerSize calls ContainerSize method on engine to calculate sum of estimation container sizes among all shards.
|
// ContainerSize calls ContainerSize method on engine to calculate sum of estimation container sizes among all shards.
|
||||||
func ContainerSize(e *StorageEngine, id *cid.ID) (uint64, error) {
|
func ContainerSize(e *StorageEngine, id cid.ID) (uint64, error) {
|
||||||
var prm ContainerSizePrm
|
var prm ContainerSizePrm
|
||||||
|
|
||||||
prm.SetContainerID(id)
|
prm.SetContainerID(id)
|
||||||
|
@ -73,10 +73,11 @@ func (e *StorageEngine) containerSize(prm ContainerSizePrm) (*ContainerSizeRes,
|
||||||
var res ContainerSizeRes
|
var res ContainerSizeRes
|
||||||
|
|
||||||
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
||||||
size, err := shard.ContainerSize(sh.Shard, prm.cid)
|
size, err := shard.ContainerSize(sh.Shard, prm.cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.reportShardError(sh, "can't get container size", err,
|
e.reportShardError(sh, "can't get container size", err,
|
||||||
zap.Stringer("container_id", prm.cid))
|
zap.Stringer("container_id", prm.cnr),
|
||||||
|
)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ func (e *StorageEngine) ListContainers(_ ListContainersPrm) (res *ListContainers
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListContainers calls ListContainers method on engine to get a unique container IDs presented in the engine objects.
|
// ListContainers calls ListContainers method on engine to get a unique container IDs presented in the engine objects.
|
||||||
func ListContainers(e *StorageEngine) ([]*cid.ID, error) {
|
func ListContainers(e *StorageEngine) ([]cid.ID, error) {
|
||||||
var prm ListContainersPrm
|
var prm ListContainersPrm
|
||||||
|
|
||||||
res, err := e.ListContainers(prm)
|
res, err := e.ListContainers(prm)
|
||||||
|
@ -117,7 +118,7 @@ func (e *StorageEngine) listContainers() (*ListContainersRes, error) {
|
||||||
defer elapsed(e.metrics.AddListContainersDuration)()
|
defer elapsed(e.metrics.AddListContainersDuration)()
|
||||||
}
|
}
|
||||||
|
|
||||||
uniqueIDs := make(map[string]*cid.ID)
|
uniqueIDs := make(map[string]cid.ID)
|
||||||
|
|
||||||
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
||||||
cnrs, err := shard.ListContainers(sh.Shard)
|
cnrs, err := shard.ListContainers(sh.Shard)
|
||||||
|
@ -127,7 +128,7 @@ func (e *StorageEngine) listContainers() (*ListContainersRes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range cnrs {
|
for i := range cnrs {
|
||||||
id := cnrs[i].String()
|
id := cnrs[i].EncodeToString()
|
||||||
if _, ok := uniqueIDs[id]; !ok {
|
if _, ok := uniqueIDs[id]; !ok {
|
||||||
uniqueIDs[id] = cnrs[i]
|
uniqueIDs[id] = cnrs[i]
|
||||||
}
|
}
|
||||||
|
@ -136,7 +137,7 @@ func (e *StorageEngine) listContainers() (*ListContainersRes, error) {
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
result := make([]*cid.ID, 0, len(uniqueIDs))
|
result := make([]cid.ID, 0, len(uniqueIDs))
|
||||||
for _, v := range uniqueIDs {
|
for _, v := range uniqueIDs {
|
||||||
result = append(result, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeletePrm groups the parameters of Delete operation.
|
// DeletePrm groups the parameters of Delete operation.
|
||||||
type DeletePrm struct {
|
type DeletePrm struct {
|
||||||
addr []*addressSDK.Address
|
addr []oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRes groups the resulting values of Delete operation.
|
// DeleteRes groups the resulting values of Delete operation.
|
||||||
|
@ -19,7 +19,7 @@ type DeleteRes struct{}
|
||||||
// WithAddresses is a Delete option to set the addresses of the objects to delete.
|
// WithAddresses is a Delete option to set the addresses of the objects to delete.
|
||||||
//
|
//
|
||||||
// Option is required.
|
// Option is required.
|
||||||
func (p *DeletePrm) WithAddresses(addr ...*addressSDK.Address) *DeletePrm {
|
func (p *DeletePrm) WithAddresses(addr ...oid.Address) *DeletePrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = append(p.addr, addr...)
|
p.addr = append(p.addr, addr...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/version"
|
"github.com/nspcc-dev/neofs-sdk-go/version"
|
||||||
|
@ -49,7 +48,7 @@ func benchmarkExists(b *testing.B, shardNum int) {
|
||||||
_ = os.RemoveAll(b.Name())
|
_ = os.RemoveAll(b.Name())
|
||||||
})
|
})
|
||||||
|
|
||||||
addr := objecttest.Address()
|
addr := oidtest.Address()
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
obj := generateObjectWithCID(b, cidtest.ID())
|
obj := generateObjectWithCID(b, cidtest.ID())
|
||||||
err := Put(e, obj)
|
err := Put(e, obj)
|
||||||
|
|
|
@ -3,10 +3,10 @@ package engine
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *StorageEngine) exists(addr *addressSDK.Address) (bool, error) {
|
func (e *StorageEngine) exists(addr oid.Address) (bool, error) {
|
||||||
shPrm := new(shard.ExistsPrm).WithAddress(addr)
|
shPrm := new(shard.ExistsPrm).WithAddress(addr)
|
||||||
alreadyRemoved := false
|
alreadyRemoved := false
|
||||||
exists := false
|
exists := false
|
||||||
|
|
|
@ -7,13 +7,13 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetPrm groups the parameters of Get operation.
|
// GetPrm groups the parameters of Get operation.
|
||||||
type GetPrm struct {
|
type GetPrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRes groups the resulting values of Get operation.
|
// GetRes groups the resulting values of Get operation.
|
||||||
|
@ -24,7 +24,7 @@ type GetRes struct {
|
||||||
// WithAddress is a Get option to set the address of the requested object.
|
// WithAddress is a Get option to set the address of the requested object.
|
||||||
//
|
//
|
||||||
// Option is required.
|
// Option is required.
|
||||||
func (p *GetPrm) WithAddress(addr *addressSDK.Address) *GetPrm {
|
func (p *GetPrm) WithAddress(addr oid.Address) *GetPrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ func (e *StorageEngine) get(prm *GetPrm) (*GetRes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reads object from local storage by provided address.
|
// Get reads object from local storage by provided address.
|
||||||
func Get(storage *StorageEngine, addr *addressSDK.Address) (*objectSDK.Object, error) {
|
func Get(storage *StorageEngine, addr oid.Address) (*objectSDK.Object, error) {
|
||||||
res, err := storage.Get(new(GetPrm).
|
res, err := storage.Get(new(GetPrm).
|
||||||
WithAddress(addr),
|
WithAddress(addr),
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,12 +7,12 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HeadPrm groups the parameters of Head operation.
|
// HeadPrm groups the parameters of Head operation.
|
||||||
type HeadPrm struct {
|
type HeadPrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
raw bool
|
raw bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ type HeadRes struct {
|
||||||
// WithAddress is a Head option to set the address of the requested object.
|
// WithAddress is a Head option to set the address of the requested object.
|
||||||
//
|
//
|
||||||
// Option is required.
|
// Option is required.
|
||||||
func (p *HeadPrm) WithAddress(addr *addressSDK.Address) *HeadPrm {
|
func (p *HeadPrm) WithAddress(addr oid.Address) *HeadPrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ func (e *StorageEngine) head(prm *HeadPrm) (*HeadRes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head reads object header from local storage by provided address.
|
// Head reads object header from local storage by provided address.
|
||||||
func Head(storage *StorageEngine, addr *addressSDK.Address) (*objectSDK.Object, error) {
|
func Head(storage *StorageEngine, addr oid.Address) (*objectSDK.Object, error) {
|
||||||
res, err := storage.Head(new(HeadPrm).
|
res, err := storage.Head(new(HeadPrm).
|
||||||
WithAddress(addr),
|
WithAddress(addr),
|
||||||
)
|
)
|
||||||
|
@ -153,7 +153,7 @@ func Head(storage *StorageEngine, addr *addressSDK.Address) (*objectSDK.Object,
|
||||||
|
|
||||||
// HeadRaw reads object header from local storage by provided address and raw
|
// HeadRaw reads object header from local storage by provided address and raw
|
||||||
// flag.
|
// flag.
|
||||||
func HeadRaw(storage *StorageEngine, addr *addressSDK.Address, raw bool) (*objectSDK.Object, error) {
|
func HeadRaw(storage *StorageEngine, addr oid.Address, raw bool) (*objectSDK.Object, error) {
|
||||||
res, err := storage.Head(new(HeadPrm).
|
res, err := storage.Head(new(HeadPrm).
|
||||||
WithAddress(addr).
|
WithAddress(addr).
|
||||||
WithRaw(raw),
|
WithRaw(raw),
|
||||||
|
|
|
@ -7,31 +7,31 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHeadRaw(t *testing.T) {
|
func TestHeadRaw(t *testing.T) {
|
||||||
defer os.RemoveAll(t.Name())
|
defer os.RemoveAll(t.Name())
|
||||||
|
|
||||||
cid := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
splitID := object.NewSplitID()
|
splitID := object.NewSplitID()
|
||||||
|
|
||||||
parent := generateObjectWithCID(t, cid)
|
parent := generateObjectWithCID(t, cnr)
|
||||||
addAttribute(parent, "foo", "bar")
|
addAttribute(parent, "foo", "bar")
|
||||||
|
|
||||||
parentAddr := addressSDK.NewAddress()
|
var parentAddr oid.Address
|
||||||
parentAddr.SetContainerID(cid)
|
parentAddr.SetContainer(cnr)
|
||||||
|
|
||||||
idParent, _ := parent.ID()
|
idParent, _ := parent.ID()
|
||||||
parentAddr.SetObjectID(idParent)
|
parentAddr.SetObject(idParent)
|
||||||
|
|
||||||
child := generateObjectWithCID(t, cid)
|
child := generateObjectWithCID(t, cnr)
|
||||||
child.SetParent(parent)
|
child.SetParent(parent)
|
||||||
child.SetParentID(idParent)
|
child.SetParentID(idParent)
|
||||||
child.SetSplitID(splitID)
|
child.SetSplitID(splitID)
|
||||||
|
|
||||||
link := generateObjectWithCID(t, cid)
|
link := generateObjectWithCID(t, cnr)
|
||||||
link.SetParent(parent)
|
link.SetParent(parent)
|
||||||
link.SetParentID(idParent)
|
link.SetParentID(idParent)
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,13 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InhumePrm encapsulates parameters for inhume operation.
|
// InhumePrm encapsulates parameters for inhume operation.
|
||||||
type InhumePrm struct {
|
type InhumePrm struct {
|
||||||
tombstone *addressSDK.Address
|
tombstone *oid.Address
|
||||||
addrs []*addressSDK.Address
|
addrs []oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// InhumeRes encapsulates results of inhume operation.
|
// InhumeRes encapsulates results of inhume operation.
|
||||||
|
@ -25,10 +25,10 @@ type InhumeRes struct{}
|
||||||
//
|
//
|
||||||
// tombstone should not be nil, addr should not be empty.
|
// tombstone should not be nil, addr should not be empty.
|
||||||
// Should not be called along with MarkAsGarbage.
|
// Should not be called along with MarkAsGarbage.
|
||||||
func (p *InhumePrm) WithTarget(tombstone *addressSDK.Address, addrs ...*addressSDK.Address) *InhumePrm {
|
func (p *InhumePrm) WithTarget(tombstone oid.Address, addrs ...oid.Address) *InhumePrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addrs = addrs
|
p.addrs = addrs
|
||||||
p.tombstone = tombstone
|
p.tombstone = &tombstone
|
||||||
}
|
}
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
@ -37,7 +37,7 @@ func (p *InhumePrm) WithTarget(tombstone *addressSDK.Address, addrs ...*addressS
|
||||||
// MarkAsGarbage marks an object to be physically removed from local storage.
|
// MarkAsGarbage marks an object to be physically removed from local storage.
|
||||||
//
|
//
|
||||||
// Should not be called along with WithTarget.
|
// Should not be called along with WithTarget.
|
||||||
func (p *InhumePrm) MarkAsGarbage(addrs ...*addressSDK.Address) *InhumePrm {
|
func (p *InhumePrm) MarkAsGarbage(addrs ...oid.Address) *InhumePrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addrs = addrs
|
p.addrs = addrs
|
||||||
p.tombstone = nil
|
p.tombstone = nil
|
||||||
|
@ -73,7 +73,7 @@ func (e *StorageEngine) inhume(prm *InhumePrm) (*InhumeRes, error) {
|
||||||
|
|
||||||
for i := range prm.addrs {
|
for i := range prm.addrs {
|
||||||
if prm.tombstone != nil {
|
if prm.tombstone != nil {
|
||||||
shPrm.WithTarget(prm.tombstone, prm.addrs[i])
|
shPrm.WithTarget(*prm.tombstone, prm.addrs[i])
|
||||||
} else {
|
} else {
|
||||||
shPrm.MarkAsGarbage(prm.addrs[i])
|
shPrm.MarkAsGarbage(prm.addrs[i])
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ func (e *StorageEngine) inhume(prm *InhumePrm) (*InhumeRes, error) {
|
||||||
// 0 - fail
|
// 0 - fail
|
||||||
// 1 - object locked
|
// 1 - object locked
|
||||||
// 2 - ok
|
// 2 - ok
|
||||||
func (e *StorageEngine) inhumeAddr(addr *addressSDK.Address, prm *shard.InhumePrm, checkExists bool) (status uint8) {
|
func (e *StorageEngine) inhumeAddr(addr oid.Address, prm *shard.InhumePrm, checkExists bool) (status uint8) {
|
||||||
root := false
|
root := false
|
||||||
var errLocked apistatus.ObjectLocked
|
var errLocked apistatus.ObjectLocked
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ func (e *StorageEngine) processExpiredTombstones(ctx context.Context, addrs []me
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *StorageEngine) processExpiredLocks(ctx context.Context, lockers []*addressSDK.Address) {
|
func (e *StorageEngine) processExpiredLocks(ctx context.Context, lockers []oid.Address) {
|
||||||
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
||||||
sh.HandleExpiredLocks(lockers)
|
sh.HandleExpiredLocks(lockers)
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ func TestStorageEngine_Inhume(t *testing.T) {
|
||||||
_, err = e.Inhume(inhumePrm)
|
_, err = e.Inhume(inhumePrm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
addrs, err := Select(e, &cnr, fs)
|
addrs, err := Select(e, cnr, fs)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Empty(t, addrs)
|
require.Empty(t, addrs)
|
||||||
})
|
})
|
||||||
|
@ -71,7 +71,7 @@ func TestStorageEngine_Inhume(t *testing.T) {
|
||||||
_, err = e.Inhume(inhumePrm)
|
_, err = e.Inhume(inhumePrm)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
addrs, err := Select(e, &cnr, fs)
|
addrs, err := Select(e, cnr, fs)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Empty(t, addrs)
|
require.Empty(t, addrs)
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrEndOfListing is returned from an object listing with cursor
|
// ErrEndOfListing is returned from an object listing with cursor
|
||||||
|
@ -40,12 +40,12 @@ func (p *ListWithCursorPrm) WithCursor(cursor *Cursor) *ListWithCursorPrm {
|
||||||
|
|
||||||
// ListWithCursorRes contains values returned from ListWithCursor operation.
|
// ListWithCursorRes contains values returned from ListWithCursor operation.
|
||||||
type ListWithCursorRes struct {
|
type ListWithCursorRes struct {
|
||||||
addrList []*addressSDK.Address
|
addrList []oid.Address
|
||||||
cursor *Cursor
|
cursor *Cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressList returns addresses selected by ListWithCursor operation.
|
// AddressList returns addresses selected by ListWithCursor operation.
|
||||||
func (l ListWithCursorRes) AddressList() []*addressSDK.Address {
|
func (l ListWithCursorRes) AddressList() []oid.Address {
|
||||||
return l.addrList
|
return l.addrList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ func (l ListWithCursorRes) Cursor() *Cursor {
|
||||||
// Returns ErrEndOfListing if there are no more objects to return or count
|
// Returns ErrEndOfListing if there are no more objects to return or count
|
||||||
// parameter set to zero.
|
// parameter set to zero.
|
||||||
func (e *StorageEngine) ListWithCursor(prm *ListWithCursorPrm) (*ListWithCursorRes, error) {
|
func (e *StorageEngine) ListWithCursor(prm *ListWithCursorPrm) (*ListWithCursorRes, error) {
|
||||||
result := make([]*addressSDK.Address, 0, prm.count)
|
result := make([]oid.Address, 0, prm.count)
|
||||||
|
|
||||||
// 1. Get available shards and sort them.
|
// 1. Get available shards and sort them.
|
||||||
e.mtx.RLock()
|
e.mtx.RLock()
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ func TestListWithCursor(t *testing.T) {
|
||||||
|
|
||||||
const total = 20
|
const total = 20
|
||||||
|
|
||||||
expected := make([]*addressSDK.Address, 0, total)
|
expected := make([]oid.Address, 0, total)
|
||||||
got := make([]*addressSDK.Address, 0, total)
|
got := make([]oid.Address, 0, total)
|
||||||
|
|
||||||
for i := 0; i < total; i++ {
|
for i := 0; i < total; i++ {
|
||||||
containerID := cidtest.ID()
|
containerID := cidtest.ID()
|
||||||
|
@ -59,9 +59,9 @@ func TestListWithCursor(t *testing.T) {
|
||||||
require.Equal(t, expected, got)
|
require.Equal(t, expected, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortAddresses(addr []*addressSDK.Address) []*addressSDK.Address {
|
func sortAddresses(addr []oid.Address) []oid.Address {
|
||||||
sort.Slice(addr, func(i, j int) bool {
|
sort.Slice(addr, func(i, j int) bool {
|
||||||
return addr[i].String() < addr[j].String()
|
return addr[i].EncodeToString() < addr[j].EncodeToString()
|
||||||
})
|
})
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,9 +25,6 @@ func (e *StorageEngine) Lock(idCnr cid.ID, locker oid.ID, locked []oid.ID) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *StorageEngine) lock(idCnr cid.ID, locker oid.ID, locked []oid.ID) error {
|
func (e *StorageEngine) lock(idCnr cid.ID, locker oid.ID, locked []oid.ID) error {
|
||||||
var addr address.Address
|
|
||||||
addr.SetContainerID(idCnr)
|
|
||||||
|
|
||||||
for i := range locked {
|
for i := range locked {
|
||||||
switch e.lockSingle(idCnr, locker, locked[i], true) {
|
switch e.lockSingle(idCnr, locker, locked[i], true) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -55,11 +51,11 @@ func (e *StorageEngine) lockSingle(idCnr cid.ID, locker, locked oid.ID, checkExi
|
||||||
root := false
|
root := false
|
||||||
var errIrregular apistatus.LockNonRegularObject
|
var errIrregular apistatus.LockNonRegularObject
|
||||||
|
|
||||||
var addrLocked address.Address
|
var addrLocked oid.Address
|
||||||
addrLocked.SetContainerID(idCnr)
|
addrLocked.SetContainer(idCnr)
|
||||||
addrLocked.SetObjectID(locked)
|
addrLocked.SetObject(locked)
|
||||||
|
|
||||||
e.iterateOverSortedShards(&addrLocked, func(_ int, sh hashedShard) (stop bool) {
|
e.iterateOverSortedShards(addrLocked, func(_ int, sh hashedShard) (stop bool) {
|
||||||
defer func() {
|
defer func() {
|
||||||
// if object is root we continue since information about it
|
// if object is root we continue since information about it
|
||||||
// can be presented in other shards
|
// can be presented in other shards
|
||||||
|
@ -70,7 +66,7 @@ func (e *StorageEngine) lockSingle(idCnr cid.ID, locker, locked oid.ID, checkExi
|
||||||
|
|
||||||
if checkExists {
|
if checkExists {
|
||||||
exRes, err := sh.Exists(new(shard.ExistsPrm).
|
exRes, err := sh.Exists(new(shard.ExistsPrm).
|
||||||
WithAddress(&addrLocked),
|
WithAddress(addrLocked),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var siErr *objectSDK.SplitInfoError
|
var siErr *objectSDK.SplitInfoError
|
||||||
|
|
|
@ -13,8 +13,6 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
|
@ -61,26 +59,26 @@ func TestLockUserScenario(t *testing.T) {
|
||||||
cnr := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
var objAddr address.Address
|
var objAddr oid.Address
|
||||||
objAddr.SetContainerID(cnr)
|
objAddr.SetContainer(cnr)
|
||||||
|
|
||||||
var tombAddr address.Address
|
var tombAddr oid.Address
|
||||||
tombAddr.SetContainerID(cnr)
|
tombAddr.SetContainer(cnr)
|
||||||
tombAddr.SetObjectID(tombID)
|
tombAddr.SetObject(tombID)
|
||||||
|
|
||||||
var lockerAddr address.Address
|
var lockerAddr oid.Address
|
||||||
lockerAddr.SetContainerID(cnr)
|
lockerAddr.SetContainer(cnr)
|
||||||
lockerAddr.SetObjectID(lockerID)
|
lockerAddr.SetObject(lockerID)
|
||||||
|
|
||||||
var tombForLockAddr address.Address
|
var tombForLockAddr oid.Address
|
||||||
tombForLockAddr.SetContainerID(cnr)
|
tombForLockAddr.SetContainer(cnr)
|
||||||
tombForLockAddr.SetObjectID(tombForLockID)
|
tombForLockAddr.SetObject(tombForLockID)
|
||||||
|
|
||||||
// 1.
|
// 1.
|
||||||
obj := generateObjectWithCID(t, cnr)
|
obj := generateObjectWithCID(t, cnr)
|
||||||
|
|
||||||
id, _ := obj.ID()
|
id, _ := obj.ID()
|
||||||
objAddr.SetObjectID(id)
|
objAddr.SetObject(id)
|
||||||
|
|
||||||
err = Put(e, obj)
|
err = Put(e, obj)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -90,7 +88,7 @@ func TestLockUserScenario(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// 3.
|
// 3.
|
||||||
_, err = e.Inhume(new(InhumePrm).WithTarget(&tombAddr, &objAddr))
|
_, err = e.Inhume(new(InhumePrm).WithTarget(tombAddr, objAddr))
|
||||||
require.ErrorAs(t, err, new(apistatus.ObjectLocked))
|
require.ErrorAs(t, err, new(apistatus.ObjectLocked))
|
||||||
|
|
||||||
// 4.
|
// 4.
|
||||||
|
@ -106,7 +104,7 @@ func TestLockUserScenario(t *testing.T) {
|
||||||
err = Put(e, tombObj)
|
err = Put(e, tombObj)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = e.Inhume(new(InhumePrm).WithTarget(&tombForLockAddr, &lockerAddr))
|
_, err = e.Inhume(new(InhumePrm).WithTarget(tombForLockAddr, lockerAddr))
|
||||||
require.NoError(t, err, new(apistatus.ObjectLocked))
|
require.NoError(t, err, new(apistatus.ObjectLocked))
|
||||||
|
|
||||||
// 5.
|
// 5.
|
||||||
|
@ -117,7 +115,7 @@ func TestLockUserScenario(t *testing.T) {
|
||||||
// delay for GC
|
// delay for GC
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
_, err = e.Inhume(new(InhumePrm).WithTarget(&tombAddr, &objAddr))
|
_, err = e.Inhume(new(InhumePrm).WithTarget(tombAddr, objAddr))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +177,7 @@ func TestLockExpiration(t *testing.T) {
|
||||||
err = e.Lock(cnr, idLock, []oid.ID{id})
|
err = e.Lock(cnr, idLock, []oid.ID{id})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = e.Inhume(new(InhumePrm).WithTarget(objecttest.Address(), objectcore.AddressOf(obj)))
|
_, err = e.Inhume(new(InhumePrm).WithTarget(oidtest.Address(), objectcore.AddressOf(obj)))
|
||||||
require.ErrorAs(t, err, new(apistatus.ObjectLocked))
|
require.ErrorAs(t, err, new(apistatus.ObjectLocked))
|
||||||
|
|
||||||
// 3.
|
// 3.
|
||||||
|
@ -192,6 +190,6 @@ func TestLockExpiration(t *testing.T) {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
// 4.
|
// 4.
|
||||||
_, err = e.Inhume(new(InhumePrm).WithTarget(objecttest.Address(), objectcore.AddressOf(obj)))
|
_, err = e.Inhume(new(InhumePrm).WithTarget(oidtest.Address(), objectcore.AddressOf(obj)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import (
|
||||||
type RngPrm struct {
|
type RngPrm struct {
|
||||||
off, ln uint64
|
off, ln uint64
|
||||||
|
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// RngRes groups the resulting values of GetRange operation.
|
// RngRes groups the resulting values of GetRange operation.
|
||||||
|
@ -27,7 +27,7 @@ type RngRes struct {
|
||||||
// WithAddress is a GetRng option to set the address of the requested object.
|
// WithAddress is a GetRng option to set the address of the requested object.
|
||||||
//
|
//
|
||||||
// Option is required.
|
// Option is required.
|
||||||
func (p *RngPrm) WithAddress(addr *addressSDK.Address) *RngPrm {
|
func (p *RngPrm) WithAddress(addr oid.Address) *RngPrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,9 @@ func (e *StorageEngine) getRange(prm *RngPrm) (*RngRes, error) {
|
||||||
return nil, outError
|
return nil, outError
|
||||||
}
|
}
|
||||||
e.reportShardError(shardWithMeta, "meta info was present, but object is missing",
|
e.reportShardError(shardWithMeta, "meta info was present, but object is missing",
|
||||||
metaError, zap.Stringer("address", prm.addr))
|
metaError,
|
||||||
|
zap.Stringer("address", prm.addr),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RngRes{
|
return &RngRes{
|
||||||
|
@ -176,7 +178,7 @@ func (e *StorageEngine) getRange(prm *RngPrm) (*RngRes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRange reads object payload range from local storage by provided address.
|
// GetRange reads object payload range from local storage by provided address.
|
||||||
func GetRange(storage *StorageEngine, addr *addressSDK.Address, rng *objectSDK.Range) ([]byte, error) {
|
func GetRange(storage *StorageEngine, addr oid.Address, rng *objectSDK.Range) ([]byte, error) {
|
||||||
res, err := storage.GetRange(new(RngPrm).
|
res, err := storage.GetRange(new(RngPrm).
|
||||||
WithAddress(addr).
|
WithAddress(addr).
|
||||||
WithPayloadRange(rng),
|
WithPayloadRange(rng),
|
||||||
|
|
|
@ -1,30 +1,27 @@
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SelectPrm groups the parameters of Select operation.
|
// SelectPrm groups the parameters of Select operation.
|
||||||
type SelectPrm struct {
|
type SelectPrm struct {
|
||||||
cid *cid.ID
|
cnr cid.ID
|
||||||
filters object.SearchFilters
|
filters object.SearchFilters
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectRes groups the resulting values of Select operation.
|
// SelectRes groups the resulting values of Select operation.
|
||||||
type SelectRes struct {
|
type SelectRes struct {
|
||||||
addrList []*addressSDK.Address
|
addrList []oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithContainerID is a Select option to set the container id to search in.
|
// WithContainerID is a Select option to set the container id to search in.
|
||||||
func (p *SelectPrm) WithContainerID(cid *cid.ID) *SelectPrm {
|
func (p *SelectPrm) WithContainerID(cnr cid.ID) *SelectPrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.cid = cid
|
p.cnr = cnr
|
||||||
}
|
}
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
@ -40,7 +37,7 @@ func (p *SelectPrm) WithFilters(fs object.SearchFilters) *SelectPrm {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressList returns list of addresses of the selected objects.
|
// AddressList returns list of addresses of the selected objects.
|
||||||
func (r *SelectRes) AddressList() []*addressSDK.Address {
|
func (r *SelectRes) AddressList() []oid.Address {
|
||||||
return r.addrList
|
return r.addrList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,32 +60,24 @@ func (e *StorageEngine) _select(prm *SelectPrm) (*SelectRes, error) {
|
||||||
defer elapsed(e.metrics.AddSearchDuration)()
|
defer elapsed(e.metrics.AddSearchDuration)()
|
||||||
}
|
}
|
||||||
|
|
||||||
addrList := make([]*addressSDK.Address, 0)
|
addrList := make([]oid.Address, 0)
|
||||||
uniqueMap := make(map[string]struct{})
|
uniqueMap := make(map[string]struct{})
|
||||||
|
|
||||||
var outError error
|
var outError error
|
||||||
|
|
||||||
shPrm := new(shard.SelectPrm).
|
shPrm := new(shard.SelectPrm).
|
||||||
WithContainerID(prm.cid).
|
WithContainerID(prm.cnr).
|
||||||
WithFilters(prm.filters)
|
WithFilters(prm.filters)
|
||||||
|
|
||||||
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
||||||
res, err := sh.Select(shPrm)
|
res, err := sh.Select(shPrm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch {
|
e.reportShardError(sh, "could not select objects from shard", err)
|
||||||
case errors.Is(err, meta.ErrMissingContainerID): // should never happen
|
return false
|
||||||
e.log.Error("missing container ID parameter")
|
|
||||||
outError = err
|
|
||||||
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
e.reportShardError(sh, "could not select objects from shard", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for _, addr := range res.AddressList() { // save only unique values
|
for _, addr := range res.AddressList() { // save only unique values
|
||||||
if _, ok := uniqueMap[addr.String()]; !ok {
|
if _, ok := uniqueMap[addr.EncodeToString()]; !ok {
|
||||||
uniqueMap[addr.String()] = struct{}{}
|
uniqueMap[addr.EncodeToString()] = struct{}{}
|
||||||
addrList = append(addrList, addr)
|
addrList = append(addrList, addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +109,7 @@ func (e *StorageEngine) list(limit uint64) (*SelectRes, error) {
|
||||||
defer elapsed(e.metrics.AddListObjectsDuration)()
|
defer elapsed(e.metrics.AddListObjectsDuration)()
|
||||||
}
|
}
|
||||||
|
|
||||||
addrList := make([]*addressSDK.Address, 0, limit)
|
addrList := make([]oid.Address, 0, limit)
|
||||||
uniqueMap := make(map[string]struct{})
|
uniqueMap := make(map[string]struct{})
|
||||||
ln := uint64(0)
|
ln := uint64(0)
|
||||||
|
|
||||||
|
@ -131,8 +120,8 @@ func (e *StorageEngine) list(limit uint64) (*SelectRes, error) {
|
||||||
e.reportShardError(sh, "could not select objects from shard", err)
|
e.reportShardError(sh, "could not select objects from shard", err)
|
||||||
} else {
|
} else {
|
||||||
for _, addr := range res.AddressList() { // save only unique values
|
for _, addr := range res.AddressList() { // save only unique values
|
||||||
if _, ok := uniqueMap[addr.String()]; !ok {
|
if _, ok := uniqueMap[addr.EncodeToString()]; !ok {
|
||||||
uniqueMap[addr.String()] = struct{}{}
|
uniqueMap[addr.EncodeToString()] = struct{}{}
|
||||||
addrList = append(addrList, addr)
|
addrList = append(addrList, addr)
|
||||||
|
|
||||||
ln++
|
ln++
|
||||||
|
@ -152,9 +141,9 @@ func (e *StorageEngine) list(limit uint64) (*SelectRes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select selects objects from local storage using provided filters.
|
// Select selects objects from local storage using provided filters.
|
||||||
func Select(storage *StorageEngine, cid *cid.ID, fs object.SearchFilters) ([]*addressSDK.Address, error) {
|
func Select(storage *StorageEngine, cnr cid.ID, fs object.SearchFilters) ([]oid.Address, error) {
|
||||||
res, err := storage.Select(new(SelectPrm).
|
res, err := storage.Select(new(SelectPrm).
|
||||||
WithContainerID(cid).
|
WithContainerID(cnr).
|
||||||
WithFilters(fs),
|
WithFilters(fs),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -166,7 +155,7 @@ func Select(storage *StorageEngine, cid *cid.ID, fs object.SearchFilters) ([]*ad
|
||||||
|
|
||||||
// List returns `limit` available physically storage object addresses in
|
// List returns `limit` available physically storage object addresses in
|
||||||
// engine. If limit is zero, then returns all available object addresses.
|
// engine. If limit is zero, then returns all available object addresses.
|
||||||
func List(storage *StorageEngine, limit uint64) ([]*addressSDK.Address, error) {
|
func List(storage *StorageEngine, limit uint64) ([]oid.Address, error) {
|
||||||
res, err := storage.List(limit)
|
res, err := storage.List(limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/nspcc-dev/hrw"
|
"github.com/nspcc-dev/hrw"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/panjf2000/ants/v2"
|
"github.com/panjf2000/ants/v2"
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
)
|
)
|
||||||
|
@ -79,7 +79,7 @@ func (e *StorageEngine) shardWeight(sh *shard.Shard) float64 {
|
||||||
return float64(weightValues.FreeSpace)
|
return float64(weightValues.FreeSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *StorageEngine) sortShardsByWeight(objAddr fmt.Stringer) []hashedShard {
|
func (e *StorageEngine) sortShardsByWeight(objAddr interface{ EncodeToString() string }) []hashedShard {
|
||||||
e.mtx.RLock()
|
e.mtx.RLock()
|
||||||
defer e.mtx.RUnlock()
|
defer e.mtx.RUnlock()
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ func (e *StorageEngine) sortShardsByWeight(objAddr fmt.Stringer) []hashedShard {
|
||||||
weights = append(weights, e.shardWeight(sh.Shard))
|
weights = append(weights, e.shardWeight(sh.Shard))
|
||||||
}
|
}
|
||||||
|
|
||||||
hrw.SortSliceByWeightValue(shards, weights, hrw.Hash([]byte(objAddr.String())))
|
hrw.SortSliceByWeightValue(shards, weights, hrw.Hash([]byte(objAddr.EncodeToString())))
|
||||||
|
|
||||||
return shards
|
return shards
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ func (e *StorageEngine) unsortedShards() []hashedShard {
|
||||||
return shards
|
return shards
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *StorageEngine) iterateOverSortedShards(addr *addressSDK.Address, handler func(int, hashedShard) (stop bool)) {
|
func (e *StorageEngine) iterateOverSortedShards(addr oid.Address, handler func(int, hashedShard) (stop bool)) {
|
||||||
for i, sh := range e.sortShardsByWeight(addr) {
|
for i, sh := range e.sortShardsByWeight(addr) {
|
||||||
if handler(i, sh) {
|
if handler(i, sh) {
|
||||||
break
|
break
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db *DB) Containers() (list []*cid.ID, err error) {
|
func (db *DB) Containers() (list []cid.ID, err error) {
|
||||||
err = db.boltDB.View(func(tx *bbolt.Tx) error {
|
err = db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||||
list, err = db.containers(tx)
|
list, err = db.containers(tx)
|
||||||
|
|
||||||
|
@ -19,16 +19,15 @@ func (db *DB) Containers() (list []*cid.ID, err error) {
|
||||||
return list, err
|
return list, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) containers(tx *bbolt.Tx) ([]*cid.ID, error) {
|
func (db *DB) containers(tx *bbolt.Tx) ([]cid.ID, error) {
|
||||||
result := make([]*cid.ID, 0)
|
result := make([]cid.ID, 0)
|
||||||
unique := make(map[string]struct{})
|
unique := make(map[string]struct{})
|
||||||
|
var cnr cid.ID
|
||||||
|
|
||||||
err := tx.ForEach(func(name []byte, _ *bbolt.Bucket) error {
|
err := tx.ForEach(func(name []byte, _ *bbolt.Bucket) error {
|
||||||
id := parseContainerID(name, unique)
|
if parseContainerID(&cnr, name, unique) {
|
||||||
|
result = append(result, cnr)
|
||||||
if id != nil {
|
unique[cnr.EncodeToString()] = struct{}{}
|
||||||
result = append(result, id)
|
|
||||||
unique[id.String()] = struct{}{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -37,7 +36,7 @@ func (db *DB) containers(tx *bbolt.Tx) ([]*cid.ID, error) {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) ContainerSize(id *cid.ID) (size uint64, err error) {
|
func (db *DB) ContainerSize(id cid.ID) (size uint64, err error) {
|
||||||
err = db.boltDB.Update(func(tx *bbolt.Tx) error {
|
err = db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||||
size, err = db.containerSize(tx, id)
|
size, err = db.containerSize(tx, id)
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ func (db *DB) ContainerSize(id *cid.ID) (size uint64, err error) {
|
||||||
return size, err
|
return size, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) containerSize(tx *bbolt.Tx, id *cid.ID) (uint64, error) {
|
func (db *DB) containerSize(tx *bbolt.Tx, id cid.ID) (uint64, error) {
|
||||||
containerVolume, err := tx.CreateBucketIfNotExists(containerVolumeBucketName)
|
containerVolume, err := tx.CreateBucketIfNotExists(containerVolumeBucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -59,19 +58,18 @@ func (db *DB) containerSize(tx *bbolt.Tx, id *cid.ID) (uint64, error) {
|
||||||
return parseContainerSize(containerVolume.Get(key)), nil
|
return parseContainerSize(containerVolume.Get(key)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseContainerID(name []byte, ignore map[string]struct{}) *cid.ID {
|
func parseContainerID(dst *cid.ID, name []byte, ignore map[string]struct{}) bool {
|
||||||
var containerID cid.ID
|
|
||||||
strContainerID := strings.Split(string(name), invalidBase58String)[0]
|
strContainerID := strings.Split(string(name), invalidBase58String)[0]
|
||||||
|
|
||||||
if _, ok := ignore[strContainerID]; ok {
|
if _, ok := ignore[strContainerID]; ok {
|
||||||
return nil
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := containerID.DecodeString(strContainerID); err != nil {
|
if err := dst.DecodeString(strContainerID); err != nil {
|
||||||
return nil
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return &containerID
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseContainerSize(v []byte) uint64 {
|
func parseContainerSize(v []byte) uint64 {
|
||||||
|
@ -82,7 +80,7 @@ func parseContainerSize(v []byte) uint64 {
|
||||||
return binary.LittleEndian.Uint64(v)
|
return binary.LittleEndian.Uint64(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func changeContainerSize(tx *bbolt.Tx, id *cid.ID, delta uint64, increase bool) error {
|
func changeContainerSize(tx *bbolt.Tx, id cid.ID, delta uint64, increase bool) error {
|
||||||
containerVolume, err := tx.CreateBucketIfNotExists(containerVolumeBucketName)
|
containerVolume, err := tx.CreateBucketIfNotExists(containerVolumeBucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ func TestDB_Containers(t *testing.T) {
|
||||||
|
|
||||||
cnr, _ := obj.ContainerID()
|
cnr, _ := obj.ContainerID()
|
||||||
|
|
||||||
cids[cnr.String()] = 0
|
cids[cnr.EncodeToString()] = 0
|
||||||
|
|
||||||
err := putBig(db, obj)
|
err := putBig(db, obj)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -35,16 +35,16 @@ func TestDB_Containers(t *testing.T) {
|
||||||
lst, err := db.Containers()
|
lst, err := db.Containers()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for _, cid := range lst {
|
for _, cnr := range lst {
|
||||||
i, ok := cids[cid.String()]
|
i, ok := cids[cnr.EncodeToString()]
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, 0, i)
|
require.Equal(t, 0, i)
|
||||||
|
|
||||||
cids[cid.String()] = 1
|
cids[cnr.EncodeToString()] = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// require.Contains not working since cnrs is a ptr slice
|
// require.Contains not working since cnrs is a ptr slice
|
||||||
assertContains := func(cnrs []*cid.ID, cnr cid.ID) {
|
assertContains := func(cnrs []cid.ID, cnr cid.ID) {
|
||||||
found := false
|
found := false
|
||||||
for i := 0; !found && i < len(cnrs); i++ {
|
for i := 0; !found && i < len(cnrs); i++ {
|
||||||
found = cnrs[i].Equals(cnr)
|
found = cnrs[i].Equals(cnr)
|
||||||
|
@ -64,7 +64,7 @@ func TestDB_Containers(t *testing.T) {
|
||||||
|
|
||||||
assertContains(cnrs, cnr)
|
assertContains(cnrs, cnr)
|
||||||
|
|
||||||
require.NoError(t, meta.Inhume(db, object.AddressOf(obj), objecttest.Address()))
|
require.NoError(t, meta.Inhume(db, object.AddressOf(obj), oidtest.Address()))
|
||||||
|
|
||||||
cnrs, err = db.Containers()
|
cnrs, err = db.Containers()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -104,7 +104,7 @@ func TestDB_ContainersCount(t *testing.T) {
|
||||||
{L, objectSDK.TypeLock},
|
{L, objectSDK.TypeLock},
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := make([]*cid.ID, 0, R+T+SG+L)
|
expected := make([]cid.ID, 0, R+T+SG+L)
|
||||||
|
|
||||||
for _, upload := range uploadObjects {
|
for _, upload := range uploadObjects {
|
||||||
for i := 0; i < upload.amount; i++ {
|
for i := 0; i < upload.amount; i++ {
|
||||||
|
@ -115,19 +115,19 @@ func TestDB_ContainersCount(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cnr, _ := obj.ContainerID()
|
cnr, _ := obj.ContainerID()
|
||||||
expected = append(expected, &cnr)
|
expected = append(expected, cnr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(expected, func(i, j int) bool {
|
sort.Slice(expected, func(i, j int) bool {
|
||||||
return expected[i].String() < expected[j].String()
|
return expected[i].EncodeToString() < expected[j].EncodeToString()
|
||||||
})
|
})
|
||||||
|
|
||||||
got, err := db.Containers()
|
got, err := db.Containers()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
sort.Slice(got, func(i, j int) bool {
|
sort.Slice(got, func(i, j int) bool {
|
||||||
return got[i].String() < got[j].String()
|
return got[i].EncodeToString() < got[j].EncodeToString()
|
||||||
})
|
})
|
||||||
|
|
||||||
require.Equal(t, expected, got)
|
require.Equal(t, expected, got)
|
||||||
|
@ -169,7 +169,7 @@ func TestDB_ContainerSize(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for cnr, volume := range cids {
|
for cnr, volume := range cids {
|
||||||
n, err := db.ContainerSize(&cnr)
|
n, err := db.ContainerSize(cnr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, volume, int(n))
|
require.Equal(t, volume, int(n))
|
||||||
}
|
}
|
||||||
|
@ -182,12 +182,12 @@ func TestDB_ContainerSize(t *testing.T) {
|
||||||
require.NoError(t, meta.Inhume(
|
require.NoError(t, meta.Inhume(
|
||||||
db,
|
db,
|
||||||
object.AddressOf(obj),
|
object.AddressOf(obj),
|
||||||
objecttest.Address(),
|
oidtest.Address(),
|
||||||
))
|
))
|
||||||
|
|
||||||
volume -= int(obj.PayloadSize())
|
volume -= int(obj.PayloadSize())
|
||||||
|
|
||||||
n, err := db.ContainerSize(&cnr)
|
n, err := db.ContainerSize(cnr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, volume, int(n))
|
require.Equal(t, volume, int(n))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ func TestReset(t *testing.T) {
|
||||||
obj := generateObject(t)
|
obj := generateObject(t)
|
||||||
addr := object.AddressOf(obj)
|
addr := object.AddressOf(obj)
|
||||||
|
|
||||||
addrToInhume := objecttest.Address()
|
addrToInhume := oidtest.Address()
|
||||||
|
|
||||||
assertExists := func(addr *addressSDK.Address, expExists bool, assertErr func(error) bool) {
|
assertExists := func(addr oid.Address, expExists bool, assertErr func(error) bool) {
|
||||||
exists, err := meta.Exists(db, addr)
|
exists, err := meta.Exists(db, addr)
|
||||||
if assertErr != nil {
|
if assertErr != nil {
|
||||||
require.True(t, assertErr(err))
|
require.True(t, assertErr(err))
|
||||||
|
@ -37,7 +37,7 @@ func TestReset(t *testing.T) {
|
||||||
err = putBig(db, obj)
|
err = putBig(db, obj)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = meta.Inhume(db, addrToInhume, objecttest.Address())
|
err = meta.Inhume(db, addrToInhume, oidtest.Address())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assertExists(addr, true, nil)
|
assertExists(addr, true, nil)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/version"
|
"github.com/nspcc-dev/neofs-sdk-go/version"
|
||||||
|
@ -23,8 +23,8 @@ func putBig(db *meta.DB, obj *object.Object) error {
|
||||||
return meta.Put(db, obj, nil)
|
return meta.Put(db, obj, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSelect(t *testing.T, db *meta.DB, cnr cid.ID, fs object.SearchFilters, exp ...*addressSDK.Address) {
|
func testSelect(t *testing.T, db *meta.DB, cnr cid.ID, fs object.SearchFilters, exp ...oid.Address) {
|
||||||
res, err := meta.Select(db, &cnr, fs)
|
res, err := meta.Select(db, cnr, fs)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, res, len(exp))
|
require.Len(t, res, len(exp))
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,13 @@ import (
|
||||||
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeletePrm groups the parameters of Delete operation.
|
// DeletePrm groups the parameters of Delete operation.
|
||||||
type DeletePrm struct {
|
type DeletePrm struct {
|
||||||
addrs []*addressSDK.Address
|
addrs []oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteRes groups the resulting values of Delete operation.
|
// DeleteRes groups the resulting values of Delete operation.
|
||||||
|
@ -24,7 +24,7 @@ type DeleteRes struct{}
|
||||||
// WithAddresses is a Delete option to set the addresses of the objects to delete.
|
// WithAddresses is a Delete option to set the addresses of the objects to delete.
|
||||||
//
|
//
|
||||||
// Option is required.
|
// Option is required.
|
||||||
func (p *DeletePrm) WithAddresses(addrs ...*addressSDK.Address) *DeletePrm {
|
func (p *DeletePrm) WithAddresses(addrs ...oid.Address) *DeletePrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addrs = addrs
|
p.addrs = addrs
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ func (p *DeletePrm) WithAddresses(addrs ...*addressSDK.Address) *DeletePrm {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes objects from DB.
|
// Delete removes objects from DB.
|
||||||
func Delete(db *DB, addrs ...*addressSDK.Address) error {
|
func Delete(db *DB, addrs ...oid.Address) error {
|
||||||
_, err := db.Delete(new(DeletePrm).WithAddresses(addrs...))
|
_, err := db.Delete(new(DeletePrm).WithAddresses(addrs...))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func Delete(db *DB, addrs ...*addressSDK.Address) error {
|
||||||
type referenceNumber struct {
|
type referenceNumber struct {
|
||||||
all, cur int
|
all, cur int
|
||||||
|
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
|
|
||||||
obj *objectSDK.Object
|
obj *objectSDK.Object
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func (db *DB) Delete(prm *DeletePrm) (*DeleteRes, error) {
|
||||||
return new(DeleteRes), err
|
return new(DeleteRes), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []*addressSDK.Address) error {
|
func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []oid.Address) error {
|
||||||
refCounter := make(referenceCounter, len(addrs))
|
refCounter := make(referenceCounter, len(addrs))
|
||||||
|
|
||||||
for i := range addrs {
|
for i := range addrs {
|
||||||
|
@ -85,7 +85,7 @@ func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []*addressSDK.Address) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) delete(tx *bbolt.Tx, addr *addressSDK.Address, refCounter referenceCounter) error {
|
func (db *DB) delete(tx *bbolt.Tx, addr oid.Address, refCounter referenceCounter) error {
|
||||||
// remove record from the garbage bucket
|
// remove record from the garbage bucket
|
||||||
garbageBKT := tx.Bucket(garbageBucketName)
|
garbageBKT := tx.Bucket(garbageBucketName)
|
||||||
if garbageBKT != nil {
|
if garbageBKT != nil {
|
||||||
|
@ -108,7 +108,7 @@ func (db *DB) delete(tx *bbolt.Tx, addr *addressSDK.Address, refCounter referenc
|
||||||
// if object is an only link to a parent, then remove parent
|
// if object is an only link to a parent, then remove parent
|
||||||
if parent := obj.Parent(); parent != nil {
|
if parent := obj.Parent(); parent != nil {
|
||||||
parAddr := object.AddressOf(parent)
|
parAddr := object.AddressOf(parent)
|
||||||
sParAddr := parAddr.String()
|
sParAddr := parAddr.EncodeToString()
|
||||||
|
|
||||||
nRef, ok := refCounter[sParAddr]
|
nRef, ok := refCounter[sParAddr]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -152,17 +152,13 @@ func (db *DB) deleteObject(
|
||||||
}
|
}
|
||||||
|
|
||||||
// parentLength returns amount of available children from parentid index.
|
// parentLength returns amount of available children from parentid index.
|
||||||
func parentLength(tx *bbolt.Tx, addr *addressSDK.Address) int {
|
func parentLength(tx *bbolt.Tx, addr oid.Address) int {
|
||||||
cnr, _ := addr.ContainerID()
|
bkt := tx.Bucket(parentBucketName(addr.Container()))
|
||||||
|
|
||||||
bkt := tx.Bucket(parentBucketName(&cnr))
|
|
||||||
if bkt == nil {
|
if bkt == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, _ := addr.ObjectID()
|
lst, err := decodeList(bkt.Get(objectKey(addr.Object())))
|
||||||
|
|
||||||
lst, err := decodeList(bkt.Get(objectKey(&obj)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -232,11 +228,9 @@ func delListIndexItem(tx *bbolt.Tx, item namedBucketItem) error {
|
||||||
func delUniqueIndexes(tx *bbolt.Tx, obj *objectSDK.Object, isParent bool) error {
|
func delUniqueIndexes(tx *bbolt.Tx, obj *objectSDK.Object, isParent bool) error {
|
||||||
addr := object.AddressOf(obj)
|
addr := object.AddressOf(obj)
|
||||||
|
|
||||||
id, _ := addr.ObjectID()
|
objKey := objectKey(addr.Object())
|
||||||
|
|
||||||
objKey := objectKey(&id)
|
|
||||||
addrKey := addressKey(addr)
|
addrKey := addressKey(addr)
|
||||||
cnr, _ := addr.ContainerID()
|
cnr := addr.Container()
|
||||||
|
|
||||||
// add value to primary unique bucket
|
// add value to primary unique bucket
|
||||||
if !isParent {
|
if !isParent {
|
||||||
|
@ -244,11 +238,11 @@ func delUniqueIndexes(tx *bbolt.Tx, obj *objectSDK.Object, isParent bool) error
|
||||||
|
|
||||||
switch obj.Type() {
|
switch obj.Type() {
|
||||||
case objectSDK.TypeRegular:
|
case objectSDK.TypeRegular:
|
||||||
bucketName = primaryBucketName(&cnr)
|
bucketName = primaryBucketName(cnr)
|
||||||
case objectSDK.TypeTombstone:
|
case objectSDK.TypeTombstone:
|
||||||
bucketName = tombstoneBucketName(&cnr)
|
bucketName = tombstoneBucketName(cnr)
|
||||||
case objectSDK.TypeStorageGroup:
|
case objectSDK.TypeStorageGroup:
|
||||||
bucketName = storageGroupBucketName(&cnr)
|
bucketName = storageGroupBucketName(cnr)
|
||||||
case objectSDK.TypeLock:
|
case objectSDK.TypeLock:
|
||||||
bucketName = bucketNameLockers(cnr)
|
bucketName = bucketNameLockers(cnr)
|
||||||
default:
|
default:
|
||||||
|
@ -261,17 +255,17 @@ func delUniqueIndexes(tx *bbolt.Tx, obj *objectSDK.Object, isParent bool) error
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
delUniqueIndexItem(tx, namedBucketItem{
|
delUniqueIndexItem(tx, namedBucketItem{
|
||||||
name: parentBucketName(&cnr),
|
name: parentBucketName(cnr),
|
||||||
key: objKey,
|
key: objKey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
delUniqueIndexItem(tx, namedBucketItem{ // remove from small blobovnicza id index
|
delUniqueIndexItem(tx, namedBucketItem{ // remove from small blobovnicza id index
|
||||||
name: smallBucketName(&cnr),
|
name: smallBucketName(cnr),
|
||||||
key: objKey,
|
key: objKey,
|
||||||
})
|
})
|
||||||
delUniqueIndexItem(tx, namedBucketItem{ // remove from root index
|
delUniqueIndexItem(tx, namedBucketItem{ // remove from root index
|
||||||
name: rootBucketName(&cnr),
|
name: rootBucketName(cnr),
|
||||||
key: objKey,
|
key: objKey,
|
||||||
})
|
})
|
||||||
delUniqueIndexItem(tx, namedBucketItem{ // remove from ToMoveIt index
|
delUniqueIndexItem(tx, namedBucketItem{ // remove from ToMoveIt index
|
||||||
|
|
|
@ -9,18 +9,18 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDB_Delete(t *testing.T) {
|
func TestDB_Delete(t *testing.T) {
|
||||||
db := newDB(t)
|
db := newDB(t)
|
||||||
|
|
||||||
cid := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
parent := generateObjectWithCID(t, cid)
|
parent := generateObjectWithCID(t, cnr)
|
||||||
addAttribute(parent, "foo", "bar")
|
addAttribute(parent, "foo", "bar")
|
||||||
|
|
||||||
child := generateObjectWithCID(t, cid)
|
child := generateObjectWithCID(t, cnr)
|
||||||
child.SetParent(parent)
|
child.SetParent(parent)
|
||||||
idParent, _ := parent.ID()
|
idParent, _ := parent.ID()
|
||||||
child.SetParentID(idParent)
|
child.SetParentID(idParent)
|
||||||
|
@ -43,7 +43,7 @@ func TestDB_Delete(t *testing.T) {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// inhume parent and child so they will be on graveyard
|
// inhume parent and child so they will be on graveyard
|
||||||
ts := generateObjectWithCID(t, cid)
|
ts := generateObjectWithCID(t, cnr)
|
||||||
|
|
||||||
err = meta.Inhume(db, object.AddressOf(child), object.AddressOf(ts))
|
err = meta.Inhume(db, object.AddressOf(child), object.AddressOf(ts))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -71,18 +71,18 @@ func TestDB_Delete(t *testing.T) {
|
||||||
func TestDeleteAllChildren(t *testing.T) {
|
func TestDeleteAllChildren(t *testing.T) {
|
||||||
db := newDB(t)
|
db := newDB(t)
|
||||||
|
|
||||||
cid := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
|
|
||||||
// generate parent object
|
// generate parent object
|
||||||
parent := generateObjectWithCID(t, cid)
|
parent := generateObjectWithCID(t, cnr)
|
||||||
|
|
||||||
// generate 2 children
|
// generate 2 children
|
||||||
child1 := generateObjectWithCID(t, cid)
|
child1 := generateObjectWithCID(t, cnr)
|
||||||
child1.SetParent(parent)
|
child1.SetParent(parent)
|
||||||
idParent, _ := parent.ID()
|
idParent, _ := parent.ID()
|
||||||
child1.SetParentID(idParent)
|
child1.SetParentID(idParent)
|
||||||
|
|
||||||
child2 := generateObjectWithCID(t, cid)
|
child2 := generateObjectWithCID(t, cnr)
|
||||||
child2.SetParent(parent)
|
child2.SetParent(parent)
|
||||||
child2.SetParentID(idParent)
|
child2.SetParentID(idParent)
|
||||||
|
|
||||||
|
@ -108,10 +108,10 @@ func TestDeleteAllChildren(t *testing.T) {
|
||||||
func TestGraveOnlyDelete(t *testing.T) {
|
func TestGraveOnlyDelete(t *testing.T) {
|
||||||
db := newDB(t)
|
db := newDB(t)
|
||||||
|
|
||||||
addr := objecttest.Address()
|
addr := oidtest.Address()
|
||||||
|
|
||||||
// inhume non-existent object by address
|
// inhume non-existent object by address
|
||||||
require.NoError(t, meta.Inhume(db, addr, nil))
|
require.NoError(t, meta.Inhume(db, addr, oidtest.Address()))
|
||||||
|
|
||||||
// delete the object data
|
// delete the object data
|
||||||
require.NoError(t, meta.Delete(db, addr))
|
require.NoError(t, meta.Delete(db, addr))
|
||||||
|
|
|
@ -7,13 +7,13 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExistsPrm groups the parameters of Exists operation.
|
// ExistsPrm groups the parameters of Exists operation.
|
||||||
type ExistsPrm struct {
|
type ExistsPrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExistsRes groups the resulting values of Exists operation.
|
// ExistsRes groups the resulting values of Exists operation.
|
||||||
|
@ -24,7 +24,7 @@ type ExistsRes struct {
|
||||||
var ErrLackSplitInfo = errors.New("no split info on parent object")
|
var ErrLackSplitInfo = errors.New("no split info on parent object")
|
||||||
|
|
||||||
// WithAddress is an Exists option to set object checked for existence.
|
// WithAddress is an Exists option to set object checked for existence.
|
||||||
func (p *ExistsPrm) WithAddress(addr *addressSDK.Address) *ExistsPrm {
|
func (p *ExistsPrm) WithAddress(addr oid.Address) *ExistsPrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func (p *ExistsRes) Exists() bool {
|
||||||
// Exists checks if object is presented in DB.
|
// Exists checks if object is presented in DB.
|
||||||
//
|
//
|
||||||
// See DB.Exists docs.
|
// See DB.Exists docs.
|
||||||
func Exists(db *DB, addr *addressSDK.Address) (bool, error) {
|
func Exists(db *DB, addr oid.Address) (bool, error) {
|
||||||
r, err := db.Exists(new(ExistsPrm).WithAddress(addr))
|
r, err := db.Exists(new(ExistsPrm).WithAddress(addr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -65,7 +65,7 @@ func (db *DB) Exists(prm *ExistsPrm) (res *ExistsRes, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) exists(tx *bbolt.Tx, addr *addressSDK.Address) (exists bool, err error) {
|
func (db *DB) exists(tx *bbolt.Tx, addr oid.Address) (exists bool, err error) {
|
||||||
// check graveyard first
|
// check graveyard first
|
||||||
switch inGraveyard(tx, addr) {
|
switch inGraveyard(tx, addr) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -78,19 +78,18 @@ func (db *DB) exists(tx *bbolt.Tx, addr *addressSDK.Address) (exists bool, err e
|
||||||
return false, errRemoved
|
return false, errRemoved
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, _ := addr.ObjectID()
|
objKey := objectKey(addr.Object())
|
||||||
objKey := objectKey(&obj)
|
|
||||||
|
|
||||||
cnr, _ := addr.ContainerID()
|
cnr := addr.Container()
|
||||||
|
|
||||||
// if graveyard is empty, then check if object exists in primary bucket
|
// if graveyard is empty, then check if object exists in primary bucket
|
||||||
if inBucket(tx, primaryBucketName(&cnr), objKey) {
|
if inBucket(tx, primaryBucketName(cnr), objKey) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if primary bucket is empty, then check if object exists in parent bucket
|
// if primary bucket is empty, then check if object exists in parent bucket
|
||||||
if inBucket(tx, parentBucketName(&cnr), objKey) {
|
if inBucket(tx, parentBucketName(cnr), objKey) {
|
||||||
splitInfo, err := getSplitInfo(tx, &cnr, objKey)
|
splitInfo, err := getSplitInfo(tx, cnr, objKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -106,7 +105,7 @@ func (db *DB) exists(tx *bbolt.Tx, addr *addressSDK.Address) (exists bool, err e
|
||||||
// * 0 if object is not marked for deletion;
|
// * 0 if object is not marked for deletion;
|
||||||
// * 1 if object with GC mark;
|
// * 1 if object with GC mark;
|
||||||
// * 2 if object is covered with tombstone.
|
// * 2 if object is covered with tombstone.
|
||||||
func inGraveyard(tx *bbolt.Tx, addr *addressSDK.Address) uint8 {
|
func inGraveyard(tx *bbolt.Tx, addr oid.Address) uint8 {
|
||||||
graveyard := tx.Bucket(graveyardBucketName)
|
graveyard := tx.Bucket(graveyardBucketName)
|
||||||
if graveyard == nil {
|
if graveyard == nil {
|
||||||
// incorrect metabase state, does not make
|
// incorrect metabase state, does not make
|
||||||
|
@ -152,8 +151,8 @@ func inBucket(tx *bbolt.Tx, name, key []byte) bool {
|
||||||
|
|
||||||
// getSplitInfo returns SplitInfo structure from root index. Returns error
|
// getSplitInfo returns SplitInfo structure from root index. Returns error
|
||||||
// if there is no `key` record in root index.
|
// if there is no `key` record in root index.
|
||||||
func getSplitInfo(tx *bbolt.Tx, cid *cid.ID, key []byte) (*objectSDK.SplitInfo, error) {
|
func getSplitInfo(tx *bbolt.Tx, cnr cid.ID, key []byte) (*objectSDK.SplitInfo, error) {
|
||||||
rawSplitInfo := getFromBucket(tx, rootBucketName(cid), key)
|
rawSplitInfo := getFromBucket(tx, rootBucketName(cnr), key)
|
||||||
if len(rawSplitInfo) == 0 {
|
if len(rawSplitInfo) == 0 {
|
||||||
return nil, ErrLackSplitInfo
|
return nil, ErrLackSplitInfo
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,10 +68,10 @@ func TestDB_Exists(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("virtual object", func(t *testing.T) {
|
t.Run("virtual object", func(t *testing.T) {
|
||||||
cid := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
parent := generateObjectWithCID(t, cid)
|
parent := generateObjectWithCID(t, cnr)
|
||||||
|
|
||||||
child := generateObjectWithCID(t, cid)
|
child := generateObjectWithCID(t, cnr)
|
||||||
child.SetParent(parent)
|
child.SetParent(parent)
|
||||||
idParent, _ := parent.ID()
|
idParent, _ := parent.ID()
|
||||||
child.SetParentID(idParent)
|
child.SetParentID(idParent)
|
||||||
|
@ -86,19 +86,19 @@ func TestDB_Exists(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("merge split info", func(t *testing.T) {
|
t.Run("merge split info", func(t *testing.T) {
|
||||||
cid := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
splitID := objectSDK.NewSplitID()
|
splitID := objectSDK.NewSplitID()
|
||||||
|
|
||||||
parent := generateObjectWithCID(t, cid)
|
parent := generateObjectWithCID(t, cnr)
|
||||||
addAttribute(parent, "foo", "bar")
|
addAttribute(parent, "foo", "bar")
|
||||||
|
|
||||||
child := generateObjectWithCID(t, cid)
|
child := generateObjectWithCID(t, cnr)
|
||||||
child.SetParent(parent)
|
child.SetParent(parent)
|
||||||
idParent, _ := parent.ID()
|
idParent, _ := parent.ID()
|
||||||
child.SetParentID(idParent)
|
child.SetParentID(idParent)
|
||||||
child.SetSplitID(splitID)
|
child.SetSplitID(splitID)
|
||||||
|
|
||||||
link := generateObjectWithCID(t, cid)
|
link := generateObjectWithCID(t, cnr)
|
||||||
link.SetParent(parent)
|
link.SetParent(parent)
|
||||||
link.SetParentID(idParent)
|
link.SetParentID(idParent)
|
||||||
idChild, _ := child.ID()
|
idChild, _ := child.ID()
|
||||||
|
|
|
@ -6,13 +6,13 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetPrm groups the parameters of Get operation.
|
// GetPrm groups the parameters of Get operation.
|
||||||
type GetPrm struct {
|
type GetPrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
raw bool
|
raw bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ type GetRes struct {
|
||||||
// WithAddress is a Get option to set the address of the requested object.
|
// WithAddress is a Get option to set the address of the requested object.
|
||||||
//
|
//
|
||||||
// Option is required.
|
// Option is required.
|
||||||
func (p *GetPrm) WithAddress(addr *addressSDK.Address) *GetPrm {
|
func (p *GetPrm) WithAddress(addr oid.Address) *GetPrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ func (r *GetRes) Header() *objectSDK.Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reads the object from DB.
|
// Get reads the object from DB.
|
||||||
func Get(db *DB, addr *addressSDK.Address) (*objectSDK.Object, error) {
|
func Get(db *DB, addr oid.Address) (*objectSDK.Object, error) {
|
||||||
r, err := db.Get(new(GetPrm).WithAddress(addr))
|
r, err := db.Get(new(GetPrm).WithAddress(addr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -59,7 +59,7 @@ func Get(db *DB, addr *addressSDK.Address) (*objectSDK.Object, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRaw reads physically stored object from DB.
|
// GetRaw reads physically stored object from DB.
|
||||||
func GetRaw(db *DB, addr *addressSDK.Address, raw bool) (*objectSDK.Object, error) {
|
func GetRaw(db *DB, addr oid.Address, raw bool) (*objectSDK.Object, error) {
|
||||||
r, err := db.Get(new(GetPrm).WithAddress(addr).WithRaw(raw))
|
r, err := db.Get(new(GetPrm).WithAddress(addr).WithRaw(raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -84,10 +84,8 @@ func (db *DB) Get(prm *GetPrm) (res *GetRes, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) get(tx *bbolt.Tx, addr *addressSDK.Address, checkGraveyard, raw bool) (*objectSDK.Object, error) {
|
func (db *DB) get(tx *bbolt.Tx, addr oid.Address, checkGraveyard, raw bool) (*objectSDK.Object, error) {
|
||||||
id, _ := addr.ObjectID()
|
key := objectKey(addr.Object())
|
||||||
key := objectKey(&id)
|
|
||||||
cnr, _ := addr.ContainerID()
|
|
||||||
|
|
||||||
if checkGraveyard {
|
if checkGraveyard {
|
||||||
switch inGraveyard(tx, addr) {
|
switch inGraveyard(tx, addr) {
|
||||||
|
@ -102,22 +100,23 @@ func (db *DB) get(tx *bbolt.Tx, addr *addressSDK.Address, checkGraveyard, raw bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cnr := addr.Container()
|
||||||
obj := objectSDK.New()
|
obj := objectSDK.New()
|
||||||
|
|
||||||
// check in primary index
|
// check in primary index
|
||||||
data := getFromBucket(tx, primaryBucketName(&cnr), key)
|
data := getFromBucket(tx, primaryBucketName(cnr), key)
|
||||||
if len(data) != 0 {
|
if len(data) != 0 {
|
||||||
return obj, obj.Unmarshal(data)
|
return obj, obj.Unmarshal(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not found then check in tombstone index
|
// if not found then check in tombstone index
|
||||||
data = getFromBucket(tx, tombstoneBucketName(&cnr), key)
|
data = getFromBucket(tx, tombstoneBucketName(cnr), key)
|
||||||
if len(data) != 0 {
|
if len(data) != 0 {
|
||||||
return obj, obj.Unmarshal(data)
|
return obj, obj.Unmarshal(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not found then check in storage group index
|
// if not found then check in storage group index
|
||||||
data = getFromBucket(tx, storageGroupBucketName(&cnr), key)
|
data = getFromBucket(tx, storageGroupBucketName(cnr), key)
|
||||||
if len(data) != 0 {
|
if len(data) != 0 {
|
||||||
return obj, obj.Unmarshal(data)
|
return obj, obj.Unmarshal(data)
|
||||||
}
|
}
|
||||||
|
@ -129,7 +128,7 @@ func (db *DB) get(tx *bbolt.Tx, addr *addressSDK.Address, checkGraveyard, raw bo
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not found then check if object is a virtual
|
// if not found then check if object is a virtual
|
||||||
return getVirtualObject(tx, &cnr, key, raw)
|
return getVirtualObject(tx, cnr, key, raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFromBucket(tx *bbolt.Tx, name, key []byte) []byte {
|
func getFromBucket(tx *bbolt.Tx, name, key []byte) []byte {
|
||||||
|
@ -141,12 +140,12 @@ func getFromBucket(tx *bbolt.Tx, name, key []byte) []byte {
|
||||||
return bkt.Get(key)
|
return bkt.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVirtualObject(tx *bbolt.Tx, cid *cid.ID, key []byte, raw bool) (*objectSDK.Object, error) {
|
func getVirtualObject(tx *bbolt.Tx, cnr cid.ID, key []byte, raw bool) (*objectSDK.Object, error) {
|
||||||
if raw {
|
if raw {
|
||||||
return nil, getSplitInfoError(tx, cid, key)
|
return nil, getSplitInfoError(tx, cnr, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
parentBucket := tx.Bucket(parentBucketName(cid))
|
parentBucket := tx.Bucket(parentBucketName(cnr))
|
||||||
if parentBucket == nil {
|
if parentBucket == nil {
|
||||||
var errNotFound apistatus.ObjectNotFound
|
var errNotFound apistatus.ObjectNotFound
|
||||||
|
|
||||||
|
@ -168,7 +167,7 @@ func getVirtualObject(tx *bbolt.Tx, cid *cid.ID, key []byte, raw bool) (*objectS
|
||||||
// but later list might be sorted so first or last value can be more
|
// but later list might be sorted so first or last value can be more
|
||||||
// prioritized to choose
|
// prioritized to choose
|
||||||
virtualOID := relativeLst[len(relativeLst)-1]
|
virtualOID := relativeLst[len(relativeLst)-1]
|
||||||
data := getFromBucket(tx, primaryBucketName(cid), virtualOID)
|
data := getFromBucket(tx, primaryBucketName(cnr), virtualOID)
|
||||||
|
|
||||||
child := objectSDK.New()
|
child := objectSDK.New()
|
||||||
|
|
||||||
|
@ -188,8 +187,8 @@ func getVirtualObject(tx *bbolt.Tx, cid *cid.ID, key []byte, raw bool) (*objectS
|
||||||
return par, nil
|
return par, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSplitInfoError(tx *bbolt.Tx, cid *cid.ID, key []byte) error {
|
func getSplitInfoError(tx *bbolt.Tx, cnr cid.ID, key []byte) error {
|
||||||
splitInfo, err := getSplitInfo(tx, cid, key)
|
splitInfo, err := getSplitInfo(tx, cnr, key)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return objectSDK.NewSplitInfoError(splitInfo)
|
return objectSDK.NewSplitInfoError(splitInfo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -74,13 +73,13 @@ func TestDB_Get(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("put virtual object", func(t *testing.T) {
|
t.Run("put virtual object", func(t *testing.T) {
|
||||||
cid := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
splitID := objectSDK.NewSplitID()
|
splitID := objectSDK.NewSplitID()
|
||||||
|
|
||||||
parent := generateObjectWithCID(t, cid)
|
parent := generateObjectWithCID(t, cnr)
|
||||||
addAttribute(parent, "foo", "bar")
|
addAttribute(parent, "foo", "bar")
|
||||||
|
|
||||||
child := generateObjectWithCID(t, cid)
|
child := generateObjectWithCID(t, cnr)
|
||||||
child.SetParent(parent)
|
child.SetParent(parent)
|
||||||
idParent, _ := parent.ID()
|
idParent, _ := parent.ID()
|
||||||
child.SetParentID(idParent)
|
child.SetParentID(idParent)
|
||||||
|
@ -116,15 +115,16 @@ func TestDB_Get(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("get removed object", func(t *testing.T) {
|
t.Run("get removed object", func(t *testing.T) {
|
||||||
obj := objecttest.Address()
|
obj := oidtest.Address()
|
||||||
ts := objecttest.Address()
|
ts := oidtest.Address()
|
||||||
|
|
||||||
require.NoError(t, meta.Inhume(db, obj, ts))
|
require.NoError(t, meta.Inhume(db, obj, ts))
|
||||||
_, err := meta.Get(db, obj)
|
_, err := meta.Get(db, obj)
|
||||||
require.ErrorAs(t, err, new(apistatus.ObjectAlreadyRemoved))
|
require.ErrorAs(t, err, new(apistatus.ObjectAlreadyRemoved))
|
||||||
|
|
||||||
obj = objecttest.Address()
|
obj = oidtest.Address()
|
||||||
require.NoError(t, meta.Inhume(db, obj, nil))
|
_, err = db.Inhume(new(meta.InhumePrm).WithAddresses(obj))
|
||||||
|
require.NoError(t, err)
|
||||||
_, err = meta.Get(db, obj)
|
_, err = meta.Get(db, obj)
|
||||||
require.ErrorAs(t, err, new(apistatus.ObjectNotFound))
|
require.ErrorAs(t, err, new(apistatus.ObjectNotFound))
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,18 +5,18 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GarbageObject represents descriptor of the
|
// GarbageObject represents descriptor of the
|
||||||
// object that has been marked with GC.
|
// object that has been marked with GC.
|
||||||
type GarbageObject struct {
|
type GarbageObject struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address returns garbage object address.
|
// Address returns garbage object address.
|
||||||
func (g GarbageObject) Address() *addressSDK.Address {
|
func (g GarbageObject) Address() oid.Address {
|
||||||
return g.addr
|
return g.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ type GarbageHandler func(GarbageObject) error
|
||||||
// iteration process.
|
// iteration process.
|
||||||
type GarbageIterationPrm struct {
|
type GarbageIterationPrm struct {
|
||||||
h GarbageHandler
|
h GarbageHandler
|
||||||
offset *addressSDK.Address
|
offset *oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHandler sets a handler that will be called on every
|
// SetHandler sets a handler that will be called on every
|
||||||
|
@ -49,8 +49,8 @@ func (g *GarbageIterationPrm) SetHandler(h GarbageHandler) *GarbageIterationPrm
|
||||||
// next element.
|
// next element.
|
||||||
//
|
//
|
||||||
// Nil offset means start an integration from the beginning.
|
// Nil offset means start an integration from the beginning.
|
||||||
func (g *GarbageIterationPrm) SetOffset(offset *addressSDK.Address) *GarbageIterationPrm {
|
func (g *GarbageIterationPrm) SetOffset(offset oid.Address) *GarbageIterationPrm {
|
||||||
g.offset = offset
|
g.offset = &offset
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,18 +68,18 @@ func (db *DB) IterateOverGarbage(p *GarbageIterationPrm) error {
|
||||||
// TombstonedObject represents descriptor of the
|
// TombstonedObject represents descriptor of the
|
||||||
// object that has been covered with tombstone.
|
// object that has been covered with tombstone.
|
||||||
type TombstonedObject struct {
|
type TombstonedObject struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
tomb *addressSDK.Address
|
tomb oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address returns tombstoned object address.
|
// Address returns tombstoned object address.
|
||||||
func (g TombstonedObject) Address() *addressSDK.Address {
|
func (g TombstonedObject) Address() oid.Address {
|
||||||
return g.addr
|
return g.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tombstone returns address of a tombstone that
|
// Tombstone returns address of a tombstone that
|
||||||
// covers object.
|
// covers object.
|
||||||
func (g TombstonedObject) Tombstone() *addressSDK.Address {
|
func (g TombstonedObject) Tombstone() oid.Address {
|
||||||
return g.tomb
|
return g.tomb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ type TombstonedHandler func(object TombstonedObject) error
|
||||||
// iteration process.
|
// iteration process.
|
||||||
type GraveyardIterationPrm struct {
|
type GraveyardIterationPrm struct {
|
||||||
h TombstonedHandler
|
h TombstonedHandler
|
||||||
offset *addressSDK.Address
|
offset *oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHandler sets a handler that will be called on every
|
// SetHandler sets a handler that will be called on every
|
||||||
|
@ -112,8 +112,8 @@ func (g *GraveyardIterationPrm) SetHandler(h TombstonedHandler) *GraveyardIterat
|
||||||
// next element.
|
// next element.
|
||||||
//
|
//
|
||||||
// Nil offset means start an integration from the beginning.
|
// Nil offset means start an integration from the beginning.
|
||||||
func (g *GraveyardIterationPrm) SetOffset(offset *addressSDK.Address) *GraveyardIterationPrm {
|
func (g *GraveyardIterationPrm) SetOffset(offset oid.Address) *GraveyardIterationPrm {
|
||||||
g.offset = offset
|
g.offset = &offset
|
||||||
return g
|
return g
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ func (g graveyardHandler) handleKV(k, v []byte) error {
|
||||||
return g.h(o)
|
return g.h(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) iterateDeletedObj(tx *bbolt.Tx, h kvHandler, offset *addressSDK.Address) error {
|
func (db *DB) iterateDeletedObj(tx *bbolt.Tx, h kvHandler, offset *oid.Address) error {
|
||||||
var bkt *bbolt.Bucket
|
var bkt *bbolt.Bucket
|
||||||
switch t := h.(type) {
|
switch t := h.(type) {
|
||||||
case graveyardHandler:
|
case graveyardHandler:
|
||||||
|
@ -178,7 +178,7 @@ func (db *DB) iterateDeletedObj(tx *bbolt.Tx, h kvHandler, offset *addressSDK.Ad
|
||||||
if offset == nil {
|
if offset == nil {
|
||||||
k, v = c.First()
|
k, v = c.First()
|
||||||
} else {
|
} else {
|
||||||
rawAddr := addressKey(offset)
|
rawAddr := addressKey(*offset)
|
||||||
|
|
||||||
k, v = c.Seek(rawAddr)
|
k, v = c.Seek(rawAddr)
|
||||||
if bytes.Equal(k, rawAddr) {
|
if bytes.Equal(k, rawAddr) {
|
||||||
|
@ -202,32 +202,23 @@ func (db *DB) iterateDeletedObj(tx *bbolt.Tx, h kvHandler, offset *addressSDK.Ad
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func garbageFromKV(k []byte) (GarbageObject, error) {
|
func garbageFromKV(k []byte) (res GarbageObject, err error) {
|
||||||
addr, err := addressFromKey(k)
|
err = decodeAddressFromKey(&res.addr, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GarbageObject{}, fmt.Errorf("could not parse address: %w", err)
|
err = fmt.Errorf("could not parse address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return GarbageObject{
|
return
|
||||||
addr: addr,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func graveFromKV(k, v []byte) (TombstonedObject, error) {
|
func graveFromKV(k, v []byte) (res TombstonedObject, err error) {
|
||||||
target, err := addressFromKey(k)
|
if err = decodeAddressFromKey(&res.addr, k); err != nil {
|
||||||
if err != nil {
|
err = fmt.Errorf("decode tombstone target from key: %w", err)
|
||||||
return TombstonedObject{}, fmt.Errorf("could not parse address: %w", err)
|
} else if err = decodeAddressFromKey(&res.tomb, v); err != nil {
|
||||||
|
err = fmt.Errorf("decode tombstone address from value: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tomb, err := addressFromKey(v)
|
return
|
||||||
if err != nil {
|
|
||||||
return TombstonedObject{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return TombstonedObject{
|
|
||||||
addr: target,
|
|
||||||
tomb: tomb,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DropGraves deletes tombstoned objects from the
|
// DropGraves deletes tombstoned objects from the
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,27 +39,23 @@ func TestDB_Iterate_OffsetNotFound(t *testing.T) {
|
||||||
obj1 := generateObject(t)
|
obj1 := generateObject(t)
|
||||||
obj2 := generateObject(t)
|
obj2 := generateObject(t)
|
||||||
|
|
||||||
addr1 := addressSDK.NewAddress()
|
var addr1 oid.Address
|
||||||
err := addr1.Parse("AUSF6rhReoAdPVKYUZWW9o2LbtTvekn54B3JXi7pdzmn/2daLhLB7yVXbjBaKkckkuvjX22BxRYuSHy9RPxuH9PZS")
|
err := addr1.DecodeString("AUSF6rhReoAdPVKYUZWW9o2LbtTvekn54B3JXi7pdzmn/2daLhLB7yVXbjBaKkckkuvjX22BxRYuSHy9RPxuH9PZS")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
addr2 := addressSDK.NewAddress()
|
var addr2 oid.Address
|
||||||
err = addr2.Parse("CwYYr6sFLU1zK6DeBTVd8SReADUoxYobUhSrxgXYxCVn/ANYbnJoQqdjmU5Dhk3LkxYj5E9nJHQFf8LjTEcap9TxM")
|
err = addr2.DecodeString("CwYYr6sFLU1zK6DeBTVd8SReADUoxYobUhSrxgXYxCVn/ANYbnJoQqdjmU5Dhk3LkxYj5E9nJHQFf8LjTEcap9TxM")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
addr3 := addressSDK.NewAddress()
|
var addr3 oid.Address
|
||||||
err = addr3.Parse("6ay4GfhR9RgN28d5ufg63toPetkYHGcpcW7G3b7QWSek/ANYbnJoQqdjmU5Dhk3LkxYj5E9nJHQFf8LjTEcap9TxM")
|
err = addr3.DecodeString("6ay4GfhR9RgN28d5ufg63toPetkYHGcpcW7G3b7QWSek/ANYbnJoQqdjmU5Dhk3LkxYj5E9nJHQFf8LjTEcap9TxM")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cnr, _ := addr1.ContainerID()
|
obj1.SetContainerID(addr1.Container())
|
||||||
obj1.SetContainerID(cnr)
|
obj1.SetID(addr1.Object())
|
||||||
id, _ := addr1.ObjectID()
|
|
||||||
obj1.SetID(id)
|
|
||||||
|
|
||||||
cnr, _ = addr2.ContainerID()
|
obj2.SetContainerID(addr2.Container())
|
||||||
obj2.SetContainerID(cnr)
|
obj2.SetID(addr2.Object())
|
||||||
id, _ = addr2.ObjectID()
|
|
||||||
obj2.SetID(id)
|
|
||||||
|
|
||||||
err = putBig(db, obj1)
|
err = putBig(db, obj1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -75,14 +71,14 @@ func TestDB_Iterate_OffsetNotFound(t *testing.T) {
|
||||||
iterGCPRM := new(meta.GarbageIterationPrm).
|
iterGCPRM := new(meta.GarbageIterationPrm).
|
||||||
SetOffset(object.AddressOf(obj2)).
|
SetOffset(object.AddressOf(obj2)).
|
||||||
SetHandler(func(garbage meta.GarbageObject) error {
|
SetHandler(func(garbage meta.GarbageObject) error {
|
||||||
require.Equal(t, *garbage.Address(), *addr1)
|
require.Equal(t, garbage.Address(), addr1)
|
||||||
counter++
|
counter++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
err = db.IterateOverGarbage(iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error {
|
err = db.IterateOverGarbage(iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error {
|
||||||
require.Equal(t, *garbage.Address(), *addr1)
|
require.Equal(t, garbage.Address(), addr1)
|
||||||
counter++
|
counter++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -96,7 +92,7 @@ func TestDB_Iterate_OffsetNotFound(t *testing.T) {
|
||||||
|
|
||||||
iterGCPRM.SetOffset(addr3)
|
iterGCPRM.SetOffset(addr3)
|
||||||
err = db.IterateOverGarbage(iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error {
|
err = db.IterateOverGarbage(iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error {
|
||||||
require.Equal(t, *garbage.Address(), *addr1)
|
require.Equal(t, garbage.Address(), addr1)
|
||||||
counter++
|
counter++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -135,7 +131,7 @@ func TestDB_IterateDeletedObjects(t *testing.T) {
|
||||||
inhumePrm := new(meta.InhumePrm)
|
inhumePrm := new(meta.InhumePrm)
|
||||||
|
|
||||||
// inhume with tombstone
|
// inhume with tombstone
|
||||||
addrTombstone := objecttest.Address()
|
addrTombstone := oidtest.Address()
|
||||||
|
|
||||||
_, err = db.Inhume(inhumePrm.
|
_, err = db.Inhume(inhumePrm.
|
||||||
WithAddresses(object.AddressOf(obj1), object.AddressOf(obj2)).
|
WithAddresses(object.AddressOf(obj1), object.AddressOf(obj2)).
|
||||||
|
@ -152,13 +148,13 @@ func TestDB_IterateDeletedObjects(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
counterAll int
|
counterAll int
|
||||||
buriedTS, buriedGC []*addressSDK.Address
|
buriedTS, buriedGC []oid.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
iterGravePRM := new(meta.GraveyardIterationPrm)
|
iterGravePRM := new(meta.GraveyardIterationPrm)
|
||||||
|
|
||||||
err = db.IterateOverGraveyard(iterGravePRM.SetHandler(func(tomstoned meta.TombstonedObject) error {
|
err = db.IterateOverGraveyard(iterGravePRM.SetHandler(func(tomstoned meta.TombstonedObject) error {
|
||||||
require.Equal(t, *addrTombstone, *tomstoned.Tombstone())
|
require.Equal(t, addrTombstone, tomstoned.Tombstone())
|
||||||
|
|
||||||
buriedTS = append(buriedTS, tomstoned.Address())
|
buriedTS = append(buriedTS, tomstoned.Address())
|
||||||
counterAll++
|
counterAll++
|
||||||
|
@ -179,12 +175,12 @@ func TestDB_IterateDeletedObjects(t *testing.T) {
|
||||||
|
|
||||||
// objects covered with a tombstone
|
// objects covered with a tombstone
|
||||||
// also receive GS mark
|
// also receive GS mark
|
||||||
garbageExpected := []*addressSDK.Address{
|
garbageExpected := []oid.Address{
|
||||||
object.AddressOf(obj1), object.AddressOf(obj2),
|
object.AddressOf(obj1), object.AddressOf(obj2),
|
||||||
object.AddressOf(obj3), object.AddressOf(obj4),
|
object.AddressOf(obj3), object.AddressOf(obj4),
|
||||||
}
|
}
|
||||||
|
|
||||||
graveyardExpected := []*addressSDK.Address{
|
graveyardExpected := []oid.Address{
|
||||||
object.AddressOf(obj1), object.AddressOf(obj2),
|
object.AddressOf(obj1), object.AddressOf(obj2),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +215,7 @@ func TestDB_IterateOverGraveyard_Offset(t *testing.T) {
|
||||||
inhumePrm := new(meta.InhumePrm)
|
inhumePrm := new(meta.InhumePrm)
|
||||||
|
|
||||||
// inhume with tombstone
|
// inhume with tombstone
|
||||||
addrTombstone := objecttest.Address()
|
addrTombstone := oidtest.Address()
|
||||||
|
|
||||||
_, err = db.Inhume(inhumePrm.
|
_, err = db.Inhume(inhumePrm.
|
||||||
WithAddresses(object.AddressOf(obj1), object.AddressOf(obj2), object.AddressOf(obj3), object.AddressOf(obj4)).
|
WithAddresses(object.AddressOf(obj1), object.AddressOf(obj2), object.AddressOf(obj3), object.AddressOf(obj4)).
|
||||||
|
@ -227,7 +223,7 @@ func TestDB_IterateOverGraveyard_Offset(t *testing.T) {
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expectedGraveyard := []*addressSDK.Address{
|
expectedGraveyard := []oid.Address{
|
||||||
object.AddressOf(obj1), object.AddressOf(obj2),
|
object.AddressOf(obj1), object.AddressOf(obj2),
|
||||||
object.AddressOf(obj3), object.AddressOf(obj4),
|
object.AddressOf(obj3), object.AddressOf(obj4),
|
||||||
}
|
}
|
||||||
|
@ -236,13 +232,13 @@ func TestDB_IterateOverGraveyard_Offset(t *testing.T) {
|
||||||
counter int
|
counter int
|
||||||
firstIterationSize = len(expectedGraveyard) / 2
|
firstIterationSize = len(expectedGraveyard) / 2
|
||||||
|
|
||||||
gotGraveyard []*addressSDK.Address
|
gotGraveyard []oid.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
iterGraveyardPrm := new(meta.GraveyardIterationPrm)
|
iterGraveyardPrm := new(meta.GraveyardIterationPrm)
|
||||||
|
|
||||||
err = db.IterateOverGraveyard(iterGraveyardPrm.SetHandler(func(tombstoned meta.TombstonedObject) error {
|
err = db.IterateOverGraveyard(iterGraveyardPrm.SetHandler(func(tombstoned meta.TombstonedObject) error {
|
||||||
require.Equal(t, *addrTombstone, *tombstoned.Tombstone())
|
require.Equal(t, addrTombstone, tombstoned.Tombstone())
|
||||||
|
|
||||||
gotGraveyard = append(gotGraveyard, tombstoned.Address())
|
gotGraveyard = append(gotGraveyard, tombstoned.Address())
|
||||||
|
|
||||||
|
@ -262,7 +258,7 @@ func TestDB_IterateOverGraveyard_Offset(t *testing.T) {
|
||||||
iterGraveyardPrm.SetOffset(offset)
|
iterGraveyardPrm.SetOffset(offset)
|
||||||
|
|
||||||
err = db.IterateOverGraveyard(iterGraveyardPrm.SetHandler(func(tombstoned meta.TombstonedObject) error {
|
err = db.IterateOverGraveyard(iterGraveyardPrm.SetHandler(func(tombstoned meta.TombstonedObject) error {
|
||||||
require.Equal(t, *addrTombstone, *tombstoned.Tombstone())
|
require.Equal(t, addrTombstone, tombstoned.Tombstone())
|
||||||
|
|
||||||
gotGraveyard = append(gotGraveyard, tombstoned.Address())
|
gotGraveyard = append(gotGraveyard, tombstoned.Address())
|
||||||
counter++
|
counter++
|
||||||
|
@ -319,7 +315,7 @@ func TestDB_IterateOverGarbage_Offset(t *testing.T) {
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expectedGarbage := []*addressSDK.Address{
|
expectedGarbage := []oid.Address{
|
||||||
object.AddressOf(obj1), object.AddressOf(obj2),
|
object.AddressOf(obj1), object.AddressOf(obj2),
|
||||||
object.AddressOf(obj3), object.AddressOf(obj4),
|
object.AddressOf(obj3), object.AddressOf(obj4),
|
||||||
}
|
}
|
||||||
|
@ -328,7 +324,7 @@ func TestDB_IterateOverGarbage_Offset(t *testing.T) {
|
||||||
counter int
|
counter int
|
||||||
firstIterationSize = len(expectedGarbage) / 2
|
firstIterationSize = len(expectedGarbage) / 2
|
||||||
|
|
||||||
gotGarbage []*addressSDK.Address
|
gotGarbage []oid.Address
|
||||||
)
|
)
|
||||||
|
|
||||||
iterGarbagePrm := new(meta.GarbageIterationPrm)
|
iterGarbagePrm := new(meta.GarbageIterationPrm)
|
||||||
|
@ -394,7 +390,7 @@ func TestDB_DropGraves(t *testing.T) {
|
||||||
inhumePrm := new(meta.InhumePrm)
|
inhumePrm := new(meta.InhumePrm)
|
||||||
|
|
||||||
// inhume with tombstone
|
// inhume with tombstone
|
||||||
addrTombstone := objecttest.Address()
|
addrTombstone := oidtest.Address()
|
||||||
|
|
||||||
_, err = db.Inhume(inhumePrm.
|
_, err = db.Inhume(inhumePrm.
|
||||||
WithAddresses(object.AddressOf(obj1), object.AddressOf(obj2)).
|
WithAddresses(object.AddressOf(obj1), object.AddressOf(obj2)).
|
||||||
|
|
|
@ -7,22 +7,22 @@ import (
|
||||||
|
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InhumePrm encapsulates parameters for Inhume operation.
|
// InhumePrm encapsulates parameters for Inhume operation.
|
||||||
type InhumePrm struct {
|
type InhumePrm struct {
|
||||||
tomb *addressSDK.Address
|
tomb *oid.Address
|
||||||
|
|
||||||
target []*addressSDK.Address
|
target []oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// InhumeRes encapsulates results of Inhume operation.
|
// InhumeRes encapsulates results of Inhume operation.
|
||||||
type InhumeRes struct{}
|
type InhumeRes struct{}
|
||||||
|
|
||||||
// WithAddresses sets a list of object addresses that should be inhumed.
|
// WithAddresses sets a list of object addresses that should be inhumed.
|
||||||
func (p *InhumePrm) WithAddresses(addrs ...*addressSDK.Address) *InhumePrm {
|
func (p *InhumePrm) WithAddresses(addrs ...oid.Address) *InhumePrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.target = addrs
|
p.target = addrs
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,9 @@ func (p *InhumePrm) WithAddresses(addrs ...*addressSDK.Address) *InhumePrm {
|
||||||
//
|
//
|
||||||
// addr should not be nil.
|
// addr should not be nil.
|
||||||
// Should not be called along with WithGCMark.
|
// Should not be called along with WithGCMark.
|
||||||
func (p *InhumePrm) WithTombstoneAddress(addr *addressSDK.Address) *InhumePrm {
|
func (p *InhumePrm) WithTombstoneAddress(addr oid.Address) *InhumePrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.tomb = addr
|
p.tomb = &addr
|
||||||
}
|
}
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
@ -56,7 +56,7 @@ func (p *InhumePrm) WithGCMark() *InhumePrm {
|
||||||
// Inhume inhumes the object by specified address.
|
// Inhume inhumes the object by specified address.
|
||||||
//
|
//
|
||||||
// tomb should not be nil.
|
// tomb should not be nil.
|
||||||
func Inhume(db *DB, target, tomb *addressSDK.Address) error {
|
func Inhume(db *DB, target, tomb oid.Address) error {
|
||||||
_, err := db.Inhume(new(InhumePrm).
|
_, err := db.Inhume(new(InhumePrm).
|
||||||
WithAddresses(target).
|
WithAddresses(target).
|
||||||
WithTombstoneAddress(tomb),
|
WithTombstoneAddress(tomb),
|
||||||
|
@ -89,7 +89,7 @@ func (db *DB) Inhume(prm *InhumePrm) (res *InhumeRes, err error) {
|
||||||
|
|
||||||
if prm.tomb != nil {
|
if prm.tomb != nil {
|
||||||
bkt = tx.Bucket(graveyardBucketName)
|
bkt = tx.Bucket(graveyardBucketName)
|
||||||
tombKey := addressKey(prm.tomb)
|
tombKey := addressKey(*prm.tomb)
|
||||||
|
|
||||||
// it is forbidden to have a tomb-on-tomb in NeoFS,
|
// it is forbidden to have a tomb-on-tomb in NeoFS,
|
||||||
// so graveyard keys must not be addresses of tombstones
|
// so graveyard keys must not be addresses of tombstones
|
||||||
|
@ -108,8 +108,8 @@ func (db *DB) Inhume(prm *InhumePrm) (res *InhumeRes, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range prm.target {
|
for i := range prm.target {
|
||||||
id, _ := prm.target[i].ObjectID()
|
id := prm.target[i].Object()
|
||||||
cnr, _ := prm.target[i].ContainerID()
|
cnr := prm.target[i].Container()
|
||||||
|
|
||||||
// prevent locked objects to be inhumed
|
// prevent locked objects to be inhumed
|
||||||
if objectLocked(tx, cnr, id) {
|
if objectLocked(tx, cnr, id) {
|
||||||
|
@ -121,12 +121,7 @@ func (db *DB) Inhume(prm *InhumePrm) (res *InhumeRes, err error) {
|
||||||
// if object is stored and it is regular object then update bucket
|
// if object is stored and it is regular object then update bucket
|
||||||
// with container size estimations
|
// with container size estimations
|
||||||
if err == nil && obj.Type() == object.TypeRegular {
|
if err == nil && obj.Type() == object.TypeRegular {
|
||||||
err := changeContainerSize(
|
err := changeContainerSize(tx, cnr, obj.PayloadSize(), false)
|
||||||
tx,
|
|
||||||
&cnr,
|
|
||||||
obj.PayloadSize(),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -18,7 +17,7 @@ func TestDB_Inhume(t *testing.T) {
|
||||||
raw := generateObject(t)
|
raw := generateObject(t)
|
||||||
addAttribute(raw, "foo", "bar")
|
addAttribute(raw, "foo", "bar")
|
||||||
|
|
||||||
tombstoneID := objecttest.Address()
|
tombstoneID := oidtest.Address()
|
||||||
|
|
||||||
err := putBig(db, raw)
|
err := putBig(db, raw)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -39,9 +38,9 @@ func TestInhumeTombOnTomb(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
|
||||||
addr1 = objecttest.Address()
|
addr1 = oidtest.Address()
|
||||||
addr2 = objecttest.Address()
|
addr2 = oidtest.Address()
|
||||||
addr3 = objecttest.Address()
|
addr3 = oidtest.Address()
|
||||||
inhumePrm = new(meta.InhumePrm)
|
inhumePrm = new(meta.InhumePrm)
|
||||||
existsPrm = new(meta.ExistsPrm)
|
existsPrm = new(meta.ExistsPrm)
|
||||||
)
|
)
|
||||||
|
@ -78,7 +77,7 @@ func TestInhumeTombOnTomb(t *testing.T) {
|
||||||
// try to inhume addr1 (which is already a tombstone in graveyard)
|
// try to inhume addr1 (which is already a tombstone in graveyard)
|
||||||
_, err = db.Inhume(inhumePrm.
|
_, err = db.Inhume(inhumePrm.
|
||||||
WithAddresses(addr1).
|
WithAddresses(addr1).
|
||||||
WithTombstoneAddress(objecttest.Address()),
|
WithTombstoneAddress(oidtest.Address()),
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -92,15 +91,13 @@ func TestInhumeTombOnTomb(t *testing.T) {
|
||||||
func TestInhumeLocked(t *testing.T) {
|
func TestInhumeLocked(t *testing.T) {
|
||||||
db := newDB(t)
|
db := newDB(t)
|
||||||
|
|
||||||
locked := *objecttest.Address()
|
locked := oidtest.Address()
|
||||||
cnr, _ := locked.ContainerID()
|
|
||||||
id, _ := locked.ObjectID()
|
|
||||||
|
|
||||||
err := db.Lock(cnr, oidtest.ID(), []oid.ID{id})
|
err := db.Lock(locked.Container(), oidtest.ID(), []oid.ID{locked.Object()})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var prm meta.InhumePrm
|
var prm meta.InhumePrm
|
||||||
prm.WithAddresses(&locked)
|
prm.WithAddresses(locked)
|
||||||
|
|
||||||
_, err = db.Inhume(&prm)
|
_, err = db.Inhume(&prm)
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@ import (
|
||||||
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidSDK "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,7 +16,7 @@ import (
|
||||||
type ExpiredObject struct {
|
type ExpiredObject struct {
|
||||||
typ object.Type
|
typ object.Type
|
||||||
|
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type returns type of the expired object.
|
// Type returns type of the expired object.
|
||||||
|
@ -26,7 +25,7 @@ func (e *ExpiredObject) Type() object.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Address returns address of the expired object.
|
// Address returns address of the expired object.
|
||||||
func (e *ExpiredObject) Address() *addressSDK.Address {
|
func (e *ExpiredObject) Address() oid.Address {
|
||||||
return e.addr
|
return e.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +69,7 @@ func (db *DB) iterateExpired(tx *bbolt.Tx, epoch uint64, h ExpiredObjectHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bktExpired.ForEach(func(idKey, _ []byte) error {
|
return bktExpired.ForEach(func(idKey, _ []byte) error {
|
||||||
var id oidSDK.ID
|
var id oid.ID
|
||||||
|
|
||||||
err = id.DecodeString(string(idKey))
|
err = id.DecodeString(string(idKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -92,9 +91,9 @@ func (db *DB) iterateExpired(tx *bbolt.Tx, epoch uint64, h ExpiredObjectHandler)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := addressSDK.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetContainerID(cnrID)
|
addr.SetContainer(cnrID)
|
||||||
addr.SetObjectID(id)
|
addr.SetObject(id)
|
||||||
|
|
||||||
return h(&ExpiredObject{
|
return h(&ExpiredObject{
|
||||||
typ: firstIrregularObjectType(tx, cnrID, idKey),
|
typ: firstIrregularObjectType(tx, cnrID, idKey),
|
||||||
|
@ -119,13 +118,13 @@ func (db *DB) iterateExpired(tx *bbolt.Tx, epoch uint64, h ExpiredObjectHandler)
|
||||||
// Returns other errors of h directly.
|
// Returns other errors of h directly.
|
||||||
//
|
//
|
||||||
// Does not modify tss.
|
// Does not modify tss.
|
||||||
func (db *DB) IterateCoveredByTombstones(tss map[string]*addressSDK.Address, h func(*addressSDK.Address) error) error {
|
func (db *DB) IterateCoveredByTombstones(tss map[string]oid.Address, h func(oid.Address) error) error {
|
||||||
return db.boltDB.View(func(tx *bbolt.Tx) error {
|
return db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||||
return db.iterateCoveredByTombstones(tx, tss, h)
|
return db.iterateCoveredByTombstones(tx, tss, h)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) iterateCoveredByTombstones(tx *bbolt.Tx, tss map[string]*addressSDK.Address, h func(*addressSDK.Address) error) error {
|
func (db *DB) iterateCoveredByTombstones(tx *bbolt.Tx, tss map[string]oid.Address, h func(oid.Address) error) error {
|
||||||
bktGraveyard := tx.Bucket(graveyardBucketName)
|
bktGraveyard := tx.Bucket(graveyardBucketName)
|
||||||
if bktGraveyard == nil {
|
if bktGraveyard == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -133,15 +132,14 @@ func (db *DB) iterateCoveredByTombstones(tx *bbolt.Tx, tss map[string]*addressSD
|
||||||
|
|
||||||
err := bktGraveyard.ForEach(func(k, v []byte) error {
|
err := bktGraveyard.ForEach(func(k, v []byte) error {
|
||||||
if _, ok := tss[string(v)]; ok {
|
if _, ok := tss[string(v)]; ok {
|
||||||
addr, err := addressFromKey(k)
|
var addr oid.Address
|
||||||
|
|
||||||
|
err := decodeAddressFromKey(&addr, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not parse address of the object under tombstone: %w", err)
|
return fmt.Errorf("could not parse address of the object under tombstone: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cnr, _ := addr.ContainerID()
|
if objectLocked(tx, addr.Container(), addr.Object()) {
|
||||||
obj, _ := addr.ObjectID()
|
|
||||||
|
|
||||||
if objectLocked(tx, cnr, obj) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,6 @@ import (
|
||||||
object2 "github.com/nspcc-dev/neofs-node/pkg/core/object"
|
object2 "github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -20,8 +18,8 @@ func TestDB_IterateExpired(t *testing.T) {
|
||||||
|
|
||||||
const epoch = 13
|
const epoch = 13
|
||||||
|
|
||||||
mAlive := map[object.Type]*addressSDK.Address{}
|
mAlive := map[object.Type]oid.Address{}
|
||||||
mExpired := map[object.Type]*addressSDK.Address{}
|
mExpired := map[object.Type]oid.Address{}
|
||||||
|
|
||||||
for _, typ := range []object.Type{
|
for _, typ := range []object.Type{
|
||||||
object.TypeRegular,
|
object.TypeRegular,
|
||||||
|
@ -34,10 +32,8 @@ func TestDB_IterateExpired(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
expiredLocked := putWithExpiration(t, db, object.TypeRegular, epoch-1)
|
expiredLocked := putWithExpiration(t, db, object.TypeRegular, epoch-1)
|
||||||
cnrExpiredLocked, _ := expiredLocked.ContainerID()
|
|
||||||
idExpiredLocked, _ := expiredLocked.ObjectID()
|
|
||||||
|
|
||||||
require.NoError(t, db.Lock(cnrExpiredLocked, oidtest.ID(), []oid.ID{idExpiredLocked}))
|
require.NoError(t, db.Lock(expiredLocked.Container(), oidtest.ID(), []oid.ID{expiredLocked.Object()}))
|
||||||
|
|
||||||
err := db.IterateExpired(epoch, func(exp *meta.ExpiredObject) error {
|
err := db.IterateExpired(epoch, func(exp *meta.ExpiredObject) error {
|
||||||
if addr, ok := mAlive[exp.Type()]; ok {
|
if addr, ok := mAlive[exp.Type()]; ok {
|
||||||
|
@ -59,7 +55,7 @@ func TestDB_IterateExpired(t *testing.T) {
|
||||||
require.Empty(t, mExpired)
|
require.Empty(t, mExpired)
|
||||||
}
|
}
|
||||||
|
|
||||||
func putWithExpiration(t *testing.T, db *meta.DB, typ object.Type, expiresAt uint64) *addressSDK.Address {
|
func putWithExpiration(t *testing.T, db *meta.DB, typ object.Type, expiresAt uint64) oid.Address {
|
||||||
obj := generateObject(t)
|
obj := generateObject(t)
|
||||||
obj.SetType(typ)
|
obj.SetType(typ)
|
||||||
addAttribute(obj, objectV2.SysAttributeExpEpoch, strconv.FormatUint(expiresAt, 10))
|
addAttribute(obj, objectV2.SysAttributeExpEpoch, strconv.FormatUint(expiresAt, 10))
|
||||||
|
@ -72,11 +68,11 @@ func putWithExpiration(t *testing.T, db *meta.DB, typ object.Type, expiresAt uin
|
||||||
func TestDB_IterateCoveredByTombstones(t *testing.T) {
|
func TestDB_IterateCoveredByTombstones(t *testing.T) {
|
||||||
db := newDB(t)
|
db := newDB(t)
|
||||||
|
|
||||||
ts := objecttest.Address()
|
ts := oidtest.Address()
|
||||||
protected1 := objecttest.Address()
|
protected1 := oidtest.Address()
|
||||||
protected2 := objecttest.Address()
|
protected2 := oidtest.Address()
|
||||||
protectedLocked := objecttest.Address()
|
protectedLocked := oidtest.Address()
|
||||||
garbage := objecttest.Address()
|
garbage := oidtest.Address()
|
||||||
|
|
||||||
prm := new(meta.InhumePrm)
|
prm := new(meta.InhumePrm)
|
||||||
|
|
||||||
|
@ -94,13 +90,13 @@ func TestDB_IterateCoveredByTombstones(t *testing.T) {
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var handled []*addressSDK.Address
|
var handled []oid.Address
|
||||||
|
|
||||||
tss := map[string]*addressSDK.Address{
|
tss := map[string]oid.Address{
|
||||||
ts.String(): ts,
|
ts.EncodeToString(): ts,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.IterateCoveredByTombstones(tss, func(addr *addressSDK.Address) error {
|
err = db.IterateCoveredByTombstones(tss, func(addr oid.Address) error {
|
||||||
handled = append(handled, addr)
|
handled = append(handled, addr)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -111,15 +107,12 @@ func TestDB_IterateCoveredByTombstones(t *testing.T) {
|
||||||
require.Contains(t, handled, protected2)
|
require.Contains(t, handled, protected2)
|
||||||
require.Contains(t, handled, protectedLocked)
|
require.Contains(t, handled, protectedLocked)
|
||||||
|
|
||||||
cnrProtectedLocked, _ := protectedLocked.ContainerID()
|
err = db.Lock(protectedLocked.Container(), oidtest.ID(), []oid.ID{protectedLocked.Object()})
|
||||||
idProtectedLocked, _ := protectedLocked.ObjectID()
|
|
||||||
|
|
||||||
err = db.Lock(cnrProtectedLocked, oidtest.ID(), []oid.ID{idProtectedLocked})
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
handled = handled[:0]
|
handled = handled[:0]
|
||||||
|
|
||||||
err = db.IterateCoveredByTombstones(tss, func(addr *addressSDK.Address) error {
|
err = db.IterateCoveredByTombstones(tss, func(addr oid.Address) error {
|
||||||
handled = append(handled, addr)
|
handled = append(handled, addr)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,12 +42,12 @@ func (l *ListPrm) WithCursor(cursor *Cursor) *ListPrm {
|
||||||
|
|
||||||
// ListRes contains values returned from ListWithCursor operation.
|
// ListRes contains values returned from ListWithCursor operation.
|
||||||
type ListRes struct {
|
type ListRes struct {
|
||||||
addrList []*addressSDK.Address
|
addrList []oid.Address
|
||||||
cursor *Cursor
|
cursor *Cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressList returns addresses selected by ListWithCursor operation.
|
// AddressList returns addresses selected by ListWithCursor operation.
|
||||||
func (l ListRes) AddressList() []*addressSDK.Address {
|
func (l ListRes) AddressList() []oid.Address {
|
||||||
return l.addrList
|
return l.addrList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ func (l ListRes) Cursor() *Cursor {
|
||||||
//
|
//
|
||||||
// Returns ErrEndOfListing if there are no more objects to return or count
|
// Returns ErrEndOfListing if there are no more objects to return or count
|
||||||
// parameter set to zero.
|
// parameter set to zero.
|
||||||
func ListWithCursor(db *DB, count uint32, cursor *Cursor) ([]*addressSDK.Address, *Cursor, error) {
|
func ListWithCursor(db *DB, count uint32, cursor *Cursor) ([]oid.Address, *Cursor, error) {
|
||||||
r, err := db.ListWithCursor(new(ListPrm).WithCount(count).WithCursor(cursor))
|
r, err := db.ListWithCursor(new(ListPrm).WithCount(count).WithCursor(cursor))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -87,9 +87,9 @@ func (db *DB) ListWithCursor(prm *ListPrm) (res *ListRes, err error) {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) listWithCursor(tx *bbolt.Tx, count int, cursor *Cursor) ([]*addressSDK.Address, *Cursor, error) {
|
func (db *DB) listWithCursor(tx *bbolt.Tx, count int, cursor *Cursor) ([]oid.Address, *Cursor, error) {
|
||||||
threshold := cursor == nil // threshold is a flag to ignore cursor
|
threshold := cursor == nil // threshold is a flag to ignore cursor
|
||||||
result := make([]*addressSDK.Address, 0, count)
|
result := make([]oid.Address, 0, count)
|
||||||
var bucketName []byte
|
var bucketName []byte
|
||||||
|
|
||||||
c := tx.Cursor()
|
c := tx.Cursor()
|
||||||
|
@ -116,7 +116,7 @@ loop:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix := containerID.String() + "/"
|
prefix := containerID.EncodeToString() + "/"
|
||||||
|
|
||||||
result, cursor = selectNFromBucket(tx, name, prefix, result, count, cursor, threshold)
|
result, cursor = selectNFromBucket(tx, name, prefix, result, count, cursor, threshold)
|
||||||
bucketName = name
|
bucketName = name
|
||||||
|
@ -145,12 +145,12 @@ loop:
|
||||||
// object to start selecting from. Ignores inhumed objects.
|
// object to start selecting from. Ignores inhumed objects.
|
||||||
func selectNFromBucket(tx *bbolt.Tx,
|
func selectNFromBucket(tx *bbolt.Tx,
|
||||||
name []byte, // bucket name
|
name []byte, // bucket name
|
||||||
prefix string, // string of CID, optimization
|
prefix string, // string of container ID, optimization
|
||||||
to []*addressSDK.Address, // listing result
|
to []oid.Address, // listing result
|
||||||
limit int, // stop listing at `limit` items in result
|
limit int, // stop listing at `limit` items in result
|
||||||
cursor *Cursor, // start from cursor object
|
cursor *Cursor, // start from cursor object
|
||||||
threshold bool, // ignore cursor and start immediately
|
threshold bool, // ignore cursor and start immediately
|
||||||
) ([]*addressSDK.Address, *Cursor) {
|
) ([]oid.Address, *Cursor) {
|
||||||
bkt := tx.Bucket(name)
|
bkt := tx.Bucket(name)
|
||||||
if bkt == nil {
|
if bkt == nil {
|
||||||
return to, cursor
|
return to, cursor
|
||||||
|
@ -175,8 +175,8 @@ func selectNFromBucket(tx *bbolt.Tx,
|
||||||
if count >= limit {
|
if count >= limit {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
a := addressSDK.NewAddress()
|
var a oid.Address
|
||||||
if err := a.Parse(prefix + string(k)); err != nil {
|
if err := a.DecodeString(prefix + string(k)); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
offset = k
|
offset = k
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ func TestLisObjectsWithCursor(t *testing.T) {
|
||||||
total = containers * 5 // regular + ts + sg + child + lock
|
total = containers * 5 // regular + ts + sg + child + lock
|
||||||
)
|
)
|
||||||
|
|
||||||
expected := make([]*addressSDK.Address, 0, total)
|
expected := make([]oid.Address, 0, total)
|
||||||
|
|
||||||
// fill metabase with objects
|
// fill metabase with objects
|
||||||
for i := 0; i < containers; i++ {
|
for i := 0; i < containers; i++ {
|
||||||
|
@ -82,7 +82,7 @@ func TestLisObjectsWithCursor(t *testing.T) {
|
||||||
|
|
||||||
t.Run("success with various count", func(t *testing.T) {
|
t.Run("success with various count", func(t *testing.T) {
|
||||||
for countPerReq := 1; countPerReq <= total; countPerReq++ {
|
for countPerReq := 1; countPerReq <= total; countPerReq++ {
|
||||||
got := make([]*addressSDK.Address, 0, total)
|
got := make([]oid.Address, 0, total)
|
||||||
|
|
||||||
res, cursor, err := meta.ListWithCursor(db, uint32(countPerReq), nil)
|
res, cursor, err := meta.ListWithCursor(db, uint32(countPerReq), nil)
|
||||||
require.NoError(t, err, "count:%d", countPerReq)
|
require.NoError(t, err, "count:%d", countPerReq)
|
||||||
|
@ -125,15 +125,15 @@ func TestAddObjectDuringListingWithCursor(t *testing.T) {
|
||||||
obj := generateObject(t)
|
obj := generateObject(t)
|
||||||
err := putBig(db, obj)
|
err := putBig(db, obj)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
expected[object.AddressOf(obj).String()] = 0
|
expected[object.AddressOf(obj).EncodeToString()] = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// get half of the objects
|
// get half of the objects
|
||||||
got, cursor, err := meta.ListWithCursor(db, total/2, nil)
|
got, cursor, err := meta.ListWithCursor(db, total/2, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
for _, obj := range got {
|
for _, obj := range got {
|
||||||
if _, ok := expected[obj.String()]; ok {
|
if _, ok := expected[obj.EncodeToString()]; ok {
|
||||||
expected[obj.String()]++
|
expected[obj.EncodeToString()]++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,8 +151,8 @@ func TestAddObjectDuringListingWithCursor(t *testing.T) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
for _, obj := range got {
|
for _, obj := range got {
|
||||||
if _, ok := expected[obj.String()]; ok {
|
if _, ok := expected[obj.EncodeToString()]; ok {
|
||||||
expected[obj.String()]++
|
expected[obj.EncodeToString()]++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,9 +164,9 @@ func TestAddObjectDuringListingWithCursor(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortAddresses(addr []*addressSDK.Address) []*addressSDK.Address {
|
func sortAddresses(addr []oid.Address) []oid.Address {
|
||||||
sort.Slice(addr, func(i, j int) bool {
|
sort.Slice(addr, func(i, j int) bool {
|
||||||
return addr[i].String() < addr[j].String()
|
return addr[i].EncodeToString() < addr[j].EncodeToString()
|
||||||
})
|
})
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -20,7 +19,7 @@ const bucketNameSuffixLockers = invalidBase58String + "LOCKER"
|
||||||
|
|
||||||
// returns name of the bucket with objects of type LOCK for specified container.
|
// returns name of the bucket with objects of type LOCK for specified container.
|
||||||
func bucketNameLockers(idCnr cid.ID) []byte {
|
func bucketNameLockers(idCnr cid.ID) []byte {
|
||||||
return []byte(idCnr.String() + bucketNameSuffixLockers)
|
return []byte(idCnr.EncodeToString() + bucketNameSuffixLockers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock marks objects as locked with another object. All objects are from the
|
// Lock marks objects as locked with another object. All objects are from the
|
||||||
|
@ -39,7 +38,7 @@ func (db *DB) Lock(cnr cid.ID, locker oid.ID, locked []oid.ID) error {
|
||||||
bucketKeysLocked := make([][]byte, len(locked))
|
bucketKeysLocked := make([][]byte, len(locked))
|
||||||
|
|
||||||
for i := range locked {
|
for i := range locked {
|
||||||
bucketKeysLocked[i] = objectKey(&locked[i])
|
bucketKeysLocked[i] = objectKey(locked[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
if firstIrregularObjectType(tx, cnr, bucketKeysLocked...) != object.TypeRegular {
|
if firstIrregularObjectType(tx, cnr, bucketKeysLocked...) != object.TypeRegular {
|
||||||
|
@ -51,12 +50,12 @@ func (db *DB) Lock(cnr cid.ID, locker oid.ID, locked []oid.ID) error {
|
||||||
return fmt.Errorf("create global bucket for locked objects: %w", err)
|
return fmt.Errorf("create global bucket for locked objects: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketLockedContainer, err := bucketLocked.CreateBucketIfNotExists([]byte(cnr.String()))
|
bucketLockedContainer, err := bucketLocked.CreateBucketIfNotExists([]byte(cnr.EncodeToString()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("create container bucket for locked objects %v: %w", cnr, err)
|
return fmt.Errorf("create container bucket for locked objects %v: %w", cnr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
keyLocker := objectKey(&locker)
|
keyLocker := objectKey(locker)
|
||||||
var exLockers [][]byte
|
var exLockers [][]byte
|
||||||
var updLockers []byte
|
var updLockers []byte
|
||||||
|
|
||||||
|
@ -93,15 +92,12 @@ func (db *DB) Lock(cnr cid.ID, locker oid.ID, locked []oid.ID) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FreeLockedBy unlocks all objects in DB which are locked by lockers.
|
// FreeLockedBy unlocks all objects in DB which are locked by lockers.
|
||||||
func (db *DB) FreeLockedBy(lockers []*addressSDK.Address) error {
|
func (db *DB) FreeLockedBy(lockers []oid.Address) error {
|
||||||
return db.boltDB.Update(func(tx *bbolt.Tx) error {
|
return db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
for _, addr := range lockers {
|
for i := range lockers {
|
||||||
cnr, _ := addr.ContainerID()
|
err = freePotentialLocks(tx, lockers[i].Container(), lockers[i].Object())
|
||||||
obj, _ := addr.ObjectID()
|
|
||||||
|
|
||||||
err = freePotentialLocks(tx, cnr, obj)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -115,9 +111,9 @@ func (db *DB) FreeLockedBy(lockers []*addressSDK.Address) error {
|
||||||
func objectLocked(tx *bbolt.Tx, idCnr cid.ID, idObj oid.ID) bool {
|
func objectLocked(tx *bbolt.Tx, idCnr cid.ID, idObj oid.ID) bool {
|
||||||
bucketLocked := tx.Bucket(bucketNameLocked)
|
bucketLocked := tx.Bucket(bucketNameLocked)
|
||||||
if bucketLocked != nil {
|
if bucketLocked != nil {
|
||||||
bucketLockedContainer := bucketLocked.Bucket([]byte(idCnr.String()))
|
bucketLockedContainer := bucketLocked.Bucket([]byte(idCnr.EncodeToString()))
|
||||||
if bucketLockedContainer != nil {
|
if bucketLockedContainer != nil {
|
||||||
return bucketLockedContainer.Get(objectKey(&idObj)) != nil
|
return bucketLockedContainer.Get(objectKey(idObj)) != nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +128,9 @@ func objectLocked(tx *bbolt.Tx, idCnr cid.ID, idObj oid.ID) bool {
|
||||||
func freePotentialLocks(tx *bbolt.Tx, idCnr cid.ID, locker oid.ID) error {
|
func freePotentialLocks(tx *bbolt.Tx, idCnr cid.ID, locker oid.ID) error {
|
||||||
bucketLocked := tx.Bucket(bucketNameLocked)
|
bucketLocked := tx.Bucket(bucketNameLocked)
|
||||||
if bucketLocked != nil {
|
if bucketLocked != nil {
|
||||||
bucketLockedContainer := bucketLocked.Bucket([]byte(idCnr.String()))
|
bucketLockedContainer := bucketLocked.Bucket([]byte(idCnr.EncodeToString()))
|
||||||
if bucketLockedContainer != nil {
|
if bucketLockedContainer != nil {
|
||||||
keyLocker := objectKey(&locker)
|
keyLocker := objectKey(locker)
|
||||||
return bucketLockedContainer.ForEach(func(k, v []byte) error {
|
return bucketLockedContainer.ForEach(func(k, v []byte) error {
|
||||||
keyLockers, err := decodeList(v)
|
keyLockers, err := decodeList(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
|
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
|
||||||
|
@ -71,20 +70,20 @@ func TestDB_Lock(t *testing.T) {
|
||||||
err = db.Lock(cnr, tombID, []oid.ID{id})
|
err = db.Lock(cnr, tombID, []oid.ID{id})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var tombAddr address.Address
|
var tombAddr oid.Address
|
||||||
tombAddr.SetContainerID(cnr)
|
tombAddr.SetContainer(cnr)
|
||||||
tombAddr.SetObjectID(tombID)
|
tombAddr.SetObject(tombID)
|
||||||
|
|
||||||
// try to inhume locked object using tombstone
|
// try to inhume locked object using tombstone
|
||||||
err = meta.Inhume(db, objectcore.AddressOf(obj), &tombAddr)
|
err = meta.Inhume(db, objectcore.AddressOf(obj), tombAddr)
|
||||||
require.ErrorAs(t, err, new(apistatus.ObjectLocked))
|
require.ErrorAs(t, err, new(apistatus.ObjectLocked))
|
||||||
|
|
||||||
// inhume the tombstone
|
// inhume the tombstone
|
||||||
_, err = db.Inhume(new(meta.InhumePrm).WithAddresses(&tombAddr).WithGCMark())
|
_, err = db.Inhume(new(meta.InhumePrm).WithAddresses(tombAddr).WithGCMark())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// now we can inhume the object
|
// now we can inhume the object
|
||||||
err = meta.Inhume(db, objectcore.AddressOf(obj), &tombAddr)
|
err = meta.Inhume(db, objectcore.AddressOf(obj), tombAddr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,20 @@ package meta
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToMoveItPrm groups the parameters of ToMoveIt operation.
|
// ToMoveItPrm groups the parameters of ToMoveIt operation.
|
||||||
type ToMoveItPrm struct {
|
type ToMoveItPrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToMoveItRes groups the resulting values of ToMoveIt operation.
|
// ToMoveItRes groups the resulting values of ToMoveIt operation.
|
||||||
type ToMoveItRes struct{}
|
type ToMoveItRes struct{}
|
||||||
|
|
||||||
// WithAddress sets address of the object to move into another shard.
|
// WithAddress sets address of the object to move into another shard.
|
||||||
func (p *ToMoveItPrm) WithAddress(addr *addressSDK.Address) *ToMoveItPrm {
|
func (p *ToMoveItPrm) WithAddress(addr oid.Address) *ToMoveItPrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
@ -26,14 +26,14 @@ func (p *ToMoveItPrm) WithAddress(addr *addressSDK.Address) *ToMoveItPrm {
|
||||||
|
|
||||||
// DoNotMovePrm groups the parameters of DoNotMove operation.
|
// DoNotMovePrm groups the parameters of DoNotMove operation.
|
||||||
type DoNotMovePrm struct {
|
type DoNotMovePrm struct {
|
||||||
addr *addressSDK.Address
|
addr oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoNotMoveRes groups the resulting values of DoNotMove operation.
|
// DoNotMoveRes groups the resulting values of DoNotMove operation.
|
||||||
type DoNotMoveRes struct{}
|
type DoNotMoveRes struct{}
|
||||||
|
|
||||||
// WithAddress sets address of the object to prevent moving into another shard.
|
// WithAddress sets address of the object to prevent moving into another shard.
|
||||||
func (p *DoNotMovePrm) WithAddress(addr *addressSDK.Address) *DoNotMovePrm {
|
func (p *DoNotMovePrm) WithAddress(addr oid.Address) *DoNotMovePrm {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.addr = addr
|
p.addr = addr
|
||||||
}
|
}
|
||||||
|
@ -46,16 +46,16 @@ type MovablePrm struct{}
|
||||||
|
|
||||||
// MovableRes groups the resulting values of Movable operation.
|
// MovableRes groups the resulting values of Movable operation.
|
||||||
type MovableRes struct {
|
type MovableRes struct {
|
||||||
addrList []*addressSDK.Address
|
addrList []oid.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressList returns resulting addresses of Movable operation.
|
// AddressList returns resulting addresses of Movable operation.
|
||||||
func (p *MovableRes) AddressList() []*addressSDK.Address {
|
func (p *MovableRes) AddressList() []oid.Address {
|
||||||
return p.addrList
|
return p.addrList
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToMoveIt marks object to move it into another shard.
|
// ToMoveIt marks object to move it into another shard.
|
||||||
func ToMoveIt(db *DB, addr *addressSDK.Address) error {
|
func ToMoveIt(db *DB, addr oid.Address) error {
|
||||||
_, err := db.ToMoveIt(new(ToMoveItPrm).WithAddress(addr))
|
_, err := db.ToMoveIt(new(ToMoveItPrm).WithAddress(addr))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ func (db *DB) ToMoveIt(prm *ToMoveItPrm) (res *ToMoveItRes, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoNotMove prevents the object to be moved into another shard.
|
// DoNotMove prevents the object to be moved into another shard.
|
||||||
func DoNotMove(db *DB, addr *addressSDK.Address) error {
|
func DoNotMove(db *DB, addr oid.Address) error {
|
||||||
_, err := db.DoNotMove(new(DoNotMovePrm).WithAddress(addr))
|
_, err := db.DoNotMove(new(DoNotMovePrm).WithAddress(addr))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func (db *DB) DoNotMove(prm *DoNotMovePrm) (res *DoNotMoveRes, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movable returns all movable objects of DB.
|
// Movable returns all movable objects of DB.
|
||||||
func Movable(db *DB) ([]*addressSDK.Address, error) {
|
func Movable(db *DB) ([]oid.Address, error) {
|
||||||
r, err := db.Movable(new(MovablePrm))
|
r, err := db.Movable(new(MovablePrm))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -128,16 +128,14 @@ func (db *DB) Movable(prm *MovablePrm) (*MovableRes, error) {
|
||||||
// we can parse strings to structures in-place, but probably it seems
|
// we can parse strings to structures in-place, but probably it seems
|
||||||
// more efficient to keep bolt db TX code smaller because it might be
|
// more efficient to keep bolt db TX code smaller because it might be
|
||||||
// bottleneck.
|
// bottleneck.
|
||||||
addrs := make([]*addressSDK.Address, 0, len(strAddrs))
|
addrs := make([]oid.Address, len(strAddrs))
|
||||||
|
|
||||||
for i := range strAddrs {
|
for i := range strAddrs {
|
||||||
addr, err := addressFromKey([]byte(strAddrs[i]))
|
err = decodeAddressFromKey(&addrs[i], []byte(strAddrs[i]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't parse object address %v: %w",
|
return nil, fmt.Errorf("can't parse object address %v: %w",
|
||||||
strAddrs[i], err)
|
strAddrs[i], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs = append(addrs, addr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &MovableRes{
|
return &MovableRes{
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -151,12 +151,7 @@ func (db *DB) put(tx *bbolt.Tx, obj *objectSDK.Object, id *blobovnicza.ID, si *o
|
||||||
|
|
||||||
// update container volume size estimation
|
// update container volume size estimation
|
||||||
if obj.Type() == objectSDK.TypeRegular && !isParent {
|
if obj.Type() == objectSDK.TypeRegular && !isParent {
|
||||||
err = changeContainerSize(
|
err = changeContainerSize(tx, cnr, obj.PayloadSize(), true)
|
||||||
tx,
|
|
||||||
&cnr,
|
|
||||||
obj.PayloadSize(),
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -173,9 +168,8 @@ func putUniqueIndexes(
|
||||||
) error {
|
) error {
|
||||||
isParent := si != nil
|
isParent := si != nil
|
||||||
addr := object.AddressOf(obj)
|
addr := object.AddressOf(obj)
|
||||||
idObj, _ := addr.ObjectID()
|
cnr := addr.Container()
|
||||||
cnr, _ := addr.ContainerID()
|
objKey := objectKey(addr.Object())
|
||||||
objKey := objectKey(&idObj)
|
|
||||||
|
|
||||||
// add value to primary unique bucket
|
// add value to primary unique bucket
|
||||||
if !isParent {
|
if !isParent {
|
||||||
|
@ -183,11 +177,11 @@ func putUniqueIndexes(
|
||||||
|
|
||||||
switch obj.Type() {
|
switch obj.Type() {
|
||||||
case objectSDK.TypeRegular:
|
case objectSDK.TypeRegular:
|
||||||
bucketName = primaryBucketName(&cnr)
|
bucketName = primaryBucketName(cnr)
|
||||||
case objectSDK.TypeTombstone:
|
case objectSDK.TypeTombstone:
|
||||||
bucketName = tombstoneBucketName(&cnr)
|
bucketName = tombstoneBucketName(cnr)
|
||||||
case objectSDK.TypeStorageGroup:
|
case objectSDK.TypeStorageGroup:
|
||||||
bucketName = storageGroupBucketName(&cnr)
|
bucketName = storageGroupBucketName(cnr)
|
||||||
case objectSDK.TypeLock:
|
case objectSDK.TypeLock:
|
||||||
bucketName = bucketNameLockers(cnr)
|
bucketName = bucketNameLockers(cnr)
|
||||||
default:
|
default:
|
||||||
|
@ -211,7 +205,7 @@ func putUniqueIndexes(
|
||||||
// index blobovniczaID if it is present
|
// index blobovniczaID if it is present
|
||||||
if id != nil {
|
if id != nil {
|
||||||
err = putUniqueIndexItem(tx, namedBucketItem{
|
err = putUniqueIndexItem(tx, namedBucketItem{
|
||||||
name: smallBucketName(&cnr),
|
name: smallBucketName(cnr),
|
||||||
key: objKey,
|
key: objKey,
|
||||||
val: *id,
|
val: *id,
|
||||||
})
|
})
|
||||||
|
@ -236,7 +230,7 @@ func putUniqueIndexes(
|
||||||
}
|
}
|
||||||
|
|
||||||
err = putUniqueIndexItem(tx, namedBucketItem{
|
err = putUniqueIndexItem(tx, namedBucketItem{
|
||||||
name: rootBucketName(&cnr),
|
name: rootBucketName(cnr),
|
||||||
key: objKey,
|
key: objKey,
|
||||||
val: splitInfo,
|
val: splitInfo,
|
||||||
})
|
})
|
||||||
|
@ -251,16 +245,15 @@ func putUniqueIndexes(
|
||||||
type updateIndexItemFunc = func(tx *bbolt.Tx, item namedBucketItem) error
|
type updateIndexItemFunc = func(tx *bbolt.Tx, item namedBucketItem) error
|
||||||
|
|
||||||
func updateListIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFunc) error {
|
func updateListIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFunc) error {
|
||||||
addr := object.AddressOf(obj)
|
idObj, _ := obj.ID()
|
||||||
idObj, _ := addr.ObjectID()
|
cnr, _ := obj.ContainerID()
|
||||||
cnr, _ := addr.ContainerID()
|
objKey := objectKey(idObj)
|
||||||
objKey := objectKey(&idObj)
|
|
||||||
|
|
||||||
cs, _ := obj.PayloadChecksum()
|
cs, _ := obj.PayloadChecksum()
|
||||||
|
|
||||||
// index payload hashes
|
// index payload hashes
|
||||||
err := f(tx, namedBucketItem{
|
err := f(tx, namedBucketItem{
|
||||||
name: payloadHashBucketName(&cnr),
|
name: payloadHashBucketName(cnr),
|
||||||
key: cs.Value(),
|
key: cs.Value(),
|
||||||
val: objKey,
|
val: objKey,
|
||||||
})
|
})
|
||||||
|
@ -273,8 +266,8 @@ func updateListIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFun
|
||||||
// index parent ids
|
// index parent ids
|
||||||
if ok {
|
if ok {
|
||||||
err := f(tx, namedBucketItem{
|
err := f(tx, namedBucketItem{
|
||||||
name: parentBucketName(&cnr),
|
name: parentBucketName(cnr),
|
||||||
key: objectKey(&idParent),
|
key: objectKey(idParent),
|
||||||
val: objKey,
|
val: objKey,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -285,7 +278,7 @@ func updateListIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFun
|
||||||
// index split ids
|
// index split ids
|
||||||
if obj.SplitID() != nil {
|
if obj.SplitID() != nil {
|
||||||
err := f(tx, namedBucketItem{
|
err := f(tx, namedBucketItem{
|
||||||
name: splitBucketName(&cnr),
|
name: splitBucketName(cnr),
|
||||||
key: obj.SplitID().ToV2(),
|
key: obj.SplitID().ToV2(),
|
||||||
val: objKey,
|
val: objKey,
|
||||||
})
|
})
|
||||||
|
@ -298,16 +291,15 @@ func updateListIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFun
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateFKBTIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFunc) error {
|
func updateFKBTIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFunc) error {
|
||||||
addr := object.AddressOf(obj)
|
id, _ := obj.ID()
|
||||||
cnr, _ := addr.ContainerID()
|
cnr, _ := obj.ContainerID()
|
||||||
id, _ := addr.ObjectID()
|
|
||||||
objKey := []byte(id.EncodeToString())
|
objKey := []byte(id.EncodeToString())
|
||||||
|
|
||||||
attrs := obj.Attributes()
|
attrs := obj.Attributes()
|
||||||
|
|
||||||
err := f(tx, namedBucketItem{
|
err := f(tx, namedBucketItem{
|
||||||
name: ownerBucketName(&cnr),
|
name: ownerBucketName(cnr),
|
||||||
key: []byte(obj.OwnerID().String()),
|
key: []byte(obj.OwnerID().EncodeToString()),
|
||||||
val: objKey,
|
val: objKey,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -317,7 +309,7 @@ func updateFKBTIndexes(tx *bbolt.Tx, obj *objectSDK.Object, f updateIndexItemFun
|
||||||
// user specified attributes
|
// user specified attributes
|
||||||
for i := range attrs {
|
for i := range attrs {
|
||||||
err := f(tx, namedBucketItem{
|
err := f(tx, namedBucketItem{
|
||||||
name: attributeBucketName(&cnr, attrs[i].Key()),
|
name: attributeBucketName(cnr, attrs[i].Key()),
|
||||||
key: []byte(attrs[i].Value()),
|
key: []byte(attrs[i].Value()),
|
||||||
val: objKey,
|
val: objKey,
|
||||||
})
|
})
|
||||||
|
@ -445,34 +437,26 @@ func getVarUint(data []byte) (uint64, int, error) {
|
||||||
|
|
||||||
// updateBlobovniczaID for existing objects if they were moved from from
|
// updateBlobovniczaID for existing objects if they were moved from from
|
||||||
// one blobovnicza to another.
|
// one blobovnicza to another.
|
||||||
func updateBlobovniczaID(tx *bbolt.Tx, addr *addressSDK.Address, id *blobovnicza.ID) error {
|
func updateBlobovniczaID(tx *bbolt.Tx, addr oid.Address, id *blobovnicza.ID) error {
|
||||||
cnr, _ := addr.ContainerID()
|
bkt, err := tx.CreateBucketIfNotExists(smallBucketName(addr.Container()))
|
||||||
|
|
||||||
bkt, err := tx.CreateBucketIfNotExists(smallBucketName(&cnr))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
idObj, _ := addr.ObjectID()
|
return bkt.Put(objectKey(addr.Object()), *id)
|
||||||
|
|
||||||
return bkt.Put(objectKey(&idObj), *id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSpliInfo for existing objects if storage filled with extra information
|
// updateSpliInfo for existing objects if storage filled with extra information
|
||||||
// about last object in split hierarchy or linking object.
|
// about last object in split hierarchy or linking object.
|
||||||
func updateSplitInfo(tx *bbolt.Tx, addr *addressSDK.Address, from *objectSDK.SplitInfo) error {
|
func updateSplitInfo(tx *bbolt.Tx, addr oid.Address, from *objectSDK.SplitInfo) error {
|
||||||
cnr, _ := addr.ContainerID()
|
bkt := tx.Bucket(rootBucketName(addr.Container()))
|
||||||
|
|
||||||
bkt := tx.Bucket(rootBucketName(&cnr))
|
|
||||||
if bkt == nil {
|
if bkt == nil {
|
||||||
// if object doesn't exists and we want to update split info on it
|
// if object doesn't exists and we want to update split info on it
|
||||||
// then ignore, this should never happen
|
// then ignore, this should never happen
|
||||||
return ErrIncorrectSplitInfoUpdate
|
return ErrIncorrectSplitInfoUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
id, _ := addr.ObjectID()
|
objectKey := objectKey(addr.Object())
|
||||||
|
|
||||||
objectKey := objectKey(&id)
|
|
||||||
|
|
||||||
rawSplitInfo := bkt.Get(objectKey)
|
rawSplitInfo := bkt.Get(objectKey)
|
||||||
if len(rawSplitInfo) == 0 {
|
if len(rawSplitInfo) == 0 {
|
||||||
|
|
|
@ -18,11 +18,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func prepareObjects(t testing.TB, n int) []*objectSDK.Object {
|
func prepareObjects(t testing.TB, n int) []*objectSDK.Object {
|
||||||
cid := cidtest.ID()
|
cnr := cidtest.ID()
|
||||||
parentID := objecttest.ID()
|
parentID := objecttest.ID()
|
||||||
objs := make([]*objectSDK.Object, n)
|
objs := make([]*objectSDK.Object, n)
|
||||||
for i := range objs {
|
for i := range objs {
|
||||||
objs[i] = generateObjectWithCID(t, cid)
|
objs[i] = generateObjectWithCID(t, cnr)
|
||||||
|
|
||||||
// FKBT indices.
|
// FKBT indices.
|
||||||
attrs := make([]objectSDK.Attribute, 20)
|
attrs := make([]objectSDK.Attribute, 20)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue