mirror of
https://github.com/status-im/go-waku.git
synced 2025-02-04 09:55:08 +00:00
feat(c-bindings): expose enrs via dns discovery
This commit is contained in:
parent
2c9df85c51
commit
abcadd1bcf
@ -1045,7 +1045,7 @@ An `error` message otherwise.
|
|||||||
## DNS Discovery
|
## DNS Discovery
|
||||||
|
|
||||||
### `extern char* waku_dns_discovery(char* url, char* nameserver, int timeoutMs)`
|
### `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**
|
**Parameters**
|
||||||
|
|
||||||
@ -1060,16 +1060,21 @@ Returns a list of multiaddress given a url to a DNS discoverable ENR tree
|
|||||||
**Returns**
|
**Returns**
|
||||||
|
|
||||||
A [`JsonResponse`](#jsonresponse-type).
|
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.
|
An `error` message otherwise.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"result": [
|
"result":[
|
||||||
"/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
{
|
||||||
"/ip4/104.154.239.128/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
|
"peerID":"16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
||||||
"/ip4/47.242.210.73/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm"
|
"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"
|
||||||
|
},
|
||||||
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ import (
|
|||||||
mobile "github.com/waku-org/go-waku/mobile"
|
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
|
// The nameserver can optionally be specified to resolve the enrtree url. Otherwise NULL or
|
||||||
// empty to automatically use the default system dns.
|
// empty to automatically use the default system dns.
|
||||||
// If ms is greater than 0, the subscription must happen before the timeout
|
// If ms is greater than 0, the subscription must happen before the timeout
|
||||||
|
@ -8,6 +8,12 @@ import (
|
|||||||
"github.com/waku-org/go-waku/waku/v2/dnsdisc"
|
"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 {
|
func DnsDiscovery(url string, nameserver string, ms int) string {
|
||||||
var ctx context.Context
|
var ctx context.Context
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
@ -29,34 +35,43 @@ func DnsDiscovery(url string, nameserver string, ms int) string {
|
|||||||
return MakeJSONResponse(err)
|
return MakeJSONResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ma []string
|
var response []DnsDiscoveryItem
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
for _, addr := range n.Addresses {
|
item := DnsDiscoveryItem{
|
||||||
ma = append(ma, addr.String())
|
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 {
|
func StartDiscoveryV5() string {
|
||||||
if wakuNode == nil {
|
if wakuState.node == nil {
|
||||||
return MakeJSONResponse(errWakuNodeNotReady)
|
return MakeJSONResponse(errWakuNodeNotReady)
|
||||||
}
|
}
|
||||||
if wakuNode.DiscV5() == nil {
|
if wakuState.node.DiscV5() == nil {
|
||||||
return MakeJSONResponse(errors.New("DiscV5 is not mounted"))
|
return MakeJSONResponse(errors.New("DiscV5 is not mounted"))
|
||||||
}
|
}
|
||||||
err := wakuNode.DiscV5().Start(context.Background())
|
err := wakuState.node.DiscV5().Start(context.Background())
|
||||||
return MakeJSONResponse(err)
|
if err != nil {
|
||||||
|
return MakeJSONResponse(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return MakeJSONResponse(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func StopDiscoveryV5() string {
|
func StopDiscoveryV5() string {
|
||||||
if wakuNode == nil {
|
if wakuState.node == nil {
|
||||||
return MakeJSONResponse(errWakuNodeNotReady)
|
return MakeJSONResponse(errWakuNodeNotReady)
|
||||||
}
|
}
|
||||||
if wakuNode.DiscV5() == nil {
|
if wakuState.node.DiscV5() == nil {
|
||||||
return MakeJSONResponse(errors.New("DiscV5 is not mounted"))
|
return MakeJSONResponse(errors.New("DiscV5 is not mounted"))
|
||||||
}
|
}
|
||||||
wakuNode.DiscV5().Stop()
|
wakuState.node.DiscV5().Stop()
|
||||||
return MakeJSONResponse(nil)
|
return MakeJSONResponse(nil)
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ func (d *DiscoveryV5) iterate(ctx context.Context) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
addresses, err := utils.Multiaddress(iterator.Node())
|
_, addresses, err := utils.Multiaddress(iterator.Node())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.log.Error("extracting multiaddrs from enr", zap.Error(err))
|
d.log.Error("extracting multiaddrs from enr", zap.Error(err))
|
||||||
continue
|
continue
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p/dnsdisc"
|
"github.com/ethereum/go-ethereum/p2p/dnsdisc"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
"github.com/waku-org/go-waku/waku/v2/utils"
|
"github.com/waku-org/go-waku/waku/v2/utils"
|
||||||
|
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
@ -25,6 +26,7 @@ func WithNameserver(nameserver string) DnsDiscoveryOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DiscoveredNode struct {
|
type DiscoveredNode struct {
|
||||||
|
PeerID peer.ID
|
||||||
Addresses []ma.Multiaddr
|
Addresses []ma.Multiaddr
|
||||||
ENR *enode.Node
|
ENR *enode.Node
|
||||||
}
|
}
|
||||||
@ -48,12 +50,16 @@ func RetrieveNodes(ctx context.Context, url string, opts ...DnsDiscoveryOption)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, node := range tree.Nodes() {
|
for _, node := range tree.Nodes() {
|
||||||
m, err := utils.Multiaddress(node)
|
peerID, m, err := utils.Multiaddress(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
d := DiscoveredNode{Addresses: m}
|
d := DiscoveredNode{
|
||||||
|
PeerID: peerID,
|
||||||
|
Addresses: m,
|
||||||
|
}
|
||||||
|
|
||||||
if hasUDP(node) {
|
if hasUDP(node) {
|
||||||
d.ENR = node
|
d.ENR = node
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ func (wakuPX *WakuPeerExchange) iterate(ctx context.Context) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
addresses, err := utils.Multiaddress(iterator.Node())
|
_, addresses, err := utils.Multiaddress(iterator.Node())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
wakuPX.log.Error("extracting multiaddrs from enr", zap.Error(err))
|
wakuPX.log.Error("extracting multiaddrs from enr", zap.Error(err))
|
||||||
continue
|
continue
|
||||||
|
@ -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
|
// 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())
|
pubKey := EcdsaPubKeyToSecp256k1PublicKey(node.Pubkey())
|
||||||
peerID, err := peer.IDFromPublicKey(pubKey)
|
peerID, err := peer.IDFromPublicKey(pubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []multiaddr.Multiaddr
|
var result []multiaddr.Multiaddr
|
||||||
|
|
||||||
addr, err := enodeToMultiAddr(node)
|
addr, err := enodeToMultiAddr(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
result = append(result, addr)
|
result = append(result, addr)
|
||||||
|
|
||||||
var multiaddrRaw []byte
|
var multiaddrRaw []byte
|
||||||
if err := node.Record().Load(enr.WithEntry(MultiaddrENRField, &multiaddrRaw)); err != nil {
|
if err := node.Record().Load(enr.WithEntry(MultiaddrENRField, &multiaddrRaw)); err != nil {
|
||||||
if !enr.IsNotFound(err) {
|
if !enr.IsNotFound(err) {
|
||||||
return nil, err
|
return "", nil, err
|
||||||
} else {
|
} else {
|
||||||
// No multiaddr entry on enr
|
// No multiaddr entry on enr
|
||||||
return result, nil
|
return peerID, result, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(multiaddrRaw) < 2 {
|
if len(multiaddrRaw) < 2 {
|
||||||
// There was no error loading the multiaddr field, but its length is incorrect
|
// 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()))
|
hostInfo, err := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s", peerID.Pretty()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
offset := 0
|
offset := 0
|
||||||
for {
|
for {
|
||||||
maSize := binary.BigEndian.Uint16(multiaddrRaw[offset : offset+2])
|
maSize := binary.BigEndian.Uint16(multiaddrRaw[offset : offset+2])
|
||||||
if len(multiaddrRaw) < offset+2+int(maSize) {
|
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)]
|
maRaw := multiaddrRaw[offset+2 : offset+2+int(maSize)]
|
||||||
addr, err := multiaddr.NewMultiaddrBytes(maRaw)
|
addr, err := multiaddr.NewMultiaddrBytes(maRaw)
|
||||||
if err != nil {
|
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))
|
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
|
// EnodeToPeerInfo extracts the peer ID and multiaddresses defined in an ENR
|
||||||
func EnodeToPeerInfo(node *enode.Node) (*peer.AddrInfo, error) {
|
func EnodeToPeerInfo(node *enode.Node) (*peer.AddrInfo, error) {
|
||||||
addresses, err := Multiaddress(node)
|
_, addresses, err := Multiaddress(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -156,6 +156,6 @@ func TestMultiaddr(t *testing.T) {
|
|||||||
|
|
||||||
_ = localNode.Node() // Should not panic
|
_ = localNode.Node() // Should not panic
|
||||||
|
|
||||||
_, err = Multiaddress(localNode.Node())
|
_, _, err = Multiaddress(localNode.Node())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user