diff --git a/protocol/provideroptimizer/provider_optimizer_refactor.go b/protocol/provideroptimizer/provider_optimizer_refactor.go index f6c603906d..4da0c5f3ae 100644 --- a/protocol/provideroptimizer/provider_optimizer_refactor.go +++ b/protocol/provideroptimizer/provider_optimizer_refactor.go @@ -31,8 +31,8 @@ const ( ) var ( - OptimizerNumTiers_Refactor = 4 // TODO: make it a configurable parameter in the optimizer - MinimumEntries_Refactor = 5 // TODO: make it a configurable parameter in the optimizer + OptimizerNumTiers_Refactor = 4 + MinimumEntries_Refactor = 5 ATierChance_Refactor = 0.75 LastTierChance_Refactor = 0.0 ) @@ -48,6 +48,10 @@ type cacheInf_Refactor interface { Set(key, value interface{}, cost int64) bool } +type consumerOptimizerQoSClientInf_Refactor interface { + UpdatePairingListStake(stakeMap map[string]int64, chainId string, epoch uint64) +} + type ProviderOptimizer_Refactor struct { strategy Strategy_Refactor providersStorage cacheInf_Refactor @@ -58,6 +62,8 @@ type ProviderOptimizer_Refactor struct { selectionWeighter SelectionWeighter // weights are the providers stake OptimizerNumTiers int // number of tiers to use OptimizerMinTierEntries int // minimum number of entries in a tier to be considered for selection + consumerOptimizerQoSClient consumerOptimizerQoSClientInf_Refactor + chainId string } // The exploration mechanism makes the optimizer return providers that were not talking @@ -126,8 +132,13 @@ func (s Strategy_Refactor) GetStrategyFactor() math.LegacyDec { } // UpdateWeights update the selection weighter weights -func (po *ProviderOptimizer_Refactor) UpdateWeights_Refactor(weights map[string]int64) { +func (po *ProviderOptimizer_Refactor) UpdateWeights_Refactor(weights map[string]int64, epoch uint64) { po.selectionWeighter.SetWeights(weights) + + // Update the stake map for metrics + if po.consumerOptimizerQoSClient != nil { + po.consumerOptimizerQoSClient.UpdatePairingListStake(weights, po.chainId, epoch) + } } // AppendRelayFailure updates a provider's QoS metrics for a failed relay @@ -495,7 +506,7 @@ func (po *ProviderOptimizer_Refactor) getRelayStatsTimes_Refactor(providerAddres return nil } -func NewProviderOptimizer_Refactor(strategy Strategy_Refactor, averageBlockTIme time.Duration, wantedNumProvidersInConcurrency uint) *ProviderOptimizer_Refactor { +func NewProviderOptimizer_Refactor(strategy Strategy_Refactor, averageBlockTIme time.Duration, wantedNumProvidersInConcurrency uint, consumerOptimizerQoSClient consumerOptimizerQoSClientInf_Refactor, chainId string) *ProviderOptimizer_Refactor { cache, err := ristretto.NewCache(&ristretto.Config{NumCounters: CacheNumCounters, MaxCost: CacheMaxCost, BufferItems: 64, IgnoreInternalCost: true}) if err != nil { utils.LavaFormatFatal("failed setting up cache for queries", err) @@ -517,6 +528,8 @@ func NewProviderOptimizer_Refactor(strategy Strategy_Refactor, averageBlockTIme selectionWeighter: NewSelectionWeighter(), OptimizerNumTiers: OptimizerNumTiers_Refactor, OptimizerMinTierEntries: MinimumEntries_Refactor, + consumerOptimizerQoSClient: consumerOptimizerQoSClient, + chainId: chainId, } } diff --git a/protocol/provideroptimizer/provider_optimizer_refactor_test.go b/protocol/provideroptimizer/provider_optimizer_refactor_test.go index 085f6b2ead..661fb1e237 100644 --- a/protocol/provideroptimizer/provider_optimizer_refactor_test.go +++ b/protocol/provideroptimizer/provider_optimizer_refactor_test.go @@ -20,7 +20,7 @@ const ( func setupProviderOptimizer_Refactor(maxProvidersCount uint) *ProviderOptimizer_Refactor { averageBlockTIme := TEST_AVERAGE_BLOCK_TIME_Refactor - return NewProviderOptimizer_Refactor(StrategyBalanced_Refactor, averageBlockTIme, maxProvidersCount) + return NewProviderOptimizer_Refactor(StrategyBalanced_Refactor, averageBlockTIme, maxProvidersCount, nil, "test") } type providersGenerator_Refactor struct { @@ -668,7 +668,7 @@ func TestProviderOptimizerWeights_Refactor(t *testing.T) { improvedLatency := normalLatency - 5*time.Millisecond improvedBlock := syncBlock + 2 - providerOptimizer.UpdateWeights_Refactor(weights) + providerOptimizer.UpdateWeights_Refactor(weights, 1) for i := 0; i < 10; i++ { for idx, address := range providersGen.providersAddresses { if idx == 0 { @@ -765,7 +765,7 @@ func TestProviderOptimizerChooseProvider(t *testing.T) { weights[providersGen.providersAddresses[i]] = normalStake } } - providerOptimizer.UpdateWeights_Refactor(weights) + providerOptimizer.UpdateWeights_Refactor(weights, 1) // setup scores to all providers improvedLatency := TEST_BASE_WORLD_LATENCY_Refactor / 2 @@ -837,7 +837,7 @@ func TestProviderOptimizerRetriesWithReducedProvidersSet(t *testing.T) { weights[providersGen.providersAddresses[i]] = normalStake } } - providerOptimizer.UpdateWeights_Refactor(weights) + providerOptimizer.UpdateWeights_Refactor(weights, 1) cu := uint64(10) requestBlock := int64(1000) syncBlock := uint64(1000) @@ -907,7 +907,7 @@ func TestProviderOptimizerRetriesWithReducedProvidersSet(t *testing.T) { // providers 3,4,5 are picked. tier 0: providers 3 // tier 1: providers 4,5 // provider 5 has higher stake and should be picked more often within their tier - require.Greater(t, tierResults[0], 550) + require.Greater(t, tierResults[0], 540) require.Greater(t, tierResults[0], tierResults[1]) require.Equal(t, 3, len(res)) require.Greater(t, res[providersGen.providersAddresses[5]], res[providersGen.providersAddresses[4]]) @@ -995,9 +995,9 @@ func TestProviderOptimizerChoiceSimulation(t *testing.T) { // TestProviderOptimizerLatencySyncScore tests that a provider with 100ms latency and x sync block // has the same score as a provider with 1100ms latency but x+1 sync block -// This is true since the average block time is 10sec and the default sync factor is 0.1. So -// score_good_latency = latency + sync_factor * sync_lag + ... = 0.01 + 0.1 * 10 + ... = 1.01 + ... -// score_good_sync = latency + sync_factor * sync_lag + ... = 1.01 + 0.1 * 0 + ... = 1.01 + ... +// This is true since the average block time is 10sec and the default sync factor is 0.3. So +// score_good_latency = latency + sync_factor * sync_lag + ... = 0.01 + 0.3 * 10 + ... = 3.01 + ... +// score_good_sync = latency + sync_factor * sync_lag + ... = 3.01 + 0.3 * 0 + ... = 3.01 + ... func TestProviderOptimizerLatencySyncScore(t *testing.T) { rand.InitRandomSeed() providerOptimizer := setupProviderOptimizer_Refactor(1) @@ -1008,7 +1008,7 @@ func TestProviderOptimizerLatencySyncScore(t *testing.T) { syncBlock := uint64(1000) improvedLatency := TEST_BASE_WORLD_LATENCY_Refactor - badLatency := TEST_BASE_WORLD_LATENCY_Refactor + TEST_AVERAGE_BLOCK_TIME/10 // sync factor is 0.1 so divide by 10 + badLatency := TEST_BASE_WORLD_LATENCY_Refactor + 3*time.Second // sync factor is 0.3 so add 3 seconds // set a basic state for all providers sampleTime := time.Now() @@ -1045,5 +1045,5 @@ func TestProviderOptimizerLatencySyncScore(t *testing.T) { // choose many times - since their scores should be the same, they should be picked in a similar amount iterations := 1000 res, _ := runChooseManyTimesAndReturnResults_Refactor(t, providerOptimizer, providersGen.providersAddresses, nil, iterations, cu, requestBlock) - require.InDelta(t, res[providersGen.providersAddresses[0]], res[providersGen.providersAddresses[1]], float64(iterations)*0.05) + require.InDelta(t, res[providersGen.providersAddresses[0]], res[providersGen.providersAddresses[1]], float64(iterations)*0.1) } diff --git a/protocol/provideroptimizer/selection_tier.go b/protocol/provideroptimizer/selection_tier.go index e008361604..74dca1bef4 100644 --- a/protocol/provideroptimizer/selection_tier.go +++ b/protocol/provideroptimizer/selection_tier.go @@ -152,7 +152,7 @@ func (st *SelectionTierInst) ShiftTierChance(numTiers int, initialTierChances ma shiftedTierChances[i] = chanceForDefaultTiers + averageChance*offsetFactor } } else { - if initialTierChances[i] > 0 { + if initialTierChances[i] > LastTierChance { shiftedTierChances[i] = initialTierChances[i] + averageChance*offsetFactor } } diff --git a/x/pairing/types/qos_report_refactor.go b/x/pairing/types/qos_report_refactor.go index 34d828d1cb..eddb3d9ecc 100644 --- a/x/pairing/types/qos_report_refactor.go +++ b/x/pairing/types/qos_report_refactor.go @@ -17,7 +17,7 @@ import ( var ( DefaultFailureCost int64 = 3 - DefaultSyncFactor = sdk.NewDecWithPrec(1, 1) // 0.1 + DefaultSyncFactor = sdk.NewDecWithPrec(3, 1) // 0.3 DefaultStrategyFactor = BalancedStrategyFactor DefaultBlockErrorProbability = sdk.NewDec(-1) // default: BlockErrorProbability should not be used