gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/renter/hostdb/hosttree/scorebreakdown.go (about) 1 package hosttree 2 3 import ( 4 "math/big" 5 6 "gitlab.com/SiaPrime/SiaPrime/modules" 7 "gitlab.com/SiaPrime/SiaPrime/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) modules.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 AgeAdjustment float64 21 BurnAdjustment float64 22 CollateralAdjustment float64 23 DurationAdjustment float64 24 InteractionAdjustment float64 25 PriceAdjustment float64 26 StorageRemainingAdjustment float64 27 UptimeAdjustment float64 28 VersionAdjustment float64 29 } 30 31 var ( 32 // Previous constructions of the hostdb required the baseWeight to be large 33 // to prevent fractional results, but the current iteration of the hostdb 34 // has no issues, the scores will always be quite large. 35 baseWeight = types.NewCurrency64(1) 36 ) 37 38 // conversionRate computes the likelihood of a host with 'score' to be drawn 39 // from the hosttree assuming that all hosts have 'totalScore'. 40 func conversionRate(score, totalScore types.Currency) float64 { 41 if totalScore.IsZero() { 42 totalScore = types.NewCurrency64(1) 43 } 44 conversionRate, _ := big.NewRat(0, 1).SetFrac(score.Mul64(50).Big(), totalScore.Big()).Float64() 45 if conversionRate > 100 { 46 conversionRate = 100 47 } 48 return conversionRate 49 } 50 51 // HostScoreBreakdown converts a HostAdjustments object into a 52 // modules.HostScoreBreakdown. 53 func (h HostAdjustments) HostScoreBreakdown(totalScore types.Currency, ignoreAge, ignoreDuration, ignoreUptime bool) modules.HostScoreBreakdown { 54 // Set the ignored fields to 1. 55 if ignoreAge { 56 h.AgeAdjustment = 1.0 57 } 58 if ignoreUptime { 59 h.UptimeAdjustment = 1.0 60 } 61 if ignoreDuration { 62 h.DurationAdjustment = 1.0 63 } 64 // Create the breakdown. 65 score := h.Score() 66 return modules.HostScoreBreakdown{ 67 Score: score, 68 ConversionRate: conversionRate(score, totalScore), 69 70 AgeAdjustment: h.AgeAdjustment, 71 BurnAdjustment: h.BurnAdjustment, 72 CollateralAdjustment: h.CollateralAdjustment, 73 DurationAdjustment: h.DurationAdjustment, 74 InteractionAdjustment: h.InteractionAdjustment, 75 PriceAdjustment: h.PriceAdjustment, 76 StorageRemainingAdjustment: h.StorageRemainingAdjustment, 77 UptimeAdjustment: h.UptimeAdjustment, 78 VersionAdjustment: h.VersionAdjustment, 79 } 80 } 81 82 // Score combines the individual adjustments of the breakdown into a single 83 // score. 84 func (h HostAdjustments) Score() types.Currency { 85 // Combine the adjustments. 86 fullPenalty := h.BurnAdjustment * h.CollateralAdjustment * h.DurationAdjustment * h.InteractionAdjustment * 87 h.AgeAdjustment * h.PriceAdjustment * h.StorageRemainingAdjustment * h.UptimeAdjustment * h.VersionAdjustment 88 89 // Return a types.Currency. 90 weight := baseWeight.MulFloat(fullPenalty) 91 if weight.IsZero() { 92 // A weight of zero is problematic for for the host tree. 93 return types.NewCurrency64(1) 94 } 95 return weight 96 }