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

     1  package scorers_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/libp2p/go-libp2p-core/peer"
     8  	types "github.com/prysmaticlabs/eth2-types"
     9  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
    10  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers/peerdata"
    11  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers/scorers"
    12  	p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
    13  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    14  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    15  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    16  )
    17  
    18  func TestScorers_PeerStatus_Score(t *testing.T) {
    19  	ctx, cancel := context.WithCancel(context.Background())
    20  	defer cancel()
    21  
    22  	tests := []struct {
    23  		name   string
    24  		update func(scorer *scorers.PeerStatusScorer)
    25  		check  func(scorer *scorers.PeerStatusScorer)
    26  	}{
    27  		{
    28  			name: "nonexistent peer",
    29  			update: func(scorer *scorers.PeerStatusScorer) {
    30  				scorer.SetHeadSlot(64)
    31  			},
    32  			check: func(scorer *scorers.PeerStatusScorer) {
    33  				assert.Equal(t, 0.0, scorer.Score("peer1"), "Unexpected score")
    34  			},
    35  		},
    36  		{
    37  			name: "existent bad peer",
    38  			update: func(scorer *scorers.PeerStatusScorer) {
    39  				scorer.SetHeadSlot(0)
    40  				scorer.SetPeerStatus("peer1", &pb.Status{
    41  					HeadRoot: make([]byte, 32),
    42  					HeadSlot: 64,
    43  				}, p2ptypes.ErrWrongForkDigestVersion)
    44  			},
    45  			check: func(scorer *scorers.PeerStatusScorer) {
    46  				assert.Equal(t, scorers.BadPeerScore, scorer.Score("peer1"), "Unexpected score")
    47  			},
    48  		},
    49  		{
    50  			name: "existent peer no head slot for the host node is known",
    51  			update: func(scorer *scorers.PeerStatusScorer) {
    52  				scorer.SetHeadSlot(0)
    53  				scorer.SetPeerStatus("peer1", &pb.Status{
    54  					HeadRoot: make([]byte, 32),
    55  					HeadSlot: 64,
    56  				}, nil)
    57  			},
    58  			check: func(scorer *scorers.PeerStatusScorer) {
    59  				assert.Equal(t, 1.0, scorer.Score("peer1"), "Unexpected score")
    60  			},
    61  		},
    62  		{
    63  			name: "existent peer head is before ours",
    64  			update: func(scorer *scorers.PeerStatusScorer) {
    65  				scorer.SetHeadSlot(128)
    66  				scorer.SetPeerStatus("peer1", &pb.Status{
    67  					HeadRoot: make([]byte, 32),
    68  					HeadSlot: 64,
    69  				}, nil)
    70  			},
    71  			check: func(scorer *scorers.PeerStatusScorer) {
    72  				assert.Equal(t, 0.0, scorer.Score("peer1"), "Unexpected score")
    73  			},
    74  		},
    75  		{
    76  			name: "existent peer partial score",
    77  			update: func(scorer *scorers.PeerStatusScorer) {
    78  				headSlot := types.Slot(128)
    79  				scorer.SetHeadSlot(headSlot)
    80  				scorer.SetPeerStatus("peer1", &pb.Status{
    81  					HeadRoot: make([]byte, 32),
    82  					HeadSlot: headSlot + 64,
    83  				}, nil)
    84  				// Set another peer to a higher score.
    85  				scorer.SetPeerStatus("peer2", &pb.Status{
    86  					HeadRoot: make([]byte, 32),
    87  					HeadSlot: headSlot + 128,
    88  				}, nil)
    89  			},
    90  			check: func(scorer *scorers.PeerStatusScorer) {
    91  				headSlot := uint64(128)
    92  				assert.Equal(t, float64(headSlot+64)/float64(headSlot+128), scorer.Score("peer1"), "Unexpected score")
    93  			},
    94  		},
    95  		{
    96  			name: "existent peer full score",
    97  			update: func(scorer *scorers.PeerStatusScorer) {
    98  				headSlot := types.Slot(128)
    99  				scorer.SetHeadSlot(headSlot)
   100  				scorer.SetPeerStatus("peer1", &pb.Status{
   101  					HeadRoot: make([]byte, 32),
   102  					HeadSlot: headSlot + 64,
   103  				}, nil)
   104  			},
   105  			check: func(scorer *scorers.PeerStatusScorer) {
   106  				assert.Equal(t, 1.0, scorer.Score("peer1"), "Unexpected score")
   107  			},
   108  		},
   109  		{
   110  			name: "existent peer no max known slot",
   111  			update: func(scorer *scorers.PeerStatusScorer) {
   112  				scorer.SetHeadSlot(0)
   113  				scorer.SetPeerStatus("peer1", &pb.Status{
   114  					HeadRoot: make([]byte, 32),
   115  					HeadSlot: 0,
   116  				}, nil)
   117  			},
   118  			check: func(scorer *scorers.PeerStatusScorer) {
   119  				assert.Equal(t, 0.0, scorer.Score("peer1"), "Unexpected score")
   120  			},
   121  		},
   122  	}
   123  
   124  	for _, tt := range tests {
   125  		t.Run(tt.name, func(t *testing.T) {
   126  			peerStatuses := peers.NewStatus(ctx, &peers.StatusConfig{
   127  				ScorerParams: &scorers.Config{},
   128  			})
   129  			scorer := peerStatuses.Scorers().PeerStatusScorer()
   130  			if tt.update != nil {
   131  				tt.update(scorer)
   132  			}
   133  			tt.check(scorer)
   134  		})
   135  	}
   136  }
   137  
   138  func TestScorers_PeerStatus_IsBadPeer(t *testing.T) {
   139  	peerStatuses := peers.NewStatus(context.Background(), &peers.StatusConfig{
   140  		ScorerParams: &scorers.Config{},
   141  	})
   142  	pid := peer.ID("peer1")
   143  	assert.Equal(t, false, peerStatuses.Scorers().IsBadPeer(pid))
   144  	assert.Equal(t, false, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid))
   145  
   146  	peerStatuses.Scorers().PeerStatusScorer().SetPeerStatus(pid, &pb.Status{}, p2ptypes.ErrWrongForkDigestVersion)
   147  	assert.Equal(t, true, peerStatuses.Scorers().IsBadPeer(pid))
   148  	assert.Equal(t, true, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid))
   149  }
   150  
   151  func TestScorers_PeerStatus_BadPeers(t *testing.T) {
   152  	peerStatuses := peers.NewStatus(context.Background(), &peers.StatusConfig{
   153  		ScorerParams: &scorers.Config{},
   154  	})
   155  	pid1 := peer.ID("peer1")
   156  	pid2 := peer.ID("peer2")
   157  	pid3 := peer.ID("peer3")
   158  	assert.Equal(t, false, peerStatuses.Scorers().IsBadPeer(pid1))
   159  	assert.Equal(t, false, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid1))
   160  	assert.Equal(t, false, peerStatuses.Scorers().IsBadPeer(pid2))
   161  	assert.Equal(t, false, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid2))
   162  	assert.Equal(t, false, peerStatuses.Scorers().IsBadPeer(pid3))
   163  	assert.Equal(t, false, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid3))
   164  
   165  	peerStatuses.Scorers().PeerStatusScorer().SetPeerStatus(pid1, &pb.Status{}, p2ptypes.ErrWrongForkDigestVersion)
   166  	peerStatuses.Scorers().PeerStatusScorer().SetPeerStatus(pid2, &pb.Status{}, nil)
   167  	peerStatuses.Scorers().PeerStatusScorer().SetPeerStatus(pid3, &pb.Status{}, p2ptypes.ErrWrongForkDigestVersion)
   168  	assert.Equal(t, true, peerStatuses.Scorers().IsBadPeer(pid1))
   169  	assert.Equal(t, true, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid1))
   170  	assert.Equal(t, false, peerStatuses.Scorers().IsBadPeer(pid2))
   171  	assert.Equal(t, false, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid2))
   172  	assert.Equal(t, true, peerStatuses.Scorers().IsBadPeer(pid3))
   173  	assert.Equal(t, true, peerStatuses.Scorers().PeerStatusScorer().IsBadPeer(pid3))
   174  	assert.Equal(t, 2, len(peerStatuses.Scorers().PeerStatusScorer().BadPeers()))
   175  	assert.Equal(t, 2, len(peerStatuses.Scorers().BadPeers()))
   176  }
   177  
   178  func TestScorers_PeerStatus_PeerStatus(t *testing.T) {
   179  	peerStatuses := peers.NewStatus(context.Background(), &peers.StatusConfig{
   180  		ScorerParams: &scorers.Config{},
   181  	})
   182  	status, err := peerStatuses.Scorers().PeerStatusScorer().PeerStatus("peer1")
   183  	require.ErrorContains(t, peerdata.ErrPeerUnknown.Error(), err)
   184  	assert.Equal(t, (*pb.Status)(nil), status)
   185  
   186  	peerStatuses.Scorers().PeerStatusScorer().SetPeerStatus("peer1", &pb.Status{
   187  		HeadSlot: 128,
   188  	}, nil)
   189  	peerStatuses.Scorers().PeerStatusScorer().SetPeerStatus("peer2", &pb.Status{
   190  		HeadSlot: 128,
   191  	}, p2ptypes.ErrInvalidEpoch)
   192  	status, err = peerStatuses.Scorers().PeerStatusScorer().PeerStatus("peer1")
   193  	require.NoError(t, err)
   194  	assert.Equal(t, types.Slot(128), status.HeadSlot)
   195  	assert.Equal(t, nil, peerStatuses.Scorers().ValidationError("peer1"))
   196  	assert.ErrorContains(t, p2ptypes.ErrInvalidEpoch.Error(), peerStatuses.Scorers().ValidationError("peer2"))
   197  	assert.Equal(t, nil, peerStatuses.Scorers().ValidationError("peer3"))
   198  }