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

     1  package p2p
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/ethereum/go-ethereum/p2p/discover"
     9  	"github.com/ethereum/go-ethereum/p2p/enr"
    10  	"github.com/prysmaticlabs/go-bitfield"
    11  	mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
    12  	"github.com/prysmaticlabs/prysm/beacon-chain/cache"
    13  	"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
    14  	statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
    15  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    16  	"github.com/prysmaticlabs/prysm/shared/interfaces"
    17  	"github.com/prysmaticlabs/prysm/shared/params"
    18  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    19  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    20  )
    21  
    22  func TestStartDiscV5_DiscoverPeersWithSubnets(t *testing.T) {
    23  	// This test needs to be entirely rewritten and should be done in a follow up PR from #7885.
    24  	t.Skip("This test is now failing after PR 7885 due to false positive")
    25  	port := 2000
    26  	ipAddr, pkey := createAddrAndPrivKey(t)
    27  	genesisTime := time.Now()
    28  	genesisValidatorsRoot := make([]byte, 32)
    29  	s := &Service{
    30  		cfg:                   &Config{UDPPort: uint(port)},
    31  		genesisTime:           genesisTime,
    32  		genesisValidatorsRoot: genesisValidatorsRoot,
    33  	}
    34  	bootListener, err := s.createListener(ipAddr, pkey)
    35  	require.NoError(t, err)
    36  	defer bootListener.Close()
    37  
    38  	bootNode := bootListener.Self()
    39  	// Use shorter period for testing.
    40  	currentPeriod := pollingPeriod
    41  	pollingPeriod = 1 * time.Second
    42  	defer func() {
    43  		pollingPeriod = currentPeriod
    44  	}()
    45  
    46  	var listeners []*discover.UDPv5
    47  	for i := 1; i <= 3; i++ {
    48  		port = 3000 + i
    49  		cfg := &Config{
    50  			BootstrapNodeAddr:   []string{bootNode.String()},
    51  			Discv5BootStrapAddr: []string{bootNode.String()},
    52  			MaxPeers:            30,
    53  			UDPPort:             uint(port),
    54  		}
    55  		ipAddr, pkey := createAddrAndPrivKey(t)
    56  		s = &Service{
    57  			cfg:                   cfg,
    58  			genesisTime:           genesisTime,
    59  			genesisValidatorsRoot: genesisValidatorsRoot,
    60  		}
    61  		listener, err := s.startDiscoveryV5(ipAddr, pkey)
    62  		assert.NoError(t, err, "Could not start discovery for node")
    63  		bitV := bitfield.NewBitvector64()
    64  		bitV.SetBitAt(uint64(i), true)
    65  
    66  		entry := enr.WithEntry(attSubnetEnrKey, &bitV)
    67  		listener.LocalNode().Set(entry)
    68  		listeners = append(listeners, listener)
    69  	}
    70  	defer func() {
    71  		// Close down all peers.
    72  		for _, listener := range listeners {
    73  			listener.Close()
    74  		}
    75  	}()
    76  
    77  	// Make one service on port 4001.
    78  	port = 4001
    79  	cfg := &Config{
    80  		BootstrapNodeAddr:   []string{bootNode.String()},
    81  		Discv5BootStrapAddr: []string{bootNode.String()},
    82  		MaxPeers:            30,
    83  		UDPPort:             uint(port),
    84  	}
    85  	cfg.StateNotifier = &mock.MockStateNotifier{}
    86  	s, err = NewService(context.Background(), cfg)
    87  	require.NoError(t, err)
    88  	exitRoutine := make(chan bool)
    89  	go func() {
    90  		s.Start()
    91  		<-exitRoutine
    92  	}()
    93  	time.Sleep(50 * time.Millisecond)
    94  	// Send in a loop to ensure it is delivered (busy wait for the service to subscribe to the state feed).
    95  	for sent := 0; sent == 0; {
    96  		sent = s.stateNotifier.StateFeed().Send(&feed.Event{
    97  			Type: statefeed.Initialized,
    98  			Data: &statefeed.InitializedData{
    99  				StartTime:             time.Now(),
   100  				GenesisValidatorsRoot: make([]byte, 32),
   101  			},
   102  		})
   103  	}
   104  
   105  	// Wait for the nodes to have their local routing tables to be populated with the other nodes
   106  	time.Sleep(6 * discoveryWaitTime)
   107  
   108  	// look up 3 different subnets
   109  	ctx := context.Background()
   110  	exists, err := s.FindPeersWithSubnet(ctx, "", 1, params.BeaconNetworkConfig().MinimumPeersInSubnet)
   111  	require.NoError(t, err)
   112  	exists2, err := s.FindPeersWithSubnet(ctx, "", 2, params.BeaconNetworkConfig().MinimumPeersInSubnet)
   113  	require.NoError(t, err)
   114  	exists3, err := s.FindPeersWithSubnet(ctx, "", 3, params.BeaconNetworkConfig().MinimumPeersInSubnet)
   115  	require.NoError(t, err)
   116  	if !exists || !exists2 || !exists3 {
   117  		t.Fatal("Peer with subnet doesn't exist")
   118  	}
   119  
   120  	// Update ENR of a peer.
   121  	testService := &Service{
   122  		dv5Listener: listeners[0],
   123  		metaData: interfaces.WrappedMetadataV0(&pb.MetaDataV0{
   124  			Attnets: bitfield.NewBitvector64(),
   125  		}),
   126  	}
   127  	cache.SubnetIDs.AddAttesterSubnetID(0, 10)
   128  	testService.RefreshENR()
   129  	time.Sleep(2 * time.Second)
   130  
   131  	exists, err = s.FindPeersWithSubnet(ctx, "", 2, params.BeaconNetworkConfig().MinimumPeersInSubnet)
   132  	require.NoError(t, err)
   133  
   134  	assert.Equal(t, true, exists, "Peer with subnet doesn't exist")
   135  	assert.NoError(t, s.Stop())
   136  	exitRoutine <- true
   137  }