[#625] client/container: remove intermediate wrapper

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-01-31 16:34:01 +03:00 committed by Alex Vanin
parent 819d80a7a9
commit c34cfa1f35
28 changed files with 556 additions and 1168 deletions

View file

@ -7,7 +7,7 @@ import (
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
"github.com/nspcc-dev/neofs-node/pkg/core/container" "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl" "github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl"
containerSDK "github.com/nspcc-dev/neofs-sdk-go/container" containerSDK "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"
@ -262,7 +262,7 @@ func (s *lruNetmapSource) Epoch() (uint64, error) {
// that implements container lister. // that implements container lister.
type ttlContainerLister ttlNetCache type ttlContainerLister ttlNetCache
func newCachedContainerLister(w *wrapper.Wrapper) *ttlContainerLister { func newCachedContainerLister(c *cntClient.Client) *ttlContainerLister {
const ( const (
containerListerCacheSize = 100 containerListerCacheSize = 100
containerListerCacheTTL = 30 * time.Second containerListerCacheTTL = 30 * time.Second
@ -283,7 +283,7 @@ func newCachedContainerLister(w *wrapper.Wrapper) *ttlContainerLister {
} }
} }
return w.List(id) return c.List(id)
}) })
return (*ttlContainerLister)(lruCnrListerCache) return (*ttlContainerLister)(lruCnrListerCache)

View file

@ -14,7 +14,7 @@ import (
containerCore "github.com/nspcc-dev/neofs-node/pkg/core/container" containerCore "github.com/nspcc-dev/neofs-node/pkg/core/container"
netmapCore "github.com/nspcc-dev/neofs-node/pkg/core/netmap" netmapCore "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"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/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/event" "github.com/nspcc-dev/neofs-node/pkg/morph/event"
containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container" containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
containerTransportGRPC "github.com/nspcc-dev/neofs-node/pkg/network/transport/container/grpc" containerTransportGRPC "github.com/nspcc-dev/neofs-node/pkg/network/transport/container/grpc"
@ -43,15 +43,15 @@ const (
func initContainerService(c *cfg) { func initContainerService(c *cfg) {
// container wrapper that tries to invoke notary // container wrapper that tries to invoke notary
// requests if chain is configured so // requests if chain is configured so
wrap, err := wrapper.NewFromMorph(c.cfgMorph.client, c.cfgContainer.scriptHash, 0, wrapper.TryNotary()) wrap, err := cntClient.NewFromMorph(c.cfgMorph.client, c.cfgContainer.scriptHash, 0, cntClient.TryNotary())
fatalOnErr(err) fatalOnErr(err)
// container wrapper that always sends non-notary // container wrapper that always sends non-notary
// requests // requests
wrapperNoNotary, err := wrapper.NewFromMorph(c.cfgMorph.client, c.cfgContainer.scriptHash, 0) wrapperNoNotary, err := cntClient.NewFromMorph(c.cfgMorph.client, c.cfgContainer.scriptHash, 0)
fatalOnErr(err) fatalOnErr(err)
cnrSrc := wrapper.AsContainerSource(wrap) cnrSrc := cntClient.AsContainerSource(wrap)
eACLFetcher := &morphEACLFetcher{ eACLFetcher := &morphEACLFetcher{
w: wrap, w: wrap,
@ -209,7 +209,7 @@ func setContainerNotificationParser(c *cfg, sTyp string, p event.NotificationPar
type morphLoadWriter struct { type morphLoadWriter struct {
log *logger.Logger log *logger.Logger
cnrMorphClient *wrapper.Wrapper cnrMorphClient *cntClient.Client
key []byte key []byte
} }
@ -221,7 +221,7 @@ func (w *morphLoadWriter) Put(a containerSDK.UsedSpaceAnnouncement) error {
zap.Uint64("size", a.UsedSpace()), zap.Uint64("size", a.UsedSpace()),
) )
prm := wrapper.AnnounceLoadPrm{} prm := cntClient.AnnounceLoadPrm{}
prm.SetAnnouncement(a) prm.SetAnnouncement(a)
prm.SetReporter(w.key) prm.SetReporter(w.key)
@ -561,7 +561,7 @@ func (x *morphContainerReader) List(id *owner.ID) ([]*cid.ID, error) {
} }
type morphContainerWriter struct { type morphContainerWriter struct {
neoClient *wrapper.Wrapper neoClient *cntClient.Client
cacheEnabled bool cacheEnabled bool
containers *ttlContainerStorage containers *ttlContainerStorage
@ -570,7 +570,7 @@ type morphContainerWriter struct {
} }
func (m morphContainerWriter) Put(cnr *containerSDK.Container) (*cid.ID, error) { func (m morphContainerWriter) Put(cnr *containerSDK.Container) (*cid.ID, error) {
containerID, err := wrapper.Put(m.neoClient, cnr) containerID, err := cntClient.Put(m.neoClient, cnr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -583,7 +583,7 @@ func (m morphContainerWriter) Put(cnr *containerSDK.Container) (*cid.ID, error)
} }
func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error { func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error {
err := wrapper.Delete(m.neoClient, witness) err := cntClient.Delete(m.neoClient, witness)
if err != nil { if err != nil {
return err return err
} }
@ -602,7 +602,7 @@ func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error
} }
func (m morphContainerWriter) PutEACL(table *eaclSDK.Table) error { func (m morphContainerWriter) PutEACL(table *eaclSDK.Table) error {
err := wrapper.PutEACL(m.neoClient, table) err := cntClient.PutEACL(m.neoClient, table)
if err != nil { if err != nil {
return err return err
} }

View file

@ -14,7 +14,7 @@ import (
objectCore "github.com/nspcc-dev/neofs-node/pkg/core/object" objectCore "github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
morphClient "github.com/nspcc-dev/neofs-node/pkg/morph/client" morphClient "github.com/nspcc-dev/neofs-node/pkg/morph/client"
cntrwrp "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap" nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
objectTransportGRPC "github.com/nspcc-dev/neofs-node/pkg/network/transport/object/grpc" objectTransportGRPC "github.com/nspcc-dev/neofs-node/pkg/network/transport/object/grpc"
objectService "github.com/nspcc-dev/neofs-node/pkg/services/object" objectService "github.com/nspcc-dev/neofs-node/pkg/services/object"
@ -384,7 +384,7 @@ func initObjectService(c *cfg) {
} }
type morphEACLFetcher struct { type morphEACLFetcher struct {
w *cntrwrp.Wrapper w *cntClient.Client
} }
type signedEACLTable eaclSDK.Table type signedEACLTable eaclSDK.Table

View file

@ -7,7 +7,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/alphabet" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/alphabet"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement"
timerEvent "github.com/nspcc-dev/neofs-node/pkg/innerring/timers" timerEvent "github.com/nspcc-dev/neofs-node/pkg/innerring/timers"
container "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"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/morph/timer" "github.com/nspcc-dev/neofs-node/pkg/morph/timer"
"go.uber.org/zap" "go.uber.org/zap"
@ -32,8 +32,8 @@ type (
newEpochHandlers []newEpochHandler newEpochHandlers []newEpochHandler
cnrWrapper *container.Wrapper // to invoke stop container estimation cnrWrapper *container.Client // to invoke stop container estimation
epoch epochState // to specify which epoch to stop, and epoch duration epoch epochState // to specify which epoch to stop, and epoch duration
stopEstimationDMul uint32 // X: X/Y of epoch in blocks stopEstimationDMul uint32 // X: X/Y of epoch in blocks
stopEstimationDDiv uint32 // Y: X/Y of epoch in blocks stopEstimationDDiv uint32 // Y: X/Y of epoch in blocks

View file

@ -31,7 +31,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
auditClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/audit" auditClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/audit"
balanceClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance" balanceClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance"
cntWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
neofsClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/neofs" neofsClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/neofs"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid" "github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid"
nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap" nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
@ -469,21 +469,21 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
} }
// form morph container client's options // form morph container client's options
morphCnrOpts := make([]cntWrapper.Option, 0, 3) morphCnrOpts := make([]cntClient.Option, 0, 3)
morphCnrOpts = append(morphCnrOpts, morphCnrOpts = append(morphCnrOpts,
cntWrapper.TryNotary(), cntClient.TryNotary(),
cntWrapper.AsAlphabet(), cntClient.AsAlphabet(),
) )
if server.sideNotaryConfig.disabled { if server.sideNotaryConfig.disabled {
// in non-notary environments we customize fee for named container registration // in non-notary environments we customize fee for named container registration
// because it takes much more additional GAS than other operations. // because it takes much more additional GAS than other operations.
morphCnrOpts = append(morphCnrOpts, morphCnrOpts = append(morphCnrOpts,
cntWrapper.WithCustomFeeForNamedPut(server.feeConfig.NamedContainerRegistrationFee()), cntClient.WithCustomFeeForNamedPut(server.feeConfig.NamedContainerRegistrationFee()),
) )
} }
cnrClient, err := cntWrapper.NewFromMorph(server.morphClient, server.contracts.container, fee, morphCnrOpts...) cnrClient, err := cntClient.NewFromMorph(server.morphClient, server.contracts.container, fee, morphCnrOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -602,7 +602,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
settlementDeps := &settlementDeps{ settlementDeps := &settlementDeps{
globalConfig: globalConfig, globalConfig: globalConfig,
log: server.log, log: server.log,
cnrSrc: cntWrapper.AsContainerSource(cnrClient), cnrSrc: cntClient.AsContainerSource(cnrClient),
auditClient: server.auditClient, auditClient: server.auditClient,
nmSrc: server.netmapClient, nmSrc: server.netmapClient,
clientCache: clientCache, clientCache: clientCache,

View file

@ -5,7 +5,7 @@ import (
"encoding/hex" "encoding/hex"
clientcore "github.com/nspcc-dev/neofs-node/pkg/core/client" clientcore "github.com/nspcc-dev/neofs-node/pkg/core/client"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/services/audit" "github.com/nspcc-dev/neofs-node/pkg/services/audit"
"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"
@ -47,7 +47,7 @@ func (ap *Processor) processStartAudit(epoch uint64) {
auditCtx, ap.prevAuditCanceler = context.WithCancel(context.Background()) auditCtx, ap.prevAuditCanceler = context.WithCancel(context.Background())
for i := range containers { for i := range containers {
cnr, err := wrapper.Get(ap.containerClient, containers[i]) // get container structure cnr, err := cntClient.Get(ap.containerClient, containers[i]) // get container structure
if err != nil { if err != nil {
log.Error("can't get container info, ignore", log.Error("can't get container info, ignore",
zap.Stringer("cid", containers[i]), zap.Stringer("cid", containers[i]),

View file

@ -8,7 +8,7 @@ import (
"time" "time"
"github.com/nspcc-dev/neofs-node/pkg/core/client" "github.com/nspcc-dev/neofs-node/pkg/core/client"
wrapContainer "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap" nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
"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"
@ -41,7 +41,7 @@ type (
sgSrc SGSource sgSrc SGSource
searchTimeout time.Duration searchTimeout time.Duration
containerClient *wrapContainer.Wrapper containerClient *cntClient.Client
netmapClient *nmClient.Client netmapClient *nmClient.Client
taskManager TaskManager taskManager TaskManager
@ -53,7 +53,7 @@ type (
Params struct { Params struct {
Log *zap.Logger Log *zap.Logger
NetmapClient *nmClient.Client NetmapClient *nmClient.Client
ContainerClient *wrapContainer.Wrapper ContainerClient *cntClient.Client
IRList Indexer IRList Indexer
SGSource SGSource SGSource SGSource
RPCSearchTimeout time.Duration RPCSearchTimeout time.Duration

View file

@ -10,7 +10,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/network/payload" "github.com/nspcc-dev/neo-go/pkg/network/payload"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/core/container" "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid" "github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid"
morphsubnet "github.com/nspcc-dev/neofs-node/pkg/morph/client/subnet" morphsubnet "github.com/nspcc-dev/neofs-node/pkg/morph/client/subnet"
"github.com/nspcc-dev/neofs-node/pkg/morph/event" "github.com/nspcc-dev/neofs-node/pkg/morph/event"
@ -130,7 +130,7 @@ func (cp *Processor) approvePutContainer(ctx *putContainerContext) {
var err error var err error
prm := wrapper.PutPrm{} prm := cntClient.PutPrm{}
prm.SetContainer(e.Container()) prm.SetContainer(e.Container())
prm.SetKey(e.PublicKey()) prm.SetKey(e.PublicKey())
@ -243,7 +243,7 @@ func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
func (cp *Processor) approveDeleteContainer(e *containerEvent.Delete) { func (cp *Processor) approveDeleteContainer(e *containerEvent.Delete) {
var err error var err error
prm := wrapper.DeletePrm{} prm := cntClient.DeletePrm{}
prm.SetCID(e.ContainerID()) prm.SetCID(e.ContainerID())
prm.SetSignature(e.Signature()) prm.SetSignature(e.Signature())

View file

@ -7,7 +7,7 @@ import (
"fmt" "fmt"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/event/container" "github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
"github.com/nspcc-dev/neofs-sdk-go/eacl" "github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/session" "github.com/nspcc-dev/neofs-sdk-go/session"
@ -57,7 +57,7 @@ func (cp *Processor) checkSetEACL(e container.SetEACL) error {
} }
// receive owner of the related container // receive owner of the related container
cnr, err := wrapper.Get(cp.cnrClient, table.CID()) cnr, err := cntClient.Get(cp.cnrClient, table.CID())
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)
} }
@ -91,7 +91,7 @@ func (cp *Processor) checkSetEACL(e container.SetEACL) error {
func (cp *Processor) approveSetEACL(e container.SetEACL) { func (cp *Processor) approveSetEACL(e container.SetEACL) {
var err error var err error
prm := wrapper.PutEACLPrm{} prm := cntClient.PutEACLPrm{}
prm.SetTable(e.Table()) prm.SetTable(e.Table())
prm.SetKey(e.PublicKey()) prm.SetKey(e.PublicKey())

View file

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"github.com/nspcc-dev/neo-go/pkg/core/mempoolevent" "github.com/nspcc-dev/neo-go/pkg/core/mempoolevent"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid" "github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid"
morphsubnet "github.com/nspcc-dev/neofs-node/pkg/morph/client/subnet" morphsubnet "github.com/nspcc-dev/neofs-node/pkg/morph/client/subnet"
"github.com/nspcc-dev/neofs-node/pkg/morph/event" "github.com/nspcc-dev/neofs-node/pkg/morph/event"
@ -25,7 +25,7 @@ type (
log *zap.Logger log *zap.Logger
pool *ants.Pool pool *ants.Pool
alphabetState AlphabetState alphabetState AlphabetState
cnrClient *wrapper.Wrapper // notary must be enabled cnrClient *container.Client // notary must be enabled
idClient *neofsid.Client idClient *neofsid.Client
subnetClient *morphsubnet.Client subnetClient *morphsubnet.Client
netState NetworkState netState NetworkState
@ -37,7 +37,7 @@ type (
Log *zap.Logger Log *zap.Logger
PoolSize int PoolSize int
AlphabetState AlphabetState AlphabetState AlphabetState
ContainerClient *wrapper.Wrapper ContainerClient *container.Client
NeoFSIDClient *neofsid.Client NeoFSIDClient *neofsid.Client
SubnetClient *morphsubnet.Client SubnetClient *morphsubnet.Client
NetworkState NetworkState NetworkState NetworkState

View file

@ -4,7 +4,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/audit" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/audit"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/governance" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/governance"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
netmapEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap" netmapEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -37,7 +37,7 @@ func (np *Processor) processNewEpoch(ev netmapEvent.NewEpoch) {
return return
} }
prm := wrapper.StartEstimationPrm{} prm := cntClient.StartEstimationPrm{}
prm.SetEpoch(epoch - 1) prm.SetEpoch(epoch - 1)
prm.SetHash(ev.TxHash()) prm.SetHash(ev.TxHash())

View file

@ -6,7 +6,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/mempoolevent" "github.com/nspcc-dev/neo-go/pkg/core/mempoolevent"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
container "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap" nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
"github.com/nspcc-dev/neofs-node/pkg/morph/event" "github.com/nspcc-dev/neofs-node/pkg/morph/event"
netmapEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap" netmapEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap"
@ -60,7 +60,7 @@ type (
alphabetState AlphabetState alphabetState AlphabetState
netmapClient *nmClient.Client netmapClient *nmClient.Client
containerWrp *container.Wrapper containerWrp *container.Client
subnetContract util.Uint160 subnetContract util.Uint160
@ -86,7 +86,7 @@ type (
AlphabetState AlphabetState AlphabetState AlphabetState
CleanupEnabled bool CleanupEnabled bool
CleanupThreshold uint64 // in epochs CleanupThreshold uint64 // in epochs
ContainerWrapper *container.Wrapper ContainerWrapper *container.Client
SubnetContract *util.Uint160 SubnetContract *util.Uint160
HandleAudit event.Handler HandleAudit event.Handler

View file

@ -4,7 +4,7 @@ import (
"math/big" "math/big"
"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-node/pkg/morph/client/container/wrapper" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -76,7 +76,7 @@ func (inc *IncomeSettlementContext) Collect() {
// avgEstimation returns estimation value for single container. Right now it // avgEstimation returns estimation value for single container. Right now it
// simply calculates average of all announcements, however it can be smarter and // simply calculates average of all announcements, however it can be smarter and
// base result on reputation of announcers and clever math. // base result on reputation of announcers and clever math.
func (inc *IncomeSettlementContext) avgEstimation(e *wrapper.Estimations) (avg uint64) { func (inc *IncomeSettlementContext) avgEstimation(e *cntClient.Estimations) (avg uint64) {
if len(e.Values) == 0 { if len(e.Values) == 0 {
return 0 return 0
} }

View file

@ -7,14 +7,14 @@ import (
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"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-node/pkg/morph/client/container/wrapper" "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-sdk-go/owner" "github.com/nspcc-dev/neofs-sdk-go/owner"
"go.uber.org/zap" "go.uber.org/zap"
) )
type ( type (
EstimationFetcher interface { EstimationFetcher interface {
Estimations(uint64) ([]*wrapper.Estimations, error) Estimations(uint64) ([]*container.Estimations, error)
} }
RateFetcher interface { RateFetcher interface {

View file

@ -16,7 +16,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement/common" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement/common"
auditClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/audit" auditClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/audit"
balanceClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance" balanceClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance"
containerClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" containerClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/util/logger" "github.com/nspcc-dev/neofs-node/pkg/util/logger"
auditAPI "github.com/nspcc-dev/neofs-sdk-go/audit" auditAPI "github.com/nspcc-dev/neofs-sdk-go/audit"
containerAPI "github.com/nspcc-dev/neofs-sdk-go/container" containerAPI "github.com/nspcc-dev/neofs-sdk-go/container"
@ -55,7 +55,7 @@ type auditSettlementDeps struct {
type basicIncomeSettlementDeps struct { type basicIncomeSettlementDeps struct {
*settlementDeps *settlementDeps
cnrClient *containerClient.Wrapper cnrClient *containerClient.Client
} }
type basicSettlementConstructor struct { type basicSettlementConstructor struct {

View file

@ -1,6 +1,11 @@
package container package container
import ( import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
) )
@ -31,16 +36,86 @@ const (
listSizesMethod = "listContainerSizes" listSizesMethod = "listContainerSizes"
getSizeMethod = "getContainerSize" getSizeMethod = "getContainerSize"
// PutNamedMethod is method name for container put with an alias. It is exported to provide custom fee. // putNamedMethod is method name for container put with an alias. It is exported to provide custom fee.
PutNamedMethod = "putNamed" putNamedMethod = "putNamed"
) )
// New creates, initializes and returns the Client instance. var (
func New(c *client.StaticClient) *Client { errNilArgument = errors.New("empty argument")
return &Client{client: c} errUnsupported = errors.New("unsupported structure version")
)
// NewFromMorph returns the wrapper instance from the raw morph client.
//
// Specified fee is used for all operations by default. If WithCustomFeeForNamedPut is provided,
// the customized fee is used for Put operations with named containers.
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...Option) (*Client, error) {
o := defaultOpts()
for i := range opts {
opts[i](o)
}
if o.feePutNamedSet {
o.staticOpts = append(o.staticOpts, client.WithCustomFee(putNamedMethod, o.feePutNamed))
}
sc, err := client.NewStatic(cli, contract, fee, o.staticOpts...)
if err != nil {
return nil, fmt.Errorf("can't create container static client: %w", err)
}
return &Client{client: sc}, nil
} }
// Morph returns raw morph client. // Morph returns raw morph client.
func (c Client) Morph() *client.Client { func (c Client) Morph() *client.Client {
return c.client.Morph() return c.client.Morph()
} }
// ContractAddress returns the address of the associated contract.
func (c Client) ContractAddress() util.Uint160 {
return c.client.ContractAddress()
}
// Option allows to set an optional
// parameter of Wrapper.
type Option func(*opts)
type opts struct {
feePutNamedSet bool
feePutNamed fixedn.Fixed8
staticOpts []client.StaticClientOption
}
func defaultOpts() *opts {
return new(opts)
}
// TryNotary returns option to enable
// notary invocation tries.
func TryNotary() Option {
return func(o *opts) {
o.staticOpts = append(o.staticOpts, client.TryNotary())
}
}
// AsAlphabet returns option to sign main TX
// of notary requests with client's private
// key.
//
// Considered to be used by IR nodes only.
func AsAlphabet() Option {
return func(o *opts) {
o.staticOpts = append(o.staticOpts, client.AsAlphabet())
}
}
// WithCustomFeeForNamedPut returns option to specify custom fee for each Put operation with named container.
func WithCustomFeeForNamedPut(fee fixedn.Fixed8) Option {
return func(o *opts) {
o.feePutNamed = fee
o.feePutNamedSet = true
}
}

View file

@ -3,51 +3,75 @@ package container
import ( import (
"fmt" "fmt"
core "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
) )
// DeleteArgs groups the arguments // Delete marshals container ID, and passes it to Wrapper's Delete method
// of delete container invocation call. // along with signature and session token.
type DeleteArgs struct { //
cid []byte // container identifier // Returns error if container ID is nil.
func Delete(c *Client, witness core.RemovalWitness) error {
id := witness.ContainerID()
if id == nil {
return errNilArgument
}
sig []byte // container identifier signature binToken, err := witness.SessionToken().Marshal()
if err != nil {
return fmt.Errorf("could not marshal session token: %w", err)
}
token []byte // binary session token return c.Delete(
DeletePrm{
cid: id.ToV2().GetValue(),
signature: witness.Signature(),
token: binToken,
})
}
// DeletePrm groups parameters of Delete client operation.
type DeletePrm struct {
cid []byte
signature []byte
token []byte
client.InvokePrmOptional client.InvokePrmOptional
} }
// SetCID sets the container identifier // SetCID sets container ID.
// in a binary format. func (d *DeletePrm) SetCID(cid []byte) {
func (p *DeleteArgs) SetCID(v []byte) { d.cid = cid
p.cid = v
} }
// SetSignature sets the container identifier // SetSignature sets signature.
// owner's signature. func (d *DeletePrm) SetSignature(signature []byte) {
func (p *DeleteArgs) SetSignature(v []byte) { d.signature = signature
p.sig = v
} }
// SetSessionToken sets token of the session // SetToken sets session token.
// within which the container was removed func (d *DeletePrm) SetToken(token []byte) {
// in a NeoFS API binary format. d.token = token
func (p *DeleteArgs) SetSessionToken(v []byte) {
p.token = v
} }
// Delete invokes the call of delete container // Delete removes the container from NeoFS system
// method of NeoFS Container contract. // through Container contract call.
func (c *Client) Delete(args DeleteArgs) error { //
// Returns any error encountered that caused
// the removal to interrupt.
//
// If TryNotary is provided, calls notary contract.
func (c *Client) Delete(p DeletePrm) error {
if len(p.signature) == 0 {
return errNilArgument
}
prm := client.InvokePrm{} prm := client.InvokePrm{}
prm.SetMethod(deleteMethod) prm.SetMethod(deleteMethod)
prm.SetArgs(args.cid, args.sig, args.token) prm.SetArgs(p.cid, p.signature, p.token)
prm.InvokePrmOptional = args.InvokePrmOptional prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm) err := c.client.Invoke(prm)
if err != nil { if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", deleteMethod, err) return fmt.Errorf("could not invoke method (%s): %w", deleteMethod, err)
} }

View file

@ -3,64 +3,31 @@ package container
import ( import (
"fmt" "fmt"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
) )
// EACLArgs groups the arguments // GetEACL reads the extended ACL table from NeoFS system
// of get eACL test invoke call. // through Container contract call.
type EACLArgs struct { func (c *Client) GetEACL(cid *cid.ID) (*eacl.Table, error) {
cid []byte // container identifier if cid == nil {
} return nil, errNilArgument
}
// EACLValues groups the stack parameters v2 := cid.ToV2()
// returned by get eACL test invoke. if v2 == nil {
type EACLValues struct { return nil, errUnsupported // use other major version if there any
eacl []byte // extended ACL table }
signature []byte // RFC-6979 signature of extended ACL table prm := client.TestInvokePrm{}
prm.SetMethod(eaclMethod)
prm.SetArgs(v2.GetValue())
publicKey []byte // public key of the extended ACL table signer prms, err := c.client.TestInvoke(prm)
token []byte // token of the session within which the eACL table was set
}
// SetCID sets the container identifier
// in a binary format.
func (g *EACLArgs) SetCID(v []byte) {
g.cid = v
}
// EACL returns the eACL table
// in a binary format.
func (g *EACLValues) EACL() []byte {
return g.eacl
}
// Signature returns RFC-6979 signature of extended ACL table.
func (g *EACLValues) Signature() []byte {
return g.signature
}
// PublicKey of the signature.
func (g *EACLValues) PublicKey() []byte {
return g.publicKey
}
// SessionToken returns token of the session within which
// the eACl table was set in a NeoFS API binary format.
func (g *EACLValues) SessionToken() []byte {
return g.token
}
// EACL performs the test invoke of get eACL
// method of NeoFS Container contract.
func (c *Client) EACL(args EACLArgs) (*EACLValues, error) {
invokePrm := client.TestInvokePrm{}
invokePrm.SetMethod(eaclMethod)
invokePrm.SetArgs(args.cid)
prms, err := c.client.TestInvoke(invokePrm)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not perform test invocation (%s): %w", eaclMethod, err) return nil, fmt.Errorf("could not perform test invocation (%s): %w", eaclMethod, err)
} else if ln := len(prms); ln != 1 { } else if ln := len(prms); ln != 1 {
@ -76,7 +43,7 @@ func (c *Client) EACL(args EACLArgs) (*EACLValues, error) {
return nil, fmt.Errorf("unexpected eacl stack item count (%s): %d", eaclMethod, len(arr)) return nil, fmt.Errorf("unexpected eacl stack item count (%s): %d", eaclMethod, len(arr))
} }
eacl, err := client.BytesFromStackItem(arr[0]) rawEACL, err := client.BytesFromStackItem(arr[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get byte array of eACL (%s): %w", eaclMethod, err) return nil, fmt.Errorf("could not get byte array of eACL (%s): %w", eaclMethod, err)
} }
@ -86,20 +53,45 @@ func (c *Client) EACL(args EACLArgs) (*EACLValues, error) {
return nil, fmt.Errorf("could not get byte array of eACL signature (%s): %w", eaclMethod, err) return nil, fmt.Errorf("could not get byte array of eACL signature (%s): %w", eaclMethod, err)
} }
// Client may not return errors if the table is missing, so check this case additionally.
// The absence of a signature in the response can be taken as an eACL absence criterion,
// since unsigned table cannot be approved in the storage by design.
if len(sig) == 0 {
return nil, container.ErrEACLNotFound
}
pub, err := client.BytesFromStackItem(arr[2]) pub, err := client.BytesFromStackItem(arr[2])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get byte array of eACL public key (%s): %w", eaclMethod, err) return nil, fmt.Errorf("could not get byte array of eACL public key (%s): %w", eaclMethod, err)
} }
tok, err := client.BytesFromStackItem(arr[3]) binToken, err := client.BytesFromStackItem(arr[3])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get byte array of eACL session token (%s): %w", eaclMethod, err) return nil, fmt.Errorf("could not get byte array of eACL session token (%s): %w", eaclMethod, err)
} }
return &EACLValues{ table := eacl.NewTable()
eacl: eacl, if err = table.Unmarshal(rawEACL); err != nil {
signature: sig, // use other major version if there any
publicKey: pub, return nil, err
token: tok, }
}, nil
if len(binToken) > 0 {
tok := session.NewToken()
err = tok.Unmarshal(binToken)
if err != nil {
return nil, fmt.Errorf("could not unmarshal session token: %w", err)
}
table.SetSessionToken(tok)
}
tableSignature := signature.New()
tableSignature.SetKey(pub)
tableSignature.SetSign(sig)
table.SetSignature(tableSignature)
return table, nil
} }

View file

@ -4,58 +4,86 @@ import (
"fmt" "fmt"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
) )
// SetEACLArgs groups the arguments // PutEACL marshals table, and passes it to Wrapper's PutEACLBinary method
// of set eACL invocation call. // along with sig.Key() and sig.Sign().
type SetEACLArgs struct { //
eacl []byte // extended ACL table // Returns error if table is nil.
//
// If TryNotary is provided, calls notary contract.
func PutEACL(c *Client, table *eacl.Table) error {
if table == nil {
return errNilArgument
}
sig []byte // eACL table signature data, err := table.Marshal()
if err != nil {
return fmt.Errorf("can't marshal eacl table: %w", err)
}
pubkey []byte // binary public key binToken, err := table.SessionToken().Marshal()
if err != nil {
return fmt.Errorf("could not marshal session token: %w", err)
}
token []byte // binary session token sig := table.Signature()
return c.PutEACL(
PutEACLPrm{
table: data,
key: sig.Key(),
sig: sig.Sign(),
token: binToken,
})
}
// PutEACLPrm groups parameters of PutEACL operation.
type PutEACLPrm struct {
table []byte
key []byte
sig []byte
token []byte
client.InvokePrmOptional client.InvokePrmOptional
} }
// SetEACL sets the extended ACL table // SetTable sets table.
// in a binary format. func (p *PutEACLPrm) SetTable(table []byte) {
func (p *SetEACLArgs) SetEACL(v []byte) { p.table = table
p.eacl = v
} }
// SetSignature sets the eACL table structure // SetKey sets key.
// owner's signature. func (p *PutEACLPrm) SetKey(key []byte) {
func (p *SetEACLArgs) SetSignature(v []byte) { p.key = key
p.sig = v
} }
// SetPublicKey sets public key related to // SetSignature sets signature.
// table signature. func (p *PutEACLPrm) SetSignature(sig []byte) {
func (p *SetEACLArgs) SetPublicKey(v []byte) { p.sig = sig
p.pubkey = v
} }
// SetSessionToken sets token of the session // SetToken sets session token.
// within which the eACL table was set func (p *PutEACLPrm) SetToken(token []byte) {
// in a binary format. p.token = token
func (p *SetEACLArgs) SetSessionToken(v []byte) {
p.token = v
} }
// SetEACL invokes the call of set eACL method // PutEACL saves binary eACL table with its session token, key and signature
// of NeoFS Container contract. // in NeoFS system through Container contract call.
func (c *Client) SetEACL(args SetEACLArgs) error { //
// Returns any error encountered that caused the saving to interrupt.
func (c *Client) PutEACL(p PutEACLPrm) error {
if len(p.sig) == 0 || len(p.key) == 0 {
return errNilArgument
}
prm := client.InvokePrm{} prm := client.InvokePrm{}
prm.SetMethod(setEACLMethod) prm.SetMethod(setEACLMethod)
prm.SetArgs(args.eacl, args.sig, args.pubkey, args.token) prm.SetArgs(p.table, p.sig, p.key, p.token)
prm.InvokePrmOptional = args.InvokePrmOptional prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm) err := c.client.Invoke(prm)
if err != nil { if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", setEACLMethod, err) return fmt.Errorf("could not invoke method (%s): %w", setEACLMethod, err)
} }

View file

@ -6,33 +6,33 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
) )
// StartEstimation groups parameters of StartEstimation operation. // StartEstimationPrm groups parameters of StartEstimation operation.
type StartEstimation struct { type StartEstimationPrm struct {
epoch int64 commonEstimationPrm
}
// StopEstimationPrm groups parameters of StopEstimation operation.
type StopEstimationPrm struct {
commonEstimationPrm
}
type commonEstimationPrm struct {
epoch uint64
client.InvokePrmOptional client.InvokePrmOptional
} }
func (e *StartEstimation) SetEpoch(v int64) { // SetEpoch sets epoch.
e.epoch = v func (p *commonEstimationPrm) SetEpoch(epoch uint64) {
p.epoch = epoch
} }
type StopEstimation struct { // StartEstimation votes to produce start estimation notification.
epoch int64 func (c *Client) StartEstimation(p StartEstimationPrm) error {
client.InvokePrmOptional
}
func (e *StopEstimation) SetEpoch(v int64) {
e.epoch = v
}
func (c *Client) StartEstimation(args StartEstimation) error {
prm := client.InvokePrm{} prm := client.InvokePrm{}
prm.SetMethod(startEstimationMethod) prm.SetMethod(startEstimationMethod)
prm.SetArgs(args.epoch) prm.SetArgs(int64(p.epoch))
prm.InvokePrmOptional = args.InvokePrmOptional prm.InvokePrmOptional = p.InvokePrmOptional
if err := c.client.Invoke(prm); err != nil { if err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke method (%s): %w", startEstimationMethod, err) return fmt.Errorf("could not invoke method (%s): %w", startEstimationMethod, err)
@ -40,12 +40,12 @@ func (c *Client) StartEstimation(args StartEstimation) error {
return nil return nil
} }
func (c *Client) StopEstimation(args StopEstimation) error { // StopEstimation votes to produce stop estimation notification.
func (c *Client) StopEstimation(p StopEstimationPrm) error {
prm := client.InvokePrm{} prm := client.InvokePrm{}
prm.SetMethod(stopEstimationMethod) prm.SetMethod(stopEstimationMethod)
prm.SetArgs(args.epoch) prm.SetArgs(int64(p.epoch))
prm.InvokePrmOptional = args.InvokePrmOptional prm.InvokePrmOptional = p.InvokePrmOptional
if err := c.client.Invoke(prm); err != nil { if err := c.client.Invoke(prm); err != nil {
return fmt.Errorf("could not invoke method (%s): %w", stopEstimationMethod, err) return fmt.Errorf("could not invoke method (%s): %w", stopEstimationMethod, err)

View file

@ -2,72 +2,63 @@ package container
import ( import (
"fmt" "fmt"
"strings"
core "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
) )
// GetArgs groups the arguments type containerSource Client
// of get container test invoke call.
type GetArgs struct { func (x *containerSource) Get(cid *cid.ID) (*container.Container, error) {
cid []byte // container identifier return Get((*Client)(x), cid)
} }
// GetValues groups the stack parameters // AsContainerSource provides container Source interface
// returned by get container test invoke. // from Wrapper instance.
type GetValues struct { func AsContainerSource(w *Client) core.Source {
cnr []byte // container in a binary form return (*containerSource)(w)
signature []byte // RFC-6979 signature of container
publicKey []byte // public key of the container signer
token []byte // token of the session within which the container was created
} }
// SetCID sets the container identifier // Get marshals container ID, and passes it to Wrapper's Get method.
// in a binary format. //
func (g *GetArgs) SetCID(v []byte) { // Returns error if cid is nil.
g.cid = v func Get(c *Client, cid *cid.ID) (*container.Container, error) {
return c.Get(cid.ToV2().GetValue())
} }
// Container returns the container // Get reads the container from NeoFS system by binary identifier
// in a binary format. // through Container contract call.
func (g *GetValues) Container() []byte { //
return g.cnr // If an empty slice is returned for the requested identifier,
} // storage.ErrNotFound error is returned.
func (c *Client) Get(cid []byte) (*container.Container, error) {
prm := client.TestInvokePrm{}
prm.SetMethod(getMethod)
prm.SetArgs(cid)
// Signature returns RFC-6979 signature of the container. res, err := c.client.TestInvoke(prm)
func (g *GetValues) Signature() []byte {
return g.signature
}
// PublicKey returns public key related to signature.
func (g *GetValues) PublicKey() []byte {
return g.publicKey
}
// SessionToken returns token of the session within which
// the container was created in a NeoFS API binary format.
func (g *GetValues) SessionToken() []byte {
return g.token
}
// Get performs the test invoke of get container
// method of NeoFS Container contract.
func (c *Client) Get(args GetArgs) (*GetValues, error) {
invokePrm := client.TestInvokePrm{}
invokePrm.SetMethod(getMethod)
invokePrm.SetArgs(args.cid)
prms, err := c.client.TestInvoke(invokePrm)
if err != nil { if err != nil {
// TODO(fyrchik): reuse messages from container contract.
// Currently there are some dependency problems:
// github.com/nspcc-dev/neofs-node/pkg/innerring imports
// github.com/nspcc-dev/neofs-sdk-go/audit imports
// github.com/nspcc-dev/neofs-api-go/v2/audit: ambiguous import: found package github.com/nspcc-dev/neofs-api-go/v2/audit in multiple modules:
// github.com/nspcc-dev/neofs-api-go v1.27.1 (/home/dzeta/go/pkg/mod/github.com/nspcc-dev/neofs-api-go@v1.27.1/v2/audit)
// github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1 (/home/dzeta/go/pkg/mod/github.com/nspcc-dev/neofs-api-go/v2@v2.11.0-pre.0.20211201134523-3604d96f3fe1/audit)
if strings.Contains(err.Error(), "container does not exist") {
return nil, core.ErrNotFound
}
return nil, fmt.Errorf("could not perform test invocation (%s): %w", getMethod, err) return nil, fmt.Errorf("could not perform test invocation (%s): %w", getMethod, err)
} else if ln := len(prms); ln != 1 { } else if ln := len(res); ln != 1 {
return nil, fmt.Errorf("unexpected stack item count (%s): %d", getMethod, ln) return nil, fmt.Errorf("unexpected stack item count (%s): %d", getMethod, ln)
} }
arr, err := client.ArrayFromStackItem(prms[0]) arr, err := client.ArrayFromStackItem(res[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get item array of container (%s): %w", getMethod, err) return nil, fmt.Errorf("could not get item array of container (%s): %w", getMethod, err)
} }
@ -81,7 +72,7 @@ func (c *Client) Get(args GetArgs) (*GetValues, error) {
return nil, fmt.Errorf("could not get byte array of container (%s): %w", getMethod, err) return nil, fmt.Errorf("could not get byte array of container (%s): %w", getMethod, err)
} }
sig, err := client.BytesFromStackItem(arr[1]) sigBytes, err := client.BytesFromStackItem(arr[1])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get byte array of container signature (%s): %w", getMethod, err) return nil, fmt.Errorf("could not get byte array of container signature (%s): %w", getMethod, err)
} }
@ -91,15 +82,32 @@ func (c *Client) Get(args GetArgs) (*GetValues, error) {
return nil, fmt.Errorf("could not get byte array of public key (%s): %w", getMethod, err) return nil, fmt.Errorf("could not get byte array of public key (%s): %w", getMethod, err)
} }
tok, err := client.BytesFromStackItem(arr[3]) tokBytes, err := client.BytesFromStackItem(arr[3])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get byte array of session token (%s): %w", getMethod, err) return nil, fmt.Errorf("could not get byte array of session token (%s): %w", getMethod, err)
} }
return &GetValues{ cnr := container.New()
cnr: cnrBytes, if err := cnr.Unmarshal(cnrBytes); err != nil {
signature: sig, // use other major version if there any
publicKey: pub, return nil, fmt.Errorf("can't unmarshal container: %w", err)
token: tok, }
}, nil
if len(tokBytes) > 0 {
tok := session.NewToken()
err = tok.Unmarshal(tokBytes)
if err != nil {
return nil, fmt.Errorf("could not unmarshal session token: %w", err)
}
cnr.SetSessionToken(tok)
}
sig := signature.New()
sig.SetKey(pub)
sig.SetSign(sigBytes)
cnr.SetSignature(sig)
return cnr, nil
} }

View file

@ -3,65 +3,56 @@ package container
import ( import (
"fmt" "fmt"
v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/owner"
) )
// ListArgs groups the arguments // List returns a list of container identifiers belonging
// of list containers test invoke call. // to the specified owner of NeoFS system. The list is composed
type ListArgs struct { // through Container contract call.
ownerID []byte // container owner identifier //
} // Returns the identifiers of all NeoFS containers if pointer
// to owner identifier is nil.
func (c *Client) List(ownerID *owner.ID) ([]*cid.ID, error) {
var rawID []byte
if ownerID == nil {
rawID = []byte{}
} else if v2 := ownerID.ToV2(); v2 == nil {
return nil, errUnsupported // use other major version if there any
} else {
rawID = v2.GetValue()
}
// ListValues groups the stack parameters prm := client.TestInvokePrm{}
// returned by list containers test invoke. prm.SetMethod(listMethod)
type ListValues struct { prm.SetArgs(rawID)
cidList [][]byte // list of container identifiers
}
// SetOwnerID sets the container owner identifier res, err := c.client.TestInvoke(prm)
// in a binary format.
func (l *ListArgs) SetOwnerID(v []byte) {
l.ownerID = v
}
// CIDList returns the list of container
// identifiers in a binary format.
func (l *ListValues) CIDList() [][]byte {
return l.cidList
}
// List performs the test invoke of list container
// method of NeoFS Container contract.
func (c *Client) List(args ListArgs) (*ListValues, error) {
invokePrm := client.TestInvokePrm{}
invokePrm.SetMethod(listMethod)
invokePrm.SetArgs(args.ownerID)
prms, err := c.client.TestInvoke(invokePrm)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not perform test invocation (%s): %w", listMethod, err) return nil, fmt.Errorf("could not perform test invocation (%s): %w", listMethod, err)
} else if ln := len(prms); ln != 1 { } else if ln := len(res); ln != 1 {
return nil, fmt.Errorf("unexpected stack item count (%s): %d", listMethod, ln) return nil, fmt.Errorf("unexpected stack item count (%s): %d", listMethod, ln)
} }
prms, err = client.ArrayFromStackItem(prms[0]) res, err = client.ArrayFromStackItem(res[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", listMethod, err) return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", listMethod, err)
} }
res := &ListValues{ cidList := make([]*cid.ID, 0, len(res))
cidList: make([][]byte, 0, len(prms)), for i := range res {
} rawCid, err := client.BytesFromStackItem(res[i])
for i := range prms {
cid, err := client.BytesFromStackItem(prms[i])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get byte array from stack item (%s): %w", listMethod, err) return nil, fmt.Errorf("could not get byte array from stack item (%s): %w", listMethod, err)
} }
res.cidList = append(res.cidList, cid) v2 := new(v2refs.ContainerID)
v2.SetValue(rawCid)
cidList = append(cidList, cid.NewFromV2(v2))
} }
return res, nil return cidList, nil
} }

View file

@ -3,94 +3,61 @@ package container
import ( import (
"fmt" "fmt"
v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
) )
// PutSizeArgs groups the arguments // AnnounceLoadPrm groups parameters of AnnounceLoad operation.
// of "put container size" invocation call. type AnnounceLoadPrm struct {
type PutSizeArgs struct { a container.UsedSpaceAnnouncement
epoch int64 key []byte
size int64
cid []byte
reporterKey []byte
client.InvokePrmOptional client.InvokePrmOptional
} }
// SetEpoch sets the number of the epoch when // SetAnnouncement sets announcement.
// size was estimated. func (a2 *AnnounceLoadPrm) SetAnnouncement(a container.UsedSpaceAnnouncement) {
func (p *PutSizeArgs) SetEpoch(v uint64) { a2.a = a
p.epoch = int64(v)
} }
// SetSize sets estimation of the container size. // SetReporter sets public key of the reporter.
func (p *PutSizeArgs) SetSize(v uint64) { func (a2 *AnnounceLoadPrm) SetReporter(key []byte) {
p.size = int64(v) a2.key = key
} }
// SetContainerID sets identifier of the container // AnnounceLoad saves container size estimation calculated by storage node
// being evaluated. // with key in NeoFS system through Container contract call.
func (p *PutSizeArgs) SetContainerID(v []byte) { //
p.cid = v // Returns any error encountered that caused the saving to interrupt.
} func (c *Client) AnnounceLoad(p AnnounceLoadPrm) error {
v2 := p.a.ContainerID().ToV2()
if v2 == nil {
return errUnsupported // use other major version if there any
}
// SetReporterKey ыуеы public key of the storage node
// that collected size estimation.
func (p *PutSizeArgs) SetReporterKey(v []byte) {
p.reporterKey = v
}
// PutSize invokes the call of put container size method
// of NeoFS Container contract.
func (c *Client) PutSize(args PutSizeArgs) error {
prm := client.InvokePrm{} prm := client.InvokePrm{}
prm.SetMethod(putSizeMethod) prm.SetMethod(putSizeMethod)
prm.SetArgs(args.epoch, args.cid, args.size, args.reporterKey) prm.SetArgs(int64(p.a.Epoch()), v2.GetValue(), int64(p.a.UsedSpace()), p.key)
prm.InvokePrmOptional = args.InvokePrmOptional prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm) err := c.client.Invoke(prm)
if err != nil { if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", putSizeMethod, err) return fmt.Errorf("could not invoke method (%s): %w", putSizeMethod, err)
} }
return nil return nil
} }
// ListSizesArgs groups the arguments // EstimationID is an identity of container load estimation inside Container contract.
// of "list container sizes" test invoke call.. type EstimationID []byte
type ListSizesArgs struct {
epoch int64
}
// SetEpoch sets the number of the epoch to select // ListLoadEstimationsByEpoch returns a list of container load estimations for to the specified epoch.
// the estimations. // The list is composed through Container contract call.
func (p *ListSizesArgs) SetEpoch(v uint64) { func (c *Client) ListLoadEstimationsByEpoch(epoch uint64) ([]EstimationID, error) {
p.epoch = int64(v)
}
// ListSizesValues groups the stack items
// returned by "list container sizes" test invoke.
type ListSizesValues struct {
ids [][]byte
}
// IDList returns list of identifiers of the
// container load estimations.
func (v *ListSizesValues) IDList() [][]byte {
return v.ids
}
// ListSizes performs the test invoke of "list container sizes"
// method of NeoFS Container contract.
func (c *Client) ListSizes(args ListSizesArgs) (*ListSizesValues, error) {
invokePrm := client.TestInvokePrm{} invokePrm := client.TestInvokePrm{}
invokePrm.SetMethod(listSizesMethod) invokePrm.SetMethod(listSizesMethod)
invokePrm.SetArgs(args.epoch) invokePrm.SetArgs(int64(epoch))
prms, err := c.client.TestInvoke(invokePrm) prms, err := c.client.TestInvoke(invokePrm)
if err != nil { if err != nil {
@ -104,65 +71,42 @@ func (c *Client) ListSizes(args ListSizesArgs) (*ListSizesValues, error) {
return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", listSizesMethod, err) return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", listSizesMethod, err)
} }
res := &ListSizesValues{ res := make([]EstimationID, 0, len(prms))
ids: make([][]byte, 0, len(prms)),
}
for i := range prms { for i := range prms {
id, err := client.BytesFromStackItem(prms[i]) id, err := client.BytesFromStackItem(prms[i])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get ID byte array from stack item (%s): %w", listSizesMethod, err) return nil, fmt.Errorf("could not get ID byte array from stack item (%s): %w", listSizesMethod, err)
} }
res.ids = append(res.ids, id) res = append(res, id)
} }
return res, nil return res, nil
} }
// GetSizeArgs groups the arguments // Estimation is a structure of single container load estimation
// of "get container size" test invoke call.. // reported by storage node.
type GetSizeArgs struct {
id []byte
}
// SetID sets identifier of the container estimation.
func (p *GetSizeArgs) SetID(v []byte) {
p.id = v
}
type Estimation struct { type Estimation struct {
Size int64 Size uint64
Reporter []byte Reporter []byte
} }
// Estimations is a structure of grouped container load estimation inside Container contract.
type Estimations struct { type Estimations struct {
ContainerID []byte ContainerID *cid.ID
Estimations []Estimation Values []Estimation
} }
// GetSizeValues groups the stack items // GetUsedSpaceEstimations returns a list of container load estimations by ID.
// returned by "get container size" test invoke. // The list is composed through Container contract call.
type GetSizeValues struct { func (c *Client) GetUsedSpaceEstimations(id EstimationID) (*Estimations, error) {
est Estimations prm := client.TestInvokePrm{}
} prm.SetMethod(getSizeMethod)
prm.SetArgs([]byte(id))
// Estimations returns list of the container load estimations. prms, err := c.client.TestInvoke(prm)
func (v *GetSizeValues) Estimations() Estimations {
return v.est
}
// GetContainerSize performs the test invoke of "get container size"
// method of NeoFS Container contract.
func (c *Client) GetContainerSize(args GetSizeArgs) (*GetSizeValues, error) {
invokePrm := client.TestInvokePrm{}
invokePrm.SetMethod(getSizeMethod)
invokePrm.SetArgs(args.id)
prms, err := c.client.TestInvoke(invokePrm)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not perform test invocation (%s): %w", getSizeMethod, err) return nil, fmt.Errorf("could not perform test invocation (%s): %w", getSizeMethod, err)
} else if ln := len(prms); ln != 1 { } else if ln := len(prms); ln != 1 {
@ -176,9 +120,7 @@ func (c *Client) GetContainerSize(args GetSizeArgs) (*GetSizeValues, error) {
return nil, fmt.Errorf("unexpected stack item count of estimations fields (%s)", getSizeMethod) return nil, fmt.Errorf("unexpected stack item count of estimations fields (%s)", getSizeMethod)
} }
es := Estimations{} rawCID, err := client.BytesFromStackItem(prms[0])
es.ContainerID, err = client.BytesFromStackItem(prms[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get container ID byte array from stack item (%s): %w", getSizeMethod, err) return nil, fmt.Errorf("could not get container ID byte array from stack item (%s): %w", getSizeMethod, err)
} }
@ -188,7 +130,12 @@ func (c *Client) GetContainerSize(args GetSizeArgs) (*GetSizeValues, error) {
return nil, fmt.Errorf("could not get estimation list array from stack item (%s): %w", getSizeMethod, err) return nil, fmt.Errorf("could not get estimation list array from stack item (%s): %w", getSizeMethod, err)
} }
es.Estimations = make([]Estimation, 0, len(prms)) v2 := new(v2refs.ContainerID)
v2.SetValue(rawCID)
res := &Estimations{
ContainerID: cid.NewFromV2(v2),
Values: make([]Estimation, 0, len(prms)),
}
for i := range prms { for i := range prms {
arr, err := client.ArrayFromStackItem(prms[i]) arr, err := client.ArrayFromStackItem(prms[i])
@ -198,22 +145,21 @@ func (c *Client) GetContainerSize(args GetSizeArgs) (*GetSizeValues, error) {
return nil, fmt.Errorf("unexpected stack item count of estimation fields (%s)", getSizeMethod) return nil, fmt.Errorf("unexpected stack item count of estimation fields (%s)", getSizeMethod)
} }
e := Estimation{} reporter, err := client.BytesFromStackItem(arr[0])
e.Reporter, err = client.BytesFromStackItem(arr[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get reporter byte array from stack item (%s): %w", getSizeMethod, err) return nil, fmt.Errorf("could not get reporter byte array from stack item (%s): %w", getSizeMethod, err)
} }
e.Size, err = client.IntFromStackItem(arr[1]) sz, err := client.IntFromStackItem(arr[1])
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get estimation size from stack item (%s): %w", getSizeMethod, err) return nil, fmt.Errorf("could not get estimation size from stack item (%s): %w", getSizeMethod, err)
} }
es.Estimations = append(es.Estimations, e) res.Values = append(res.Values, Estimation{
Reporter: reporter,
Size: uint64(sz),
})
} }
return &GetSizeValues{ return res, nil
est: es,
}, nil
} }

View file

@ -1,82 +1,128 @@
package container package container
import ( import (
"crypto/sha256"
"fmt" "fmt"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
) )
// PutArgs groups the arguments // Put marshals container, and passes it to Wrapper's Put method
// of put container invocation call. // along with sig.Key() and sig.Sign().
type PutArgs struct { //
cnr []byte // container in a binary format // Returns error if container is nil.
func Put(c *Client, cnr *container.Container) (*cid.ID, error) {
if cnr == nil {
return nil, errNilArgument
}
sig []byte // binary container signature data, err := cnr.Marshal()
if err != nil {
return nil, fmt.Errorf("can't marshal container: %w", err)
}
publicKey []byte // public key of container owner binToken, err := cnr.SessionToken().Marshal()
if err != nil {
return nil, fmt.Errorf("could not marshal session token: %w", err)
}
token []byte // binary session token sig := cnr.Signature()
name, zone string // native name and zone name, zone := container.GetNativeNameWithZone(cnr)
err = c.Put(PutPrm{
cnr: data,
key: sig.Key(),
sig: sig.Sign(),
token: binToken,
name: name,
zone: zone,
})
if err != nil {
return nil, err
}
id := cid.New()
id.SetSHA256(sha256.Sum256(data))
return id, nil
}
// PutPrm groups parameters of Put operation.
type PutPrm struct {
cnr []byte
key []byte
sig []byte
token []byte
name string
zone string
client.InvokePrmOptional client.InvokePrmOptional
} }
// SetPublicKey sets the public key of container owner // SetContainer sets container data.
// in a binary format. func (p *PutPrm) SetContainer(cnr []byte) {
func (p *PutArgs) SetPublicKey(v []byte) { p.cnr = cnr
p.publicKey = v
} }
// SetContainer sets the container structure // SetKey sets public key.
// in a binary format. func (p *PutPrm) SetKey(key []byte) {
func (p *PutArgs) SetContainer(v []byte) { p.key = key
p.cnr = v
} }
// SetSignature sets the container structure // SetSignature sets signature.
// owner's signature. func (p *PutPrm) SetSignature(sig []byte) {
func (p *PutArgs) SetSignature(v []byte) { p.sig = sig
p.sig = v
} }
// SetSessionToken sets token of the session // SetToken sets session token.
// within which the container was created func (p *PutPrm) SetToken(token []byte) {
// in a binary format. p.token = token
func (p *PutArgs) SetSessionToken(v []byte) {
p.token = v
} }
// SetNativeNameWithZone sets container native name and its zone. // SetName sets native name.
func (p *PutArgs) SetNativeNameWithZone(name, zone string) { func (p *PutPrm) SetName(name string) {
p.name, p.zone = name, zone p.name = name
} }
// Put invokes the call of put (named if name is set) container method // SetZone sets zone.
// of NeoFS Container contract. func (p *PutPrm) SetZone(zone string) {
func (c *Client) Put(args PutArgs) error { p.zone = zone
}
// Put saves binary container with its session token, key and signature
// in NeoFS system through Container contract call.
//
// Returns calculated container identifier and any error
// encountered that caused the saving to interrupt.
//
// If TryNotary is provided, calls notary contract.
func (c *Client) Put(p PutPrm) error {
if len(p.sig) == 0 || len(p.key) == 0 {
return errNilArgument
}
var ( var (
method string method string
prm client.InvokePrm prm client.InvokePrm
) )
if args.name != "" { if p.name != "" {
method = PutNamedMethod method = putNamedMethod
prm.SetArgs(p.cnr, p.sig, p.key, p.token, p.name, p.zone)
prm.SetArgs(args.cnr, args.sig, args.publicKey, args.token, args.name, args.zone)
} else { } else {
method = putMethod method = putMethod
prm.SetArgs(p.cnr, p.sig, p.key, p.token)
prm.SetArgs(args.cnr, args.sig, args.publicKey, args.token)
} }
prm.SetMethod(method) prm.SetMethod(method)
prm.InvokePrmOptional = args.InvokePrmOptional prm.InvokePrmOptional = p.InvokePrmOptional
err := c.client.Invoke(prm) err := c.client.Invoke(prm)
if err != nil { if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", method, err) return fmt.Errorf("could not invoke method (%s): %w", method, err)
} }
return nil return nil
} }

