feat: add dns-discovery flags to wakunode and chat2 example (#52)

This commit is contained in:
Richard Ramos 2021-09-30 19:03:19 -04:00 committed by GitHub
parent 9416077adf
commit c8a83f04de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 179 additions and 293 deletions

View File

@ -5,13 +5,13 @@ go 1.15
replace github.com/status-im/go-waku => ../.. replace github.com/status-im/go-waku => ../..
require ( require (
github.com/ethereum/go-ethereum v1.10.1 github.com/ethereum/go-ethereum v1.10.4
github.com/gdamore/tcell/v2 v2.2.0 github.com/gdamore/tcell/v2 v2.2.0
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.2
github.com/ipfs/go-log v1.0.5 github.com/ipfs/go-log v1.0.5
github.com/libp2p/go-libp2p-core v0.8.6 github.com/libp2p/go-libp2p-core v0.8.6
github.com/rivo/tview v0.0.0-20210312174852-ae9464cc3598 github.com/rivo/tview v0.0.0-20210312174852-ae9464cc3598
github.com/status-im/go-waku v0.0.0-20210428201044-3d8aae5b81b9 github.com/status-im/go-waku v0.0.0-20210428201044-3d8aae5b81b9
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
google.golang.org/protobuf v1.26.0 google.golang.org/protobuf v1.26.0
) )

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
"github.com/status-im/go-waku/waku/v2/discovery"
"github.com/status-im/go-waku/waku/v2/node" "github.com/status-im/go-waku/waku/v2/node"
"github.com/status-im/go-waku/waku/v2/protocol/store" "github.com/status-im/go-waku/waku/v2/protocol/store"
) )
@ -42,6 +43,10 @@ func main() {
lightPushNodeFlag := flag.String("lightpushnode", "", "Multiaddr of peer to to request lightpush of published messages") lightPushNodeFlag := flag.String("lightpushnode", "", "Multiaddr of peer to to request lightpush of published messages")
keepAliveFlag := flag.Int64("keep-alive", 300, "interval in seconds for pinging peers to keep the connection alive.") keepAliveFlag := flag.Int64("keep-alive", 300, "interval in seconds for pinging peers to keep the connection alive.")
dnsDiscoveryFlag := flag.Bool("dns-discovery", false, "enable dns discovery")
dnsDiscoveryUrlFlag := flag.String("dns-discovery-url", "", "URL for DNS node list in format 'enrtree://<key>@<fqdn>'")
dnsDiscoveryNameServerFlag := flag.String("dns-discovery-nameserver", "", "DNS name server IP to query (empty to use system default)")
flag.Parse() flag.Parse()
hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprintf("0.0.0.0:%d", *port)) hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprintf("0.0.0.0:%d", *port))
@ -146,6 +151,25 @@ func main() {
} }
enableDiscovery := *dnsDiscoveryFlag
dnsDiscoveryUrl := *dnsDiscoveryUrlFlag
dnsDiscoveryNameServer := *dnsDiscoveryNameServerFlag
if enableDiscovery && dnsDiscoveryUrl != "" {
ui.displayMessage(fmt.Sprintf("attempting DNS discovery with %s", dnsDiscoveryUrl))
multiaddresses, err := discovery.RetrieveNodes(ctx, dnsDiscoveryUrl, discovery.WithNameserver(dnsDiscoveryNameServer))
if err != nil {
ui.displayMessage("DNS discovery error: " + err.Error())
} else {
for _, m := range multiaddresses {
err = wakuNode.DialPeerWithMultiAddress(m)
if err != nil {
ui.displayMessage("error dialing peer: " + err.Error())
}
}
}
}
if len(storenode) == 0 { if len(storenode) == 0 {
ui.displayMessage(fmt.Sprintf("No store node configured. Choosing one at random from %s fleet...", *fleetFlag)) ui.displayMessage(fmt.Sprintf("No store node configured. Choosing one at random from %s fleet...", *fleetFlag))
storenode = getRandomFleetNode(fleetData, *fleetFlag) storenode = getRandomFleetNode(fleetData, *fleetFlag)

View File

@ -14,6 +14,7 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/p2p/enode"
dssql "github.com/ipfs/go-ds-sql" dssql "github.com/ipfs/go-ds-sql"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p"
@ -25,6 +26,7 @@ import (
"github.com/status-im/go-waku/waku/persistence" "github.com/status-im/go-waku/waku/persistence"
"github.com/status-im/go-waku/waku/persistence/sqlite" "github.com/status-im/go-waku/waku/persistence/sqlite"
"github.com/status-im/go-waku/waku/v2/discovery"
"github.com/status-im/go-waku/waku/v2/node" "github.com/status-im/go-waku/waku/v2/node"
"github.com/status-im/go-waku/waku/v2/protocol/relay" "github.com/status-im/go-waku/waku/v2/protocol/relay"
) )
@ -74,6 +76,9 @@ var rootCmd = &cobra.Command{
enableMetrics, _ := cmd.Flags().GetBool("metrics") enableMetrics, _ := cmd.Flags().GetBool("metrics")
metricsAddress, _ := cmd.Flags().GetString("metrics-address") metricsAddress, _ := cmd.Flags().GetString("metrics-address")
metricsPort, _ := cmd.Flags().GetInt("metrics-port") metricsPort, _ := cmd.Flags().GetInt("metrics-port")
enableDnsDiscovery, _ := cmd.Flags().GetBool("dns-discovery")
dnsDiscoveryUrl, _ := cmd.Flags().GetString("dns-discovery-url")
dnsDiscoveryNameServer, _ := cmd.Flags().GetString("dns-discovery-nameserver")
hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprint("0.0.0.0:", port)) hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprint("0.0.0.0:", port))
@ -172,8 +177,9 @@ var rootCmd = &cobra.Command{
} else { } else {
if storenode != "" { if storenode != "" {
_, err = wakuNode.AddStorePeer(storenode) _, err = wakuNode.AddStorePeer(storenode)
checkError(err, "Error adding store peer") if err != nil {
log.Error("error adding store peer ", err)
}
} }
} }
@ -181,11 +187,40 @@ var rootCmd = &cobra.Command{
for _, n := range staticnodes { for _, n := range staticnodes {
go func(node string) { go func(node string) {
err = wakuNode.DialPeer(node) err = wakuNode.DialPeer(node)
checkError(err, "Error dialing peer") if err != nil {
log.Error("error dialing peer ", err)
}
}(n) }(n)
} }
} }
if enableDnsDiscovery {
for _, addr := range wakuNode.ListenAddresses() {
ip, _ := addr.ValueForProtocol(multiaddr.P_IP4)
enr := enode.NewV4(&prvKey.PublicKey, net.ParseIP(ip), hostAddr.Port, 0)
log.Info("ENR: ", enr)
}
if dnsDiscoveryUrl != "" {
log.Info("attempting DNS discovery with ", dnsDiscoveryUrl)
multiaddresses, err := discovery.RetrieveNodes(ctx, dnsDiscoveryUrl, discovery.WithNameserver(dnsDiscoveryNameServer))
if err != nil {
log.Warn("dns discovery error ", err)
} else {
log.Info("found dns entries ", multiaddresses)
for _, m := range multiaddresses {
err = wakuNode.DialPeerWithMultiAddress(m)
if err != nil {
log.Error("error dialing peer ", err)
}
}
}
} else {
log.Fatal("DNS discovery URL is required")
}
}
if len(lightpushnodes) > 0 && !lightpush { if len(lightpushnodes) > 0 && !lightpush {
checkError(errors.New("LightPush protocol was not started"), "") checkError(errors.New("LightPush protocol was not started"), "")
} else { } else {
@ -260,6 +295,9 @@ func init() {
rootCmd.Flags().Bool("metrics", false, "Enable the metrics server") rootCmd.Flags().Bool("metrics", false, "Enable the metrics server")
rootCmd.Flags().String("metrics-address", "127.0.0.1", "Listening address of the metrics server") rootCmd.Flags().String("metrics-address", "127.0.0.1", "Listening address of the metrics server")
rootCmd.Flags().Int("metrics-port", 8008, "Listening HTTP port of the metrics server") rootCmd.Flags().Int("metrics-port", 8008, "Listening HTTP port of the metrics server")
rootCmd.Flags().Bool("dns-discovery", false, "enable dns discovery")
rootCmd.Flags().String("dns-discovery-url", "", "URL for DNS node list in format 'enrtree://<key>@<fqdn>'")
rootCmd.Flags().String("dns-discovery-nameserver", "", "DNS nameserver IP to query (empty to use system's default)")
} }
func initConfig() { func initConfig() {

View File

@ -1,6 +1,7 @@
package discovery package discovery
import ( import (
"context"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/p2p/dnsdisc" "github.com/ethereum/go-ethereum/p2p/dnsdisc"
@ -10,12 +11,32 @@ import (
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
) )
type DnsDiscoveryParameters struct {
nameserver string
}
type DnsDiscoveryOption func(*DnsDiscoveryParameters)
// WithMultiaddress is a WakuNodeOption that configures libp2p to listen on a list of multiaddresses
func WithNameserver(nameserver string) DnsDiscoveryOption {
return func(params *DnsDiscoveryParameters) {
params.nameserver = nameserver
}
}
// RetrieveNodes returns a list of multiaddress given a url to a DNS discoverable // RetrieveNodes returns a list of multiaddress given a url to a DNS discoverable
// ENR tree // ENR tree
func RetrieveNodes(url string) ([]ma.Multiaddr, error) { func RetrieveNodes(ctx context.Context, url string, opts ...DnsDiscoveryOption) ([]ma.Multiaddr, error) {
var multiAddrs []ma.Multiaddr var multiAddrs []ma.Multiaddr
client := dnsdisc.NewClient(dnsdisc.Config{}) params := new(DnsDiscoveryParameters)
for _, opt := range opts {
opt(params)
}
client := dnsdisc.NewClient(dnsdisc.Config{
Resolver: GetResolver(ctx, params.nameserver),
})
tree, err := client.SyncTree(url) tree, err := client.SyncTree(url)
if err != nil { if err != nil {
@ -23,19 +44,18 @@ func RetrieveNodes(url string) ([]ma.Multiaddr, error) {
} }
for _, node := range tree.Nodes() { for _, node := range tree.Nodes() {
m, err := enodeToMultiAddr(node) m, err := EnodeToMultiAddr(node)
if err != nil { if err != nil {
return nil, err return nil, err
} }
multiAddrs = append(multiAddrs, m) multiAddrs = append(multiAddrs, m)
} }
return multiAddrs, nil return multiAddrs, nil
} }
func enodeToMultiAddr(node *enode.Node) (ma.Multiaddr, error) { func EnodeToMultiAddr(node *enode.Node) (ma.Multiaddr, error) {
peerID, err := peer.IDFromPublicKey(&ECDSAPublicKey{node.Pubkey()}) peerID, err := peer.IDFromPublicKey(&ECDSAPublicKey{node.Pubkey()})
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -0,0 +1,20 @@
package discovery
import (
"context"
"net"
)
func GetResolver(ctx context.Context, nameserver string) *net.Resolver {
if nameserver == "" {
return net.DefaultResolver
}
return &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{}
return d.DialContext(ctx, network, net.JoinHostPort(nameserver, "53"))
},
}
}

View File

@ -352,11 +352,11 @@ func (w *WakuNode) HasHistory() bool {
return false return false
} }
func (w *WakuNode) ListenAddresses() []string { func (w *WakuNode) ListenAddresses() []ma.Multiaddr {
hostInfo, _ := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", w.host.ID().Pretty())) hostInfo, _ := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", w.host.ID().Pretty()))
var result []string var result []ma.Multiaddr
for _, addr := range w.host.Addrs() { for _, addr := range w.host.Addrs() {
result = append(result, addr.Encapsulate(hostInfo).String()) result = append(result, addr.Encapsulate(hostInfo))
} }
return result return result
} }
@ -690,6 +690,15 @@ func (node *WakuNode) LightPush(ctx context.Context, message *pb.WakuMessage, to
} }
} }
func (w *WakuNode) DialPeerWithMultiAddress(address ma.Multiaddr) error {
info, err := peer.AddrInfoFromP2pAddr(address)
if err != nil {
return err
}
return w.connect(*info)
}
func (w *WakuNode) DialPeer(address string) error { func (w *WakuNode) DialPeer(address string) error {
p, err := ma.NewMultiaddr(address) p, err := ma.NewMultiaddr(address)
if err != nil { if err != nil {
@ -813,7 +822,7 @@ func (w *WakuNode) startKeepAlive(t time.Duration) {
} }
defer w.peersMutex.Unlock() defer w.peersMutex.Unlock()
log.Debug("###PING before fetching result") log.Debug("###PING before fetching result")
pingTicker := time.NewTicker(time.Duration(1) * time.Second) pingTicker := time.NewTicker(time.Duration(1) * time.Second)
isError := false isError := false
select { select {