[#363] Define global config and use it to fetch basic income rate

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-02-02 14:12:41 +03:00 committed by Alex Vanin
parent be2ed6bf4c
commit 487c9b7589
7 changed files with 89 additions and 9 deletions

View file

@ -104,4 +104,6 @@ func defaultConfiguration(cfg *viper.Viper) {
cfg.SetDefault("audit.pdp.max_sleep_interval", "5s") cfg.SetDefault("audit.pdp.max_sleep_interval", "5s")
cfg.SetDefault("audit.pdp.pairs_pool_size", "10") cfg.SetDefault("audit.pdp.pairs_pool_size", "10")
cfg.SetDefault("audit.por.pool_size", "10") cfg.SetDefault("audit.por.pool_size", "10")
cfg.SetDefault("settlement.basic_income_rate", 0)
} }

View file

@ -0,0 +1,39 @@
package config
/*
Config package contains GlobalConfig structure that implements config
reader from both local and global configurations. Most of the time inner ring
does not need this, as for application it has static config with timeouts,
caches sizes etc. However there are routines that use global configuration
values that can be changed in runtime, e.g. basic income rate. Local
configuration value overrides global one so it is easy to debug and test
in different environments.
Implemented as a part of https://github.com/nspcc-dev/neofs-node/issues/363
*/
import (
netmapClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
"github.com/spf13/viper"
)
type GlobalConfig struct {
cfg *viper.Viper
nm *netmapClient.Wrapper
}
func NewGlobalConfigReader(cfg *viper.Viper, nm *netmapClient.Wrapper) *GlobalConfig {
return &GlobalConfig{
cfg: cfg,
nm: nm,
}
}
func (c *GlobalConfig) BasicIncomeRate() (uint64, error) {
value := c.cfg.GetUint64("settlement.basic_income_rate")
if value != 0 {
return value, nil
}
return c.nm.BasinIncomeRate()
}

View file

@ -9,6 +9,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
crypto "github.com/nspcc-dev/neofs-crypto" crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/pkg/innerring/config"
"github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/alphabet" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/alphabet"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/audit" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/audit"
@ -238,6 +239,9 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
return nil, err return nil, err
} }
// create global runtime config reader
globalConfig := config.NewGlobalConfigReader(cfg, nmClient)
clientCache := newClientCache(&clientCacheParams{ clientCache := newClientCache(&clientCacheParams{
Log: log, Log: log,
Key: server.key, Key: server.key,
@ -300,6 +304,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
basicSettlementDeps := &basicIncomeSettlementDeps{ basicSettlementDeps := &basicIncomeSettlementDeps{
settlementDeps: settlementDeps, settlementDeps: settlementDeps,
cnrClient: cnrClient, cnrClient: cnrClient,
cfg: globalConfig,
} }
auditSettlementCalc := auditSettlement.NewCalculator( auditSettlementCalc := auditSettlement.NewCalculator(

View file

@ -20,11 +20,17 @@ func (inc *IncomeSettlementContext) Collect() {
// todo: save state of bank wallet // todo: save state of bank wallet
cachedRate := inc.rate.BasicRate() cachedRate, err := inc.rate.BasicRate()
if err != nil {
inc.log.Error("can't get basic income rate",
zap.String("error", err.Error()))
return
}
cnrEstimations, err := inc.estimations.Estimations(inc.epoch) cnrEstimations, err := inc.estimations.Estimations(inc.epoch)
if err != nil { if err != nil {
inc.log.Warn("can't fetch container size estimations", inc.log.Error("can't fetch container size estimations",
zap.Uint64("epoch", inc.epoch)) zap.Uint64("epoch", inc.epoch))
return return

View file

@ -18,7 +18,7 @@ type (
} }
RateFetcher interface { RateFetcher interface {
BasicRate() uint64 BasicRate() (uint64, error)
} }
IncomeSettlementContext struct { IncomeSettlementContext struct {

View file

@ -26,6 +26,10 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
type globalConfig interface {
BasicIncomeRate() (uint64, error)
}
type settlementDeps struct { type settlementDeps struct {
log *logger.Logger log *logger.Logger
@ -47,6 +51,7 @@ type auditSettlementDeps struct {
type basicIncomeSettlementDeps struct { type basicIncomeSettlementDeps struct {
*settlementDeps *settlementDeps
cnrClient *containerClient.Wrapper cnrClient *containerClient.Wrapper
cfg globalConfig
} }
type basicSettlementConstructor struct { type basicSettlementConstructor struct {
@ -226,8 +231,8 @@ func (b basicIncomeSettlementDeps) Transfer(sender, recipient *owner.ID, amount
b.transfer(sender, recipient, amount, basicIncomeAuditDetails) b.transfer(sender, recipient, amount, basicIncomeAuditDetails)
} }
func (b basicIncomeSettlementDeps) BasicRate() uint64 { func (b basicIncomeSettlementDeps) BasicRate() (uint64, error) {
return 1_0000_0000 // fixme: read from config and from chain return b.cfg.BasicIncomeRate()
} }
func (b basicIncomeSettlementDeps) Estimations(epoch uint64) ([]*wrapper.Estimations, error) { func (b basicIncomeSettlementDeps) Estimations(epoch uint64) ([]*wrapper.Estimations, error) {

View file

@ -5,24 +5,47 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
const maxObjectSizeConfig = "MaxObjectSize" const (
maxObjectSizeConfig = "MaxObjectSize"
basicIncomeRateConfig = "BasicIncomeRate"
)
// MaxObjectSize receives max object size configuration // MaxObjectSize receives max object size configuration
// value through the Netmap contract call. // value through the Netmap contract call.
func (w *Wrapper) MaxObjectSize() (uint64, error) { func (w *Wrapper) MaxObjectSize() (uint64, error) {
objectSize, err := w.readUInt64Config(maxObjectSizeConfig)
if err != nil {
return 0, errors.Wrapf(err, "(%T) could not get epoch number", w)
}
return objectSize, nil
}
// BasicIncomeRate returns basic income rate configuration value from network
// config in netmap contract.
func (w *Wrapper) BasinIncomeRate() (uint64, error) {
rate, err := w.readUInt64Config(basicIncomeRateConfig)
if err != nil {
return 0, errors.Wrapf(err, "(%T) could not get basic income rate", w)
}
return rate, nil
}
func (w *Wrapper) readUInt64Config(key string) (uint64, error) {
args := netmap.ConfigArgs{} args := netmap.ConfigArgs{}
args.SetKey([]byte(maxObjectSizeConfig)) args.SetKey([]byte(key))
vals, err := w.client.Config(args, netmap.IntegerAssert) vals, err := w.client.Config(args, netmap.IntegerAssert)
if err != nil { if err != nil {
return 0, errors.Wrapf(err, "(%T) could not get epoch number", w) return 0, err
} }
v := vals.Value() v := vals.Value()
sz, ok := v.(int64) sz, ok := v.(int64)
if !ok { if !ok {
return 0, errors.Errorf("(%T) invalid epoch value type %T", w, v) return 0, errors.Errorf("(%T) invalid value type %T", w, v)
} }
return uint64(sz), nil return uint64(sz), nil