forked from TrueCloudLab/frostfs-node
[#625] client/container: remove intermediate wrapper
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
819d80a7a9
commit
c34cfa1f35
28 changed files with 556 additions and 1168 deletions
|
@ -1,6 +1,11 @@
|
|||
package container
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
|
@ -31,16 +36,86 @@ const (
|
|||
listSizesMethod = "listContainerSizes"
|
||||
getSizeMethod = "getContainerSize"
|
||||
|
||||
// PutNamedMethod is method name for container put with an alias. It is exported to provide custom fee.
|
||||
PutNamedMethod = "putNamed"
|
||||
// putNamedMethod is method name for container put with an alias. It is exported to provide custom fee.
|
||||
putNamedMethod = "putNamed"
|
||||
)
|
||||
|
||||
// New creates, initializes and returns the Client instance.
|
||||
func New(c *client.StaticClient) *Client {
|
||||
return &Client{client: c}
|
||||
var (
|
||||
errNilArgument = errors.New("empty argument")
|
||||
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.
|
||||
func (c Client) Morph() *client.Client {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,51 +3,75 @@ package container
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
core "github.com/nspcc-dev/neofs-node/pkg/core/container"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// DeleteArgs groups the arguments
|
||||
// of delete container invocation call.
|
||||
type DeleteArgs struct {
|
||||
cid []byte // container identifier
|
||||
// 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(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
|
||||
}
|
||||
|
||||
// SetCID sets the container identifier
|
||||
// in a binary format.
|
||||
func (p *DeleteArgs) SetCID(v []byte) {
|
||||
p.cid = v
|
||||
// SetCID sets container ID.
|
||||
func (d *DeletePrm) SetCID(cid []byte) {
|
||||
d.cid = cid
|
||||
}
|
||||
|
||||
// SetSignature sets the container identifier
|
||||
// owner's signature.
|
||||
func (p *DeleteArgs) SetSignature(v []byte) {
|
||||
p.sig = v
|
||||
// SetSignature sets signature.
|
||||
func (d *DeletePrm) SetSignature(signature []byte) {
|
||||
d.signature = signature
|
||||
}
|
||||
|
||||
// SetSessionToken sets token of the session
|
||||
// within which the container was removed
|
||||
// in a NeoFS API binary format.
|
||||
func (p *DeleteArgs) SetSessionToken(v []byte) {
|
||||
p.token = v
|
||||
// SetToken sets session token.
|
||||
func (d *DeletePrm) SetToken(token []byte) {
|
||||
d.token = token
|
||||
}
|
||||
|
||||
// Delete invokes the call of delete container
|
||||
// method of NeoFS Container contract.
|
||||
func (c *Client) Delete(args DeleteArgs) error {
|
||||
// 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 (c *Client) Delete(p DeletePrm) error {
|
||||
if len(p.signature) == 0 {
|
||||
return errNilArgument
|
||||
}
|
||||
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(deleteMethod)
|
||||
prm.SetArgs(args.cid, args.sig, args.token)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(p.cid, p.signature, p.token)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
err := c.client.Invoke(prm)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", deleteMethod, err)
|
||||
}
|
||||
|
|
|
@ -3,64 +3,31 @@ package container
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/container"
|
||||
"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
|
||||
// of get eACL test invoke call.
|
||||
type EACLArgs struct {
|
||||
cid []byte // container identifier
|
||||
}
|
||||
// GetEACL reads the extended ACL table from NeoFS system
|
||||
// through Container contract call.
|
||||
func (c *Client) GetEACL(cid *cid.ID) (*eacl.Table, error) {
|
||||
if cid == nil {
|
||||
return nil, errNilArgument
|
||||
}
|
||||
|
||||
// EACLValues groups the stack parameters
|
||||
// returned by get eACL test invoke.
|
||||
type EACLValues struct {
|
||||
eacl []byte // extended ACL table
|
||||
v2 := cid.ToV2()
|
||||
if v2 == nil {
|
||||
return nil, errUnsupported // use other major version if there any
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
prms, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w", eaclMethod, err)
|
||||
} 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))
|
||||
}
|
||||
|
||||
eacl, err := client.BytesFromStackItem(arr[0])
|
||||
rawEACL, err := client.BytesFromStackItem(arr[0])
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
// 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])
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, fmt.Errorf("could not get byte array of eACL session token (%s): %w", eaclMethod, err)
|
||||
}
|
||||
|
||||
return &EACLValues{
|
||||
eacl: eacl,
|
||||
signature: sig,
|
||||
publicKey: pub,
|
||||
token: tok,
|
||||
}, nil
|
||||
table := eacl.NewTable()
|
||||
if err = table.Unmarshal(rawEACL); err != nil {
|
||||
// use other major version if there any
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -4,58 +4,86 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||
)
|
||||
|
||||
// SetEACLArgs groups the arguments
|
||||
// of set eACL invocation call.
|
||||
type SetEACLArgs struct {
|
||||
eacl []byte // extended ACL table
|
||||
// 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(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
|
||||
}
|
||||
|
||||
// SetEACL sets the extended ACL table
|
||||
// in a binary format.
|
||||
func (p *SetEACLArgs) SetEACL(v []byte) {
|
||||
p.eacl = v
|
||||
// SetTable sets table.
|
||||
func (p *PutEACLPrm) SetTable(table []byte) {
|
||||
p.table = table
|
||||
}
|
||||
|
||||
// SetSignature sets the eACL table structure
|
||||
// owner's signature.
|
||||
func (p *SetEACLArgs) SetSignature(v []byte) {
|
||||
p.sig = v
|
||||
// SetKey sets key.
|
||||
func (p *PutEACLPrm) SetKey(key []byte) {
|
||||
p.key = key
|
||||
}
|
||||
|
||||
// SetPublicKey sets public key related to
|
||||
// table signature.
|
||||
func (p *SetEACLArgs) SetPublicKey(v []byte) {
|
||||
p.pubkey = v
|
||||
// SetSignature sets signature.
|
||||
func (p *PutEACLPrm) SetSignature(sig []byte) {
|
||||
p.sig = sig
|
||||
}
|
||||
|
||||
// SetSessionToken sets token of the session
|
||||
// within which the eACL table was set
|
||||
// in a binary format.
|
||||
func (p *SetEACLArgs) SetSessionToken(v []byte) {
|
||||
p.token = v
|
||||
// SetToken sets session token.
|
||||
func (p *PutEACLPrm) SetToken(token []byte) {
|
||||
p.token = token
|
||||
}
|
||||
|
||||
// SetEACL invokes the call of set eACL method
|
||||
// of NeoFS Container contract.
|
||||
func (c *Client) SetEACL(args SetEACLArgs) error {
|
||||
// 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 (c *Client) PutEACL(p PutEACLPrm) error {
|
||||
if len(p.sig) == 0 || len(p.key) == 0 {
|
||||
return errNilArgument
|
||||
}
|
||||
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(setEACLMethod)
|
||||
prm.SetArgs(args.eacl, args.sig, args.pubkey, args.token)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(p.table, p.sig, p.key, p.token)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
err := c.client.Invoke(prm)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", setEACLMethod, err)
|
||||
}
|
||||
|
|
|
@ -6,33 +6,33 @@ import (
|
|||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// StartEstimation groups parameters of StartEstimation operation.
|
||||
type StartEstimation struct {
|
||||
epoch int64
|
||||
// StartEstimationPrm groups parameters of StartEstimation operation.
|
||||
type StartEstimationPrm struct {
|
||||
commonEstimationPrm
|
||||
}
|
||||
|
||||
// StopEstimationPrm groups parameters of StopEstimation operation.
|
||||
type StopEstimationPrm struct {
|
||||
commonEstimationPrm
|
||||
}
|
||||
|
||||
type commonEstimationPrm struct {
|
||||
epoch uint64
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
func (e *StartEstimation) SetEpoch(v int64) {
|
||||
e.epoch = v
|
||||
// SetEpoch sets epoch.
|
||||
func (p *commonEstimationPrm) SetEpoch(epoch uint64) {
|
||||
p.epoch = epoch
|
||||
}
|
||||
|
||||
type StopEstimation struct {
|
||||
epoch int64
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
func (e *StopEstimation) SetEpoch(v int64) {
|
||||
e.epoch = v
|
||||
}
|
||||
|
||||
func (c *Client) StartEstimation(args StartEstimation) error {
|
||||
// StartEstimation votes to produce start estimation notification.
|
||||
func (c *Client) StartEstimation(p StartEstimationPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(startEstimationMethod)
|
||||
prm.SetArgs(args.epoch)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(int64(p.epoch))
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
if err := c.client.Invoke(prm); err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", startEstimationMethod, err)
|
||||
|
@ -40,12 +40,12 @@ func (c *Client) StartEstimation(args StartEstimation) error {
|
|||
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.SetMethod(stopEstimationMethod)
|
||||
prm.SetArgs(args.epoch)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(int64(p.epoch))
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
if err := c.client.Invoke(prm); err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", stopEstimationMethod, err)
|
||||
|
|
|
@ -2,72 +2,63 @@ package container
|
|||
|
||||
import (
|
||||
"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-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
|
||||
// of get container test invoke call.
|
||||
type GetArgs struct {
|
||||
cid []byte // container identifier
|
||||
type containerSource Client
|
||||
|
||||
func (x *containerSource) Get(cid *cid.ID) (*container.Container, error) {
|
||||
return Get((*Client)(x), cid)
|
||||
}
|
||||
|
||||
// GetValues groups the stack parameters
|
||||
// returned by get container test invoke.
|
||||
type GetValues struct {
|
||||
cnr []byte // container in a binary form
|
||||
|
||||
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
|
||||
// AsContainerSource provides container Source interface
|
||||
// from Wrapper instance.
|
||||
func AsContainerSource(w *Client) core.Source {
|
||||
return (*containerSource)(w)
|
||||
}
|
||||
|
||||
// SetCID sets the container identifier
|
||||
// in a binary format.
|
||||
func (g *GetArgs) SetCID(v []byte) {
|
||||
g.cid = v
|
||||
// Get marshals container ID, and passes it to Wrapper's Get method.
|
||||
//
|
||||
// Returns error if cid is nil.
|
||||
func Get(c *Client, cid *cid.ID) (*container.Container, error) {
|
||||
return c.Get(cid.ToV2().GetValue())
|
||||
}
|
||||
|
||||
// Container returns the container
|
||||
// in a binary format.
|
||||
func (g *GetValues) Container() []byte {
|
||||
return g.cnr
|
||||
}
|
||||
// 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 (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.
|
||||
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)
|
||||
res, err := c.client.TestInvoke(prm)
|
||||
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)
|
||||
} 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)
|
||||
}
|
||||
|
||||
arr, err := client.ArrayFromStackItem(prms[0])
|
||||
arr, err := client.ArrayFromStackItem(res[0])
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
sig, err := client.BytesFromStackItem(arr[1])
|
||||
sigBytes, err := client.BytesFromStackItem(arr[1])
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
tok, err := client.BytesFromStackItem(arr[3])
|
||||
tokBytes, err := client.BytesFromStackItem(arr[3])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get byte array of session token (%s): %w", getMethod, err)
|
||||
}
|
||||
|
||||
return &GetValues{
|
||||
cnr: cnrBytes,
|
||||
signature: sig,
|
||||
publicKey: pub,
|
||||
token: tok,
|
||||
}, nil
|
||||
cnr := container.New()
|
||||
if err := cnr.Unmarshal(cnrBytes); err != nil {
|
||||
// use other major version if there any
|
||||
return nil, fmt.Errorf("can't unmarshal container: %w", err)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -3,65 +3,56 @@ package container
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
"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
|
||||
// of list containers test invoke call.
|
||||
type ListArgs struct {
|
||||
ownerID []byte // container owner identifier
|
||||
}
|
||||
// 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 (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
|
||||
// returned by list containers test invoke.
|
||||
type ListValues struct {
|
||||
cidList [][]byte // list of container identifiers
|
||||
}
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(listMethod)
|
||||
prm.SetArgs(rawID)
|
||||
|
||||
// SetOwnerID sets the container owner identifier
|
||||
// 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)
|
||||
res, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
prms, err = client.ArrayFromStackItem(prms[0])
|
||||
res, err = client.ArrayFromStackItem(res[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", listMethod, err)
|
||||
}
|
||||
|
||||
res := &ListValues{
|
||||
cidList: make([][]byte, 0, len(prms)),
|
||||
}
|
||||
|
||||
for i := range prms {
|
||||
cid, err := client.BytesFromStackItem(prms[i])
|
||||
cidList := make([]*cid.ID, 0, len(res))
|
||||
for i := range res {
|
||||
rawCid, err := client.BytesFromStackItem(res[i])
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -3,94 +3,61 @@ package container
|
|||
import (
|
||||
"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-sdk-go/container"
|
||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||
)
|
||||
|
||||
// PutSizeArgs groups the arguments
|
||||
// of "put container size" invocation call.
|
||||
type PutSizeArgs struct {
|
||||
epoch int64
|
||||
|
||||
size int64
|
||||
|
||||
cid []byte
|
||||
|
||||
reporterKey []byte
|
||||
// AnnounceLoadPrm groups parameters of AnnounceLoad operation.
|
||||
type AnnounceLoadPrm struct {
|
||||
a container.UsedSpaceAnnouncement
|
||||
key []byte
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetEpoch sets the number of the epoch when
|
||||
// size was estimated.
|
||||
func (p *PutSizeArgs) SetEpoch(v uint64) {
|
||||
p.epoch = int64(v)
|
||||
// SetAnnouncement sets announcement.
|
||||
func (a2 *AnnounceLoadPrm) SetAnnouncement(a container.UsedSpaceAnnouncement) {
|
||||
a2.a = a
|
||||
}
|
||||
|
||||
// SetSize sets estimation of the container size.
|
||||
func (p *PutSizeArgs) SetSize(v uint64) {
|
||||
p.size = int64(v)
|
||||
// SetReporter sets public key of the reporter.
|
||||
func (a2 *AnnounceLoadPrm) SetReporter(key []byte) {
|
||||
a2.key = key
|
||||
}
|
||||
|
||||
// SetContainerID sets identifier of the container
|
||||
// being evaluated.
|
||||
func (p *PutSizeArgs) SetContainerID(v []byte) {
|
||||
p.cid = v
|
||||
}
|
||||
// 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 (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.SetMethod(putSizeMethod)
|
||||
prm.SetArgs(args.epoch, args.cid, args.size, args.reporterKey)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(int64(p.a.Epoch()), v2.GetValue(), int64(p.a.UsedSpace()), p.key)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
err := c.client.Invoke(prm)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", putSizeMethod, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListSizesArgs groups the arguments
|
||||
// of "list container sizes" test invoke call..
|
||||
type ListSizesArgs struct {
|
||||
epoch int64
|
||||
}
|
||||
// EstimationID is an identity of container load estimation inside Container contract.
|
||||
type EstimationID []byte
|
||||
|
||||
// SetEpoch sets the number of the epoch to select
|
||||
// the estimations.
|
||||
func (p *ListSizesArgs) SetEpoch(v uint64) {
|
||||
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) {
|
||||
// ListLoadEstimationsByEpoch returns a list of container load estimations for to the specified epoch.
|
||||
// The list is composed through Container contract call.
|
||||
func (c *Client) ListLoadEstimationsByEpoch(epoch uint64) ([]EstimationID, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
|
||||
invokePrm.SetMethod(listSizesMethod)
|
||||
invokePrm.SetArgs(args.epoch)
|
||||
invokePrm.SetArgs(int64(epoch))
|
||||
|
||||
prms, err := c.client.TestInvoke(invokePrm)
|
||||
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)
|
||||
}
|
||||
|
||||
res := &ListSizesValues{
|
||||
ids: make([][]byte, 0, len(prms)),
|
||||
}
|
||||
|
||||
res := make([]EstimationID, 0, len(prms))
|
||||
for i := range prms {
|
||||
id, err := client.BytesFromStackItem(prms[i])
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
// GetSizeArgs groups the arguments
|
||||
// of "get container size" test invoke call..
|
||||
type GetSizeArgs struct {
|
||||
id []byte
|
||||
}
|
||||
|
||||
// SetID sets identifier of the container estimation.
|
||||
func (p *GetSizeArgs) SetID(v []byte) {
|
||||
p.id = v
|
||||
}
|
||||
|
||||
// Estimation is a structure of single container load estimation
|
||||
// reported by storage node.
|
||||
type Estimation struct {
|
||||
Size int64
|
||||
Size uint64
|
||||
|
||||
Reporter []byte
|
||||
}
|
||||
|
||||
// Estimations is a structure of grouped container load estimation inside Container contract.
|
||||
type Estimations struct {
|
||||
ContainerID []byte
|
||||
ContainerID *cid.ID
|
||||
|
||||
Estimations []Estimation
|
||||
Values []Estimation
|
||||
}
|
||||
|
||||
// GetSizeValues groups the stack items
|
||||
// returned by "get container size" test invoke.
|
||||
type GetSizeValues struct {
|
||||
est Estimations
|
||||
}
|
||||
// GetUsedSpaceEstimations returns a list of container load estimations by ID.
|
||||
// The list is composed through Container contract call.
|
||||
func (c *Client) GetUsedSpaceEstimations(id EstimationID) (*Estimations, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(getSizeMethod)
|
||||
prm.SetArgs([]byte(id))
|
||||
|
||||
// Estimations returns list of the container load estimations.
|
||||
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)
|
||||
prms, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w", getSizeMethod, err)
|
||||
} 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)
|
||||
}
|
||||
|
||||
es := Estimations{}
|
||||
|
||||
es.ContainerID, err = client.BytesFromStackItem(prms[0])
|
||||
rawCID, err := client.BytesFromStackItem(prms[0])
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
e := Estimation{}
|
||||
|
||||
e.Reporter, err = client.BytesFromStackItem(arr[0])
|
||||
reporter, err := client.BytesFromStackItem(arr[0])
|
||||
if err != nil {
|
||||
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 {
|
||||
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{
|
||||
est: es,
|
||||
}, nil
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
@ -1,82 +1,128 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
|
||||
"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
|
||||
// of put container invocation call.
|
||||
type PutArgs struct {
|
||||
cnr []byte // container in a binary format
|
||||
// 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(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
|
||||
}
|
||||
|
||||
// SetPublicKey sets the public key of container owner
|
||||
// in a binary format.
|
||||
func (p *PutArgs) SetPublicKey(v []byte) {
|
||||
p.publicKey = v
|
||||
// SetContainer sets container data.
|
||||
func (p *PutPrm) SetContainer(cnr []byte) {
|
||||
p.cnr = cnr
|
||||
}
|
||||
|
||||
// SetContainer sets the container structure
|
||||
// in a binary format.
|
||||
func (p *PutArgs) SetContainer(v []byte) {
|
||||
p.cnr = v
|
||||
// SetKey sets public key.
|
||||
func (p *PutPrm) SetKey(key []byte) {
|
||||
p.key = key
|
||||
}
|
||||
|
||||
// SetSignature sets the container structure
|
||||
// owner's signature.
|
||||
func (p *PutArgs) SetSignature(v []byte) {
|
||||
p.sig = v
|
||||
// SetSignature sets signature.
|
||||
func (p *PutPrm) SetSignature(sig []byte) {
|
||||
p.sig = sig
|
||||
}
|
||||
|
||||
// SetSessionToken sets token of the session
|
||||
// within which the container was created
|
||||
// in a binary format.
|
||||
func (p *PutArgs) SetSessionToken(v []byte) {
|
||||
p.token = v
|
||||
// SetToken sets session token.
|
||||
func (p *PutPrm) SetToken(token []byte) {
|
||||
p.token = token
|
||||
}
|
||||
|
||||
// SetNativeNameWithZone sets container native name and its zone.
|
||||
func (p *PutArgs) SetNativeNameWithZone(name, zone string) {
|
||||
p.name, p.zone = name, zone
|
||||
// SetName sets native name.
|
||||
func (p *PutPrm) SetName(name string) {
|
||||
p.name = name
|
||||
}
|
||||
|
||||
// Put invokes the call of put (named if name is set) container method
|
||||
// of NeoFS Container contract.
|
||||
func (c *Client) Put(args PutArgs) error {
|
||||
// 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 (c *Client) Put(p PutPrm) error {
|
||||
if len(p.sig) == 0 || len(p.key) == 0 {
|
||||
return errNilArgument
|
||||
}
|
||||
|
||||
var (
|
||||
method string
|
||||
prm client.InvokePrm
|
||||
)
|
||||
|
||||
if args.name != "" {
|
||||
method = PutNamedMethod
|
||||
|
||||
prm.SetArgs(args.cnr, args.sig, args.publicKey, args.token, args.name, args.zone)
|
||||
if p.name != "" {
|
||||
method = putNamedMethod
|
||||
prm.SetArgs(p.cnr, p.sig, p.key, p.token, p.name, p.zone)
|
||||
} else {
|
||||
method = putMethod
|
||||
|
||||
prm.SetArgs(args.cnr, args.sig, args.publicKey, args.token)
|
||||
prm.SetArgs(p.cnr, p.sig, p.key, p.token)
|
||||
}
|
||||
|
||||
prm.SetMethod(method)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
err := c.client.Invoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", method, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue