github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/internal/p2p/peermanager_scoring_test.go (about)

     1  package p2p
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/ari-anchor/sei-tendermint/libs/log"
    10  
    11  	"github.com/stretchr/testify/require"
    12  	dbm "github.com/tendermint/tm-db"
    13  
    14  	"github.com/ari-anchor/sei-tendermint/crypto/ed25519"
    15  	"github.com/ari-anchor/sei-tendermint/types"
    16  )
    17  
    18  func TestPeerScoring(t *testing.T) {
    19  	// coppied from p2p_test shared variables
    20  	selfKey := ed25519.GenPrivKeyFromSecret([]byte{0xf9, 0x1b, 0x08, 0xaa, 0x38, 0xee, 0x34, 0xdd})
    21  	selfID := types.NodeIDFromPubKey(selfKey.PubKey())
    22  
    23  	// create a mock peer manager
    24  	db := dbm.NewMemDB()
    25  	peerManager, err := NewPeerManager(log.NewNopLogger(), selfID, db, PeerManagerOptions{})
    26  	require.NoError(t, err)
    27  
    28  	// create a fake node
    29  	id := types.NodeID(strings.Repeat("a1", 20))
    30  	added, err := peerManager.Add(NodeAddress{NodeID: id, Protocol: "memory"})
    31  	require.NoError(t, err)
    32  	require.True(t, added)
    33  
    34  	ctx, cancel := context.WithCancel(context.Background())
    35  	defer cancel()
    36  
    37  	t.Run("Synchronous", func(t *testing.T) {
    38  		// update the manager and make sure it's correct
    39  		defaultScore := DefaultMutableScore
    40  		require.EqualValues(t, defaultScore, peerManager.Scores()[id])
    41  
    42  		// add a bunch of good status updates and watch things increase.
    43  		for i := 1; i < 10; i++ {
    44  			peerManager.processPeerEvent(ctx, PeerUpdate{
    45  				NodeID: id,
    46  				Status: PeerStatusGood,
    47  			})
    48  			require.EqualValues(t, defaultScore+int64(i), peerManager.Scores()[id])
    49  		}
    50  		// watch the corresponding decreases respond to update
    51  		for i := 1; i < 10; i++ {
    52  			peerManager.processPeerEvent(ctx, PeerUpdate{
    53  				NodeID: id,
    54  				Status: PeerStatusBad,
    55  			})
    56  			require.EqualValues(t, DefaultMutableScore+int64(9)-int64(i), peerManager.Scores()[id])
    57  		}
    58  
    59  		// Dial failure should decrease score
    60  		_ = peerManager.DialFailed(ctx, NodeAddress{NodeID: id, Protocol: "memory"})
    61  		require.EqualValues(t, DefaultMutableScore-1, peerManager.Scores()[id])
    62  
    63  		// Disconnect every 3 times should also decrease score
    64  		for i := 1; i < 7; i++ {
    65  			peerManager.Disconnected(ctx, id)
    66  		}
    67  		require.EqualValues(t, DefaultMutableScore-3, peerManager.Scores()[id])
    68  	})
    69  	t.Run("AsynchronousIncrement", func(t *testing.T) {
    70  		start := peerManager.Scores()[id]
    71  		pu := peerManager.Subscribe(ctx)
    72  		pu.SendUpdate(ctx, PeerUpdate{
    73  			NodeID: id,
    74  			Status: PeerStatusGood,
    75  		})
    76  		require.Eventually(t,
    77  			func() bool { return start+1 == peerManager.Scores()[id] },
    78  			time.Second,
    79  			time.Millisecond,
    80  			"startAt=%d score=%d", start, peerManager.Scores()[id])
    81  	})
    82  	t.Run("AsynchronousDecrement", func(t *testing.T) {
    83  		start := peerManager.Scores()[id]
    84  		pu := peerManager.Subscribe(ctx)
    85  		pu.SendUpdate(ctx, PeerUpdate{
    86  			NodeID: id,
    87  			Status: PeerStatusBad,
    88  		})
    89  		require.Eventually(t,
    90  			func() bool { return start-1 == peerManager.Scores()[id] },
    91  			time.Second,
    92  			time.Millisecond,
    93  			"startAt=%d score=%d", start, peerManager.Scores()[id])
    94  	})
    95  	t.Run("TestNonPersistantPeerUpperBound", func(t *testing.T) {
    96  		start := int64(peerManager.Scores()[id] + 1)
    97  		for i := start; i <= int64(PeerScorePersistent)+start; i++ {
    98  			peerManager.processPeerEvent(ctx, PeerUpdate{
    99  				NodeID: id,
   100  				Status: PeerStatusGood,
   101  			})
   102  
   103  			if i >= int64(PeerScorePersistent) {
   104  				require.EqualValues(t, MaxPeerScoreNotPersistent, peerManager.Scores()[id])
   105  			} else {
   106  				require.EqualValues(t, i, peerManager.Scores()[id])
   107  			}
   108  		}
   109  	})
   110  }