mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-27 00:55:17 +00:00
740 lines
24 KiB
Go
740 lines
24 KiB
Go
|
package blossomsub
|
||
|
|
||
|
import (
|
||
|
"math"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||
|
)
|
||
|
|
||
|
func TestPeerScoreThreshold_AtomicValidation(t *testing.T) {
|
||
|
testPeerScoreThresholdsValidation(t, false)
|
||
|
}
|
||
|
|
||
|
func TestPeerScoreThreshold_SkipAtomicValidation(t *testing.T) {
|
||
|
testPeerScoreThresholdsValidation(t, true)
|
||
|
}
|
||
|
|
||
|
func testPeerScoreThresholdsValidation(t *testing.T, skipAtomicValidation bool) {
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
PublishThreshold: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: -1,
|
||
|
PublishThreshold: 0,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: -1,
|
||
|
PublishThreshold: -2,
|
||
|
GraylistThreshold: 0,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
AcceptPXThreshold: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
OpportunisticGraftThreshold: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: -1,
|
||
|
PublishThreshold: -2,
|
||
|
GraylistThreshold: -3,
|
||
|
AcceptPXThreshold: 1,
|
||
|
OpportunisticGraftThreshold: 2}).validate() != nil {
|
||
|
t.Fatal("expected validation success")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: math.Inf(-1),
|
||
|
PublishThreshold: -2,
|
||
|
GraylistThreshold: -3,
|
||
|
AcceptPXThreshold: 1,
|
||
|
OpportunisticGraftThreshold: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: -1,
|
||
|
PublishThreshold: math.Inf(-1),
|
||
|
GraylistThreshold: -3,
|
||
|
AcceptPXThreshold: 1,
|
||
|
OpportunisticGraftThreshold: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: -1,
|
||
|
PublishThreshold: -2,
|
||
|
GraylistThreshold: math.Inf(-1),
|
||
|
AcceptPXThreshold: 1,
|
||
|
OpportunisticGraftThreshold: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: -1,
|
||
|
PublishThreshold: -2,
|
||
|
GraylistThreshold: -3,
|
||
|
AcceptPXThreshold: math.NaN(),
|
||
|
OpportunisticGraftThreshold: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreThresholds{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
GossipThreshold: -1,
|
||
|
PublishThreshold: -2,
|
||
|
GraylistThreshold: -3,
|
||
|
AcceptPXThreshold: 1,
|
||
|
OpportunisticGraftThreshold: math.Inf(0),
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestBitmaskScoreParamsValidation_InvalidParams_AtomicValidation(t *testing.T) {
|
||
|
testBitmaskScoreParamsValidationWithInvalidParameters(t, false)
|
||
|
}
|
||
|
|
||
|
func TestBitmaskScoreParamsValidation_InvalidParams_SkipAtomicValidation(t *testing.T) {
|
||
|
testBitmaskScoreParamsValidationWithInvalidParameters(t, true)
|
||
|
}
|
||
|
|
||
|
func testBitmaskScoreParamsValidationWithInvalidParameters(t *testing.T, skipAtomicValidation bool) {
|
||
|
|
||
|
if skipAtomicValidation {
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: true}).validate() != nil {
|
||
|
t.Fatal("expected validation success")
|
||
|
}
|
||
|
} else {
|
||
|
if (&BitmaskScoreParams{}).validate() == nil {
|
||
|
t.Fatal("expected validation failure")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskWeight: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshWeight: -1,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshWeight: 1,
|
||
|
TimeInMeshQuantum: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshWeight: 1,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
TimeInMeshCap: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
FirstMessageDeliveriesWeight: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
FirstMessageDeliveriesWeight: 1,
|
||
|
FirstMessageDeliveriesDecay: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
FirstMessageDeliveriesWeight: 1,
|
||
|
FirstMessageDeliveriesDecay: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
FirstMessageDeliveriesWeight: 1,
|
||
|
FirstMessageDeliveriesDecay: .5,
|
||
|
FirstMessageDeliveriesCap: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshMessageDeliveriesWeight: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: 2}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: .5,
|
||
|
MeshMessageDeliveriesCap: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: .5,
|
||
|
MeshMessageDeliveriesCap: 5,
|
||
|
MeshMessageDeliveriesThreshold: -3,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: .5,
|
||
|
MeshMessageDeliveriesCap: 5,
|
||
|
MeshMessageDeliveriesThreshold: 3,
|
||
|
MeshMessageDeliveriesWindow: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: .5,
|
||
|
MeshMessageDeliveriesCap: 5,
|
||
|
MeshMessageDeliveriesThreshold: 3,
|
||
|
MeshMessageDeliveriesWindow: time.Millisecond,
|
||
|
MeshMessageDeliveriesActivation: time.Millisecond}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshFailurePenaltyWeight: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshFailurePenaltyWeight: -1,
|
||
|
MeshFailurePenaltyDecay: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
MeshFailurePenaltyWeight: -1,
|
||
|
MeshFailurePenaltyDecay: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
InvalidMessageDeliveriesWeight: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
InvalidMessageDeliveriesWeight: -1,
|
||
|
InvalidMessageDeliveriesDecay: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
InvalidMessageDeliveriesWeight: -1,
|
||
|
InvalidMessageDeliveriesDecay: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestBitmaskScoreParamsValidation_ValidParams_AtomicValidation(t *testing.T) {
|
||
|
// Don't use these params in production!
|
||
|
if (&BitmaskScoreParams{
|
||
|
SkipAtomicValidation: false,
|
||
|
BitmaskWeight: 1,
|
||
|
TimeInMeshWeight: 0.01,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
TimeInMeshCap: 10,
|
||
|
FirstMessageDeliveriesWeight: 1,
|
||
|
FirstMessageDeliveriesDecay: 0.5,
|
||
|
FirstMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: 0.5,
|
||
|
MeshMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesThreshold: 5,
|
||
|
MeshMessageDeliveriesWindow: time.Millisecond,
|
||
|
MeshMessageDeliveriesActivation: time.Second,
|
||
|
MeshFailurePenaltyWeight: -1,
|
||
|
MeshFailurePenaltyDecay: 0.5,
|
||
|
InvalidMessageDeliveriesWeight: -1,
|
||
|
InvalidMessageDeliveriesDecay: 0.5,
|
||
|
}).validate() != nil {
|
||
|
t.Fatal("expected validation success")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestBitmaskScoreParamsValidation_NonAtomicValidation(t *testing.T) {
|
||
|
// Don't use these params in production!
|
||
|
// In non-atomic (selective) validation mode, the subset of parameters passes
|
||
|
// validation if the individual parameters values pass validation.
|
||
|
p := &BitmaskScoreParams{}
|
||
|
setBitmaskParamAndValidate(t, p, func(params *BitmaskScoreParams) {
|
||
|
params.SkipAtomicValidation = true
|
||
|
})
|
||
|
// including bitmask weight.
|
||
|
setBitmaskParamAndValidate(t, p, func(params *BitmaskScoreParams) {
|
||
|
params.BitmaskWeight = 1
|
||
|
})
|
||
|
// including time in mesh parameters.
|
||
|
setBitmaskParamAndValidate(t, p, func(params *BitmaskScoreParams) {
|
||
|
params.TimeInMeshWeight = 0.01
|
||
|
params.TimeInMeshQuantum = time.Second
|
||
|
params.TimeInMeshCap = 10
|
||
|
})
|
||
|
// including first message delivery parameters.
|
||
|
setBitmaskParamAndValidate(t, p, func(params *BitmaskScoreParams) {
|
||
|
params.FirstMessageDeliveriesWeight = 1
|
||
|
params.FirstMessageDeliveriesDecay = 0.5
|
||
|
params.FirstMessageDeliveriesCap = 10
|
||
|
})
|
||
|
// including mesh message delivery parameters.
|
||
|
setBitmaskParamAndValidate(t, p, func(params *BitmaskScoreParams) {
|
||
|
params.MeshMessageDeliveriesWeight = -1
|
||
|
params.MeshMessageDeliveriesDecay = 0.5
|
||
|
params.MeshMessageDeliveriesCap = 10
|
||
|
params.MeshMessageDeliveriesThreshold = 5
|
||
|
params.MeshMessageDeliveriesWindow = time.Millisecond
|
||
|
params.MeshMessageDeliveriesActivation = time.Second
|
||
|
})
|
||
|
// including mesh failure penalty parameters.
|
||
|
setBitmaskParamAndValidate(t, p, func(params *BitmaskScoreParams) {
|
||
|
params.MeshFailurePenaltyWeight = -1
|
||
|
params.MeshFailurePenaltyDecay = 0.5
|
||
|
})
|
||
|
// including invalid message delivery parameters.
|
||
|
setBitmaskParamAndValidate(t, p, func(params *BitmaskScoreParams) {
|
||
|
params.InvalidMessageDeliveriesWeight = -1
|
||
|
params.InvalidMessageDeliveriesDecay = 0.5
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestPeerScoreParamsValidation_InvalidParams_AtomicValidation(t *testing.T) {
|
||
|
testPeerScoreParamsValidationWithInvalidParams(t, false)
|
||
|
}
|
||
|
|
||
|
func TestPeerScoreParamsValidation_InvalidParams_SkipAtomicValidation(t *testing.T) {
|
||
|
testPeerScoreParamsValidationWithInvalidParams(t, true)
|
||
|
}
|
||
|
|
||
|
func testPeerScoreParamsValidationWithInvalidParams(t *testing.T, skipAtomicValidation bool) {
|
||
|
appScore := func(peer.ID) float64 { return 0 }
|
||
|
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: -1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
if skipAtomicValidation {
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
}).validate() != nil {
|
||
|
t.Fatal("expected validation success")
|
||
|
}
|
||
|
} else {
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: -1}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Millisecond,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: -1,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 2,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
BehaviourPenaltyWeight: 1}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
BehaviourPenaltyWeight: -1,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
BehaviourPenaltyWeight: -1,
|
||
|
BehaviourPenaltyDecay: 2,
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation error")
|
||
|
}
|
||
|
|
||
|
// Checks the bitmask parameters for invalid values such as infinite and
|
||
|
// NaN numbers.
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
Bitmasks: map[string]*BitmaskScoreParams{
|
||
|
"test": {
|
||
|
BitmaskWeight: math.Inf(0),
|
||
|
TimeInMeshWeight: math.NaN(),
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
TimeInMeshCap: 10,
|
||
|
FirstMessageDeliveriesWeight: math.Inf(1),
|
||
|
FirstMessageDeliveriesDecay: 0.5,
|
||
|
FirstMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesWeight: math.Inf(-1),
|
||
|
MeshMessageDeliveriesDecay: math.NaN(),
|
||
|
MeshMessageDeliveriesCap: math.Inf(0),
|
||
|
MeshMessageDeliveriesThreshold: 5,
|
||
|
MeshMessageDeliveriesWindow: time.Millisecond,
|
||
|
MeshMessageDeliveriesActivation: time.Second,
|
||
|
MeshFailurePenaltyWeight: -1,
|
||
|
MeshFailurePenaltyDecay: math.NaN(),
|
||
|
InvalidMessageDeliveriesWeight: math.Inf(0),
|
||
|
InvalidMessageDeliveriesDecay: math.NaN(),
|
||
|
},
|
||
|
},
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation failure")
|
||
|
}
|
||
|
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: math.Inf(0),
|
||
|
IPColocationFactorWeight: math.Inf(-1),
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
BehaviourPenaltyWeight: math.Inf(0),
|
||
|
BehaviourPenaltyDecay: math.NaN(),
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation failure")
|
||
|
}
|
||
|
|
||
|
if (&PeerScoreParams{
|
||
|
SkipAtomicValidation: skipAtomicValidation,
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
Bitmasks: map[string]*BitmaskScoreParams{
|
||
|
"test": {
|
||
|
BitmaskWeight: -1,
|
||
|
TimeInMeshWeight: 0.01,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
TimeInMeshCap: 10,
|
||
|
FirstMessageDeliveriesWeight: 1,
|
||
|
FirstMessageDeliveriesDecay: 0.5,
|
||
|
FirstMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: 0.5,
|
||
|
MeshMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesThreshold: 5,
|
||
|
MeshMessageDeliveriesWindow: time.Millisecond,
|
||
|
MeshMessageDeliveriesActivation: time.Second,
|
||
|
MeshFailurePenaltyWeight: -1,
|
||
|
MeshFailurePenaltyDecay: 0.5,
|
||
|
InvalidMessageDeliveriesWeight: -1,
|
||
|
InvalidMessageDeliveriesDecay: 0.5,
|
||
|
},
|
||
|
},
|
||
|
}).validate() == nil {
|
||
|
t.Fatal("expected validation failure")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestPeerScoreParamsValidation_ValidParams_AtomicValidation(t *testing.T) {
|
||
|
appScore := func(peer.ID) float64 { return 0 }
|
||
|
|
||
|
// don't use these params in production!
|
||
|
if (&PeerScoreParams{
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
BehaviourPenaltyWeight: -1,
|
||
|
BehaviourPenaltyDecay: 0.999,
|
||
|
}).validate() != nil {
|
||
|
t.Fatal("expected validation success")
|
||
|
}
|
||
|
|
||
|
if (&PeerScoreParams{
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
BehaviourPenaltyWeight: -1,
|
||
|
BehaviourPenaltyDecay: 0.999,
|
||
|
}).validate() != nil {
|
||
|
t.Fatal("expected validation success")
|
||
|
}
|
||
|
|
||
|
if (&PeerScoreParams{
|
||
|
BitmaskScoreCap: 1,
|
||
|
AppSpecificScore: appScore,
|
||
|
DecayInterval: time.Second,
|
||
|
DecayToZero: 0.01,
|
||
|
IPColocationFactorWeight: -1,
|
||
|
IPColocationFactorThreshold: 1,
|
||
|
Bitmasks: map[string]*BitmaskScoreParams{
|
||
|
"test": {
|
||
|
BitmaskWeight: 1,
|
||
|
TimeInMeshWeight: 0.01,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
TimeInMeshCap: 10,
|
||
|
FirstMessageDeliveriesWeight: 1,
|
||
|
FirstMessageDeliveriesDecay: 0.5,
|
||
|
FirstMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: 0.5,
|
||
|
MeshMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesThreshold: 5,
|
||
|
MeshMessageDeliveriesWindow: time.Millisecond,
|
||
|
MeshMessageDeliveriesActivation: time.Second,
|
||
|
MeshFailurePenaltyWeight: -1,
|
||
|
MeshFailurePenaltyDecay: 0.5,
|
||
|
InvalidMessageDeliveriesWeight: -1,
|
||
|
InvalidMessageDeliveriesDecay: 0.5,
|
||
|
},
|
||
|
},
|
||
|
}).validate() != nil {
|
||
|
t.Fatal("expected validation success")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestPeerScoreParamsValidation_ValidParams_SkipAtomicValidation(t *testing.T) {
|
||
|
appScore := func(peer.ID) float64 { return 0 }
|
||
|
|
||
|
// don't use these params in production!
|
||
|
p := &PeerScoreParams{}
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.SkipAtomicValidation = true
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.AppSpecificScore = appScore
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.DecayInterval = time.Second
|
||
|
params.DecayToZero = 0.01
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.IPColocationFactorWeight = -1
|
||
|
params.IPColocationFactorThreshold = 1
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.BehaviourPenaltyWeight = -1
|
||
|
params.BehaviourPenaltyDecay = 0.999
|
||
|
})
|
||
|
|
||
|
p = &PeerScoreParams{SkipAtomicValidation: true, AppSpecificScore: appScore}
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.BitmaskScoreCap = 1
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.DecayInterval = time.Second
|
||
|
params.DecayToZero = 0.01
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.IPColocationFactorWeight = -1
|
||
|
params.IPColocationFactorThreshold = 1
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.BehaviourPenaltyWeight = -1
|
||
|
params.BehaviourPenaltyDecay = 0.999
|
||
|
})
|
||
|
setParamAndValidate(t, p, func(params *PeerScoreParams) {
|
||
|
params.Bitmasks = map[string]*BitmaskScoreParams{
|
||
|
"test": {
|
||
|
BitmaskWeight: 1,
|
||
|
TimeInMeshWeight: 0.01,
|
||
|
TimeInMeshQuantum: time.Second,
|
||
|
TimeInMeshCap: 10,
|
||
|
FirstMessageDeliveriesWeight: 1,
|
||
|
FirstMessageDeliveriesDecay: 0.5,
|
||
|
FirstMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesWeight: -1,
|
||
|
MeshMessageDeliveriesDecay: 0.5,
|
||
|
MeshMessageDeliveriesCap: 10,
|
||
|
MeshMessageDeliveriesThreshold: 5,
|
||
|
MeshMessageDeliveriesWindow: time.Millisecond,
|
||
|
MeshMessageDeliveriesActivation: time.Second,
|
||
|
MeshFailurePenaltyWeight: -1,
|
||
|
MeshFailurePenaltyDecay: 0.5,
|
||
|
InvalidMessageDeliveriesWeight: -1,
|
||
|
InvalidMessageDeliveriesDecay: 0.5,
|
||
|
},
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestScoreParameterDecay(t *testing.T) {
|
||
|
decay1hr := ScoreParameterDecay(time.Hour)
|
||
|
if decay1hr != .9987216039048303 {
|
||
|
t.Fatalf("expected .9987216039048303, got %f", decay1hr)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func setParamAndValidate(t *testing.T, params *PeerScoreParams, set func(*PeerScoreParams)) {
|
||
|
set(params)
|
||
|
if err := params.validate(); err != nil {
|
||
|
t.Fatalf("expected validation success, got: %s", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func setBitmaskParamAndValidate(t *testing.T, params *BitmaskScoreParams, set func(bitmask *BitmaskScoreParams)) {
|
||
|
set(params)
|
||
|
if err := params.validate(); err != nil {
|
||
|
t.Fatalf("expected validation success, got: %s", err)
|
||
|
}
|
||
|
}
|