forked from TrueCloudLab/frostfs-node
[#625] client/netmap: remove intermediate wrapper
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
8c5c3ac9e8
commit
97d18bc515
36 changed files with 511 additions and 1011 deletions
|
@ -4,29 +4,37 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// AddPeerArgs groups the arguments
|
||||
// of add peer invocation call.
|
||||
type AddPeerArgs struct {
|
||||
info []byte
|
||||
// AddPeerPrm groups parameters of AddPeer operation.
|
||||
type AddPeerPrm struct {
|
||||
nodeInfo *netmap.NodeInfo
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetInfo sets the peer information.
|
||||
func (a *AddPeerArgs) SetInfo(v []byte) {
|
||||
a.info = v
|
||||
// SetNodeInfo sets new peer NodeInfo.
|
||||
func (a *AddPeerPrm) SetNodeInfo(nodeInfo *netmap.NodeInfo) {
|
||||
a.nodeInfo = nodeInfo
|
||||
}
|
||||
|
||||
// AddPeer invokes the call of add peer method
|
||||
// of NeoFS Netmap contract.
|
||||
func (c *Client) AddPeer(args AddPeerArgs) error {
|
||||
prm := client.InvokePrm{}
|
||||
// AddPeer registers peer in NeoFS network through
|
||||
// Netmap contract call.
|
||||
func (c *Client) AddPeer(p AddPeerPrm) error {
|
||||
if p.nodeInfo == nil {
|
||||
return fmt.Errorf("nil node info (%s)", addPeerMethod)
|
||||
}
|
||||
|
||||
rawNodeInfo, err := p.nodeInfo.Marshal()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't marshal node info (%s): %w", addPeerMethod, err)
|
||||
}
|
||||
|
||||
prm := client.InvokePrm{}
|
||||
prm.SetMethod(addPeerMethod)
|
||||
prm.SetArgs(args.info)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(rawNodeInfo)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
if err := c.client.Invoke(prm); err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", addPeerMethod, err)
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package netmap
|
||||
|
||||
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-sdk-go/netmap"
|
||||
)
|
||||
|
@ -38,9 +42,54 @@ const (
|
|||
configListMethod = "listConfig"
|
||||
)
|
||||
|
||||
// New creates, initializes and returns the Client instance.
|
||||
func New(c *client.StaticClient) *Client {
|
||||
return &Client{client: c}
|
||||
// NewFromMorph returns the wrapper instance from the raw morph client.
|
||||
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...Option) (*Client, error) {
|
||||
o := defaultOpts()
|
||||
|
||||
for i := range opts {
|
||||
opts[i](o)
|
||||
}
|
||||
|
||||
sc, err := client.NewStatic(cli, contract, fee, ([]client.StaticClientOption)(*o)...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't create netmap static client: %w", err)
|
||||
}
|
||||
|
||||
return &Client{client: sc}, nil
|
||||
}
|
||||
|
||||
// Option allows to set an optional
|
||||
// parameter of Wrapper.
|
||||
type Option func(*opts)
|
||||
|
||||
type opts []client.StaticClientOption
|
||||
|
||||
func defaultOpts() *opts {
|
||||
return new(opts)
|
||||
}
|
||||
|
||||
// TryNotary returns option to enable
|
||||
// notary invocation tries.
|
||||
func TryNotary() Option {
|
||||
return func(o *opts) {
|
||||
*o = append(*o, 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 = append(*o, client.AsAlphabet())
|
||||
}
|
||||
}
|
||||
|
||||
// ContractAddress returns the address of the associated contract.
|
||||
func (c Client) ContractAddress() util.Uint160 {
|
||||
return c.client.ContractAddress()
|
||||
}
|
||||
|
||||
// Morph returns raw morph client.
|
||||
|
|
|
@ -2,60 +2,153 @@ package netmap
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// ConfigArgs groups the arguments
|
||||
// of get config value test invoke call.
|
||||
type ConfigArgs struct {
|
||||
key []byte
|
||||
}
|
||||
const (
|
||||
maxObjectSizeConfig = "MaxObjectSize"
|
||||
basicIncomeRateConfig = "BasicIncomeRate"
|
||||
auditFeeConfig = "AuditFee"
|
||||
epochDurationConfig = "EpochDuration"
|
||||
containerFeeConfig = "ContainerFee"
|
||||
containerAliasFeeConfig = "ContainerAliasFee"
|
||||
etIterationsConfig = "EigenTrustIterations"
|
||||
etAlphaConfig = "EigenTrustAlpha"
|
||||
irCandidateFeeConfig = "InnerRingCandidateFee"
|
||||
withdrawFeeConfig = "WithdrawFee"
|
||||
)
|
||||
|
||||
// SetKey sets binary key to configuration parameter.
|
||||
func (c *ConfigArgs) SetKey(v []byte) {
|
||||
c.key = v
|
||||
}
|
||||
|
||||
// ConfigValues groups the stack parameters
|
||||
// returned by get config test invoke.
|
||||
type ConfigValues struct {
|
||||
val interface{}
|
||||
}
|
||||
|
||||
// Value returns configuration value.
|
||||
func (c ConfigValues) Value() interface{} {
|
||||
return c.val
|
||||
}
|
||||
|
||||
// Config performs the test invoke of get config value
|
||||
// method of NeoFS Netmap contract.
|
||||
func (c *Client) Config(args ConfigArgs, assert func(stackitem.Item) (interface{}, error)) (*ConfigValues, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
|
||||
prm.SetMethod(configMethod)
|
||||
prm.SetArgs(args.key)
|
||||
|
||||
items, err := c.client.TestInvoke(prm)
|
||||
// MaxObjectSize receives max object size configuration
|
||||
// value through the Netmap contract call.
|
||||
func (c *Client) MaxObjectSize() (uint64, error) {
|
||||
objectSize, err := c.readUInt64Config(maxObjectSizeConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
configMethod, err)
|
||||
return 0, fmt.Errorf("(%T) could not get epoch number: %w", c, err)
|
||||
}
|
||||
|
||||
if ln := len(items); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
configMethod, ln)
|
||||
}
|
||||
return objectSize, nil
|
||||
}
|
||||
|
||||
val, err := assert(items[0])
|
||||
// BasicIncomeRate returns basic income rate configuration value from network
|
||||
// config in netmap contract.
|
||||
func (c *Client) BasicIncomeRate() (uint64, error) {
|
||||
rate, err := c.readUInt64Config(basicIncomeRateConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("value type assertion failed: %w", err)
|
||||
return 0, fmt.Errorf("(%T) could not get basic income rate: %w", c, err)
|
||||
}
|
||||
|
||||
return &ConfigValues{
|
||||
val: val,
|
||||
}, nil
|
||||
return rate, nil
|
||||
}
|
||||
|
||||
// AuditFee returns audit fee configuration value from network
|
||||
// config in netmap contract.
|
||||
func (c *Client) AuditFee() (uint64, error) {
|
||||
fee, err := c.readUInt64Config(auditFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get audit fee: %w", c, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// EpochDuration returns number of sidechain blocks per one NeoFS epoch.
|
||||
func (c *Client) EpochDuration() (uint64, error) {
|
||||
epochDuration, err := c.readUInt64Config(epochDurationConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get epoch duration: %w", c, err)
|
||||
}
|
||||
|
||||
return epochDuration, nil
|
||||
}
|
||||
|
||||
// ContainerFee returns fee paid by container owner to each alphabet node
|
||||
// for container registration.
|
||||
func (c *Client) ContainerFee() (uint64, error) {
|
||||
fee, err := c.readUInt64Config(containerFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get container fee: %w", c, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// ContainerAliasFee returns additional fee paid by container owner to each
|
||||
// alphabet node for container nice name registration.
|
||||
func (c *Client) ContainerAliasFee() (uint64, error) {
|
||||
fee, err := c.readUInt64Config(containerAliasFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get container alias fee: %w", c, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// EigenTrustIterations returns global configuration value of iteration cycles
|
||||
// for EigenTrust algorithm per epoch.
|
||||
func (c *Client) EigenTrustIterations() (uint64, error) {
|
||||
iterations, err := c.readUInt64Config(etIterationsConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get eigen trust iterations: %w", c, err)
|
||||
}
|
||||
|
||||
return iterations, nil
|
||||
}
|
||||
|
||||
// EigenTrustAlpha returns global configuration value of alpha parameter.
|
||||
// It receives the alpha as a string and tries to convert it to float.
|
||||
func (c *Client) EigenTrustAlpha() (float64, error) {
|
||||
strAlpha, err := c.readStringConfig(etAlphaConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get eigen trust alpha: %w", c, err)
|
||||
}
|
||||
|
||||
return strconv.ParseFloat(strAlpha, 64)
|
||||
}
|
||||
|
||||
// InnerRingCandidateFee returns global configuration value of fee paid by
|
||||
// node to be in inner ring candidates list.
|
||||
func (c *Client) InnerRingCandidateFee() (uint64, error) {
|
||||
fee, err := c.readUInt64Config(irCandidateFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get inner ring candidate fee: %w", c, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// WithdrawFee returns global configuration value of fee paid by user to
|
||||
// withdraw assets from NeoFS contract.
|
||||
func (c *Client) WithdrawFee() (uint64, error) {
|
||||
fee, err := c.readUInt64Config(withdrawFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get withdraw fee: %w", c, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
func (c *Client) readUInt64Config(key string) (uint64, error) {
|
||||
v, err := c.config([]byte(key), IntegerAssert)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// IntegerAssert is guaranteed to return int64 if the error is nil.
|
||||
return uint64(v.(int64)), nil
|
||||
}
|
||||
|
||||
func (c *Client) readStringConfig(key string) (string, error) {
|
||||
v, err := c.config([]byte(key), StringAssert)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// StringAssert is guaranteed to return string if the error is nil.
|
||||
return v.(string), nil
|
||||
}
|
||||
|
||||
// SetConfigPrm groups parameters of SetConfig operation.
|
||||
|
@ -82,42 +175,134 @@ func (s *SetConfigPrm) SetValue(value interface{}) {
|
|||
s.value = value
|
||||
}
|
||||
|
||||
// SetConfig invokes `setConfig` method of NeoFS Netmap contract.
|
||||
func (c *Client) SetConfig(args SetConfigPrm) error {
|
||||
// SetConfig sets config field.
|
||||
func (c *Client) SetConfig(p SetConfigPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(setConfigMethod)
|
||||
prm.SetArgs(args.id, args.key, args.value)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(p.id, p.key, p.value)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
return c.client.Invoke(prm)
|
||||
}
|
||||
|
||||
// IterateConfigParameters iterates over configuration parameters stored in Netmap contract and passes them to f.
|
||||
//
|
||||
// Returns f's errors directly.
|
||||
func (c *Client) IterateConfigParameters(f func(key, value []byte) error) error {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(configListMethod)
|
||||
|
||||
items, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
configListMethod, err)
|
||||
}
|
||||
|
||||
if ln := len(items); ln != 1 {
|
||||
return fmt.Errorf("unexpected stack item count (%s): %d", configListMethod, ln)
|
||||
}
|
||||
|
||||
arr, err := client.ArrayFromStackItem(items[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("record list (%s): %w", configListMethod, err)
|
||||
}
|
||||
|
||||
return iterateRecords(arr, func(key, value []byte) error {
|
||||
return f(key, value)
|
||||
})
|
||||
}
|
||||
|
||||
// ConfigWriter is an interface of NeoFS network config writer.
|
||||
type ConfigWriter interface {
|
||||
UnknownParameter(string, []byte)
|
||||
MaxObjectSize(uint64)
|
||||
BasicIncomeRate(uint64)
|
||||
AuditFee(uint64)
|
||||
EpochDuration(uint64)
|
||||
ContainerFee(uint64)
|
||||
ContainerAliasFee(uint64)
|
||||
EigenTrustIterations(uint64)
|
||||
EigenTrustAlpha(float64)
|
||||
InnerRingCandidateFee(uint64)
|
||||
WithdrawFee(uint64)
|
||||
}
|
||||
|
||||
// WriteConfig writes NeoFS network configuration received via iterator.
|
||||
//
|
||||
// Returns iterator's errors directly.
|
||||
func WriteConfig(dst ConfigWriter, iterator func(func(key, val []byte) error) error) error {
|
||||
return iterator(func(key, val []byte) error {
|
||||
switch k := string(key); k {
|
||||
default:
|
||||
dst.UnknownParameter(k, val)
|
||||
case maxObjectSizeConfig:
|
||||
dst.MaxObjectSize(bigint.FromBytes(val).Uint64())
|
||||
case basicIncomeRateConfig:
|
||||
dst.BasicIncomeRate(bigint.FromBytes(val).Uint64())
|
||||
case auditFeeConfig:
|
||||
dst.AuditFee(bigint.FromBytes(val).Uint64())
|
||||
case epochDurationConfig:
|
||||
dst.EpochDuration(bigint.FromBytes(val).Uint64())
|
||||
case containerFeeConfig:
|
||||
dst.ContainerFee(bigint.FromBytes(val).Uint64())
|
||||
case containerAliasFeeConfig:
|
||||
dst.ContainerAliasFee(bigint.FromBytes(val).Uint64())
|
||||
case etIterationsConfig:
|
||||
dst.EigenTrustIterations(bigint.FromBytes(val).Uint64())
|
||||
case etAlphaConfig:
|
||||
v, err := strconv.ParseFloat(string(val), 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("prm %s: %v", etAlphaConfig, err)
|
||||
}
|
||||
|
||||
dst.EigenTrustAlpha(v)
|
||||
case irCandidateFeeConfig:
|
||||
dst.InnerRingCandidateFee(bigint.FromBytes(val).Uint64())
|
||||
case withdrawFeeConfig:
|
||||
dst.WithdrawFee(bigint.FromBytes(val).Uint64())
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// config performs the test invoke of get config value
|
||||
// method of NeoFS Netmap contract.
|
||||
func (c *Client) config(key []byte, assert func(stackitem.Item) (interface{}, error)) (interface{}, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(configMethod)
|
||||
prm.SetArgs(key)
|
||||
|
||||
items, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
configMethod, err)
|
||||
}
|
||||
|
||||
if ln := len(items); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
configMethod, ln)
|
||||
}
|
||||
|
||||
return assert(items[0])
|
||||
}
|
||||
|
||||
// IntegerAssert converts stack item to int64.
|
||||
func IntegerAssert(item stackitem.Item) (interface{}, error) {
|
||||
return client.IntFromStackItem(item)
|
||||
}
|
||||
|
||||
// StringAssert converts stack item to string.
|
||||
func StringAssert(item stackitem.Item) (interface{}, error) {
|
||||
return client.StringFromStackItem(item)
|
||||
}
|
||||
|
||||
// ListConfigArgs groups the arguments
|
||||
// of config listing test invoke call.
|
||||
type ListConfigArgs struct {
|
||||
}
|
||||
|
||||
// ListConfigValues groups the stack parameters
|
||||
// returned by config listing test invoke.
|
||||
type ListConfigValues struct {
|
||||
rs []stackitem.Item
|
||||
}
|
||||
|
||||
// IterateRecords iterates over all config records and passes them to f.
|
||||
// iterateRecords iterates over all config records and passes them to f.
|
||||
//
|
||||
// Returns f's errors directly.
|
||||
func (x ListConfigValues) IterateRecords(f func(key, value []byte) error) error {
|
||||
for i := range x.rs {
|
||||
fields, err := client.ArrayFromStackItem(x.rs[i])
|
||||
func iterateRecords(arr []stackitem.Item, f func(key, value []byte) error) error {
|
||||
for i := range arr {
|
||||
fields, err := client.ArrayFromStackItem(arr[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("record fields: %w", err)
|
||||
}
|
||||
|
@ -143,31 +328,3 @@ func (x ListConfigValues) IterateRecords(f func(key, value []byte) error) error
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListConfig performs the test invoke of config listing method of NeoFS Netmap contract.
|
||||
func (c *Client) ListConfig(_ ListConfigArgs) (*ListConfigValues, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
|
||||
prm.SetMethod(configListMethod)
|
||||
|
||||
items, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
configListMethod, err)
|
||||
}
|
||||
|
||||
if ln := len(items); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
configListMethod, ln)
|
||||
}
|
||||
|
||||
arr, err := client.ArrayFromStackItem(items[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("record list (%s): %w",
|
||||
configListMethod, err)
|
||||
}
|
||||
|
||||
return &ListConfigValues{
|
||||
rs: arr,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -6,87 +6,51 @@ import (
|
|||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// EpochArgs groups the arguments
|
||||
// of get epoch number test invoke call.
|
||||
type EpochArgs struct{}
|
||||
|
||||
// EpochValues groups the stack parameters
|
||||
// returned by get epoch number test invoke.
|
||||
type EpochValues struct {
|
||||
num int64
|
||||
}
|
||||
|
||||
// Number return the number of NeoFS epoch.
|
||||
func (e EpochValues) Number() int64 {
|
||||
return e.num
|
||||
}
|
||||
|
||||
// Epoch performs the test invoke of get epoch number
|
||||
// method of NeoFS Netmap contract.
|
||||
func (c *Client) Epoch(_ EpochArgs) (*EpochValues, error) {
|
||||
// Epoch receives number of current NeoFS epoch
|
||||
// through the Netmap contract call.
|
||||
func (c *Client) Epoch() (uint64, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(epochMethod)
|
||||
|
||||
items, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
return 0, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
epochMethod, err)
|
||||
}
|
||||
|
||||
if ln := len(items); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
return 0, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
epochMethod, ln)
|
||||
}
|
||||
|
||||
num, err := client.IntFromStackItem(items[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get number from stack item (%s): %w", epochMethod, err)
|
||||
return 0, fmt.Errorf("could not get number from stack item (%s): %w", epochMethod, err)
|
||||
}
|
||||
|
||||
return &EpochValues{
|
||||
num: num,
|
||||
}, nil
|
||||
return uint64(num), nil
|
||||
}
|
||||
|
||||
// EpochBlockArgs groups the arguments of
|
||||
// get epoch block number test invoke call.
|
||||
type EpochBlockArgs struct{}
|
||||
|
||||
// EpochBlockValues groups the stack parameters
|
||||
// returned by get epoch block number test invoke.
|
||||
type EpochBlockValues struct {
|
||||
block int64
|
||||
}
|
||||
|
||||
// Block return the block number of NeoFS epoch.
|
||||
func (e EpochBlockValues) Block() int64 {
|
||||
return e.block
|
||||
}
|
||||
|
||||
// LastEpochBlock performs the test invoke of get epoch block number
|
||||
// method of NeoFS Netmap contract.
|
||||
func (c *Client) LastEpochBlock(_ EpochBlockArgs) (*EpochBlockValues, error) {
|
||||
// LastEpochBlock receives block number of current NeoFS epoch
|
||||
// through the Netmap contract call.
|
||||
func (c *Client) LastEpochBlock() (uint32, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(lastEpochBlockMethod)
|
||||
|
||||
items, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
return 0, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
lastEpochBlockMethod, err)
|
||||
}
|
||||
|
||||
if ln := len(items); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
return 0, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
lastEpochBlockMethod, ln)
|
||||
}
|
||||
|
||||
block, err := client.IntFromStackItem(items[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get number from stack item (%s): %w",
|
||||
return 0, fmt.Errorf("could not get number from stack item (%s): %w",
|
||||
lastEpochBlockMethod, err)
|
||||
}
|
||||
|
||||
return &EpochBlockValues{
|
||||
block: block,
|
||||
}, nil
|
||||
return uint32(block), nil
|
||||
}
|
||||
|
|
|
@ -22,16 +22,14 @@ func (u *UpdateIRPrm) SetKeys(keys keys.PublicKeys) {
|
|||
u.keys = keys
|
||||
}
|
||||
|
||||
// UpdateInnerRing updates inner ring members in netmap contract.
|
||||
// UpdateInnerRing updates inner ring keys.
|
||||
func (c *Client) UpdateInnerRing(p UpdateIRPrm) error {
|
||||
args := make([][]byte, len(p.keys))
|
||||
|
||||
for i := range args {
|
||||
args[i] = p.keys[i].Bytes()
|
||||
}
|
||||
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(updateInnerRingMethod)
|
||||
prm.SetArgs(args)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
@ -39,9 +37,8 @@ func (c *Client) UpdateInnerRing(p UpdateIRPrm) error {
|
|||
return c.client.Invoke(prm)
|
||||
}
|
||||
|
||||
// InnerRingList returns public keys of inner ring members in
|
||||
// netmap contract.
|
||||
func (c *Client) InnerRingList() (keys.PublicKeys, error) {
|
||||
// GetInnerRingList return current IR list.
|
||||
func (c *Client) GetInnerRingList() (keys.PublicKeys, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
invokePrm.SetMethod(innerRingListMethod)
|
||||
|
||||
|
|
|
@ -5,14 +5,9 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// GetNetMapValues groups the stack parameters
|
||||
// returned by get network map test invoke.
|
||||
type GetNetMapValues struct {
|
||||
peers [][]byte
|
||||
}
|
||||
|
||||
// State is an enumeration of various states of the NeoFS node.
|
||||
type State int64
|
||||
|
||||
|
@ -48,117 +43,27 @@ const (
|
|||
peerWithStateFixedPrmNumber = 2
|
||||
)
|
||||
|
||||
// Peers return the list of peers from
|
||||
// network map in a binary format.
|
||||
func (g GetNetMapValues) Peers() [][]byte {
|
||||
return g.peers
|
||||
}
|
||||
|
||||
// GetNetMapArgs groups the arguments
|
||||
// of get network map test invoke call.
|
||||
type GetNetMapArgs struct{}
|
||||
|
||||
// NetMap performs the test invoke of get network map
|
||||
// method of NeoFS Netmap contract.
|
||||
func (c *Client) NetMap(_ GetNetMapArgs) (*GetNetMapValues, error) {
|
||||
// GetNetMapByEpoch receives information list about storage nodes
|
||||
// through the Netmap contract call, composes network map
|
||||
// from them and returns it. Returns snapshot of the specified epoch number.
|
||||
func (c *Client) GetNetMapByEpoch(epoch uint64) (*netmap.Netmap, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
invokePrm.SetMethod(netMapMethod)
|
||||
|
||||
prms, err := c.client.TestInvoke(invokePrm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
netMapMethod, err)
|
||||
}
|
||||
|
||||
return peersFromStackItems(prms, netMapMethod)
|
||||
}
|
||||
|
||||
// GetSnapshotArgs groups the arguments
|
||||
// of get netmap snapshot test invoke call.
|
||||
type GetSnapshotArgs struct {
|
||||
diff uint64
|
||||
}
|
||||
|
||||
// SetDiff sets argument for snapshot method of
|
||||
// netmap contract.
|
||||
func (g *GetSnapshotArgs) SetDiff(d uint64) {
|
||||
g.diff = d
|
||||
}
|
||||
|
||||
// Snapshot performs the test invoke of get snapshot of network map
|
||||
// from NeoFS Netmap contract. Contract saves only one previous epoch,
|
||||
// so all invokes with diff > 1 return error.
|
||||
func (c *Client) Snapshot(a GetSnapshotArgs) (*GetNetMapValues, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
|
||||
invokePrm.SetMethod(snapshotMethod)
|
||||
invokePrm.SetArgs(int64(a.diff))
|
||||
|
||||
prms, err := c.client.TestInvoke(invokePrm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
netMapMethod, err)
|
||||
}
|
||||
|
||||
return peersFromStackItems(prms, snapshotMethod)
|
||||
}
|
||||
|
||||
// EpochSnapshotArgs groups the arguments
|
||||
// of snapshot by epoch test invoke call.
|
||||
type EpochSnapshotArgs struct {
|
||||
epoch uint64
|
||||
}
|
||||
|
||||
// SetEpoch sets epoch number to get snapshot.
|
||||
func (a *EpochSnapshotArgs) SetEpoch(d uint64) {
|
||||
a.epoch = d
|
||||
}
|
||||
|
||||
// EpochSnapshotValues groups the stack parameters
|
||||
// returned by snapshot by epoch test invoke.
|
||||
type EpochSnapshotValues struct {
|
||||
*GetNetMapValues
|
||||
}
|
||||
|
||||
// EpochSnapshot performs the test invoke of get snapshot of network map by epoch
|
||||
// from NeoFS Netmap contract.
|
||||
func (c *Client) EpochSnapshot(args EpochSnapshotArgs) (*EpochSnapshotValues, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
|
||||
invokePrm.SetMethod(epochSnapshotMethod)
|
||||
invokePrm.SetArgs(int64(args.epoch))
|
||||
invokePrm.SetArgs(int64(epoch))
|
||||
|
||||
prms, err := c.client.TestInvoke(invokePrm)
|
||||
res, err := c.client.TestInvoke(invokePrm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
epochSnapshotMethod, err)
|
||||
}
|
||||
|
||||
nmVals, err := peersFromStackItems(prms, epochSnapshotMethod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &EpochSnapshotValues{
|
||||
GetNetMapValues: nmVals,
|
||||
}, nil
|
||||
return unmarshalNetmap(res, epochSnapshotMethod)
|
||||
}
|
||||
|
||||
// GetNetMapCandidatesArgs groups the arguments
|
||||
// of get network map candidates test invoke call.
|
||||
type GetNetMapCandidatesArgs struct{}
|
||||
|
||||
// GetNetMapCandidatesValues groups the stack parameters
|
||||
// returned by get network map candidates test invoke.
|
||||
type GetNetMapCandidatesValues struct {
|
||||
netmapNodes []*PeerWithState
|
||||
}
|
||||
|
||||
func (g GetNetMapCandidatesValues) NetmapNodes() []*PeerWithState {
|
||||
return g.netmapNodes
|
||||
}
|
||||
|
||||
func (c *Client) Candidates(_ GetNetMapCandidatesArgs) (*GetNetMapCandidatesValues, error) {
|
||||
// GetCandidates receives information list about candidates
|
||||
// for the next epoch network map through the Netmap contract
|
||||
// call, composes network map from them and returns it.
|
||||
func (c *Client) GetCandidates() (*netmap.Netmap, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
invokePrm.SetMethod(netMapCandidatesMethod)
|
||||
|
||||
|
@ -172,10 +77,49 @@ func (c *Client) Candidates(_ GetNetMapCandidatesArgs) (*GetNetMapCandidatesValu
|
|||
return nil, fmt.Errorf("could not parse contract response: %w", err)
|
||||
}
|
||||
|
||||
return candVals, nil
|
||||
return unmarshalCandidates(candVals)
|
||||
}
|
||||
|
||||
func peersWithStateFromStackItems(stack []stackitem.Item, method string) (*GetNetMapCandidatesValues, error) {
|
||||
// NetMap performs the test invoke of get network map
|
||||
// method of NeoFS Netmap contract.
|
||||
func (c *Client) NetMap() ([][]byte, error) {
|
||||
invokePrm := client.TestInvokePrm{}
|
||||
invokePrm.SetMethod(netMapMethod)
|
||||
|
||||
prms, err := c.client.TestInvoke(invokePrm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||
netMapMethod, err)
|
||||
}
|
||||
|
||||
return peersFromStackItems(prms, netMapMethod)
|
||||
}
|
||||
|
||||
func unmarshalCandidates(rawCandidate []*PeerWithState) (*netmap.Netmap, error) {
|
||||
candidates := make([]netmap.NodeInfo, 0, len(rawCandidate))
|
||||
|
||||
for _, candidate := range rawCandidate {
|
||||
nodeInfo := netmap.NewNodeInfo()
|
||||
if err := nodeInfo.Unmarshal(candidate.Peer()); err != nil {
|
||||
return nil, fmt.Errorf("can't unmarshal peer info: %w", err)
|
||||
}
|
||||
|
||||
switch candidate.State() {
|
||||
case Online:
|
||||
nodeInfo.SetState(netmap.NodeStateOnline)
|
||||
case Offline:
|
||||
nodeInfo.SetState(netmap.NodeStateOffline)
|
||||
default:
|
||||
nodeInfo.SetState(0)
|
||||
}
|
||||
|
||||
candidates = append(candidates, *nodeInfo)
|
||||
}
|
||||
|
||||
return netmap.NewNetmap(netmap.NodesFromInfo(candidates))
|
||||
}
|
||||
|
||||
func peersWithStateFromStackItems(stack []stackitem.Item, method string) ([]*PeerWithState, error) {
|
||||
if ln := len(stack); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d", method, ln)
|
||||
}
|
||||
|
@ -185,17 +129,14 @@ func peersWithStateFromStackItems(stack []stackitem.Item, method string) (*GetNe
|
|||
return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", method, err)
|
||||
}
|
||||
|
||||
res := &GetNetMapCandidatesValues{
|
||||
netmapNodes: make([]*PeerWithState, 0, len(netmapNodes)),
|
||||
}
|
||||
|
||||
res := make([]*PeerWithState, 0, len(netmapNodes))
|
||||
for i := range netmapNodes {
|
||||
node, err := peerWithStateFromStackItem(netmapNodes[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse stack item (Peer #%d): %w", i, err)
|
||||
}
|
||||
|
||||
res.netmapNodes = append(res.netmapNodes, node)
|
||||
res = append(res, node)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
@ -238,7 +179,7 @@ func peerWithStateFromStackItem(prm stackitem.Item) (*PeerWithState, error) {
|
|||
return &res, nil
|
||||
}
|
||||
|
||||
func peersFromStackItems(stack []stackitem.Item, method string) (*GetNetMapValues, error) {
|
||||
func peersFromStackItems(stack []stackitem.Item, method string) ([][]byte, error) {
|
||||
if ln := len(stack); ln != 1 {
|
||||
return nil, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||
method, ln)
|
||||
|
@ -250,9 +191,7 @@ func peersFromStackItems(stack []stackitem.Item, method string) (*GetNetMapValue
|
|||
method, err)
|
||||
}
|
||||
|
||||
res := &GetNetMapValues{
|
||||
peers: make([][]byte, 0, len(peers)),
|
||||
}
|
||||
res := make([][]byte, 0, len(peers))
|
||||
|
||||
for i := range peers {
|
||||
peer, err := peerInfoFromStackItem(peers[i])
|
||||
|
@ -260,7 +199,7 @@ func peersFromStackItems(stack []stackitem.Item, method string) (*GetNetMapValue
|
|||
return nil, fmt.Errorf("could not parse stack item (Peer #%d): %w", i, err)
|
||||
}
|
||||
|
||||
res.peers = append(res.peers, peer)
|
||||
res = append(res, peer)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
|
|
@ -6,27 +6,12 @@ import (
|
|||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// NewEpochArgs groups the arguments
|
||||
// of new epoch invocation call.
|
||||
type NewEpochArgs struct {
|
||||
number int64 // new epoch number
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetEpochNumber sets the new epoch number.
|
||||
func (a *NewEpochArgs) SetEpochNumber(v int64) {
|
||||
a.number = v
|
||||
}
|
||||
|
||||
// NewEpoch invokes the call of new epoch method
|
||||
// of NeoFS Netmap contract.
|
||||
func (c *Client) NewEpoch(args NewEpochArgs) error {
|
||||
// NewEpoch updates NeoFS epoch number through
|
||||
// Netmap contract call.
|
||||
func (c *Client) NewEpoch(epoch uint64) error {
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(newEpochMethod)
|
||||
prm.SetArgs(args.number)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(int64(epoch))
|
||||
|
||||
if err := c.client.Invoke(prm); err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", newEpochMethod, err)
|
||||
|
|
52
pkg/morph/client/netmap/snapshot.go
Normal file
52
pkg/morph/client/netmap/snapshot.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
package netmap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// GetNetMap receives information list about storage nodes
|
||||
// through the Netmap contract call, composes network map
|
||||
// from them and returns it. With diff == 0 returns current
|
||||
// network map, else return snapshot of previous network map.
|
||||
func (c *Client) GetNetMap(diff uint64) (*netmap.Netmap, error) {
|
||||
return c.getNetMap(diff)
|
||||
}
|
||||
|
||||
// Snapshot returns current netmap node infos.
|
||||
// Consider using pkg/morph/client/netmap for this.
|
||||
func (c *Client) Snapshot() (*netmap.Netmap, error) {
|
||||
return c.getNetMap(0)
|
||||
}
|
||||
|
||||
func (c *Client) getNetMap(diff uint64) (*netmap.Netmap, error) {
|
||||
prm := client.TestInvokePrm{}
|
||||
prm.SetMethod(snapshotMethod)
|
||||
prm.SetArgs(int64(diff))
|
||||
|
||||
res, err := c.client.TestInvoke(prm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return unmarshalNetmap(res, snapshotMethod)
|
||||
}
|
||||
|
||||
func unmarshalNetmap(items []stackitem.Item, method string) (*netmap.Netmap, error) {
|
||||
rawPeers, err := peersFromStackItems(items, method)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]netmap.NodeInfo, len(rawPeers))
|
||||
for i := range rawPeers {
|
||||
if err := result[i].Unmarshal(rawPeers[i]); err != nil {
|
||||
return nil, fmt.Errorf("can't unmarshal node info (%s): %w", method, err)
|
||||
}
|
||||
}
|
||||
|
||||
return netmap.NewNetmap(netmap.NodesFromInfo(result))
|
||||
}
|
|
@ -4,42 +4,36 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// UpdateStateArgs groups the arguments
|
||||
// of update state invocation call.
|
||||
type UpdateStateArgs struct {
|
||||
key []byte // peer public key
|
||||
|
||||
state int64 // new peer state
|
||||
// UpdatePeerPrm groups parameters of UpdatePeerState operation.
|
||||
type UpdatePeerPrm struct {
|
||||
key []byte
|
||||
state netmap.NodeState
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetPublicKey sets peer public key
|
||||
// in a binary format.
|
||||
func (u *UpdateStateArgs) SetPublicKey(v []byte) {
|
||||
u.key = v
|
||||
// SetKey sets public key.
|
||||
func (u *UpdatePeerPrm) SetKey(key []byte) {
|
||||
u.key = key
|
||||
}
|
||||
|
||||
// SetState sets the new peer state.
|
||||
func (u *UpdateStateArgs) SetState(v int64) {
|
||||
u.state = v
|
||||
// SetState sets node state.
|
||||
func (u *UpdatePeerPrm) SetState(state netmap.NodeState) {
|
||||
u.state = state
|
||||
}
|
||||
|
||||
// UpdateState invokes the call of update state method
|
||||
// of NeoFS Netmap contract.
|
||||
func (c *Client) UpdateState(args UpdateStateArgs) error {
|
||||
// UpdatePeerState changes peer status through Netmap contract call.
|
||||
func (c *Client) UpdatePeerState(p UpdatePeerPrm) error {
|
||||
prm := client.InvokePrm{}
|
||||
|
||||
prm.SetMethod(updateStateMethod)
|
||||
prm.SetArgs(args.state, args.key)
|
||||
prm.InvokePrmOptional = args.InvokePrmOptional
|
||||
prm.SetArgs(int64(p.state.ToV2()), p.key)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
err := c.client.Invoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", updateStateMethod, err)
|
||||
if err := c.client.Invoke(prm); err != nil {
|
||||
return fmt.Errorf("could not invoke smart contract: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
)
|
||||
|
||||
// AddPeerPrm groups parameters of AddPeer operation.
|
||||
type AddPeerPrm struct {
|
||||
nodeInfo *netmap.NodeInfo
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetNodeInfo sets new peer NodeInfo.
|
||||
func (a *AddPeerPrm) SetNodeInfo(nodeInfo *netmap.NodeInfo) {
|
||||
a.nodeInfo = nodeInfo
|
||||
}
|
||||
|
||||
// AddPeer registers peer in NeoFS network through
|
||||
// Netmap contract call.
|
||||
func (w *Wrapper) AddPeer(prm AddPeerPrm) error {
|
||||
if prm.nodeInfo == nil {
|
||||
return errors.New("nil node info")
|
||||
}
|
||||
|
||||
rawNodeInfo, err := prm.nodeInfo.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
args := netmap.AddPeerArgs{}
|
||||
args.SetInfo(rawNodeInfo)
|
||||
args.InvokePrmOptional = prm.InvokePrmOptional
|
||||
|
||||
if err := w.client.AddPeer(args); err != nil {
|
||||
return fmt.Errorf("could not invoke smart contract: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,276 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
)
|
||||
|
||||
const (
|
||||
maxObjectSizeConfig = "MaxObjectSize"
|
||||
basicIncomeRateConfig = "BasicIncomeRate"
|
||||
auditFeeConfig = "AuditFee"
|
||||
epochDurationConfig = "EpochDuration"
|
||||
containerFeeConfig = "ContainerFee"
|
||||
containerAliasFeeConfig = "ContainerAliasFee"
|
||||
etIterationsConfig = "EigenTrustIterations"
|
||||
etAlphaConfig = "EigenTrustAlpha"
|
||||
irCandidateFeeConfig = "InnerRingCandidateFee"
|
||||
withdrawFeeConfig = "WithdrawFee"
|
||||
)
|
||||
|
||||
// MaxObjectSize receives max object size configuration
|
||||
// value through the Netmap contract call.
|
||||
func (w *Wrapper) MaxObjectSize() (uint64, error) {
|
||||
objectSize, err := w.readUInt64Config(maxObjectSizeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get epoch number: %w", w, err)
|
||||
}
|
||||
|
||||
return objectSize, nil
|
||||
}
|
||||
|
||||
// BasicIncomeRate returns basic income rate configuration value from network
|
||||
// config in netmap contract.
|
||||
func (w *Wrapper) BasicIncomeRate() (uint64, error) {
|
||||
rate, err := w.readUInt64Config(basicIncomeRateConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get basic income rate: %w", w, err)
|
||||
}
|
||||
|
||||
return rate, nil
|
||||
}
|
||||
|
||||
// AuditFee returns audit fee configuration value from network
|
||||
// config in netmap contract.
|
||||
func (w *Wrapper) AuditFee() (uint64, error) {
|
||||
fee, err := w.readUInt64Config(auditFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get audit fee: %w", w, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// EpochDuration returns number of sidechain blocks per one NeoFS epoch.
|
||||
func (w *Wrapper) EpochDuration() (uint64, error) {
|
||||
epochDuration, err := w.readUInt64Config(epochDurationConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get epoch duration: %w", w, err)
|
||||
}
|
||||
|
||||
return epochDuration, nil
|
||||
}
|
||||
|
||||
// ContainerFee returns fee paid by container owner to each alphabet node
|
||||
// for container registration.
|
||||
func (w *Wrapper) ContainerFee() (uint64, error) {
|
||||
fee, err := w.readUInt64Config(containerFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get container fee: %w", w, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// ContainerAliasFee returns additional fee paid by container owner to each
|
||||
// alphabet node for container nice name registration.
|
||||
func (w *Wrapper) ContainerAliasFee() (uint64, error) {
|
||||
fee, err := w.readUInt64Config(containerAliasFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get container alias fee: %w", w, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// EigenTrustIterations returns global configuration value of iteration cycles
|
||||
// for EigenTrust algorithm per epoch.
|
||||
func (w *Wrapper) EigenTrustIterations() (uint64, error) {
|
||||
iterations, err := w.readUInt64Config(etIterationsConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get eigen trust iterations: %w", w, err)
|
||||
}
|
||||
|
||||
return iterations, nil
|
||||
}
|
||||
|
||||
// EigenTrustAlpha returns global configuration value of alpha parameter.
|
||||
// It receives the alpha as a string and tries to convert it to float.
|
||||
func (w *Wrapper) EigenTrustAlpha() (float64, error) {
|
||||
strAlpha, err := w.readStringConfig(etAlphaConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get eigen trust alpha: %w", w, err)
|
||||
}
|
||||
|
||||
return strconv.ParseFloat(strAlpha, 64)
|
||||
}
|
||||
|
||||
// InnerRingCandidateFee returns global configuration value of fee paid by
|
||||
// node to be in inner ring candidates list.
|
||||
func (w *Wrapper) InnerRingCandidateFee() (uint64, error) {
|
||||
fee, err := w.readUInt64Config(irCandidateFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get inner ring candidate fee: %w", w, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
// WithdrawFee returns global configuration value of fee paid by user to
|
||||
// withdraw assets from NeoFS contract.
|
||||
func (w *Wrapper) WithdrawFee() (uint64, error) {
|
||||
fee, err := w.readUInt64Config(withdrawFeeConfig)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get withdraw fee: %w", w, err)
|
||||
}
|
||||
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
func (w *Wrapper) readUInt64Config(key string) (uint64, error) {
|
||||
args := netmap.ConfigArgs{}
|
||||
args.SetKey([]byte(key))
|
||||
|
||||
vals, err := w.client.Config(args, netmap.IntegerAssert)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
v := vals.Value()
|
||||
|
||||
numeric, ok := v.(int64)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("(%T) invalid value type %T", w, v)
|
||||
}
|
||||
|
||||
return uint64(numeric), nil
|
||||
}
|
||||
|
||||
func (w *Wrapper) readStringConfig(key string) (string, error) {
|
||||
args := netmap.ConfigArgs{}
|
||||
args.SetKey([]byte(key))
|
||||
|
||||
vals, err := w.client.Config(args, netmap.StringAssert)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
v := vals.Value()
|
||||
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("(%T) invalid value type %T", w, v)
|
||||
}
|
||||
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// SetConfigPrm groups parameters of SetConfig operation.
|
||||
type SetConfigPrm struct {
|
||||
id []byte
|
||||
key []byte
|
||||
value interface{}
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetID sets ID of the config value.
|
||||
func (s *SetConfigPrm) SetID(id []byte) {
|
||||
s.id = id
|
||||
}
|
||||
|
||||
// SetKey sets key of the config value.
|
||||
func (s *SetConfigPrm) SetKey(key []byte) {
|
||||
s.key = key
|
||||
}
|
||||
|
||||
// SetValue sets value of the config value.
|
||||
func (s *SetConfigPrm) SetValue(value interface{}) {
|
||||
s.value = value
|
||||
}
|
||||
|
||||
// SetConfig sets config field.
|
||||
func (w *Wrapper) SetConfig(prm SetConfigPrm) error {
|
||||
args := netmap.SetConfigPrm{}
|
||||
|
||||
args.SetID(prm.id)
|
||||
args.SetKey(prm.key)
|
||||
args.SetValue(prm.value)
|
||||
args.InvokePrmOptional = prm.InvokePrmOptional
|
||||
|
||||
return w.client.SetConfig(args)
|
||||
}
|
||||
|
||||
// IterateConfigParameters iterates over configuration parameters stored in Netmap contract and passes them to f.
|
||||
//
|
||||
// Returns f's errors directly.
|
||||
func (w *Wrapper) IterateConfigParameters(f func(key, value []byte) error) error {
|
||||
var args netmap.ListConfigArgs
|
||||
|
||||
v, err := w.client.ListConfig(args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("client error: %w", err)
|
||||
}
|
||||
|
||||
return v.IterateRecords(func(key, value []byte) error {
|
||||
return f(key, value)
|
||||
})
|
||||
}
|
||||
|
||||
// ConfigWriter is an interface of NeoFS network config writer.
|
||||
type ConfigWriter interface {
|
||||
UnknownParameter(string, []byte)
|
||||
MaxObjectSize(uint64)
|
||||
BasicIncomeRate(uint64)
|
||||
AuditFee(uint64)
|
||||
EpochDuration(uint64)
|
||||
ContainerFee(uint64)
|
||||
ContainerAliasFee(uint64)
|
||||
EigenTrustIterations(uint64)
|
||||
EigenTrustAlpha(float64)
|
||||
InnerRingCandidateFee(uint64)
|
||||
WithdrawFee(uint64)
|
||||
}
|
||||
|
||||
// WriteConfig writes NeoFS network configuration received via iterator.
|
||||
//
|
||||
// Returns iterator's errors directly.
|
||||
func WriteConfig(dst ConfigWriter, iterator func(func(key, val []byte) error) error) error {
|
||||
return iterator(func(key, val []byte) error {
|
||||
switch k := string(key); k {
|
||||
default:
|
||||
dst.UnknownParameter(k, val)
|
||||
case maxObjectSizeConfig:
|
||||
dst.MaxObjectSize(bigint.FromBytes(val).Uint64())
|
||||
case basicIncomeRateConfig:
|
||||
dst.BasicIncomeRate(bigint.FromBytes(val).Uint64())
|
||||
case auditFeeConfig:
|
||||
dst.AuditFee(bigint.FromBytes(val).Uint64())
|
||||
case epochDurationConfig:
|
||||
dst.EpochDuration(bigint.FromBytes(val).Uint64())
|
||||
case containerFeeConfig:
|
||||
dst.ContainerFee(bigint.FromBytes(val).Uint64())
|
||||
case containerAliasFeeConfig:
|
||||
dst.ContainerAliasFee(bigint.FromBytes(val).Uint64())
|
||||
case etIterationsConfig:
|
||||
dst.EigenTrustIterations(bigint.FromBytes(val).Uint64())
|
||||
case etAlphaConfig:
|
||||
v, err := strconv.ParseFloat(string(val), 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("prm %s: %v", etAlphaConfig, err)
|
||||
}
|
||||
|
||||
dst.EigenTrustAlpha(v)
|
||||
case irCandidateFeeConfig:
|
||||
dst.InnerRingCandidateFee(bigint.FromBytes(val).Uint64())
|
||||
case withdrawFeeConfig:
|
||||
dst.WithdrawFee(bigint.FromBytes(val).Uint64())
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
)
|
||||
|
||||
// Epoch receives number of current NeoFS epoch
|
||||
// through the Netmap contract call.
|
||||
func (w *Wrapper) Epoch() (uint64, error) {
|
||||
args := netmap.EpochArgs{}
|
||||
|
||||
vals, err := w.client.Epoch(args)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get epoch number: %w", w, err)
|
||||
}
|
||||
|
||||
return uint64(vals.Number()), nil
|
||||
}
|
||||
|
||||
// LastEpochBlock receives block number of current NeoFS epoch
|
||||
// through the Netmap contract call.
|
||||
func (w *Wrapper) LastEpochBlock() (uint32, error) {
|
||||
args := netmap.EpochBlockArgs{}
|
||||
|
||||
vals, err := w.client.LastEpochBlock(args)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("(%T) could not get epoch block number: %w", w, err)
|
||||
}
|
||||
|
||||
return uint32(vals.Block()), nil
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
)
|
||||
|
||||
// UpdateIRPrm groups parameters of UpdateInnerRing
|
||||
// invocation.
|
||||
type UpdateIRPrm struct {
|
||||
keys keys.PublicKeys
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetKeys sets new inner ring keys.
|
||||
func (u *UpdateIRPrm) SetKeys(keys keys.PublicKeys) {
|
||||
u.keys = keys
|
||||
}
|
||||
|
||||
// UpdateInnerRing updates inner ring keys.
|
||||
func (w *Wrapper) UpdateInnerRing(prm UpdateIRPrm) error {
|
||||
args := netmap.UpdateIRPrm{}
|
||||
|
||||
args.SetKeys(prm.keys)
|
||||
args.InvokePrmOptional = prm.InvokePrmOptional
|
||||
|
||||
return w.client.UpdateInnerRing(args)
|
||||
}
|
||||
|
||||
// GetInnerRingList return current IR list.
|
||||
func (w *Wrapper) GetInnerRingList() (keys.PublicKeys, error) {
|
||||
return w.client.InnerRingList()
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
client "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// GetNetMap receives information list about storage nodes
|
||||
// through the Netmap contract call, composes network map
|
||||
// from them and returns it. With diff == 0 returns current
|
||||
// network map, else return snapshot of previous network map.
|
||||
func (w Wrapper) GetNetMap(diff uint64) (*netmap.Netmap, error) {
|
||||
args := client.GetSnapshotArgs{}
|
||||
args.SetDiff(diff)
|
||||
|
||||
vals, err := w.client.Snapshot(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return unmarshalNetmap(vals.Peers())
|
||||
}
|
||||
|
||||
// GetNetMapByEpoch receives information list about storage nodes
|
||||
// through the Netmap contract call, composes network map
|
||||
// from them and returns it. Returns snapshot of the specified epoch number.
|
||||
func (w Wrapper) GetNetMapByEpoch(epoch uint64) (*netmap.Netmap, error) {
|
||||
args := client.EpochSnapshotArgs{}
|
||||
args.SetEpoch(epoch)
|
||||
|
||||
vals, err := w.client.EpochSnapshot(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return unmarshalNetmap(vals.Peers())
|
||||
}
|
||||
|
||||
// GetCandidates receives information list about candidates
|
||||
// for the next epoch network map through the Netmap contract
|
||||
// call, composes network map from them and returns it.
|
||||
func (w Wrapper) GetCandidates() (*netmap.Netmap, error) {
|
||||
args := client.GetNetMapCandidatesArgs{}
|
||||
|
||||
vals, err := w.client.Candidates(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return unmarshalCandidates(vals.NetmapNodes())
|
||||
}
|
||||
|
||||
func unmarshalNetmap(rawPeers [][]byte) (*netmap.Netmap, error) {
|
||||
infos := make([]netmap.NodeInfo, 0, len(rawPeers))
|
||||
|
||||
for _, peer := range rawPeers {
|
||||
nodeInfo := netmap.NewNodeInfo()
|
||||
if err := nodeInfo.Unmarshal(peer); err != nil {
|
||||
return nil, fmt.Errorf("can't unmarshal peer info: %w", err)
|
||||
}
|
||||
|
||||
infos = append(infos, *nodeInfo)
|
||||
}
|
||||
|
||||
nodes := netmap.NodesFromInfo(infos)
|
||||
|
||||
return netmap.NewNetmap(nodes)
|
||||
}
|
||||
|
||||
func unmarshalCandidates(rawCandidate []*client.PeerWithState) (*netmap.Netmap, error) {
|
||||
candidates := make([]netmap.NodeInfo, 0, len(rawCandidate))
|
||||
|
||||
for _, candidate := range rawCandidate {
|
||||
nodeInfo := netmap.NewNodeInfo()
|
||||
if err := nodeInfo.Unmarshal(candidate.Peer()); err != nil {
|
||||
return nil, fmt.Errorf("can't unmarshal peer info: %w", err)
|
||||
}
|
||||
|
||||
switch candidate.State() {
|
||||
case client.Online:
|
||||
nodeInfo.SetState(netmap.NodeStateOnline)
|
||||
case client.Offline:
|
||||
nodeInfo.SetState(netmap.NodeStateOffline)
|
||||
default:
|
||||
nodeInfo.SetState(0)
|
||||
}
|
||||
|
||||
candidates = append(candidates, *nodeInfo)
|
||||
}
|
||||
|
||||
nodes := netmap.NodesFromInfo(candidates)
|
||||
|
||||
return netmap.NewNetmap(nodes)
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
|
||||
// NewEpoch updates NeoFS epoch number through
|
||||
// Netmap contract call.
|
||||
func (w *Wrapper) NewEpoch(e uint64) error {
|
||||
var args netmap.NewEpochArgs
|
||||
args.SetEpochNumber(int64(e))
|
||||
|
||||
return w.client.NewEpoch(args)
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
netmap2 "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// Snapshot returns current netmap node infos.
|
||||
// Consider using pkg/morph/client/netmap for this.
|
||||
func (w *Wrapper) Snapshot() (*netmap.Netmap, error) {
|
||||
res, err := w.client.Snapshot(netmap2.GetSnapshotArgs{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peers := res.Peers()
|
||||
result := make([]netmap.NodeInfo, len(peers))
|
||||
|
||||
for i := range peers {
|
||||
if err := result[i].Unmarshal(peers[i]); err != nil {
|
||||
return nil, fmt.Errorf("can't unmarshal node info: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return netmap.NewNetmap(netmap.NodesFromInfo(result))
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package wrapper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||
contract "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||
)
|
||||
|
||||
// UpdatePeerPrm groups parameters of UpdatePeerState operation.
|
||||
type UpdatePeerPrm struct {
|
||||
key []byte
|
||||
state netmap.NodeState
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetKey sets public key.
|
||||
func (u *UpdatePeerPrm) SetKey(key []byte) {
|
||||
u.key = key
|
||||
}
|
||||
|
||||
// SetState sets node state.
|
||||
func (u *UpdatePeerPrm) SetState(state netmap.NodeState) {
|
||||
u.state = state
|
||||
}
|
||||
|
||||
// UpdatePeerState changes peer status through Netmap contract
|
||||
// call.
|
||||
func (w *Wrapper) UpdatePeerState(prm UpdatePeerPrm) error {
|
||||
args := contract.UpdateStateArgs{}
|
||||
|
||||
args.SetPublicKey(prm.key)
|
||||
args.SetState(int64(prm.state.ToV2()))
|
||||
args.InvokePrmOptional = prm.InvokePrmOptional
|
||||
|
||||
// invoke smart contract call
|
||||
if err := w.client.UpdateState(args); err != nil {
|
||||
return fmt.Errorf("could not invoke smart contract: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,79 +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/internal"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||
)
|
||||
|
||||
// Wrapper is a wrapper over netmap contract
|
||||
// client which implements:
|
||||
// * network map storage;
|
||||
// * tool for peer state updating.
|
||||
//
|
||||
// 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 *netmap.Client
|
||||
}
|
||||
|
||||
// Option allows to set an optional
|
||||
// parameter of Wrapper.
|
||||
type Option func(*opts)
|
||||
|
||||
type opts []client.StaticClientOption
|
||||
|
||||
func defaultOpts() *opts {
|
||||
return new(opts)
|
||||
}
|
||||
|
||||
// NewFromMorph returns the wrapper instance from the raw morph client.
|
||||
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...Option) (*Wrapper, error) {
|
||||
o := defaultOpts()
|
||||
|
||||
for i := range opts {
|
||||
opts[i](o)
|
||||
}
|
||||
|
||||
staticClient, err := client.NewStatic(cli, contract, fee, ([]client.StaticClientOption)(*o)...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't create netmap static client: %w", err)
|
||||
}
|
||||
|
||||
return &Wrapper{
|
||||
StaticClient: staticClient,
|
||||
client: netmap.New(staticClient),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 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 = append(*o, 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 = append(*o, client.AsAlphabet())
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue