From 8a71873f540fc44ae246d337ae89fb77f041598a Mon Sep 17 00:00:00 2001 From: Gabriel mermelstein Date: Fri, 31 Jan 2025 16:25:39 +0200 Subject: [PATCH] chore: automatically choosing ports --- waku/nwaku.go | 49 +++++++++++++++++++++++ waku/nwaku_test.go | 98 +++++++++++++++++++++++++++++++++------------- 2 files changed, 119 insertions(+), 28 deletions(-) diff --git a/waku/nwaku.go b/waku/nwaku.go index 3c46fb3..dc05c5c 100644 --- a/waku/nwaku.go +++ b/waku/nwaku.go @@ -317,6 +317,7 @@ import ( "encoding/json" "errors" "fmt" + "net" "strconv" "strings" "sync" @@ -1255,3 +1256,51 @@ func getContextTimeoutMilliseconds(ctx context.Context) int { func FormatWakuRelayTopic(clusterId uint16, shard uint16) string { return fmt.Sprintf("/waku/2/rs/%d/%d", clusterId, shard) } + +func GetFreePortIfNeeded(tcpPort int, discV5UDPPort int, logger *zap.Logger) (int, int, error) { + if tcpPort == 0 { + for i := 0; i < 10; i++ { + tcpAddr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort("localhost", "0")) + if err != nil { + logger.Warn("unable to resolve tcp addr: %v", zap.Error(err)) + continue + } + tcpListener, err := net.ListenTCP("tcp", tcpAddr) + if err != nil { + logger.Warn("unable to listen on addr", zap.Stringer("addr", tcpAddr), zap.Error(err)) + continue + } + tcpPort = tcpListener.Addr().(*net.TCPAddr).Port + tcpListener.Close() + break + } + if tcpPort == 0 { + return -1, -1, errors.New("could not obtain a free TCP port") + } + } + + if discV5UDPPort == 0 { + for i := 0; i < 10; i++ { + udpAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort("localhost", "0")) + if err != nil { + logger.Warn("unable to resolve udp addr: %v", zap.Error(err)) + continue + } + + udpListener, err := net.ListenUDP("udp", udpAddr) + if err != nil { + logger.Warn("unable to listen on addr", zap.Stringer("addr", udpAddr), zap.Error(err)) + continue + } + + discV5UDPPort = udpListener.LocalAddr().(*net.UDPAddr).Port + udpListener.Close() + break + } + if discV5UDPPort == 0 { + return -1, -1, errors.New("could not obtain a free UDP port") + } + } + + return tcpPort, discV5UDPPort, nil +} diff --git a/waku/nwaku_test.go b/waku/nwaku_test.go index ba7ed71..39129f9 100644 --- a/waku/nwaku_test.go +++ b/waku/nwaku_test.go @@ -191,6 +191,9 @@ func TestPeerExchange(t *testing.T) { logger, err := zap.NewDevelopment() require.NoError(t, err) + tcpPort, udpPort, err := GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node that will be discovered by PeerExchange discV5NodeWakuConfig := WakuConfig{ Relay: true, @@ -199,8 +202,8 @@ func TestPeerExchange(t *testing.T) { ClusterID: 16, Shards: []uint16{64}, PeerExchange: false, - Discv5UdpPort: 9010, - TcpPort: 60010, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } discV5Node, err := NewWakuNode(&discV5NodeWakuConfig, logger.Named("discV5Node")) @@ -213,6 +216,9 @@ func TestPeerExchange(t *testing.T) { discv5NodeEnr, err := discV5Node.ENR() require.NoError(t, err) + tcpPort, udpPort, err = GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node which serves as PeerExchange server pxServerWakuConfig := WakuConfig{ Relay: true, @@ -221,9 +227,9 @@ func TestPeerExchange(t *testing.T) { ClusterID: 16, Shards: []uint16{64}, PeerExchange: true, - Discv5UdpPort: 9011, + Discv5UdpPort: udpPort, Discv5BootstrapNodes: []string{discv5NodeEnr.String()}, - TcpPort: 60011, + TcpPort: tcpPort, } pxServerNode, err := NewWakuNode(&pxServerWakuConfig, logger.Named("pxServerNode")) @@ -259,6 +265,9 @@ func TestPeerExchange(t *testing.T) { }, options) require.NoError(t, err) + tcpPort, udpPort, err = GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start light node which uses PeerExchange to discover peers pxClientWakuConfig := WakuConfig{ Relay: false, @@ -267,8 +276,8 @@ func TestPeerExchange(t *testing.T) { ClusterID: 16, Shards: []uint16{64}, PeerExchange: true, - Discv5UdpPort: 9012, - TcpPort: 60012, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, PeerExchangeNode: serverNodeMa[0].String(), } @@ -318,14 +327,17 @@ func TestDnsDiscover(t *testing.T) { logger, err := zap.NewDevelopment() require.NoError(t, err) + tcpPort, udpPort, err := GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + nameserver := "8.8.8.8" nodeWakuConfig := WakuConfig{ Relay: true, LogLevel: "DEBUG", ClusterID: 16, Shards: []uint16{64}, - Discv5UdpPort: 9020, - TcpPort: 60020, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } node, err := NewWakuNode(&nodeWakuConfig, logger.Named("node")) @@ -346,6 +358,9 @@ func TestDial(t *testing.T) { logger, err := zap.NewDevelopment() require.NoError(t, err) + tcpPort, udpPort, err := GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node that will initiate the dial dialerNodeWakuConfig := WakuConfig{ Relay: true, @@ -353,14 +368,17 @@ func TestDial(t *testing.T) { Discv5Discovery: false, ClusterID: 16, Shards: []uint16{64}, - Discv5UdpPort: 9030, - TcpPort: 60030, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } dialerNode, err := NewWakuNode(&dialerNodeWakuConfig, logger.Named("dialerNode")) require.NoError(t, err) require.NoError(t, dialerNode.Start()) + tcpPort, udpPort, err = GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node that will receive the dial receiverNodeWakuConfig := WakuConfig{ Relay: true, @@ -368,8 +386,8 @@ func TestDial(t *testing.T) { Discv5Discovery: false, ClusterID: 16, Shards: []uint16{64}, - Discv5UdpPort: 9031, - TcpPort: 60031, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } receiverNode, err := NewWakuNode(&receiverNodeWakuConfig, logger.Named("receiverNode")) @@ -408,6 +426,9 @@ func TestRelay(t *testing.T) { logger, err := zap.NewDevelopment() require.NoError(t, err) + tcpPort, udpPort, err := GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node that will send the message senderNodeWakuConfig := WakuConfig{ Relay: true, @@ -415,14 +436,17 @@ func TestRelay(t *testing.T) { Discv5Discovery: false, ClusterID: 16, Shards: []uint16{64}, - Discv5UdpPort: 9040, - TcpPort: 60040, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } senderNode, err := NewWakuNode(&senderNodeWakuConfig, logger.Named("senderNode")) require.NoError(t, err) require.NoError(t, senderNode.Start()) + tcpPort, udpPort, err = GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node that will receive the message receiverNodeWakuConfig := WakuConfig{ Relay: true, @@ -430,8 +454,8 @@ func TestRelay(t *testing.T) { Discv5Discovery: false, ClusterID: 16, Shards: []uint16{64}, - Discv5UdpPort: 9041, - TcpPort: 60041, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } receiverNode, err := NewWakuNode(&receiverNodeWakuConfig, logger.Named("receiverNode")) require.NoError(t, err) @@ -488,6 +512,9 @@ func TestTopicHealth(t *testing.T) { clusterId := uint16(16) shardId := uint16(64) + tcpPort, udpPort, err := GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node1 wakuConfig1 := WakuConfig{ Relay: true, @@ -495,14 +522,17 @@ func TestTopicHealth(t *testing.T) { Discv5Discovery: false, ClusterID: clusterId, Shards: []uint16{shardId}, - Discv5UdpPort: 9050, - TcpPort: 60050, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } node1, err := NewWakuNode(&wakuConfig1, logger.Named("node1")) require.NoError(t, err) require.NoError(t, node1.Start()) + tcpPort, udpPort, err = GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node2 wakuConfig2 := WakuConfig{ Relay: true, @@ -510,8 +540,8 @@ func TestTopicHealth(t *testing.T) { Discv5Discovery: false, ClusterID: clusterId, Shards: []uint16{shardId}, - Discv5UdpPort: 9051, - TcpPort: 60051, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } node2, err := NewWakuNode(&wakuConfig2, logger.Named("node2")) require.NoError(t, err) @@ -557,6 +587,9 @@ func TestConnectionChange(t *testing.T) { clusterId := uint16(16) shardId := uint16(64) + tcpPort, udpPort, err := GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node1 wakuConfig1 := WakuConfig{ Relay: true, @@ -564,14 +597,17 @@ func TestConnectionChange(t *testing.T) { Discv5Discovery: false, ClusterID: clusterId, Shards: []uint16{shardId}, - Discv5UdpPort: 9060, - TcpPort: 60060, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } node1, err := NewWakuNode(&wakuConfig1, logger.Named("node1")) require.NoError(t, err) require.NoError(t, node1.Start()) + tcpPort, udpPort, err = GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node2 wakuConfig2 := WakuConfig{ Relay: true, @@ -579,8 +615,8 @@ func TestConnectionChange(t *testing.T) { Discv5Discovery: false, ClusterID: clusterId, Shards: []uint16{shardId}, - Discv5UdpPort: 9061, - TcpPort: 60061, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, } node2, err := NewWakuNode(&wakuConfig2, logger.Named("node2")) require.NoError(t, err) @@ -640,6 +676,9 @@ func TestStore(t *testing.T) { logger, err := zap.NewDevelopment() require.NoError(t, err) + tcpPort, udpPort, err := GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node that will send the message senderNodeWakuConfig := WakuConfig{ Relay: true, @@ -648,8 +687,8 @@ func TestStore(t *testing.T) { Discv5Discovery: false, ClusterID: 16, Shards: []uint16{64}, - Discv5UdpPort: 9070, - TcpPort: 60070, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, LegacyStore: false, } @@ -657,6 +696,9 @@ func TestStore(t *testing.T) { require.NoError(t, err) require.NoError(t, senderNode.Start()) + tcpPort, udpPort, err = GetFreePortIfNeeded(0, 0, logger) + require.NoError(t, err) + // start node that will receive the message receiverNodeWakuConfig := WakuConfig{ Relay: true, @@ -665,8 +707,8 @@ func TestStore(t *testing.T) { Discv5Discovery: false, ClusterID: 16, Shards: []uint16{64}, - Discv5UdpPort: 9071, - TcpPort: 60071, + Discv5UdpPort: udpPort, + TcpPort: tcpPort, LegacyStore: false, } receiverNode, err := NewWakuNode(&receiverNodeWakuConfig, logger.Named("receiverNode"))