github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/p2p/peers/scorers/bad_responses_test.go (about)

     1  package scorers_test
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  	"testing"
     7  
     8  	"github.com/libp2p/go-libp2p-core/network"
     9  	"github.com/libp2p/go-libp2p-core/peer"
    10  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
    11  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers/peerdata"
    12  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers/scorers"
    13  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    14  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    15  )
    16  
    17  func TestScorers_BadResponses_Score(t *testing.T) {
    18  	ctx, cancel := context.WithCancel(context.Background())
    19  	defer cancel()
    20  
    21  	peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
    22  		PeerLimit: 30,
    23  		ScorerParams: &scorers.Config{
    24  			BadResponsesScorerConfig: &scorers.BadResponsesScorerConfig{
    25  				Threshold: 4,
    26  			},
    27  		},
    28  	})
    29  	scorer := peerStatuses.Scorers().BadResponsesScorer()
    30  
    31  	assert.Equal(t, 0.0, scorer.Score("peer1"), "Unexpected score for unregistered peer")
    32  	scorer.Increment("peer1")
    33  	assert.Equal(t, -0.25, scorer.Score("peer1"))
    34  	scorer.Increment("peer1")
    35  	assert.Equal(t, -0.5, scorer.Score("peer1"))
    36  	scorer.Increment("peer1")
    37  	scorer.Increment("peer1")
    38  	assert.Equal(t, -1.0, scorer.Score("peer1"))
    39  	assert.Equal(t, true, scorer.IsBadPeer("peer1"))
    40  }
    41  
    42  func TestScorers_BadResponses_ParamsThreshold(t *testing.T) {
    43  	ctx, cancel := context.WithCancel(context.Background())
    44  	defer cancel()
    45  
    46  	maxBadResponses := 2
    47  	peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
    48  		PeerLimit: 30,
    49  		ScorerParams: &scorers.Config{
    50  			BadResponsesScorerConfig: &scorers.BadResponsesScorerConfig{
    51  				Threshold: maxBadResponses,
    52  			},
    53  		},
    54  	})
    55  	scorer := peerStatuses.Scorers()
    56  	assert.Equal(t, maxBadResponses, scorer.BadResponsesScorer().Params().Threshold)
    57  }
    58  
    59  func TestScorers_BadResponses_Count(t *testing.T) {
    60  	ctx, cancel := context.WithCancel(context.Background())
    61  	defer cancel()
    62  
    63  	peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
    64  		PeerLimit:    30,
    65  		ScorerParams: &scorers.Config{},
    66  	})
    67  	scorer := peerStatuses.Scorers()
    68  
    69  	pid := peer.ID("peer1")
    70  	_, err := scorer.BadResponsesScorer().Count(pid)
    71  	assert.ErrorContains(t, peerdata.ErrPeerUnknown.Error(), err)
    72  
    73  	peerStatuses.Add(nil, pid, nil, network.DirUnknown)
    74  	count, err := scorer.BadResponsesScorer().Count(pid)
    75  	assert.NoError(t, err)
    76  	assert.Equal(t, 0, count)
    77  }
    78  
    79  func TestScorers_BadResponses_Decay(t *testing.T) {
    80  	ctx, cancel := context.WithCancel(context.Background())
    81  	defer cancel()
    82  
    83  	maxBadResponses := 2
    84  	peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
    85  		PeerLimit: 30,
    86  		ScorerParams: &scorers.Config{
    87  			BadResponsesScorerConfig: &scorers.BadResponsesScorerConfig{
    88  				Threshold: maxBadResponses,
    89  			},
    90  		},
    91  	})
    92  	scorer := peerStatuses.Scorers().BadResponsesScorer()
    93  
    94  	// Peer 1 has 0 bad responses.
    95  	pid1 := peer.ID("peer1")
    96  	peerStatuses.Add(nil, pid1, nil, network.DirUnknown)
    97  	badResponses, err := scorer.Count(pid1)
    98  	require.NoError(t, err)
    99  	assert.Equal(t, 0, badResponses)
   100  
   101  	// Peer 2 has 1 bad response.
   102  	pid2 := peer.ID("peer2")
   103  	peerStatuses.Add(nil, pid2, nil, network.DirUnknown)
   104  	scorer.Increment(pid2)
   105  	badResponses, err = scorer.Count(pid2)
   106  	require.NoError(t, err)
   107  	assert.Equal(t, 1, badResponses)
   108  
   109  	// Peer 3 has 2 bad response.
   110  	pid3 := peer.ID("peer3")
   111  	peerStatuses.Add(nil, pid3, nil, network.DirUnknown)
   112  	scorer.Increment(pid3)
   113  	scorer.Increment(pid3)
   114  	badResponses, err = scorer.Count(pid3)
   115  	require.NoError(t, err)
   116  	assert.Equal(t, 2, badResponses)
   117  
   118  	// Decay the values
   119  	scorer.Decay()
   120  
   121  	// Ensure the new values are as expected
   122  	badResponses, err = scorer.Count(pid1)
   123  	require.NoError(t, err)
   124  	assert.Equal(t, 0, badResponses, "unexpected bad responses for pid1")
   125  
   126  	badResponses, err = scorer.Count(pid2)
   127  	require.NoError(t, err)
   128  	assert.Equal(t, 0, badResponses, "unexpected bad responses for pid2")
   129  
   130  	badResponses, err = scorer.Count(pid3)
   131  	require.NoError(t, err)
   132  	assert.Equal(t, 1, badResponses, "unexpected bad responses for pid3")
   133  }
   134  
   135  func TestScorers_BadResponses_IsBadPeer(t *testing.T) {
   136  	ctx, cancel := context.WithCancel(context.Background())
   137  	defer cancel()
   138  
   139  	peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
   140  		PeerLimit:    30,
   141  		ScorerParams: &scorers.Config{},
   142  	})
   143  	scorer := peerStatuses.Scorers().BadResponsesScorer()
   144  	pid := peer.ID("peer1")
   145  	assert.Equal(t, false, scorer.IsBadPeer(pid))
   146  
   147  	peerStatuses.Add(nil, pid, nil, network.DirUnknown)
   148  	assert.Equal(t, false, scorer.IsBadPeer(pid))
   149  
   150  	for i := 0; i < scorers.DefaultBadResponsesThreshold; i++ {
   151  		scorer.Increment(pid)
   152  		if i == scorers.DefaultBadResponsesThreshold-1 {
   153  			assert.Equal(t, true, scorer.IsBadPeer(pid), "Unexpected peer status")
   154  		} else {
   155  			assert.Equal(t, false, scorer.IsBadPeer(pid), "Unexpected peer status")
   156  		}
   157  	}
   158  }
   159  
   160  func TestScorers_BadResponses_BadPeers(t *testing.T) {
   161  	ctx, cancel := context.WithCancel(context.Background())
   162  	defer cancel()
   163  
   164  	peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
   165  		PeerLimit:    30,
   166  		ScorerParams: &scorers.Config{},
   167  	})
   168  	scorer := peerStatuses.Scorers().BadResponsesScorer()
   169  	pids := []peer.ID{peer.ID("peer1"), peer.ID("peer2"), peer.ID("peer3"), peer.ID("peer4"), peer.ID("peer5")}
   170  	for i := 0; i < len(pids); i++ {
   171  		peerStatuses.Add(nil, pids[i], nil, network.DirUnknown)
   172  	}
   173  	for i := 0; i < scorers.DefaultBadResponsesThreshold; i++ {
   174  		scorer.Increment(pids[1])
   175  		scorer.Increment(pids[2])
   176  		scorer.Increment(pids[4])
   177  	}
   178  	assert.Equal(t, false, scorer.IsBadPeer(pids[0]), "Invalid peer status")
   179  	assert.Equal(t, true, scorer.IsBadPeer(pids[1]), "Invalid peer status")
   180  	assert.Equal(t, true, scorer.IsBadPeer(pids[2]), "Invalid peer status")
   181  	assert.Equal(t, false, scorer.IsBadPeer(pids[3]), "Invalid peer status")
   182  	assert.Equal(t, true, scorer.IsBadPeer(pids[4]), "Invalid peer status")
   183  	want := []peer.ID{pids[1], pids[2], pids[4]}
   184  	badPeers := scorer.BadPeers()
   185  	sort.Slice(badPeers, func(i, j int) bool {
   186  		return badPeers[i] < badPeers[j]
   187  	})
   188  	assert.DeepEqual(t, want, badPeers, "Unexpected list of bad peers")
   189  }