View file

@ -1,424 +0,0 @@
package wrapper
import (
"crypto/sha256"
"errors"
"fmt"
"strings"
v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs"
core "github.com/nspcc-dev/neofs-node/pkg/core/container"
staticli "github.com/nspcc-dev/neofs-node/pkg/morph/client"
client "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/owner"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
)
var (
errNilArgument = errors.New("empty argument")
errUnsupported = errors.New("unsupported structure version")
)
// Put marshals container, and passes it to Wrapper's Put method
// along with sig.Key() and sig.Sign().
//
// Returns error if container is nil.
func Put(w *Wrapper, cnr *container.Container) (*cid.ID, error) {
if cnr == nil {
return nil, errNilArgument
}
data, err := cnr.Marshal()
if err != nil {
return nil, fmt.Errorf("can't marshal container: %w", err)
}
binToken, err := cnr.SessionToken().Marshal()
if err != nil {
return nil, fmt.Errorf("could not marshal session token: %w", err)
}
sig := cnr.Signature()
name, zone := container.GetNativeNameWithZone(cnr)
err = w.Put(PutPrm{
cnr: data,
key: sig.Key(),
sig: sig.Sign(),
token: binToken,
name: name,
zone: zone,
})
if err != nil {
return nil, err
}
id := cid.New()
id.SetSHA256(sha256.Sum256(data))
return id, nil
}
// PutPrm groups parameters of Put operation.
type PutPrm struct {
cnr []byte
key []byte
sig []byte
token []byte
name string
zone string
staticli.InvokePrmOptional
}
// SetContainer sets container data.
func (p *PutPrm) SetContainer(cnr []byte) {
p.cnr = cnr
}
// SetKey sets public key.
func (p *PutPrm) SetKey(key []byte) {
p.key = key
}
// SetSignature sets signature.
func (p *PutPrm) SetSignature(sig []byte) {
p.sig = sig
}
// SetToken sets session token.
func (p *PutPrm) SetToken(token []byte) {
p.token = token
}
// SetName sets native name.
func (p *PutPrm) SetName(name string) {
p.name = name
}
// SetZone sets zone.
func (p *PutPrm) SetZone(zone string) {
p.zone = zone
}
// Put saves binary container with its session token, key and signature
// in NeoFS system through Container contract call.
//
// Returns calculated container identifier and any error
// encountered that caused the saving to interrupt.
//
// If TryNotary is provided, calls notary contract.
func (w *Wrapper) Put(prm PutPrm) error {
if len(prm.sig) == 0 || len(prm.key) == 0 {
return errNilArgument
}
var args client.PutArgs
args.SetContainer(prm.cnr)
args.SetSignature(prm.sig)
args.SetPublicKey(prm.key)
args.SetSessionToken(prm.token)
args.SetNativeNameWithZone(prm.name, prm.zone)
args.InvokePrmOptional = prm.InvokePrmOptional
err := w.client.Put(args)
if err != nil {
return err
}
return nil
}
type containerSource Wrapper
func (x *containerSource) Get(cid *cid.ID) (*container.Container, error) {
return Get((*Wrapper)(x), cid)
}
// AsContainerSource provides container Source interface
// from Wrapper instance.
func AsContainerSource(w *Wrapper) core.Source {
return (*containerSource)(w)
}
// Get marshals container ID, and passes it to Wrapper's Get method.
//
// Returns error if cid is nil.
func Get(w *Wrapper, cid *cid.ID) (*container.Container, error) {
return w.Get(cid.ToV2().GetValue())
}
// Get reads the container from NeoFS system by binary identifier
// through Container contract call.
//
// If an empty slice is returned for the requested identifier,
// storage.ErrNotFound error is returned.
func (w *Wrapper) Get(cid []byte) (*container.Container, error) {
var args client.GetArgs
args.SetCID(cid)
// ask RPC neo node to get serialized container
rpcAnswer, err := w.client.Get(args)
if err != nil {
// TODO(fyrchik): reuse messages from container contract.
// Currently there are some dependency problems:
// github.com/nspcc-dev/neofs-node/pkg/innerring imports
// github.com/nspcc-dev/neofs-sdk-go/audit imports
// github.com/nspcc-dev/neofs-api-go/v2/audit: ambiguous import: found package github.com/nspcc-dev/neofs-api-go/v2/audit in multiple modules:
// github.com/nspcc-dev/neofs-api-go v1.27.1 (/home/dzeta/go/pkg/mod/github.com/nspcc-dev/neofs-api-go@v1.27.1/v2/audit)
// github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1 (/home/dzeta/go/pkg/mod/github.com/nspcc-dev/neofs-api-go/v2@v2.11.0-pre.0.20211201134523-3604d96f3fe1/audit)
if strings.Contains(err.Error(), "container does not exist") {
return nil, core.ErrNotFound
}
return nil, err
}
// unmarshal container
cnr := container.New()
if err := cnr.Unmarshal(rpcAnswer.Container()); err != nil {
// use other major version if there any
return nil, fmt.Errorf("can't unmarshal container: %w", err)
}
binToken := rpcAnswer.SessionToken()
if len(binToken) > 0 {
tok := session.NewToken()
err = tok.Unmarshal(binToken)
if err != nil {
return nil, fmt.Errorf("could not unmarshal session token: %w", err)
}
cnr.SetSessionToken(tok)
}
sig := signature.New()
sig.SetKey(rpcAnswer.PublicKey())
sig.SetSign(rpcAnswer.Signature())
cnr.SetSignature(sig)
return cnr, nil
}
// Delete marshals container ID, and passes it to Wrapper's Delete method
// along with signature and session token.
//
// Returns error if container ID is nil.
func Delete(w *Wrapper, witness core.RemovalWitness) error {
id := witness.ContainerID()
if id == nil {
return errNilArgument
}
binToken, err := witness.SessionToken().Marshal()
if err != nil {
return fmt.Errorf("could not marshal session token: %w", err)
}
return w.Delete(
DeletePrm{
cid: id.ToV2().GetValue(),
signature: witness.Signature(),
token: binToken,
})
}
// DeletePrm groups parameters of Delete client operation.
type DeletePrm struct {
cid []byte
signature []byte
token []byte
staticli.InvokePrmOptional
}
// SetCID sets container ID.
func (d *DeletePrm) SetCID(cid []byte) {
d.cid = cid
}
// SetSignature sets signature.
func (d *DeletePrm) SetSignature(signature []byte) {
d.signature = signature
}
// SetToken sets session token.
func (d *DeletePrm) SetToken(token []byte) {
d.token = token
}
// Delete removes the container from NeoFS system
// through Container contract call.
//
// Returns any error encountered that caused
// the removal to interrupt.
//
// If TryNotary is provided, calls notary contract.
func (w *Wrapper) Delete(prm DeletePrm) error {
if len(prm.signature) == 0 {
return errNilArgument
}
var args client.DeleteArgs
args.SetSignature(prm.signature)
args.SetCID(prm.cid)
args.SetSessionToken(prm.token)
args.InvokePrmOptional = prm.InvokePrmOptional
return w.client.Delete(args)
}
// List returns a list of container identifiers belonging
// to the specified owner of NeoFS system. The list is composed
// through Container contract call.
//
// Returns the identifiers of all NeoFS containers if pointer
// to owner identifier is nil.
func (w *Wrapper) List(ownerID *owner.ID) ([]*cid.ID, error) {
args := client.ListArgs{}
if ownerID == nil {
args.SetOwnerID([]byte{})
} else if v2 := ownerID.ToV2(); v2 == nil {
return nil, errUnsupported // use other major version if there any
} else {
args.SetOwnerID(v2.GetValue())
}
// ask RPC neo node to get serialized container
rpcAnswer, err := w.client.List(args)
if err != nil {
return nil, err
}
rawIDs := rpcAnswer.CIDList()
result := make([]*cid.ID, 0, len(rawIDs))
for i := range rawIDs {
v2 := new(v2refs.ContainerID)
v2.SetValue(rawIDs[i])
id := cid.NewFromV2(v2)
result = append(result, id)
}
return result, nil
}
// AnnounceLoadPrm groups parameters of AnnounceLoad operation.
type AnnounceLoadPrm struct {
a container.UsedSpaceAnnouncement
key []byte
staticli.InvokePrmOptional
}
// SetAnnouncement sets announcement.
func (a2 *AnnounceLoadPrm) SetAnnouncement(a container.UsedSpaceAnnouncement) {
a2.a = a
}
// SetReporter sets public key of the reporter.
func (a2 *AnnounceLoadPrm) SetReporter(key []byte) {
a2.key = key
}
// AnnounceLoad saves container size estimation calculated by storage node
// with key in NeoFS system through Container contract call.
//
// Returns any error encountered that caused the saving to interrupt.
func (w *Wrapper) AnnounceLoad(prm AnnounceLoadPrm) error {
v2 := prm.a.ContainerID().ToV2()
if v2 == nil {
return errUnsupported // use other major version if there any
}
args := client.PutSizeArgs{}
args.SetContainerID(v2.GetValue())
args.SetEpoch(prm.a.Epoch())
args.SetSize(prm.a.UsedSpace())
args.SetReporterKey(prm.key)
args.InvokePrmOptional = prm.InvokePrmOptional
return w.client.PutSize(args)
}
// EstimationID is an identity of container load estimation inside Container contract.
type EstimationID []byte
// ListLoadEstimationsByEpoch returns a list of container load estimations for to the specified epoch.
// The list is composed through Container contract call.
func (w *Wrapper) ListLoadEstimationsByEpoch(epoch uint64) ([]EstimationID, error) {
args := client.ListSizesArgs{}
args.SetEpoch(epoch)
// ask RPC neo node to get serialized container
rpcAnswer, err := w.client.ListSizes(args)
if err != nil {
return nil, err
}
rawIDs := rpcAnswer.IDList()
result := make([]EstimationID, 0, len(rawIDs))
for i := range rawIDs {
result = append(result, rawIDs[i])
}
return result, nil
}
// Estimation is a structure of single container load estimation
// reported by storage node.
type Estimation struct {
Size uint64
Reporter []byte
}
// Estimations is a structure of grouped container load estimation inside Container contract.
type Estimations struct {
ContainerID *cid.ID
Values []Estimation
}
// GetUsedSpaceEstimations returns a list of container load estimations by ID.
// The list is composed through Container contract call.
func (w *Wrapper) GetUsedSpaceEstimations(id EstimationID) (*Estimations, error) {
args := client.GetSizeArgs{}
args.SetID(id)
rpcAnswer, err := w.client.GetContainerSize(args)
if err != nil {
return nil, err
}
es := rpcAnswer.Estimations()
v2 := new(v2refs.ContainerID)
v2.SetValue(es.ContainerID)
res := &Estimations{
ContainerID: cid.NewFromV2(v2),
Values: make([]Estimation, 0, len(es.Estimations)),
}
for i := range es.Estimations {
res.Values = append(res.Values, Estimation{
Size: uint64(es.Estimations[i].Size),
Reporter: es.Estimations[i].Reporter,
})
}
return res, nil
}

