diff --git a/waku/v2/node/address_test.go b/waku/v2/node/address_test.go index 75e59e4c..172f963d 100644 --- a/waku/v2/node/address_test.go +++ b/waku/v2/node/address_test.go @@ -24,22 +24,25 @@ func TestExternalAddressSelection(t *testing.T) { addrs := []ma.Multiaddr{a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11} w := &WakuNode{} - extAddr, multiaddr, err := w.getENRAddresses(addrs) + extAddr, multiaddr, err := w.getENRAddresses([]ma.Multiaddr{a1, a2, a3, a4, a5, a6, a7, a8}) a5NoP2P, _ := decapsulateP2P(a5) - a8RelayNode, _ := decapsulateCircuitRelayAddr(a8) - require.NoError(t, err) require.Equal(t, extAddr.IP, net.IPv4(192, 168, 0, 106)) require.Equal(t, extAddr.Port, 60000) require.Equal(t, multiaddr[0].String(), a5NoP2P.String()) - require.Equal(t, multiaddr[1].String(), a8RelayNode.String()) - require.Len(t, multiaddr, 5) + require.Len(t, multiaddr, 1) // Should only have 1, without circuit relay + a12, _ := ma.NewMultiaddr("/ip4/188.23.1.8/tcp/30303/p2p/16Uiu2HAmUVVrJo1KMw4QwUANYF7Ws4mfcRqf9xHaaGP87GbMuY2f") // VALID addrs = append(addrs, a12) - extAddr, _, err = w.getENRAddresses(addrs) require.NoError(t, err) require.Equal(t, extAddr.IP, net.IPv4(188, 23, 1, 8)) require.Equal(t, extAddr.Port, 30303) + + a8RelayNode, _ := decapsulateCircuitRelayAddr(a8) + _, multiaddr, err = w.getENRAddresses([]ma.Multiaddr{a1, a8}) + require.NoError(t, err) + require.Len(t, multiaddr, 1) + require.Equal(t, multiaddr[0].String(), a8RelayNode.String()) // Should have included circuit-relay addr } diff --git a/waku/v2/node/localnode.go b/waku/v2/node/localnode.go index 6e21e868..7549d8ae 100644 --- a/waku/v2/node/localnode.go +++ b/waku/v2/node/localnode.go @@ -5,7 +5,6 @@ import ( "crypto/ecdsa" "encoding/binary" "errors" - "fmt" "math" "net" "strconv" @@ -68,19 +67,47 @@ func (w *WakuNode) updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.M } } - // Adding extra multiaddresses - var fieldRaw []byte - for _, addr := range multiaddrs { - maRaw := addr.Bytes() - maSize := make([]byte, 2) - binary.BigEndian.PutUint16(maSize, uint16(len(maRaw))) + // Adding extra multiaddresses. It will to add as many multiaddresses as possible + // without exceeding the enr max size of 300bytes + var addrAggr []ma.Multiaddr + var err error + for i := len(multiaddrs) - 1; i >= 0; i-- { + addrAggr = append(addrAggr, multiaddrs[0:i]...) + err = func() (err error) { + defer func() { + if e := recover(); e != nil { + err = errors.New("could not write enr record") + } + }() - fieldRaw = append(fieldRaw, maSize...) - fieldRaw = append(fieldRaw, maRaw...) + var fieldRaw []byte + for _, addr := range addrAggr { + maRaw := addr.Bytes() + maSize := make([]byte, 2) + binary.BigEndian.PutUint16(maSize, uint16(len(maRaw))) + + fieldRaw = append(fieldRaw, maSize...) + fieldRaw = append(fieldRaw, maRaw...) + } + + if len(fieldRaw) != 0 { + localnode.Set(enr.WithEntry(utils.MultiaddrENRField, fieldRaw)) + } + + // This is to trigger the signing record err due to exceeding 300bytes limit + _ = localnode.Node() + + return nil + }() + + if err == nil { + break + } } - if len(fieldRaw) != 0 { - localnode.Set(enr.WithEntry(utils.MultiaddrENRField, fieldRaw)) + // In case multiaddr could not be populated at all + if err != nil { + localnode.Delete(enr.WithEntry(utils.MultiaddrENRField, struct{}{})) } return nil @@ -163,8 +190,6 @@ func selectMostExternalAddress(addresses []ma.Multiaddr) (*net.TCPAddr, error) { if err != nil { continue } - - fmt.Println(ipAddr, addr) ipAddrs = append(ipAddrs, ipAddr) } @@ -270,13 +295,18 @@ func (w *WakuNode) getENRAddresses(addrs []ma.Multiaddr) (extAddr *net.TCPAddr, return nil, nil, err } - circuitAddrs, err := selectCircuitRelayListenAddresses(addrs) - if err != nil { - return nil, nil, err - } - multiaddr = append(multiaddr, wssAddrs...) - multiaddr = append(multiaddr, circuitAddrs...) + + // to use WSS, you should have a valid certificate with a domain name. + // that means you're reachable. So circuit relay addresses are ignored + if len(wssAddrs) == 0 { + circuitAddrs, err := selectCircuitRelayListenAddresses(addrs) + if err != nil { + return nil, nil, err + } + + multiaddr = append(multiaddr, circuitAddrs...) + } return } diff --git a/waku/v2/utils/enr_test.go b/waku/v2/utils/enr_test.go index 09a87a37..e00a921b 100644 --- a/waku/v2/utils/enr_test.go +++ b/waku/v2/utils/enr_test.go @@ -3,7 +3,6 @@ package utils import ( "encoding/binary" "errors" - "fmt" "math" "net" "testing" @@ -26,7 +25,7 @@ func TestEnodeToMultiAddr(t *testing.T) { require.Equal(t, expectedMultiAddr, actualMultiAddr.String()) } -// TODO: this function is duplicated in localnode.go. Extract to utils +// TODO: this function is duplicated in localnode.go. Remove duplication func updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.Multiaddr, ipAddr *net.TCPAddr, udpPort uint, wakuFlags WakuEnrBitfield, advertiseAddr *net.IP, shouldAutoUpdate bool, log *zap.Logger) error { localnode.SetFallbackUDP(int(udpPort)) localnode.Set(enr.WithEntry(WakuENRField, wakuFlags)) @@ -70,19 +69,45 @@ func updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.Multiaddr, ipAd } } - // Adding extra multiaddresses - var fieldRaw []byte - for _, addr := range multiaddrs { - maRaw := addr.Bytes() - maSize := make([]byte, 2) - binary.BigEndian.PutUint16(maSize, uint16(len(maRaw))) + var addrAggr []ma.Multiaddr + var err error + for i := len(multiaddrs) - 1; i >= 0; i-- { + addrAggr = append(addrAggr, multiaddrs[0:i]...) + err = func() (err error) { + defer func() { + if e := recover(); e != nil { + err = errors.New("could not write enr record") + } + }() - fieldRaw = append(fieldRaw, maSize...) - fieldRaw = append(fieldRaw, maRaw...) + var fieldRaw []byte + for _, addr := range addrAggr { + maRaw := addr.Bytes() + maSize := make([]byte, 2) + binary.BigEndian.PutUint16(maSize, uint16(len(maRaw))) + + fieldRaw = append(fieldRaw, maSize...) + fieldRaw = append(fieldRaw, maRaw...) + } + + if len(fieldRaw) != 0 { + localnode.Set(enr.WithEntry(MultiaddrENRField, fieldRaw)) + } + + // This is to trigger the signing record err due to exceeding 300bytes limit + _ = localnode.Node() + + return nil + }() + + if err == nil { + break + } } - if len(fieldRaw) != 0 { - localnode.Set(enr.WithEntry(MultiaddrENRField, fieldRaw)) + // In case multiaddr could not be populated at all + if err != nil { + localnode.Delete(enr.WithEntry(MultiaddrENRField, struct{}{})) } return nil @@ -106,19 +131,10 @@ func TestMultiaddr(t *testing.T) { db, _ := enode.OpenDB("") localNode := enode.NewLocalNode(db, key) err := updateLocalNode(localNode, multiaddrValues, &net.TCPAddr{IP: net.IPv4(192, 168, 1, 241), Port: 60000}, 50000, wakuFlag, nil, false, Logger()) - if err != nil { - fmt.Println("ERROR WRITING ENR", err) - } else { - fmt.Println("==========================================") - fmt.Println(localNode.Node()) - fmt.Println("==========================================") + require.NoError(t, err) - multiaddresses, err := Multiaddress(localNode.Node()) - require.NoError(t, err) - - for _, a := range multiaddresses { - fmt.Println(a) - } - } + _ = localNode.Node() // Should not panic + _, err = Multiaddress(localNode.Node()) + require.NoError(t, err) }