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 }