diff --git a/waku/node.go b/waku/node.go index b6c26a6e..a392b155 100644 --- a/waku/node.go +++ b/waku/node.go @@ -216,15 +216,6 @@ func Execute(options Options) { addPeers(wakuNode, options.LightPush.Nodes, lightpush.LightPushID_v20beta1) addPeers(wakuNode, options.Filter.Nodes, filter.FilterID_v20beta1) - if options.DNSDiscovery.Enable || options.DiscV5.Enable { - for _, addr := range wakuNode.ListenAddresses() { - ip, _ := addr.ValueForProtocol(multiaddr.P_IP4) - // TODO: use enode.New - enr := enode.NewV4(&prvKey.PublicKey, net.ParseIP(ip), hostAddr.Port, 0) - log.Info("ENR: ", enr) - } - } - if err = wakuNode.Start(); err != nil { log.Fatal(fmt.Errorf("could not start waku node, %w", err)) } diff --git a/waku/v2/dnsdisc/enr_test.go b/waku/v2/dnsdisc/enr_test.go index 28c69274..98551452 100644 --- a/waku/v2/dnsdisc/enr_test.go +++ b/waku/v2/dnsdisc/enr_test.go @@ -4,21 +4,9 @@ import ( "context" "testing" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/status-im/go-waku/waku/v2/utils" "github.com/stretchr/testify/require" ) -func TestEnodeToMultiAddr(t *testing.T) { - enr := "enr:-IS4QAmC_o1PMi5DbR4Bh4oHVyQunZblg4bTaottPtBodAhJZvxVlWW-4rXITPNg4mwJ8cW__D9FBDc9N4mdhyMqB-EBgmlkgnY0gmlwhIbRi9KJc2VjcDI1NmsxoQOevTdO6jvv3fRruxguKR-3Ge4bcFsLeAIWEDjrfaigNoN0Y3CCdl8" - - parsedNode := enode.MustParse(enr) - expectedMultiAddr := "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ" - actualMultiAddr, err := utils.EnodeToMultiAddr(parsedNode) - require.NoError(t, err) - require.Equal(t, expectedMultiAddr, actualMultiAddr.String()) -} - // TestRetrieveNodes uses a live connection, so it could be // flaky, it should though pay for itself and should be fairly stable func TestRetrieveNodes(t *testing.T) { diff --git a/waku/v2/node/wakunode2.go b/waku/v2/node/wakunode2.go index 5cb73b48..182af24d 100644 --- a/waku/v2/node/wakunode2.go +++ b/waku/v2/node/wakunode2.go @@ -175,6 +175,20 @@ func (w *WakuNode) onAddrChange() { } } +func (w *WakuNode) logAddress(addr ma.Multiaddr) { + log.Info("Listening on ", addr) + + // TODO: make this optional depending on DNS Disc being enabled + if w.opts.privKey != nil { + enr, ip, err := utils.GetENRandIP(addr, w.opts.privKey) + if err != nil { + log.Error("could not obtain ENR record from multiaddress", err) + } else { + log.Info(fmt.Sprintf("ENR for IP %s: %s", ip, enr)) + } + } +} + func (w *WakuNode) checkForAddressChanges() { addrs := w.ListenAddresses() first := make(chan struct{}, 1) @@ -185,7 +199,7 @@ func (w *WakuNode) checkForAddressChanges() { return case <-first: for _, addr := range addrs { - log.Info("Listening on ", addr) + w.logAddress(addr) } case <-w.addressChangesSub.Out(): newAddrs := w.ListenAddresses() @@ -205,7 +219,7 @@ func (w *WakuNode) checkForAddressChanges() { log.Warn("Change in host multiaddresses") for _, addr := range newAddrs { w.addrChan <- addr - log.Warn("Listening on ", addr) + w.logAddress(addr) } } } diff --git a/waku/v2/utils/peer.go b/waku/v2/utils/peer.go index 2ecc3dea..0e777561 100644 --- a/waku/v2/utils/peer.go +++ b/waku/v2/utils/peer.go @@ -2,15 +2,19 @@ package utils import ( "context" + "crypto/ecdsa" "errors" "fmt" "math/rand" + "net" + "strconv" "sync" "time" ma "github.com/multiformats/go-multiaddr" "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" logging "github.com/ipfs/go-log" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" @@ -134,3 +138,38 @@ func EnodeToPeerInfo(node *enode.Node) (*peer.AddrInfo, error) { return peer.AddrInfoFromP2pAddr(address) } + +func GetENRandIP(addr ma.Multiaddr, privK *ecdsa.PrivateKey) (*enode.Node, *net.TCPAddr, error) { + ip, err := addr.ValueForProtocol(ma.P_IP4) + if err != nil { + return nil, nil, err + } + + portStr, err := addr.ValueForProtocol(ma.P_TCP) + if err != nil { + return nil, nil, err + } + + port, err := strconv.Atoi(portStr) + if err != nil { + return nil, nil, err + } + + tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port)) + if err != nil { + return nil, nil, err + } + + r := &enr.Record{} + r.Set(enr.TCP(port)) + r.Set(enr.IP(net.ParseIP(ip))) + + err = enode.SignV4(r, privK) + if err != nil { + return nil, nil, err + } + + node, err := enode.New(enode.ValidSchemes, r) + + return node, tcpAddr, err +} diff --git a/waku/v2/utils/peer_test.go b/waku/v2/utils/peer_test.go index f32ae92b..db0f5835 100644 --- a/waku/v2/utils/peer_test.go +++ b/waku/v2/utils/peer_test.go @@ -3,10 +3,18 @@ package utils import ( "context" "crypto/rand" + "fmt" + "net" "testing" "time" + gcrypto "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p/enode" + crypto "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" "github.com/status-im/go-waku/tests" "github.com/stretchr/testify/require" ) @@ -79,3 +87,33 @@ func TestSelectPeerWithLowestRTT(t *testing.T) { _, err = SelectPeerWithLowestRTT(ctx, h1, proto) require.NoError(t, err) } + +func TestEnodeToMultiAddr(t *testing.T) { + enr := "enr:-IS4QAmC_o1PMi5DbR4Bh4oHVyQunZblg4bTaottPtBodAhJZvxVlWW-4rXITPNg4mwJ8cW__D9FBDc9N4mdhyMqB-EBgmlkgnY0gmlwhIbRi9KJc2VjcDI1NmsxoQOevTdO6jvv3fRruxguKR-3Ge4bcFsLeAIWEDjrfaigNoN0Y3CCdl8" + + parsedNode := enode.MustParse(enr) + expectedMultiAddr := "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ" + actualMultiAddr, err := EnodeToMultiAddr(parsedNode) + require.NoError(t, err) + require.Equal(t, expectedMultiAddr, actualMultiAddr.String()) +} + +func TestGetENRandIP(t *testing.T) { + key, _ := gcrypto.GenerateKey() + privKey := crypto.PrivKey((*crypto.Secp256k1PrivateKey)(key)) + id, _ := peer.IDFromPublicKey(privKey.GetPublic()) + + hostAddr := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 9999} + hostMultiAddr, _ := manet.FromNetAddr(hostAddr) + hostInfo, _ := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", id.Pretty())) + ogMultiaddress := hostMultiAddr.Encapsulate(hostInfo) + + node, resTCPAddr, err := GetENRandIP(ogMultiaddress, key) + require.NoError(t, err) + require.Equal(t, hostAddr, resTCPAddr) + + parsedNode := enode.MustParse(node.String()) + resMultiaddress, err := EnodeToMultiAddr(parsedNode) + require.NoError(t, err) + require.Equal(t, ogMultiaddress.String(), resMultiaddress.String()) +}