feat(c-bindings): expose enrs via dns discovery

This commit is contained in:
Richard Ramos 2023-02-16 18:10:20 -04:00 committed by RichΛrd
parent 2c9df85c51
commit abcadd1bcf
8 changed files with 62 additions and 35 deletions

View File

@ -1045,7 +1045,7 @@ An `error` message otherwise.
## DNS Discovery
### `extern char* waku_dns_discovery(char* url, char* nameserver, int timeoutMs)`
Returns a list of multiaddress given a url to a DNS discoverable ENR tree
Returns a list of multiaddress and enrs given a url to a DNS discoverable ENR tree
**Parameters**
@ -1060,16 +1060,21 @@ Returns a list of multiaddress given a url to a DNS discoverable ENR tree
**Returns**
A [`JsonResponse`](#jsonresponse-type).
If the execution is successful, the `result` field contains an array with multiaddresses.
If the execution is successful, the `result` field contains an array objects describing the multiaddresses, enr and peerID each node found has.
An `error` message otherwise.
```json
{
"result": [
"/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"/ip4/104.154.239.128/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
"/ip4/47.242.210.73/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm"
]
"result":[
{
"peerID":"16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"multiaddrs":[
"/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ"
],
"enr":"enr:-M-4QCtJKX2WDloRYDT4yjeMGKUCRRcMlsNiZP3cnPO0HZn6IdJ035RPCqsQ5NvTyjqHzKnTM6pc2LoKliV4CeV0WrgBgmlkgnY0gmlwhIbRi9KKbXVsdGlhZGRyc7EALzYobm9kZS0wMS5kby1hbXMzLndha3V2Mi50ZXN0LnN0YXR1c2ltLm5ldAYfQN4DiXNlY3AyNTZrMaEDnr03Tuo77930a7sYLikftxnuG3BbC3gCFhA4632ooDaDdGNwgnZfg3VkcIIjKIV3YWt1Mg8"
},
...
}
```

View File

@ -6,7 +6,8 @@ import (
mobile "github.com/waku-org/go-waku/mobile"
)
// Returns a list of multiaddress given a url to a DNS discoverable ENR tree
// Returns a list of objects containing the peerID, enr and multiaddresses for each node found
// given a url to a DNS discoverable ENR tree
// The nameserver can optionally be specified to resolve the enrtree url. Otherwise NULL or
// empty to automatically use the default system dns.
// If ms is greater than 0, the subscription must happen before the timeout

View File

@ -8,6 +8,12 @@ import (
"github.com/waku-org/go-waku/waku/v2/dnsdisc"
)
type DnsDiscoveryItem struct {
PeerID string `json:"peerID,omitempty"`
Addresses []string `json:"multiaddrs,omitempty"`
ENR string `json:"enr,omitempty"`
}
func DnsDiscovery(url string, nameserver string, ms int) string {
var ctx context.Context
var cancel context.CancelFunc
@ -29,34 +35,43 @@ func DnsDiscovery(url string, nameserver string, ms int) string {
return MakeJSONResponse(err)
}
var ma []string
var response []DnsDiscoveryItem
for _, n := range nodes {
for _, addr := range n.Addresses {
ma = append(ma, addr.String())
item := DnsDiscoveryItem{
PeerID: n.PeerID.String(),
}
for _, addr := range n.Addresses {
item.Addresses = append(item.Addresses, addr.String())
}
item.ENR = n.ENR.String()
response = append(response, item)
}
return PrepareJSONResponse(ma, nil)
return PrepareJSONResponse(response, nil)
}
func StartDiscoveryV5() string {
if wakuNode == nil {
if wakuState.node == nil {
return MakeJSONResponse(errWakuNodeNotReady)
}
if wakuNode.DiscV5() == nil {
if wakuState.node.DiscV5() == nil {
return MakeJSONResponse(errors.New("DiscV5 is not mounted"))
}
err := wakuNode.DiscV5().Start(context.Background())
return MakeJSONResponse(err)
err := wakuState.node.DiscV5().Start(context.Background())
if err != nil {
return MakeJSONResponse(err)
}
return MakeJSONResponse(nil)
}
func StopDiscoveryV5() string {
if wakuNode == nil {
if wakuState.node == nil {
return MakeJSONResponse(errWakuNodeNotReady)
}
if wakuNode.DiscV5() == nil {
if wakuState.node.DiscV5() == nil {
return MakeJSONResponse(errors.New("DiscV5 is not mounted"))
}
wakuNode.DiscV5().Stop()
wakuState.node.DiscV5().Stop()
return MakeJSONResponse(nil)
}

View File

@ -288,7 +288,7 @@ func (d *DiscoveryV5) iterate(ctx context.Context) error {
break
}
addresses, err := utils.Multiaddress(iterator.Node())
_, addresses, err := utils.Multiaddress(iterator.Node())
if err != nil {
d.log.Error("extracting multiaddrs from enr", zap.Error(err))
continue

View File

@ -6,6 +6,7 @@ import (
"github.com/ethereum/go-ethereum/p2p/dnsdisc"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/waku-org/go-waku/waku/v2/utils"
ma "github.com/multiformats/go-multiaddr"
@ -25,6 +26,7 @@ func WithNameserver(nameserver string) DnsDiscoveryOption {
}
type DiscoveredNode struct {
PeerID peer.ID
Addresses []ma.Multiaddr
ENR *enode.Node
}
@ -48,12 +50,16 @@ func RetrieveNodes(ctx context.Context, url string, opts ...DnsDiscoveryOption)
}
for _, node := range tree.Nodes() {
m, err := utils.Multiaddress(node)
peerID, m, err := utils.Multiaddress(node)
if err != nil {
return nil, err
}
d := DiscoveredNode{Addresses: m}
d := DiscoveredNode{
PeerID: peerID,
Addresses: m,
}
if hasUDP(node) {
d.ENR = node
}

View File

@ -343,7 +343,7 @@ func (wakuPX *WakuPeerExchange) iterate(ctx context.Context) error {
break
}
addresses, err := utils.Multiaddress(iterator.Node())
_, addresses, err := utils.Multiaddress(iterator.Node())
if err != nil {
wakuPX.log.Error("extracting multiaddrs from enr", zap.Error(err))
continue

View File

@ -56,51 +56,51 @@ func enodeToMultiAddr(node *enode.Node) (multiaddr.Multiaddr, error) {
}
// Multiaddress is used to extract all the multiaddresses that are part of a ENR record
func Multiaddress(node *enode.Node) ([]multiaddr.Multiaddr, error) {
func Multiaddress(node *enode.Node) (peer.ID, []multiaddr.Multiaddr, error) {
pubKey := EcdsaPubKeyToSecp256k1PublicKey(node.Pubkey())
peerID, err := peer.IDFromPublicKey(pubKey)
if err != nil {
return nil, err
return "", nil, err
}
var result []multiaddr.Multiaddr
addr, err := enodeToMultiAddr(node)
if err != nil {
return nil, err
return "", nil, err
}
result = append(result, addr)
var multiaddrRaw []byte
if err := node.Record().Load(enr.WithEntry(MultiaddrENRField, &multiaddrRaw)); err != nil {
if !enr.IsNotFound(err) {
return nil, err
return "", nil, err
} else {
// No multiaddr entry on enr
return result, nil
return peerID, result, nil
}
}
if len(multiaddrRaw) < 2 {
// There was no error loading the multiaddr field, but its length is incorrect
return result, nil
return peerID, result, nil
}
hostInfo, err := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s", peerID.Pretty()))
if err != nil {
return nil, err
return "", nil, err
}
offset := 0
for {
maSize := binary.BigEndian.Uint16(multiaddrRaw[offset : offset+2])
if len(multiaddrRaw) < offset+2+int(maSize) {
return nil, errors.New("invalid multiaddress field length")
return "", nil, errors.New("invalid multiaddress field length")
}
maRaw := multiaddrRaw[offset+2 : offset+2+int(maSize)]
addr, err := multiaddr.NewMultiaddrBytes(maRaw)
if err != nil {
return nil, fmt.Errorf("invalid multiaddress field length")
return "", nil, fmt.Errorf("invalid multiaddress field length")
}
result = append(result, addr.Encapsulate(hostInfo))
@ -111,12 +111,12 @@ func Multiaddress(node *enode.Node) ([]multiaddr.Multiaddr, error) {
}
}
return result, nil
return peerID, result, nil
}
// EnodeToPeerInfo extracts the peer ID and multiaddresses defined in an ENR
func EnodeToPeerInfo(node *enode.Node) (*peer.AddrInfo, error) {
addresses, err := Multiaddress(node)
_, addresses, err := Multiaddress(node)
if err != nil {
return nil, err
}

View File

@ -156,6 +156,6 @@ func TestMultiaddr(t *testing.T) {
_ = localNode.Node() // Should not panic
_, err = Multiaddress(localNode.Node())
_, _, err = Multiaddress(localNode.Node())
require.NoError(t, err)
}