lnd.xprv/chanfitness/rate_limit.go
carla 70bca1f350
chanfitness: add flap count based rate limiting
To prevent flapping peers from endlessly dos-ing us with online and
offline events, we rate limit the number of events we will store per
period using their flap rate to determine how often we will add their
events to our in memory list of online events.

Since we are tracking online events, we need to track the aggregate
change over the rate limited period, otherwise we will lose track of
a peer's current state. For example, if we store an online event, then
do not store the subsequent offline event, we will believe that the
peer is online when they actually aren't. To address this, we "stage"
a single event which keeps track of all the events that occurred while
we were rate limiting the peer. At the end of the rate limting period,
we will store the last state for that peer, thereby ensureing that
we maintain our record of their most recent state.
2020-09-08 13:47:20 +02:00

38 lines
1.1 KiB
Go

package chanfitness
import "time"
// rateLimitScale is the number of events we allow per rate limited tier.
// Increasing this value makes our rate limiting more lenient, decreasing it
// makes us less lenient.
const rateLimitScale = 200
// rateLimits is the set of rate limit tiers we apply to our peers based on
// their flap count. A peer can be placed in their tier by dividing their flap
// count by the rateLimitScale and returning the value at that index.
var rateLimits = []time.Duration{
time.Second,
time.Second * 5,
time.Second * 30,
time.Minute,
time.Minute * 30,
time.Hour,
}
// getRateLimit returns the value of the rate limited tier that we are on based
// on current flap count. If a peer's flap count exceeds the top tier, we just
// return our highest tier.
func getRateLimit(flapCount int) time.Duration {
// Figure out the tier we fall into based on our current flap count.
tier := flapCount / rateLimitScale
// If we have more events than our number of tiers, we just use the
// last tier
tierLen := len(rateLimits)
if tier >= tierLen {
tier = tierLen - 1
}
return rateLimits[tier]
}