github.com/celestiaorg/celestia-node@v0.15.0-beta.1/nodebuilder/tests/p2p_test.go (about)

     1  //go:build p2p || integration
     2  
     3  package tests
     4  
     5  import (
     6  	"context"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/libp2p/go-libp2p/core/host"
    11  	"github.com/libp2p/go-libp2p/core/network"
    12  	"github.com/libp2p/go-libp2p/core/peer"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/celestiaorg/celestia-node/nodebuilder"
    17  	"github.com/celestiaorg/celestia-node/nodebuilder/node"
    18  	"github.com/celestiaorg/celestia-node/nodebuilder/tests/swamp"
    19  )
    20  
    21  /*
    22  Test-Case: Full/Light Nodes connection to Bridge as a Bootstrapper
    23  Steps:
    24  1. Create a Bridge Node(BN)
    25  2. Start a BN
    26  3. Create full/light nodes with bridge node as bootstrap peer
    27  4. Start full/light nodes
    28  5. Check that nodes are connected to bridge
    29  */
    30  func TestBridgeNodeAsBootstrapper(t *testing.T) {
    31  	ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout)
    32  	t.Cleanup(cancel)
    33  
    34  	sw := swamp.NewSwamp(t)
    35  
    36  	// create and start BN
    37  	bridge := sw.NewBridgeNode()
    38  	err := bridge.Start(ctx)
    39  	require.NoError(t, err)
    40  
    41  	addr := host.InfoFromHost(bridge.Host)
    42  
    43  	full := sw.NewFullNode(nodebuilder.WithBootstrappers([]peer.AddrInfo{*addr}))
    44  	light := sw.NewLightNode(nodebuilder.WithBootstrappers([]peer.AddrInfo{*addr}))
    45  
    46  	for _, nd := range []*nodebuilder.Node{full, light} {
    47  		// start node and ensure that BN is correctly set as bootstrapper
    48  		require.NoError(t, nd.Start(ctx))
    49  		assert.Equal(t, *addr, nd.Bootstrappers[0])
    50  		// ensure that node is actually connected to BN
    51  		client := getAdminClient(ctx, nd, t)
    52  		connectedenss, err := client.P2P.Connectedness(ctx, addr.ID)
    53  		require.NoError(t, err)
    54  		assert.Equal(t, connectedenss, network.Connected)
    55  	}
    56  }
    57  
    58  /*
    59  Test-Case: Connect Full And Light using Bridge node as a bootstrapper
    60  Steps:
    61   1. Create a Bridge Node(BN)
    62   2. Start a BN
    63   3. Create full/light nodes with bridge node as bootstrapped peer
    64   4. Start full/light nodes
    65   5. Ensure that nodes are connected to bridge
    66   6. Wait until light will find full node
    67   7. Check that full and light nodes are connected to each other
    68  */
    69  func TestFullDiscoveryViaBootstrapper(t *testing.T) {
    70  	ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout)
    71  	t.Cleanup(cancel)
    72  
    73  	const defaultTimeInterval = time.Second * 2
    74  
    75  	sw := swamp.NewSwamp(t)
    76  
    77  	// create and start a BN
    78  	cfg := nodebuilder.DefaultConfig(node.Bridge)
    79  	setTimeInterval(cfg, defaultTimeInterval)
    80  	bridge := sw.NewNodeWithConfig(node.Bridge, cfg)
    81  	err := bridge.Start(ctx)
    82  	require.NoError(t, err)
    83  
    84  	// use BN as the bootstrapper
    85  	bootstrapper := host.InfoFromHost(bridge.Host)
    86  
    87  	// create FN with BN as bootstrapper
    88  	cfg = nodebuilder.DefaultConfig(node.Full)
    89  	setTimeInterval(cfg, defaultTimeInterval)
    90  	full := sw.NewNodeWithConfig(
    91  		node.Full,
    92  		cfg,
    93  		nodebuilder.WithBootstrappers([]peer.AddrInfo{*bootstrapper}),
    94  	)
    95  
    96  	// create LN with BN as bootstrapper
    97  	cfg = nodebuilder.DefaultConfig(node.Light)
    98  	setTimeInterval(cfg, defaultTimeInterval)
    99  	light := sw.NewNodeWithConfig(
   100  		node.Light,
   101  		cfg,
   102  		nodebuilder.WithBootstrappers([]peer.AddrInfo{*bootstrapper}),
   103  	)
   104  
   105  	// start FN and LN and ensure they are both connected to BN as a bootstrapper
   106  	nodes := []*nodebuilder.Node{full, light}
   107  	for index := range nodes {
   108  		require.NoError(t, nodes[index].Start(ctx))
   109  		assert.Equal(t, *bootstrapper, nodes[index].Bootstrappers[0])
   110  		// ensure that node is actually connected to BN
   111  		client := getAdminClient(ctx, nodes[index], t)
   112  		connectedness, err := client.P2P.Connectedness(ctx, bootstrapper.ID)
   113  		require.NoError(t, err)
   114  		assert.Equal(t, connectedness, network.Connected)
   115  	}
   116  
   117  	for {
   118  		if ctx.Err() != nil {
   119  			t.Fatal(ctx.Err())
   120  		}
   121  		// LN discovered FN successfully and is now connected
   122  		client := getAdminClient(ctx, light, t)
   123  		connectedness, err := client.P2P.Connectedness(ctx, host.InfoFromHost(full.Host).ID)
   124  		require.NoError(t, err)
   125  		if connectedness == network.Connected {
   126  			break
   127  		}
   128  	}
   129  }
   130  
   131  /*
   132  Test-Case: Full node discovery of disconnected full nodes
   133  Steps:
   134  1. Create a Bridge Node(BN)
   135  2. Start a BN
   136  3. Create 2 FNs with bridge node as bootstrapper peer and start them
   137  4. Check that the FNs discover each other
   138  5. Disconnect the FNs
   139  6. Create one more node with discovery process disabled (however advertisement is still enabled)
   140  7. Check that the FN with discovery disabled is still found by the other two FNs
   141  *NOTE*: this test will take some time because it relies on several cycles of peer discovery
   142  */
   143  func TestRestartNodeDiscovery(t *testing.T) {
   144  	ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout)
   145  	t.Cleanup(cancel)
   146  
   147  	const (
   148  		defaultTimeInterval = time.Second * 2
   149  		numFulls            = 2
   150  	)
   151  
   152  	sw := swamp.NewSwamp(t)
   153  
   154  	// create and start a BN as a bootstrapper
   155  	fullCfg := nodebuilder.DefaultConfig(node.Bridge)
   156  	setTimeInterval(fullCfg, defaultTimeInterval)
   157  	bridge := sw.NewNodeWithConfig(node.Bridge, fullCfg)
   158  	err := bridge.Start(ctx)
   159  	require.NoError(t, err)
   160  
   161  	bridgeAddr := host.InfoFromHost(bridge.Host)
   162  
   163  	fullCfg = nodebuilder.DefaultConfig(node.Full)
   164  	setTimeInterval(fullCfg, defaultTimeInterval)
   165  	nodesConfig := nodebuilder.WithBootstrappers([]peer.AddrInfo{*bridgeAddr})
   166  
   167  	// create two FNs and start them, ensuring they are connected to BN as
   168  	// bootstrapper
   169  	nodes := make([]*nodebuilder.Node, numFulls)
   170  	for index := 0; index < numFulls; index++ {
   171  		nodes[index] = sw.NewNodeWithConfig(node.Full, fullCfg, nodesConfig)
   172  		require.NoError(t, nodes[index].Start(ctx))
   173  		client := getAdminClient(ctx, nodes[index], t)
   174  		connectedness, err := client.P2P.Connectedness(ctx, bridgeAddr.ID)
   175  		require.NoError(t, err)
   176  		assert.Equal(t, connectedness, network.Connected)
   177  	}
   178  
   179  	// ensure FNs are connected to each other
   180  	fullClient1 := getAdminClient(ctx, nodes[0], t)
   181  	fullClient2 := getAdminClient(ctx, nodes[1], t)
   182  
   183  	connectedness, err := fullClient1.P2P.Connectedness(ctx, nodes[1].Host.ID())
   184  	require.NoError(t, err)
   185  	assert.Equal(t, connectedness, network.Connected)
   186  
   187  	// disconnect the FNs
   188  	sw.Disconnect(t, nodes[0], nodes[1])
   189  
   190  	// create and start one more FN with disabled discovery
   191  	disabledDiscoveryFN := sw.NewNodeWithConfig(node.Full, fullCfg, nodesConfig)
   192  	require.NoError(t, err)
   193  
   194  	// ensure that the FN with disabled discovery is discovered by both of the
   195  	// running FNs that have discovery enabled
   196  	connectedness, err = fullClient1.P2P.Connectedness(ctx, disabledDiscoveryFN.Host.ID())
   197  	require.NoError(t, err)
   198  	assert.Equal(t, connectedness, network.Connected)
   199  
   200  	connectedness, err = fullClient2.P2P.Connectedness(ctx, disabledDiscoveryFN.Host.ID())
   201  	require.NoError(t, err)
   202  	assert.Equal(t, connectedness, network.Connected)
   203  }