View file

@ -1,150 +0,0 @@
package wrapper
import (
"fmt"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
staticli "github.com/nspcc-dev/neofs-node/pkg/morph/client"
client "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/signature"
)
// GetEACL reads the extended ACL table from NeoFS system
// through Container contract call.
func (w *Wrapper) GetEACL(cid *cid.ID) (*eacl.Table, error) {
if cid == nil {
return nil, errNilArgument
}
args := client.EACLArgs{}
v2 := cid.ToV2()
if v2 == nil {
return nil, errUnsupported // use other major version if there any
}
args.SetCID(v2.GetValue())
rpcAnswer, err := w.client.EACL(args)
if err != nil {
return nil, err
}
// Client may not return errors if the table is missing, so check this case additionally.
// The absence of a signature in the response can be taken as an eACL absence criterion,
// since unsigned table cannot be approved in the storage by design.
sig := rpcAnswer.Signature()
if len(sig) == 0 {
return nil, container.ErrEACLNotFound
}
table := eacl.NewTable()
if err = table.Unmarshal(rpcAnswer.EACL()); err != nil {
// use other major version if there any
return nil, err
}
binToken := rpcAnswer.SessionToken()
if len(binToken) > 0 {
tok := session.NewToken()
err = tok.Unmarshal(binToken)
if err != nil {
return nil, fmt.Errorf("could not unmarshal session token: %w", err)
}
table.SetSessionToken(tok)
}
tableSignature := signature.New()
tableSignature.SetKey(rpcAnswer.PublicKey())
tableSignature.SetSign(sig)
table.SetSignature(tableSignature)
return table, nil
}
// PutEACL marshals table, and passes it to Wrapper's PutEACLBinary method
// along with sig.Key() and sig.Sign().
//
// Returns error if table is nil.
//
// If TryNotary is provided, calls notary contract.
func PutEACL(w *Wrapper, table *eacl.Table) error {
if table == nil {
return errNilArgument
}
data, err := table.Marshal()
if err != nil {
return fmt.Errorf("can't marshal eacl table: %w", err)
}
binToken, err := table.SessionToken().Marshal()
if err != nil {
return fmt.Errorf("could not marshal session token: %w", err)
}
sig := table.Signature()
return w.PutEACL(
PutEACLPrm{
table: data,
key: sig.Key(),
sig: sig.Sign(),
token: binToken,
})
}
// PutEACLPrm groups parameters of PutEACL operation.
type PutEACLPrm struct {
table []byte
key []byte
sig []byte
token []byte
staticli.InvokePrmOptional
}
// SetTable sets table.
func (p *PutEACLPrm) SetTable(table []byte) {
p.table = table
}
// SetKey sets key.
func (p *PutEACLPrm) SetKey(key []byte) {
p.key = key
}
// SetSignature sets signature.
func (p *PutEACLPrm) SetSignature(sig []byte) {
p.sig = sig
}
// SetToken sets session token.
func (p *PutEACLPrm) SetToken(token []byte) {
p.token = token
}
// PutEACL saves binary eACL table with its session token, key and signature
// in NeoFS system through Container contract call.
//
// Returns any error encountered that caused the saving to interrupt.
func (w *Wrapper) PutEACL(prm PutEACLPrm) error {
if len(prm.sig) == 0 || len(prm.key) == 0 {
return errNilArgument
}
args := client.SetEACLArgs{}
args.SetSignature(prm.sig)
args.SetPublicKey(prm.key)
args.SetEACL(prm.table)
args.SetSessionToken(prm.token)
args.InvokePrmOptional = prm.InvokePrmOptional
return w.client.SetEACL(args)
}

