diff --git a/score_params.go b/score_params.go index 4d2ffff..64d39d5 100644 --- a/score_params.go +++ b/score_params.go @@ -2,6 +2,7 @@ package pubsub import ( "fmt" + "math" "time" "github.com/libp2p/go-libp2p-core/peer" @@ -241,3 +242,17 @@ func (p *TopicScoreParams) validate() error { return nil } + +// ScoreParameterDecay computes the decay factor for a parameter, assuming the DecayInterval is 1s +// and that the value decays to zero if it drops below 0.01 +func ScoreParameterDecay(decay time.Duration) float64 { + return ScoreParameterDecayWithBase(decay, time.Second, 0.01) +} + +// ScoreParameterDecay computes the decay factor for a parameter using base as the DecayInterval +func ScoreParameterDecayWithBase(decay time.Duration, base time.Duration, decayToZero float64) float64 { + // the decay is linear, so after n ticks the value is factor^n + // so factor^n = decayToZero => factor = decayToZero^(1/n) + ticks := float64(decay / base) + return math.Pow(decayToZero, 1/ticks) +} diff --git a/score_params_test.go b/score_params_test.go index 4b1d8be..b46c36d 100644 --- a/score_params_test.go +++ b/score_params_test.go @@ -233,3 +233,10 @@ func TestPeerScoreParamsValidation(t *testing.T) { } } + +func TestScoreParameterDecay(t *testing.T) { + decay1hr := ScoreParameterDecay(time.Hour) + if decay1hr != .9987216039048303 { + t.Fatalf("expected .9987216039048303, got %f", decay1hr) + } +}