[#488] storage/calculator: Make alpha dynamic

Delete reading `alpha` from env var. Cover
retrieving `alpha` behind interface in
intermediate calculator. Add TODO to decide
if it is necessary to receive that param from
global config or not.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2021-04-29 09:03:24 +03:00 committed by Alex Vanin
parent ad4a55468e
commit 2c8c9f69c8
6 changed files with 34 additions and 14 deletions

View file

@ -102,7 +102,6 @@ const (
// config keys for cfgReputation // config keys for cfgReputation
cfgReputationContract = "reputation.scripthash" cfgReputationContract = "reputation.scripthash"
cfgReputationAlpha = "reputation.alpha"
cfgReputationWorkerPoolEnabled = "reputation.async_worker.enabled" cfgReputationWorkerPoolEnabled = "reputation.async_worker.enabled"
cfgReputationWorkerPoolSize = "reputation.async_worker.size" cfgReputationWorkerPoolSize = "reputation.async_worker.size"
@ -320,9 +319,6 @@ type cfgControlService struct {
} }
type cfgReputation struct { type cfgReputation struct {
// Alpha parameter from origin EigenTrust algorithm
// http://ilpubs.stanford.edu:8090/562/1/2002-56.pdf Ch.5.1.
alpha float64
workerPool util2.WorkerPool // pool for EigenTrust algorithm's iterations workerPool util2.WorkerPool // pool for EigenTrust algorithm's iterations
localTrustStorage *truststorage.Storage localTrustStorage *truststorage.Storage
@ -430,7 +426,6 @@ func initCfg(path string) *cfg {
healthStatus: atomic.NewInt32(int32(control.HealthStatus_HEALTH_STATUS_UNDEFINED)), healthStatus: atomic.NewInt32(int32(control.HealthStatus_HEALTH_STATUS_UNDEFINED)),
cfgReputation: cfgReputation{ cfgReputation: cfgReputation{
scriptHash: u160Reputation, scriptHash: u160Reputation,
alpha: viper.GetFloat64(cfgReputationAlpha),
workerPool: reputationWorkerPool, workerPool: reputationWorkerPool,
}, },
} }
@ -486,7 +481,6 @@ func defaultConfiguration(v *viper.Viper) {
v.SetDefault(cfgContainerWorkerPoolEnabled, true) v.SetDefault(cfgContainerWorkerPoolEnabled, true)
v.SetDefault(cfgContainerWorkerPoolSize, 10) v.SetDefault(cfgContainerWorkerPoolSize, 10)
v.SetDefault(cfgReputationAlpha, 0.5)
v.SetDefault(cfgReputationWorkerPoolEnabled, true) v.SetDefault(cfgReputationWorkerPoolEnabled, true)
v.SetDefault(cfgReputationWorkerPoolSize, 10) v.SetDefault(cfgReputationWorkerPoolSize, 10)

View file

@ -25,3 +25,13 @@ func (c *DaughtersTrustCalculator) Calculate(ctx eigentrustctrl.IterationContext
c.Calculator.Calculate(calcPrm) c.Calculator.Calculate(calcPrm)
} }
// AlphaProvider provides required alpha parameter of eigen trust algorithm.
// TODO: decide if `Alpha` should be dynamically read from global config. #497
type AlphaProvider struct {
Alpha float64
}
func (ap AlphaProvider) EigenTrustAlpha() (float64, error) {
return ap.Alpha, nil
}

View file

@ -18,7 +18,7 @@ type Prm struct {
// http://ilpubs.stanford.edu:8090/562/1/2002-56.pdf Ch.5.1. // http://ilpubs.stanford.edu:8090/562/1/2002-56.pdf Ch.5.1.
// //
// Must be in range (0, 1). // Must be in range (0, 1).
Alpha float64 AlphaProvider AlphaProvider
// Source of initial node trust values // Source of initial node trust values
// //
@ -63,8 +63,8 @@ func panicOnPrmValue(n string, v interface{}) {
// initialization and is completely ready for work. // initialization and is completely ready for work.
func New(prm Prm, opts ...Option) *Calculator { func New(prm Prm, opts ...Option) *Calculator {
switch { switch {
case prm.Alpha <= 0 || prm.Alpha >= 1: case prm.AlphaProvider == nil:
panicOnPrmValue("Alpha", prm.Alpha) panicOnPrmValue("AlphaProvider", prm.AlphaProvider)
case prm.InitialTrustSource == nil: case prm.InitialTrustSource == nil:
panicOnPrmValue("InitialTrustSource", prm.InitialTrustSource) panicOnPrmValue("InitialTrustSource", prm.InitialTrustSource)
case prm.DaughterTrustSource == nil: case prm.DaughterTrustSource == nil:
@ -84,9 +84,7 @@ func New(prm Prm, opts ...Option) *Calculator {
} }
return &Calculator{ return &Calculator{
alpha: reputation.TrustValueFromFloat64(prm.Alpha), prm: prm,
beta: reputation.TrustValueFromFloat64(1 - prm.Alpha), opts: o,
prm: prm,
opts: o,
} }
} }

View file

@ -24,6 +24,18 @@ func (p *CalculatePrm) SetEpochIteration(ei eigentrust.EpochIteration) {
} }
func (c *Calculator) Calculate(prm CalculatePrm) { func (c *Calculator) Calculate(prm CalculatePrm) {
alpha, err := c.prm.AlphaProvider.EigenTrustAlpha()
if err != nil {
c.opts.log.Debug(
"failed to get alpha param",
zap.Error(err),
)
return
}
c.alpha = reputation.TrustValueFromFloat64(alpha)
c.beta = reputation.TrustValueFromFloat64(1 - alpha)
ctx := eigentrust.IterContext{ ctx := eigentrust.IterContext{
Context: context.Background(), Context: context.Background(),
EpochIteration: prm.ei, EpochIteration: prm.ei,

View file

@ -59,3 +59,9 @@ type IntermediateWriter interface {
type IntermediateWriterProvider interface { type IntermediateWriterProvider interface {
InitIntermediateWriter(Context) (IntermediateWriter, error) InitIntermediateWriter(Context) (IntermediateWriter, error)
} }
// AlphaProvider must provide information about required
// alpha parameter for eigen trust algorithm.
type AlphaProvider interface {
EigenTrustAlpha() (float64, error)
}

View file

@ -34,7 +34,7 @@ type DaughtersTrustCalculator interface {
Calculate(ctx IterationContext) Calculate(ctx IterationContext)
} }
// IterationsProvider must provides information about numbers // IterationsProvider must provide information about numbers
// of iterations for algorithm. // of iterations for algorithm.
type IterationsProvider interface { type IterationsProvider interface {
EigenTrustIterations() (uint64, error) EigenTrustIterations() (uint64, error)