github.com/MetalBlockchain/subnet-evm@v0.6.3/peer/peer_tracker_test.go (about)

     1  // (c) 2019-2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package peer
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/MetalBlockchain/metalgo/ids"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestPeerTracker(t *testing.T) {
    14  	require := require.New(t)
    15  	p := NewPeerTracker()
    16  
    17  	// Connect some peers
    18  	numExtraPeers := 10
    19  	numPeers := desiredMinResponsivePeers + numExtraPeers
    20  	peerIDs := make([]ids.NodeID, numPeers)
    21  
    22  	for i := range peerIDs {
    23  		peerIDs[i] = ids.GenerateTestNodeID()
    24  		p.Connected(peerIDs[i], defaultPeerVersion)
    25  	}
    26  
    27  	responsivePeers := make(map[ids.NodeID]bool)
    28  
    29  	// Expect requests to go to new peers until we have desiredMinResponsivePeers responsive peers.
    30  	for i := 0; i < desiredMinResponsivePeers+numExtraPeers/2; i++ {
    31  		peer, ok := p.GetAnyPeer(nil)
    32  		require.True(ok)
    33  		require.NotNil(peer)
    34  
    35  		_, exists := responsivePeers[peer]
    36  		require.Falsef(exists, "expected connecting to a new peer, but got the same peer twice: peer %s iteration %d", peer, i)
    37  		responsivePeers[peer] = true
    38  
    39  		p.TrackPeer(peer) // mark the peer as having a message sent to it
    40  	}
    41  
    42  	// Mark some peers as responsive and others as not responsive
    43  	i := 0
    44  	for peer := range responsivePeers {
    45  		if i < desiredMinResponsivePeers {
    46  			p.TrackBandwidth(peer, 10)
    47  		} else {
    48  			responsivePeers[peer] = false // remember which peers were not responsive
    49  			p.TrackBandwidth(peer, 0)
    50  		}
    51  		i++
    52  	}
    53  
    54  	// Expect requests to go to responsive or new peers, so long as they are available
    55  	numRequests := 50
    56  	for i := 0; i < numRequests; i++ {
    57  		peer, ok := p.GetAnyPeer(nil)
    58  		require.True(ok)
    59  		require.NotNil(peer)
    60  
    61  		responsive, ok := responsivePeers[peer]
    62  		if ok {
    63  			require.Truef(responsive, "expected connecting to a responsive peer, but got a peer that was not responsive: peer %s iteration %d", peer, i)
    64  			p.TrackBandwidth(peer, 10)
    65  		} else {
    66  			responsivePeers[peer] = false // remember that we connected to this peer
    67  			p.TrackPeer(peer)             // mark the peer as having a message sent to it
    68  			p.TrackBandwidth(peer, 0)     // mark the peer as non-responsive
    69  		}
    70  	}
    71  
    72  	// Disconnect from peers that were previously responsive and ones we didn't connect to yet.
    73  	for _, peer := range peerIDs {
    74  		responsive, ok := responsivePeers[peer]
    75  		if ok && responsive || !ok {
    76  			p.Disconnected(peer)
    77  		}
    78  	}
    79  
    80  	// Requests should fall back on non-responsive peers when no other choice is left
    81  	peer, ok := p.GetAnyPeer(nil)
    82  	require.True(ok)
    83  	require.NotNil(peer)
    84  
    85  	responsive, ok := responsivePeers[peer]
    86  	require.True(ok)
    87  	require.Falsef(responsive, "expected connecting to a non-responsive peer, but got a peer that was responsive: peer %s", peer)
    88  }