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 }