mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-17 23:38:46 +00:00
f0ffd5af03
* introduces peer scorer service * gazelle * Merge branch 'master' into peer-scoring-service * fixes comment * fix build error * linter suggestions * Merge branch 'master' into peer-scoring-service * updates tests * Merge branch 'master' into peer-scoring-service * badresponses scorer tests * gazelle * Merge branch 'master' into peer-scoring-service * Merge branch 'master' into peer-scoring-service * adds scorer_test * gazelle * updates bad response default penalty * more comments * Merge branch 'master' into peer-scoring-service * Merge branch 'master' into peer-scoring-service * Merge branch 'master' into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * introduces peerdatastore into status * makes sure that commong peer data store is used * Merge branch 'peer-scoring-service' of github.com:prysmaticlabs/prysm into peer-scoring-service * linter * gazelle * updates tests * Merge branch 'master' into peer-scoring-service * fixes tests * Nishant's suggestions * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge refs/heads/master into peer-scoring-service * Merge branch 'master' into peer-scoring-service * gofmt * Nishant's suggestion to use isBadPeer * Merge refs/heads/master into peer-scoring-service
138 lines
4.3 KiB
Go
138 lines
4.3 KiB
Go
package peers_test
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/libp2p/go-libp2p-core/network"
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
|
|
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
|
)
|
|
|
|
func TestPeerScorer_NewPeerScorer(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
t.Run("default config", func(t *testing.T) {
|
|
peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
|
|
PeerLimit: 30,
|
|
ScorerParams: &peers.PeerScorerConfig{},
|
|
})
|
|
scorer := peerStatuses.Scorer()
|
|
assert.Equal(t, peers.DefaultBadResponsesThreshold, scorer.Params().BadResponsesThreshold, "Unexpected threshold value")
|
|
assert.Equal(t, peers.DefaultBadResponsesWeight, scorer.Params().BadResponsesWeight, "Unexpected weight value")
|
|
assert.Equal(t, peers.DefaultBadResponsesDecayInterval, scorer.Params().BadResponsesDecayInterval, "Unexpected decay interval value")
|
|
})
|
|
|
|
t.Run("explicit config", func(t *testing.T) {
|
|
peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
|
|
PeerLimit: 30,
|
|
ScorerParams: &peers.PeerScorerConfig{
|
|
BadResponsesThreshold: 2,
|
|
BadResponsesWeight: -1,
|
|
BadResponsesDecayInterval: 1 * time.Minute,
|
|
},
|
|
})
|
|
scorer := peerStatuses.Scorer()
|
|
assert.Equal(t, 2, scorer.Params().BadResponsesThreshold, "Unexpected threshold value")
|
|
assert.Equal(t, -1.0, scorer.Params().BadResponsesWeight, "Unexpected weight value")
|
|
assert.Equal(t, 1*time.Minute, scorer.Params().BadResponsesDecayInterval, "Unexpected decay interval value")
|
|
})
|
|
}
|
|
|
|
func TestPeerScorer_Score(t *testing.T) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer cancel()
|
|
|
|
peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
|
|
PeerLimit: 30,
|
|
ScorerParams: &peers.PeerScorerConfig{
|
|
BadResponsesThreshold: 5,
|
|
BadResponsesWeight: -0.5,
|
|
BadResponsesDecayInterval: 50 * time.Millisecond,
|
|
},
|
|
})
|
|
scorer := peerStatuses.Scorer()
|
|
|
|
sortByScore := func(pids []peer.ID) []peer.ID {
|
|
sort.Slice(pids, func(i, j int) bool {
|
|
scr1, scr2 := scorer.Score(pids[i]), scorer.Score(pids[j])
|
|
if scr1 == scr2 {
|
|
// Sort by peer ID, whenever peers have equal score.
|
|
return pids[i] < pids[j]
|
|
}
|
|
return scr1 > scr2
|
|
})
|
|
return pids
|
|
}
|
|
|
|
pids := []peer.ID{"peer1", "peer2", "peer3"}
|
|
for _, pid := range pids {
|
|
peerStatuses.Add(nil, pid, nil, network.DirUnknown)
|
|
if score := scorer.Score(pid); score < 0 {
|
|
t.Errorf("Unexpected peer score, want: >=0, got: %v", score)
|
|
}
|
|
}
|
|
assert.DeepEqual(t, []peer.ID{"peer1", "peer2", "peer3"}, sortByScore(pids), "Unexpected scores")
|
|
|
|
// Update peers' stats and test the effect on peer order.
|
|
scorer.IncrementBadResponses("peer2")
|
|
assert.DeepEqual(t, []peer.ID{"peer1", "peer3", "peer2"}, sortByScore(pids), "Unexpected scores")
|
|
scorer.IncrementBadResponses("peer1")
|
|
scorer.IncrementBadResponses("peer1")
|
|
assert.DeepEqual(t, []peer.ID{"peer3", "peer2", "peer1"}, sortByScore(pids), "Unexpected scores")
|
|
|
|
// See how decaying affects order of peers.
|
|
scorer.DecayBadResponsesStats()
|
|
assert.DeepEqual(t, []peer.ID{"peer2", "peer3", "peer1"}, sortByScore(pids), "Unexpected scores")
|
|
scorer.DecayBadResponsesStats()
|
|
assert.DeepEqual(t, []peer.ID{"peer1", "peer2", "peer3"}, sortByScore(pids), "Unexpected scores")
|
|
}
|
|
|
|
func TestPeerScorer_loop(t *testing.T) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer cancel()
|
|
|
|
peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
|
|
PeerLimit: 30,
|
|
ScorerParams: &peers.PeerScorerConfig{
|
|
BadResponsesThreshold: 5,
|
|
BadResponsesWeight: -0.5,
|
|
BadResponsesDecayInterval: 50 * time.Millisecond,
|
|
},
|
|
})
|
|
scorer := peerStatuses.Scorer()
|
|
|
|
pid1 := peer.ID("peer1")
|
|
peerStatuses.Add(nil, pid1, nil, network.DirUnknown)
|
|
for i := 0; i < scorer.Params().BadResponsesThreshold+5; i++ {
|
|
scorer.IncrementBadResponses(pid1)
|
|
}
|
|
assert.Equal(t, true, scorer.IsBadPeer(pid1), "Peer should be marked as bad")
|
|
|
|
done := make(chan struct{}, 1)
|
|
go func() {
|
|
defer func() {
|
|
done <- struct{}{}
|
|
}()
|
|
ticker := time.NewTicker(50 * time.Millisecond)
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
if scorer.IsBadPeer(pid1) == false {
|
|
return
|
|
}
|
|
case <-ctx.Done():
|
|
t.Error("Timed out")
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
<-done
|
|
assert.Equal(t, false, scorer.IsBadPeer(pid1), "Peer should not be marked as bad")
|
|
}
|