From 4f28c58fc93c2e1e72520676383f4b08cf173cbe Mon Sep 17 00:00:00 2001 From: Marco van Dijk Date: Tue, 9 Jan 2024 17:56:42 +0100 Subject: [PATCH] Modifying price-weighted curve from exponential to a highly adjustable inverted sigmoid curve --- cmd/livepeer/livepeer.go | 4 +++- cmd/livepeer/starter/starter.go | 24 ++++++++++++++++-------- server/selection_algorithm.go | 8 ++++++-- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/cmd/livepeer/livepeer.go b/cmd/livepeer/livepeer.go index 5da2ff494..07898d71a 100755 --- a/cmd/livepeer/livepeer.go +++ b/cmd/livepeer/livepeer.go @@ -130,7 +130,9 @@ func parseLivepeerConfig() starter.LivepeerConfig { cfg.SelectRandWeight = flag.Float64("selectRandFreq", *cfg.SelectRandWeight, "Weight of the random factor in the orchestrator selection algorithm") cfg.SelectStakeWeight = flag.Float64("selectStakeWeight", *cfg.SelectStakeWeight, "Weight of the stake factor in the orchestrator selection algorithm") cfg.SelectPriceWeight = flag.Float64("selectPriceWeight", *cfg.SelectPriceWeight, "Weight of the price factor in the orchestrator selection algorithm") - cfg.SelectPriceExpFactor = flag.Float64("selectPriceExpFactor", *cfg.SelectPriceExpFactor, "Expresses how significant a small change of price is for the selection algorithm; default 100") + cfg.SelectPriceExpFactorA = flag.Float64("selectPriceExpFactorA", *cfg.SelectPriceExpFactorA, "Expresses how significant a small change of price is for the selection algorithm; default 0.001") + cfg.SelectPriceExpFactorB = flag.Float64("selectPriceExpFactorB", *cfg.SelectPriceExpFactorB, "Expresses how significant a small change of price is for the selection algorithm; default 20") + cfg.SelectPriceCenter = flag.Float64("selectPriceCenter", *cfg.SelectPriceCenter, "Centers the price weighted selection curve around this number, giving increasingly diminishing returns starting at that price point; default 150") cfg.OrchPerfStatsURL = flag.String("orchPerfStatsUrl", *cfg.OrchPerfStatsURL, "URL of Orchestrator Performance Stream Tester") cfg.Region = flag.String("region", *cfg.Region, "Region in which a broadcaster is deployed; used to select the region while using the orchestrator's performance stats") cfg.MaxPricePerUnit = flag.Int("maxPricePerUnit", *cfg.MaxPricePerUnit, "The maximum transcoding price (in wei) per 'pixelsPerUnit' a broadcaster is willing to accept. If not set explicitly, broadcaster is willing to accept ANY price") diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 20ae39b12..e1de4be6e 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -92,7 +92,9 @@ type LivepeerConfig struct { SelectRandWeight *float64 SelectStakeWeight *float64 SelectPriceWeight *float64 - SelectPriceExpFactor *float64 + SelectPriceExpFactorA *float64 + SelectPriceExpFactorB *float64 + SelectPriceCenter *float64 OrchPerfStatsURL *string Region *string MaxPricePerUnit *int @@ -169,7 +171,9 @@ func DefaultLivepeerConfig() LivepeerConfig { defaultSelectRandWeight := 0.3 defaultSelectStakeWeight := 0.7 defaultSelectPriceWeight := 0.0 - defaultSelectPriceExpFactor := 100.0 + defaultSelectPriceExpFactorA := 0.001 + defaultSelectPriceExpFactorB := 20.0 + defaultSelectPriceCenter := 150.0 defaultMaxSessions := strconv.Itoa(10) defaultOrchPerfStatsURL := "" defaultRegion := "" @@ -257,7 +261,9 @@ func DefaultLivepeerConfig() LivepeerConfig { SelectRandWeight: &defaultSelectRandWeight, SelectStakeWeight: &defaultSelectStakeWeight, SelectPriceWeight: &defaultSelectPriceWeight, - SelectPriceExpFactor: &defaultSelectPriceExpFactor, + SelectPriceExpFactorA: &defaultSelectPriceExpFactorA, + SelectPriceExpFactorB: &defaultSelectPriceExpFactorB, + SelectPriceCenter: &defaultSelectPriceCenter, MaxSessions: &defaultMaxSessions, OrchPerfStatsURL: &defaultOrchPerfStatsURL, Region: &defaultRegion, @@ -1498,11 +1504,13 @@ func createSelectionAlgorithm(cfg LivepeerConfig) (common.SelectionAlgorithm, er *cfg.SelectStakeWeight, *cfg.SelectPriceWeight, *cfg.SelectRandWeight) } return server.ProbabilitySelectionAlgorithm{ - MinPerfScore: *cfg.MinPerfScore, - StakeWeight: *cfg.SelectStakeWeight, - PriceWeight: *cfg.SelectPriceWeight, - RandWeight: *cfg.SelectRandWeight, - PriceExpFactor: *cfg.SelectPriceExpFactor, + MinPerfScore: *cfg.MinPerfScore, + StakeWeight: *cfg.SelectStakeWeight, + PriceWeight: *cfg.SelectPriceWeight, + RandWeight: *cfg.SelectRandWeight, + PriceExpFactorA: *cfg.SelectPriceExpFactorA, + PriceExpFactorB: *cfg.SelectPriceExpFactorB, + PriceCenter: *cfg.SelectPriceCenter, }, nil } diff --git a/server/selection_algorithm.go b/server/selection_algorithm.go index 72bc2a663..d46e2451f 100644 --- a/server/selection_algorithm.go +++ b/server/selection_algorithm.go @@ -17,7 +17,9 @@ type ProbabilitySelectionAlgorithm struct { PriceWeight float64 RandWeight float64 - PriceExpFactor float64 + PriceExpFactorA float64 + PriceExpFactorB float64 + PriceCenter float64 } func (sa ProbabilitySelectionAlgorithm) Select(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, prices map[ethcommon.Address]float64, perfScores map[ethcommon.Address]float64) ethcommon.Address { @@ -50,9 +52,11 @@ func (sa ProbabilitySelectionAlgorithm) filter(addrs []ethcommon.Address, scores func (sa ProbabilitySelectionAlgorithm) calculateProbabilities(addrs []ethcommon.Address, stakes map[ethcommon.Address]int64, prices map[ethcommon.Address]float64) map[ethcommon.Address]float64 { pricesNorm := map[ethcommon.Address]float64{} + + // Normalize price-weighted selection according to a inverted sigmoid function for _, addr := range addrs { p := prices[addr] - pricesNorm[addr] = math.Exp(-1 * p / sa.PriceExpFactor) + pricesNorm[addr] = 1 / (1 + math.Pow(math.Exp(sa.PriceExpFactorA*(p-sa.PriceCenter)), sa.PriceExpFactorB)) } var priceSum, stakeSum float64