View file

@ -1,48 +0,0 @@
package wrapper
import (
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
)
// StartEstimationPrm groups parameters of StartEstimation operation.
type StartEstimationPrm struct {
epoch uint64
client.InvokePrmOptional
}
// SetEpoch sets epoch.
func (s *StartEstimationPrm) SetEpoch(epoch uint64) {
s.epoch = epoch
}
// StartEstimation votes to produce start estimation notification.
func (w *Wrapper) StartEstimation(prm StartEstimationPrm) error {
args := container.StartEstimation{}
args.SetEpoch(int64(prm.epoch))
args.InvokePrmOptional = prm.InvokePrmOptional
return w.client.StartEstimation(args)
}
// StopEstimationPrm groups parameters of StopEstimation operation.
type StopEstimationPrm struct {
epoch uint64
client.InvokePrmOptional
}
// SetEpoch sets epoch.
func (s *StopEstimationPrm) SetEpoch(epoch uint64) {
s.epoch = epoch
}
// StopEstimation votes to produce stop estimation notification.
func (w *Wrapper) StopEstimation(prm StopEstimationPrm) error {
args := container.StopEstimation{}
args.SetEpoch(int64(prm.epoch))
args.InvokePrmOptional = prm.InvokePrmOptional
return w.client.StopEstimation(args)
}

