forked from TrueCloudLab/frostfs-node
[#833] morph/netmap: Support ListConfig contract method
Implement `Client.ListConfig` method which calls `listConfig` method of Netmap contract. Implement `Wrapper.IterateConfigParameters` method which uses previous one. Implement `wrapper.WriteConfig` helper function which allows to interpret parameters by names. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
cb22e2bf29
commit
7582689de4
3 changed files with 156 additions and 1 deletions
|
@ -43,7 +43,8 @@ type cfg struct {
|
||||||
lastEpochBlockMethod, // get last epoch number method name
|
lastEpochBlockMethod, // get last epoch number method name
|
||||||
updateInnerRing, // update innerring method name
|
updateInnerRing, // update innerring method name
|
||||||
setConfigMethod, // set config method name
|
setConfigMethod, // set config method name
|
||||||
configMethod string // get config value method name
|
configMethod, // get config value method name
|
||||||
|
configListMethod string // list config method name
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -61,6 +62,8 @@ const (
|
||||||
defaultUpdateStateMethod = "updateState" // default update state method name
|
defaultUpdateStateMethod = "updateState" // default update state method name
|
||||||
|
|
||||||
defaultEpochSnapshotMethod = "snapshotByEpoch" // default get network map snapshot by epoch method name
|
defaultEpochSnapshotMethod = "snapshotByEpoch" // default get network map snapshot by epoch method name
|
||||||
|
|
||||||
|
defaultConfigListMethod = "listConfig" // default config listing method name
|
||||||
)
|
)
|
||||||
|
|
||||||
func defaultConfig() *cfg {
|
func defaultConfig() *cfg {
|
||||||
|
@ -78,6 +81,7 @@ func defaultConfig() *cfg {
|
||||||
updateStateMethod: defaultUpdateStateMethod,
|
updateStateMethod: defaultUpdateStateMethod,
|
||||||
updateInnerRing: defaultUpdateInnerRingMethod,
|
updateInnerRing: defaultUpdateInnerRingMethod,
|
||||||
epochSnapshotMethod: defaultEpochSnapshotMethod,
|
epochSnapshotMethod: defaultEpochSnapshotMethod,
|
||||||
|
configListMethod: defaultConfigListMethod,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,3 +218,17 @@ func WithEpochSnapshotMethod(n string) Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithConfigListMethod returns a client constructor option that
|
||||||
|
// specifies the config listing method name.
|
||||||
|
//
|
||||||
|
// Ignores empty value.
|
||||||
|
//
|
||||||
|
// If option not provided, "listConfig" is used.
|
||||||
|
func WithConfigListMethod(n string) Option {
|
||||||
|
return func(c *cfg) {
|
||||||
|
if n != "" {
|
||||||
|
c.configListMethod = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -68,3 +68,72 @@ func IntegerAssert(item stackitem.Item) (interface{}, error) {
|
||||||
func StringAssert(item stackitem.Item) (interface{}, error) {
|
func StringAssert(item stackitem.Item) (interface{}, error) {
|
||||||
return client.StringFromStackItem(item)
|
return client.StringFromStackItem(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListConfigArgs groups the arguments
|
||||||
|
// of config listing test invoke call.
|
||||||
|
type ListConfigArgs struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigValues 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.
|
||||||
|
//
|
||||||
|
// 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])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("record fields: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ln := len(fields); ln != 2 {
|
||||||
|
return fmt.Errorf("unexpected record fields number: %d", ln)
|
||||||
|
}
|
||||||
|
|
||||||
|
k, err := client.BytesFromStackItem(fields[0])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("record key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := client.BytesFromStackItem(fields[1])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("record value: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := f(k, v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListConfig performs the test invoke of config listing method of NeoFS Netmap contract.
|
||||||
|
func (c *Client) ListConfig(args ListConfigArgs) (*ListConfigValues, error) {
|
||||||
|
items, err := c.client.TestInvoke(
|
||||||
|
c.configListMethod,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not perform test invocation (%s): %w",
|
||||||
|
c.configListMethod, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ln := len(items); ln != 1 {
|
||||||
|
return nil, fmt.Errorf("unexpected stack item count (%s): %d",
|
||||||
|
c.configListMethod, ln)
|
||||||
|
}
|
||||||
|
|
||||||
|
arr, err := client.ArrayFromStackItem(items[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("record list (%s): %w",
|
||||||
|
c.configListMethod, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ListConfigValues{
|
||||||
|
rs: arr,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -159,3 +160,70 @@ func (w *Wrapper) readStringConfig(key string) (string, error) {
|
||||||
func (w *Wrapper) SetConfig(id, key []byte, value interface{}) error {
|
func (w *Wrapper) SetConfig(id, key []byte, value interface{}) error {
|
||||||
return w.client.SetConfig(id, key, value)
|
return w.client.SetConfig(id, key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
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 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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue