From 2c6d5cd7bdb29cdce93eb8923c966c048966d7ac Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 19 Dec 2022 19:21:14 -0400 Subject: [PATCH] feat: add discV5 to c-bindings --- library/README.md | 44 ++++++++++++++++++++++++++++++++++++-- library/api.go | 3 +++ library/api_discovery.go | 16 +++++++++++++- mobile/api.go | 46 ++++++++++++++++++++++++++++++++-------- mobile/api_discovery.go | 23 ++++++++++++++++++++ 5 files changed, 120 insertions(+), 12 deletions(-) diff --git a/library/README.md b/library/README.md index 8348712b..2df40ef7 100644 --- a/library/README.md +++ b/library/README.md @@ -271,8 +271,11 @@ interface JsonConfig { nodeKey?: string; keepAliveInterval?: number; relay?: boolean; - minPeersToPublish?: number + minPeersToPublish?: number; filter?: boolean; + discV5?: boolean; + discV5BootstrapNodes?: Array; + discV5UDPPort?: number; } ``` @@ -300,7 +303,12 @@ If a key is `undefined`, or `null`, a default value will be set. Default `0`. - `filter`: Enable filter protocol. Default `false`. - +- `discV5`: Enable DiscoveryV5. + Default `false` +- `discV5BootstrapNodes`: Array of bootstrap nodes ENR +- `discV5UDPPort`: UDP port for DiscoveryV5 + Default `9000` + For example: ```json { @@ -1049,7 +1057,39 @@ An `error` message otherwise. } ``` +## DiscoveryV5 +### `extern char* waku_discv5_start()` +Starts the DiscoveryV5 service to discover and connect to new peers + +**Returns** + +A [`JsonResponse`](#jsonresponse-type). +If the execution is successful, the `result` field is set to `true`. + +For example: + +```json +{ + "result": true +} +``` + +### `extern char* waku_discv5_stop()` +Stops the DiscoveryV5 service + +**Returns** + +A [`JsonResponse`](#jsonresponse-type). +If the execution is successful, the `result` field is set to `true`. + +For example: + +```json +{ + "result": true +} +``` ## Utils ### `extern char* waku_utils_base64_encode(char* data)` diff --git a/library/api.go b/library/api.go index 8dbe9473..4af5a066 100644 --- a/library/api.go +++ b/library/api.go @@ -29,6 +29,9 @@ func main() {} // - relay: Enable WakuRelay. Default `true` // - minPeersToPublish: The minimum number of peers required on a topic to allow broadcasting a message. Default `0` // - filter: Enable Filter. Default `false` +// - discV5: Enable DiscoveryV5. Default `false` +// - discV5BootstrapNodes: Array of bootstrap nodes ENR +// - discV5UDPPort: UDP port for DiscoveryV5 // - logLevel: Set the log level. Default `INFO`. Allowed values "DEBUG", "INFO", "WARN", "ERROR", "DPANIC", "PANIC", "FATAL" // //export waku_new diff --git a/library/api_discovery.go b/library/api_discovery.go index 49c9951d..054db932 100644 --- a/library/api_discovery.go +++ b/library/api_discovery.go @@ -6,7 +6,7 @@ import ( mobile "github.com/waku-org/go-waku/mobile" ) -// RetrieveNodes returns a list of multiaddress given a url to a DNS discoverable ENR tree +// Returns a list of multiaddress 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 @@ -17,3 +17,17 @@ func waku_dns_discovery(url *C.char, nameserver *C.char, ms C.int) *C.char { response := mobile.DnsDiscovery(C.GoString(url), C.GoString(nameserver), int(ms)) return C.CString(response) } + +// Starts DiscoveryV5 service to discover and connect to new peers +//export waku_discv5_start +func waku_discv5_start() *C.char { + response := mobile.StartDiscoveryV5() + return C.CString(response) +} + +// Stops DiscoveryV5 service +//export waku_discv5_stop +func waku_discv5_stop() *C.char { + response := mobile.StopDiscoveryV5() + return C.CString(response) +} diff --git a/mobile/api.go b/mobile/api.go index 23bf733c..2bb5c63e 100644 --- a/mobile/api.go +++ b/mobile/api.go @@ -19,6 +19,9 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/secp256k1" + "github.com/ethereum/go-ethereum/p2p/enode" + pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/discovery" "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" "github.com/waku-org/go-waku/waku/v2/node" @@ -42,15 +45,18 @@ func randomHex(n int) (string, error) { } type wakuConfig struct { - Host *string `json:"host,omitempty"` - Port *int `json:"port,omitempty"` - AdvertiseAddress *string `json:"advertiseAddr,omitempty"` - NodeKey *string `json:"nodeKey,omitempty"` - LogLevel *string `json:"logLevel,omitempty"` - KeepAliveInterval *int `json:"keepAliveInterval,omitempty"` - EnableRelay *bool `json:"relay"` - EnableFilter *bool `json:"filter"` - MinPeersToPublish *int `json:"minPeersToPublish"` + Host *string `json:"host,omitempty"` + Port *int `json:"port,omitempty"` + AdvertiseAddress *string `json:"advertiseAddr,omitempty"` + NodeKey *string `json:"nodeKey,omitempty"` + LogLevel *string `json:"logLevel,omitempty"` + KeepAliveInterval *int `json:"keepAliveInterval,omitempty"` + EnableRelay *bool `json:"relay"` + EnableFilter *bool `json:"filter"` + MinPeersToPublish *int `json:"minPeersToPublish"` + EnableDiscV5 *bool `json:"discV5"` + DiscV5BootstrapNodes []string `json:"discV5BootstrapNodes"` + DiscV5UDPPort *int `json:"discV5UDPPort"` } var defaultHost = "0.0.0.0" @@ -59,6 +65,8 @@ var defaultKeepAliveInterval = 20 var defaultEnableRelay = true var defaultMinPeersToPublish = 0 var defaultEnableFilter = false +var defaultEnableDiscV5 = false +var defaultDiscV5UDPPort = 9000 var defaultLogLevel = "INFO" func getConfig(configJSON string) (wakuConfig, error) { @@ -82,6 +90,10 @@ func getConfig(configJSON string) (wakuConfig, error) { config.EnableFilter = &defaultEnableFilter } + if config.EnableDiscV5 == nil { + config.EnableDiscV5 = &defaultEnableDiscV5 + } + if config.Host == nil { config.Host = &defaultHost } @@ -90,6 +102,10 @@ func getConfig(configJSON string) (wakuConfig, error) { config.Port = &defaultPort } + if config.DiscV5UDPPort == nil { + config.DiscV5UDPPort = &defaultDiscV5UDPPort + } + if config.KeepAliveInterval == nil { config.KeepAliveInterval = &defaultKeepAliveInterval } @@ -151,6 +167,18 @@ func NewNode(configJSON string) string { opts = append(opts, node.WithWakuFilter(false)) } + if *config.EnableDiscV5 { + var bootnodes []*enode.Node + for _, addr := range config.DiscV5BootstrapNodes { + bootnode, err := enode.Parse(enode.ValidSchemes, addr) + if err != nil { + return MakeJSONResponse(err) + } + bootnodes = append(bootnodes, bootnode) + } + opts = append(opts, node.WithDiscoveryV5(*config.DiscV5UDPPort, bootnodes, true, pubsub.WithDiscoveryOpts(discovery.Limit(45), discovery.TTL(time.Duration(20)*time.Second)))) + } + // for go-libp2p loggers lvl, err := logging.LevelFromString(*config.LogLevel) if err != nil { diff --git a/mobile/api_discovery.go b/mobile/api_discovery.go index df659df3..cf602205 100644 --- a/mobile/api_discovery.go +++ b/mobile/api_discovery.go @@ -2,6 +2,7 @@ package gowaku import ( "context" + "errors" "time" "github.com/waku-org/go-waku/waku/v2/dnsdisc" @@ -37,3 +38,25 @@ func DnsDiscovery(url string, nameserver string, ms int) string { return PrepareJSONResponse(ma, nil) } + +func StartDiscoveryV5() string { + if wakuNode == nil { + return MakeJSONResponse(errWakuNodeNotReady) + } + if wakuNode.DiscV5() == nil { + return MakeJSONResponse(errors.New("DiscV5 is not mounted")) + } + err := wakuNode.DiscV5().Start(context.Background()) + return MakeJSONResponse(err) +} + +func StopDiscoveryV5() string { + if wakuNode == nil { + return MakeJSONResponse(errWakuNodeNotReady) + } + if wakuNode.DiscV5() == nil { + return MakeJSONResponse(errors.New("DiscV5 is not mounted")) + } + err := wakuNode.DiscV5().Start(context.Background()) + return MakeJSONResponse(err) +}