View file

@ -1,100 +0,0 @@
package wrapper
import (
"fmt"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/internal"
)
// Wrapper is a wrapper over container contract
// client which implements container storage and
// eACL storage methods.
//
// Working wrapper must be created via constructor New.
// Using the Wrapper that has been created with new(Wrapper)
// expression (or just declaring a Wrapper variable) is unsafe
// and can lead to panic.
type Wrapper struct {
internal.StaticClient
client *container.Client
}
// Option allows to set an optional
// parameter of Wrapper.
type Option func(*opts)
type opts struct {
feePutNamedSet bool
feePutNamed fixedn.Fixed8
staticOpts []client.StaticClientOption
}
func defaultOpts() *opts {
return new(opts)
}
// Morph returns raw morph client.
func (w Wrapper) Morph() *client.Client {
return w.client.Morph()
}
// TryNotary returns option to enable
// notary invocation tries.
func TryNotary() Option {
return func(o *opts) {
o.staticOpts = append(o.staticOpts, client.TryNotary())
}
}
// AsAlphabet returns option to sign main TX
// of notary requests with client's private
// key.
//
// Considered to be used by IR nodes only.
func AsAlphabet() Option {
return func(o *opts) {
o.staticOpts = append(o.staticOpts, client.AsAlphabet())
}
}
// WithCustomFeeForNamedPut returns option to specify custom fee for each Put operation with named container.
func WithCustomFeeForNamedPut(fee fixedn.Fixed8) Option {
return func(o *opts) {
o.feePutNamed = fee
o.feePutNamedSet = true
}
}
// NewFromMorph returns the wrapper instance from the raw morph client.
//
// Specified fee is used for all operations by default. If WithCustomFeeForNamedPut is provided,
// the customized fee is used for Put operations with named containers.
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...Option) (*Wrapper, error) {
o := defaultOpts()
for i := range opts {
opts[i](o)
}
staticOpts := o.staticOpts
if o.feePutNamedSet {
staticOpts = append(staticOpts, client.WithCustomFee(container.PutNamedMethod, o.feePutNamed))
}
staticClient, err := client.NewStatic(cli, contract, fee, staticOpts...)
if err != nil {
return nil, fmt.Errorf("can't create container static client: %w", err)
}
return &Wrapper{
StaticClient: staticClient,
client: container.New(staticClient),
}, nil
}