gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/renter/hostdb/hostentry.go (about)

     1  package hostdb
     2  
     3  import (
     4  	"math"
     5  
     6  	"gitlab.com/SiaPrime/SiaPrime/modules"
     7  	"gitlab.com/SiaPrime/SiaPrime/types"
     8  )
     9  
    10  // updateHostDBEntry updates a HostDBEntries's historic interactions if more
    11  // than one block passed since the last update. This should be called every time
    12  // before the recent interactions are updated.  if passedTime is e.g. 10, this
    13  // means that the recent interactions were updated 10 blocks ago but never
    14  // since. So we need to apply the decay of 1 block before we append the recent
    15  // interactions from 10 blocks ago and then apply the decay of 9 more blocks in
    16  // which the recent interactions have been 0
    17  func updateHostHistoricInteractions(host *modules.HostDBEntry, bh types.BlockHeight) {
    18  	// Check that the last historic update was not in the future.
    19  	if host.LastHistoricUpdate >= bh {
    20  		// The hostdb may be performing a rescan, or maybe no time has passed
    21  		// since the last update, so there is nothing to do.
    22  		return
    23  	}
    24  	passedTime := bh - host.LastHistoricUpdate
    25  
    26  	// tmp float64 values for more accurate decay
    27  	hsi := host.HistoricSuccessfulInteractions
    28  	hfi := host.HistoricFailedInteractions
    29  
    30  	// Apply the decay of a single block.
    31  	decay := historicInteractionDecay
    32  	hsi *= decay
    33  	hfi *= decay
    34  
    35  	// Apply the recent interactions of that single block. Recent interactions
    36  	// cannot represent more than recentInteractionWeightLimit of historic
    37  	// interactions, unless there are less than historicInteractionDecayLimit
    38  	// total interactions, and then the recent interactions cannot count for
    39  	// more than recentInteractionWeightLimit of the decay limit.
    40  	rsi := float64(host.RecentSuccessfulInteractions)
    41  	rfi := float64(host.RecentFailedInteractions)
    42  	if hsi+hfi > historicInteractionDecayLimit {
    43  		if rsi+rfi > recentInteractionWeightLimit*(hsi+hfi) {
    44  			adjustment := recentInteractionWeightLimit * (hsi + hfi) / (rsi + rfi)
    45  			rsi *= adjustment
    46  			rfi *= adjustment
    47  		}
    48  	} else {
    49  		if rsi+rfi > recentInteractionWeightLimit*historicInteractionDecayLimit {
    50  			adjustment := recentInteractionWeightLimit * historicInteractionDecayLimit / (rsi + rfi)
    51  			rsi *= adjustment
    52  			rfi *= adjustment
    53  		}
    54  	}
    55  	hsi += rsi
    56  	hfi += rfi
    57  
    58  	// Apply the decay of the rest of the blocks
    59  	if passedTime > 1 && hsi+hfi > historicInteractionDecayLimit {
    60  		decay := math.Pow(historicInteractionDecay, float64(passedTime-1))
    61  		hsi *= decay
    62  		hfi *= decay
    63  	}
    64  
    65  	// Set new values
    66  	host.HistoricSuccessfulInteractions = hsi
    67  	host.HistoricFailedInteractions = hfi
    68  	host.RecentSuccessfulInteractions = 0
    69  	host.RecentFailedInteractions = 0
    70  
    71  	// Update the time of the last update
    72  	host.LastHistoricUpdate = bh
    73  }
    74  
    75  // IncrementSuccessfulInteractions increments the number of successful
    76  // interactions with a host for a given key
    77  func (hdb *HostDB) IncrementSuccessfulInteractions(key types.SiaPublicKey) {
    78  	hdb.mu.Lock()
    79  	defer hdb.mu.Unlock()
    80  
    81  	// Fetch the host.
    82  	host, haveHost := hdb.hostTree.Select(key)
    83  	if !haveHost {
    84  		return
    85  	}
    86  
    87  	// Update historic values if necessary
    88  	updateHostHistoricInteractions(&host, hdb.blockHeight)
    89  
    90  	// Increment the successful interactions
    91  	host.RecentSuccessfulInteractions++
    92  	hdb.hostTree.Modify(host)
    93  }
    94  
    95  // IncrementFailedInteractions increments the number of failed interactions with
    96  // a host for a given key
    97  func (hdb *HostDB) IncrementFailedInteractions(key types.SiaPublicKey) {
    98  	hdb.mu.Lock()
    99  	defer hdb.mu.Unlock()
   100  
   101  	// Fetch the host.
   102  	host, haveHost := hdb.hostTree.Select(key)
   103  	if !haveHost || !hdb.gateway.Online() {
   104  		// If we are offline it probably wasn't the host's fault
   105  		return
   106  	}
   107  
   108  	// Update historic values if necessary
   109  	updateHostHistoricInteractions(&host, hdb.blockHeight)
   110  
   111  	// Increment the failed interactions
   112  	host.RecentFailedInteractions++
   113  	hdb.hostTree.Modify(host)
   114  }