gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/hostdb/hosttree/scorebreakdown.go (about) 1 package hosttree 2 3 import ( 4 "math/big" 5 6 "gitlab.com/SkynetLabs/skyd/skymodules" 7 "go.sia.tech/siad/types" 8 ) 9 10 // ScoreBreakdown is an interface that allows us to mock the hostAdjustments 11 // during testing. 12 type ScoreBreakdown interface { 13 HostScoreBreakdown(totalScore types.Currency, ignoreAge, ignoreDuration, ignoreUptime bool) skymodules.HostScoreBreakdown 14 Score() types.Currency 15 } 16 17 // HostAdjustments contains all the adjustments relevant to a host's score and 18 // implements the scoreBreakdown interface. 19 type HostAdjustments struct { 20 AcceptContractAdjustment float64 21 AgeAdjustment float64 22 BasePriceAdjustment float64 23 BurnAdjustment float64 24 CollateralAdjustment float64 25 DurationAdjustment float64 26 InteractionAdjustment float64 27 PriceAdjustment float64 28 StorageRemainingAdjustment float64 29 UptimeAdjustment float64 30 VersionAdjustment float64 31 } 32 33 var ( 34 // Previous constructions of the hostdb required the baseWeight to be large 35 // to prevent fractional results, but the current iteration of the hostdb 36 // has no issues, the scores will always be quite large. 37 baseWeight = types.NewCurrency64(1) 38 ) 39 40 // conversionRate computes the likelihood of a host with 'score' to be drawn 41 // from the hosttree assuming that all hosts have 'totalScore'. 42 func conversionRate(score, totalScore types.Currency) float64 { 43 if totalScore.IsZero() { 44 totalScore = types.NewCurrency64(1) 45 } 46 conversionRate, _ := big.NewRat(0, 1).SetFrac(score.Mul64(50).Big(), totalScore.Big()).Float64() 47 if conversionRate > 100 { 48 conversionRate = 100 49 } 50 return conversionRate 51 } 52 53 // HostScoreBreakdown converts a HostAdjustments object into a 54 // modules.HostScoreBreakdown. 55 func (h HostAdjustments) HostScoreBreakdown(totalScore types.Currency, ignoreAge, ignoreDuration, ignoreUptime bool) skymodules.HostScoreBreakdown { 56 // Set the ignored fields to 1. 57 if ignoreAge { 58 h.AgeAdjustment = 1.0 59 } 60 if ignoreUptime { 61 h.UptimeAdjustment = 1.0 62 } 63 if ignoreDuration { 64 h.DurationAdjustment = 1.0 65 } 66 // Create the breakdown. 67 score := h.Score() 68 return skymodules.HostScoreBreakdown{ 69 Score: score, 70 ConversionRate: conversionRate(score, totalScore), 71 72 AcceptContractAdjustment: h.AcceptContractAdjustment, 73 AgeAdjustment: h.AgeAdjustment, 74 BasePriceAdjustment: h.BasePriceAdjustment, 75 BurnAdjustment: h.BurnAdjustment, 76 CollateralAdjustment: h.CollateralAdjustment, 77 DurationAdjustment: h.DurationAdjustment, 78 InteractionAdjustment: h.InteractionAdjustment, 79 PriceAdjustment: h.PriceAdjustment, 80 StorageRemainingAdjustment: h.StorageRemainingAdjustment, 81 UptimeAdjustment: h.UptimeAdjustment, 82 VersionAdjustment: h.VersionAdjustment, 83 } 84 } 85 86 // Score combines the individual adjustments of the breakdown into a single 87 // score. 88 func (h HostAdjustments) Score() types.Currency { 89 // Combine the adjustments. 90 fullPenalty := h.AgeAdjustment * 91 h.AcceptContractAdjustment * 92 h.BasePriceAdjustment * 93 h.BurnAdjustment * 94 h.CollateralAdjustment * 95 h.DurationAdjustment * 96 h.InteractionAdjustment * 97 h.PriceAdjustment * 98 h.StorageRemainingAdjustment * 99 h.UptimeAdjustment * 100 h.VersionAdjustment 101 102 // Return a types.Currency. 103 weight := baseWeight.MulFloat(fullPenalty) 104 if weight.IsZero() { 105 // A weight of zero is problematic for for the host tree. 106 return types.NewCurrency64(1) 107 } 108 return weight 109 }