diff --git a/nodebuilder/tests/p2p_test.go b/nodebuilder/tests/p2p_test.go index 613dface94..8e8b03a696 100644 --- a/nodebuilder/tests/p2p_test.go +++ b/nodebuilder/tests/p2p_test.go @@ -5,7 +5,6 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p/core/event" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" @@ -18,22 +17,22 @@ import ( ) /* -Test-Case: Full/Light Nodes connection to Bridge as a Bootstapper +Test-Case: Full/Light Nodes connection to Bridge as a Bootstrapper Steps: 1. Create a Bridge Node(BN) 2. Start a BN -3. Create full/light nodes with bridge node as bootsrapped peer +3. Create full/light nodes with bridge node as bootstrap peer 4. Start full/light nodes 5. Check that nodes are connected to bridge */ -func TestUseBridgeNodeAsBootstraper(t *testing.T) { - sw := swamp.NewSwamp(t) - - bridge := sw.NewBridgeNode() - +func TestBridgeNodeAsBootstrapper(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout) t.Cleanup(cancel) + sw := swamp.NewSwamp(t) + + // create and start BN + bridge := sw.NewBridgeNode() err := bridge.Start(ctx) require.NoError(t, err) @@ -41,10 +40,13 @@ func TestUseBridgeNodeAsBootstraper(t *testing.T) { full := sw.NewFullNode(nodebuilder.WithBootstrappers([]peer.AddrInfo{*addr})) light := sw.NewLightNode(nodebuilder.WithBootstrappers([]peer.AddrInfo{*addr})) + nodes := []*nodebuilder.Node{full, light} for index := range nodes { + // start node and ensure that BN is correctly set as bootstrapper require.NoError(t, nodes[index].Start(ctx)) assert.Equal(t, *addr, nodes[index].Bootstrappers[0]) + // ensure that node is actually connected to BN assert.True(t, nodes[index].Host.Network().Connectedness(addr.ID) == network.Connected) } } @@ -61,19 +63,27 @@ Steps: 8. Check LN is not allowed to dial with FN */ func TestAddPeerToBlackList(t *testing.T) { - sw := swamp.NewSwamp(t) - full := sw.NewFullNode() ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout) t.Cleanup(cancel) - require.NoError(t, full.Start(ctx)) - addr := host.InfoFromHost(full.Host) + sw := swamp.NewSwamp(t) + + // create and start a FN + full := sw.NewFullNode() + err := full.Start(ctx) + require.NoError(t, err) + light := sw.NewLightNode() - require.NoError(t, light.Start(ctx)) - require.NoError(t, light.ConnGater.BlockPeer(addr.ID)) + err = light.Start(ctx) + require.NoError(t, err) - require.True(t, full.ConnGater.InterceptPeerDial(host.InfoFromHost(light.Host).ID)) - require.False(t, light.ConnGater.InterceptPeerDial(addr.ID)) + // LN blocks FN + fullAddr := host.InfoFromHost(full.Host) + require.NoError(t, light.ConnGater.BlockPeer(fullAddr.ID)) + + // assert that FN can dial LN but LN cannot dial FN + assert.True(t, full.ConnGater.InterceptPeerDial(host.InfoFromHost(light.Host).ID)) + assert.False(t, light.ConnGater.InterceptPeerDial(fullAddr.ID)) } /* @@ -86,131 +96,123 @@ Steps: 5. Ensure that nodes are connected to bridge 6. Wait until light will find full node 7. Check that full and light nodes are connected to each other - 8. Stop FN and ensure that it's not connected to LN */ -func TestBootstrapNodesFromBridgeNode(t *testing.T) { +func TestFullDiscoveryViaBootstrapper(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout) + t.Cleanup(cancel) + + const defaultTimeInterval = time.Second * 2 + sw := swamp.NewSwamp(t) + + // create and start a BN cfg := nodebuilder.DefaultConfig(node.Bridge) - const defaultTimeInterval = time.Second * 10 setTimeInterval(cfg, defaultTimeInterval) - bridge := sw.NewNodeWithConfig(node.Bridge, cfg) - - ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout) - t.Cleanup(cancel) - err := bridge.Start(ctx) require.NoError(t, err) - bridgeAddr := host.InfoFromHost(bridge.Host) + // use BN as the bootstrapper + bootstrapper := host.InfoFromHost(bridge.Host) + + // create FN with BN as bootstrapper cfg = nodebuilder.DefaultConfig(node.Full) setTimeInterval(cfg, defaultTimeInterval) full := sw.NewNodeWithConfig( node.Full, cfg, - nodebuilder.WithBootstrappers([]peer.AddrInfo{*bridgeAddr}), + nodebuilder.WithBootstrappers([]peer.AddrInfo{*bootstrapper}), ) + // create LN with BN as bootstrapper cfg = nodebuilder.DefaultConfig(node.Light) setTimeInterval(cfg, defaultTimeInterval) - cfg.P2P.PeerExchange = true light := sw.NewNodeWithConfig( node.Light, cfg, - nodebuilder.WithBootstrappers([]peer.AddrInfo{*bridgeAddr}), + nodebuilder.WithBootstrappers([]peer.AddrInfo{*bootstrapper}), ) + + // start FN and LN and ensure they are both connected to BN as a bootstrapper nodes := []*nodebuilder.Node{full, light} - ch := make(chan struct{}) - sub, err := light.Host.EventBus().Subscribe(&event.EvtPeerConnectednessChanged{}) - require.NoError(t, err) - defer sub.Close() for index := range nodes { require.NoError(t, nodes[index].Start(ctx)) - assert.Equal(t, *bridgeAddr, nodes[index].Bootstrappers[0]) - assert.True(t, nodes[index].Host.Network().Connectedness(bridgeAddr.ID) == network.Connected) + assert.Equal(t, *bootstrapper, nodes[index].Bootstrappers[0]) + assert.True(t, nodes[index].Host.Network().Connectedness(bootstrapper.ID) == network.Connected) } - addrFull := host.InfoFromHost(full.Host) - go func() { - for e := range sub.Out() { - connStatus := e.(event.EvtPeerConnectednessChanged) - if connStatus.Peer == full.Host.ID() && connStatus.Connectedness == network.NotConnected { - ch <- struct{}{} - } + + for { + if ctx.Err() != nil { + t.Fatal(ctx.Err()) + } + if light.Host.Network().Connectedness(host.InfoFromHost(full.Host).ID) == network.Connected { + // LN discovered FN successfully and is now connected + break } - }() - - // ensure that the light node is connected to the full node - assert.True(t, light.Host.Network().Connectedness(addrFull.ID) == network.Connected) - - sw.Disconnect(t, light, full) - require.NoError(t, full.Stop(ctx)) - select { - case <-ctx.Done(): - t.Fatal("peer was not disconnected") - case <-ch: - assert.True(t, light.Host.Network().Connectedness(addrFull.ID) == network.NotConnected) } } /* -Test-Case: Restart full node discovery after one node is disconnected +Test-Case: Full node discovery of disconnected full nodes Steps: 1. Create a Bridge Node(BN) 2. Start a BN 3. Create 2 full nodes with bridge node as bootstrapper peer and start them 4. Check that nodes are connected to each other -5. Create one more node with disabled discovery -6. Disconnect FNs from each other -7. Check that the last FN is connected to one of the nodes +5. Disconnect the FNs +6. Create one more node with disabled discovery +7. Check that the FN with discovery disabled is still found by the other two FNs *NOTE*: this test will take some time because it relies on several cycles of peer discovery */ func TestRestartNodeDiscovery(t *testing.T) { - sw := swamp.NewSwamp(t) - cfg := nodebuilder.DefaultConfig(node.Bridge) - const defaultTimeInterval = time.Second * 2 - const fullNodes = 2 - - setTimeInterval(cfg, defaultTimeInterval) - cfg.Share.Discovery.PeersLimit = fullNodes - bridge := sw.NewNodeWithConfig(node.Bridge, cfg) - ctx, cancel := context.WithTimeout(context.Background(), swamp.DefaultTestTimeout) t.Cleanup(cancel) + const ( + defaultTimeInterval = time.Second * 2 + numFulls = 2 + ) + + sw := swamp.NewSwamp(t) + + // create and start a BN as a bootstrapper + fullCfg := nodebuilder.DefaultConfig(node.Bridge) + setTimeInterval(fullCfg, defaultTimeInterval) + bridge := sw.NewNodeWithConfig(node.Bridge, fullCfg) err := bridge.Start(ctx) require.NoError(t, err) + bridgeAddr := host.InfoFromHost(bridge.Host) - nodes := make([]*nodebuilder.Node, fullNodes) - cfg = nodebuilder.DefaultConfig(node.Full) - setTimeInterval(cfg, defaultTimeInterval) - cfg.Share.Discovery.PeersLimit = fullNodes + fullCfg = nodebuilder.DefaultConfig(node.Full) + setTimeInterval(fullCfg, defaultTimeInterval) nodesConfig := nodebuilder.WithBootstrappers([]peer.AddrInfo{*bridgeAddr}) - for index := 0; index < fullNodes; index++ { - nodes[index] = sw.NewNodeWithConfig(node.Full, cfg, nodesConfig) - } - for index := 0; index < fullNodes; index++ { + // create two FNs and start them, ensuring they are connected to BN as + // bootstrapper + nodes := make([]*nodebuilder.Node, numFulls) + for index := 0; index < numFulls; index++ { + nodes[index] = sw.NewNodeWithConfig(node.Full, fullCfg, nodesConfig) require.NoError(t, nodes[index].Start(ctx)) assert.True(t, nodes[index].Host.Network().Connectedness(bridgeAddr.ID) == network.Connected) } - // ensure full nodes are connected to each other + // ensure FNs are connected to each other require.True(t, nodes[0].Host.Network().Connectedness(nodes[1].Host.ID()) == network.Connected) - // create one more node with disabled discovery - cfg = nodebuilder.DefaultConfig(node.Full) - setTimeInterval(cfg, defaultTimeInterval) - cfg.Share.Discovery.PeersLimit = 0 - node := sw.NewNodeWithConfig(node.Full, cfg, nodesConfig) - connectSub, err := nodes[0].Host.EventBus().Subscribe(&event.EvtPeerConnectednessChanged{}) - require.NoError(t, err) - defer connectSub.Close() + // disconnect the FNs sw.Disconnect(t, nodes[0], nodes[1]) - require.NoError(t, node.Start(ctx)) - // ensure that the last node is connected to one of the nodes - require.True(t, nodes[0].Host.Network().Connectedness(node.Host.ID()) == network.Connected) + // create and start one more FN with disabled discovery + fullCfg.Share.Discovery.PeersLimit = 0 + disabledDiscoveryFN := sw.NewNodeWithConfig(node.Full, fullCfg, nodesConfig) + err = disabledDiscoveryFN.Start(ctx) + require.NoError(t, err) + + // ensure that the FN with disabled discovery is discovered by both of the + // running FNs that have discovery enabled + require.True(t, nodes[0].Host.Network().Connectedness(disabledDiscoveryFN.Host.ID()) == network.Connected) + require.True(t, nodes[1].Host.Network().Connectedness(disabledDiscoveryFN.Host.ID()) == network.Connected) } func setTimeInterval(cfg *nodebuilder.Config, interval time.Duration) {