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  }