feat(node): added waku node builder type

This commit is contained in:
Lorenzo Delgado 2023-04-05 14:27:11 +02:00 committed by GitHub
parent e8448dfdbe
commit e931fa5dc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 234 additions and 40 deletions

View File

@ -390,12 +390,17 @@ proc processInput(rfd: AsyncFD, rng: ref HmacDrbgContext) {.async.} =
(extIp, extTcpPort, extUdpPort) = setupNat(conf.nat, clientId,
Port(uint16(conf.tcpPort) + conf.portsShift),
Port(uint16(conf.udpPort) + conf.portsShift))
node = WakuNode.new(nodekey, conf.listenAddress,
Port(uint16(conf.tcpPort) + conf.portsShift),
extIp, extTcpPort,
wsBindPort = Port(uint16(conf.websocketPort) + conf.portsShift),
wsEnabled = conf.websocketSupport,
wssEnabled = conf.websocketSecureSupport)
let node = block:
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodeKey)
builder.withNetworkConfigurationDetails(conf.listenAddress, Port(uint16(conf.tcpPort) + conf.portsShift),
extIp, extTcpPort,
wsBindPort = Port(uint16(conf.websocketPort) + conf.portsShift),
wsEnabled = conf.websocketSupport,
wssEnabled = conf.websocketSecureSupport).tryGet()
builder.build().tryGet()
await node.start()
if conf.rlnRelayEthAccountPrivateKey == "" and conf.rlnRelayCredPath == "":

View File

@ -163,10 +163,11 @@ proc new*(T: type Chat2MatterBridge,
raise newException(ValueError, "Matterbridge client not reachable/healthy")
# Setup Waku v2 node
let
nodev2 = WakuNode.new(nodev2Key,
nodev2BindIp, nodev2BindPort,
nodev2ExtIp, nodev2ExtPort)
let nodev2 = block:
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodev2Key)
builder.withNetworkConfigurationDetails(nodev2BindIp, nodev2BindPort, nodev2ExtIp, nodev2ExtPort).tryGet()
builder.build().tryGet()
return Chat2MatterBridge(mbClient: mbClient,
nodev2: nodev2,

View File

@ -230,11 +230,12 @@ proc new*(T: type WakuBridge,
nodev1.configureWaku(wakuConfig)
# Setup Waku v2 node
let
nodev2 = WakuNode.new(nodev2Key,
nodev2BindIp, nodev2BindPort,
nodev2ExtIp, nodev2ExtPort,
nameResolver = nameResolver)
let nodev2 = block:
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodev2Key)
builder.withNetworkConfigurationDetails(nodev2BindIp, nodev2BindPort, nodev2ExtIp, nodev2ExtPort).tryGet()
builder.withSwitchConfiguration(nameResolver=nameResolver)
builder.build().tryGet()
return WakuBridge(nodev1: nodev1,
nodev2: nodev2,

View File

@ -334,21 +334,24 @@ proc initNode(conf: WakuNodeConf,
))
except CatchableError:
return err("failed to create waku discv5 instance: " & getCurrentExceptionMsg())
try:
node = WakuNode.new(nodekey = nodekey,
netConfig = netConfig,
peerStorage = pStorage,
maxConnections = conf.maxConnections.int,
secureKey = conf.websocketSecureKeyPath,
secureCert = conf.websocketSecureCertPath,
nameResolver = dnsResolver,
sendSignedPeerRecord = conf.relayPeerExchange, # We send our own signed peer record when peer exchange enabled
wakuDiscv5 = wakuDiscv5,
agentString = some(conf.agentString),
peerStoreCapacity = conf.peerStoreCapacity,
rng = rng)
except CatchableError:
return err("failed to create waku node instance: " & getCurrentExceptionMsg())
# Build waku node instance
var builder = WakuNodeBuilder.init()
builder.withRng(rng)
builder.withNodeKey(nodekey)
builder.withNetworkConfiguration(netConfig)
builder.withPeerStorage(pStorage, capacity = conf.peerStoreCapacity)
builder.withSwitchConfiguration(
maxConnections = some(conf.maxConnections.int),
secureKey = some(conf.websocketSecureKeyPath),
secureCert = some(conf.websocketSecureCertPath),
nameResolver = dnsResolver,
sendSignedPeerRecord = conf.relayPeerExchange, # We send our own signed peer record when peer exchange enabled
agentString = some(conf.agentString)
)
builder.withWakuDiscv5(wakuDiscv5.get(nil))
node = ? builder.build().mapErr(proc (err: string): string = "failed to create waku node instance: " & err)
ok(node)

View File

@ -42,9 +42,13 @@ proc setupAndPublish(rng: ref HmacDrbgContext) {.async.} =
let
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[]).get()
ip = ValidIpAddress.init("0.0.0.0")
node = WakuNode.new(nodeKey, ip, Port(wakuPort))
flags = CapabilitiesBitfield.init(lightpush = false, filter = false, store = false, relay = true)
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodeKey)
builder.withNetworkConfigurationDetails(ip, Port(wakuPort)).tryGet()
let node = builder.build().tryGet()
var bootstrapNodeEnr: enr.Record
discard bootstrapNodeEnr.fromURI(bootstrapNode)

View File

@ -36,9 +36,13 @@ proc setupAndSubscribe(rng: ref HmacDrbgContext) {.async.} =
let
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
ip = ValidIpAddress.init("0.0.0.0")
node = WakuNode.new(nodeKey, ip, Port(wakuPort))
flags = CapabilitiesBitfield.init(lightpush = false, filter = false, store = false, relay = true)
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodeKey)
builder.withNetworkConfigurationDetails(ip, Port(wakuPort)).tryGet()
let node = builder.build().tryGet()
var bootstrapNodeEnr: enr.Record
discard bootstrapNodeEnr.fromURI(bootstrapNode)

View File

@ -230,7 +230,11 @@ proc initAndStartNode(conf: NetworkMonitorConf): Result[WakuNode, string] =
let
bindIp = ValidIpAddress.init("0.0.0.0")
extIp = ValidIpAddress.init("127.0.0.1")
node = WakuNode.new(nodeKey, bindIp, nodeTcpPort)
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodeKey)
? builder.withNetworkConfigurationDetails(bindIp, nodeTcpPort)
let node = ? builder.build()
var discv5BootstrapEnrsRes = getBootstrapFromDiscDns(conf)
if not discv5BootstrapEnrsRes.isOk():

View File

@ -44,7 +44,7 @@ proc decodeBytes*(t: typedesc[NodeLocation], value: openArray[byte],
long: $jsonContent["lon"].getFloat(),
isp: jsonContent["isp"].getStr()
))
except CatchableError:
except Exception:
return err("failed to get the location: " & getCurrentExceptionMsg())
proc encodeString*(value: string): RestResult[string] =

View File

@ -111,11 +111,14 @@ proc main(rng: ref HmacDrbgContext): Future[int] {.async.} =
let
peer: RemotePeerInfo = parseRemotePeerInfo(conf.address)
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
node = WakuNode.new(
nodeKey,
ValidIpAddress.init("0.0.0.0"),
Port(conf.nodePort),
nameResolver = resolver)
bindIp = ValidIpAddress.init("0.0.0.0")
nodeTcpPort = Port(conf.nodePort)
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodeKey)
builder.withNetworkConfigurationDetails(bindIp, nodeTcpPort).tryGet()
builder.withSwitchConfiguration(nameResolver=resolver)
let node = builder.build().tryGet()
await node.start()

167
waku/v2/node/builder.nim Normal file
View File

@ -0,0 +1,167 @@
when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}
import
std/options,
stew/results,
stew/shims/net,
chronicles,
libp2p/crypto/crypto,
libp2p/builders,
libp2p/nameresolving/nameresolver
import
../protocol/waku_enr,
../protocol/waku_discv5,
./config,
./peer_manager,
./waku_node
type
WakuNodeBuilder* = object
# General
nodeRng: Option[ref crypto.HmacDrbgContext]
nodeKey: Option[crypto.PrivateKey]
netConfig: Option[NetConfig]
# Peer storage and peer manager
peerStorage: Option[PeerStorage]
peerStorageCapacity: Option[int]
peerManager: Option[PeerManager]
# Libp2p switch
switchMaxConnections: Option[int]
switchNameResolver: Option[NameResolver]
switchAgentString: Option[string]
switchSslSecureKey: Option[string]
switchSslSecureCert: Option[string]
switchSendSignedPeerRecord: Option[bool]
# Waku discv5
wakuDiscv5: Option[WakuDiscoveryV5]
WakuNodeBuilderResult* = Result[void, string]
## Init
proc init*(T: type WakuNodeBuilder): WakuNodeBuilder =
WakuNodeBuilder()
## General
proc withRng*(builder: var WakuNodeBuilder, rng: ref crypto.HmacDrbgContext) =
builder.nodeRng = some(rng)
proc withNodeKey*(builder: var WakuNodeBuilder, nodeKey: crypto.PrivateKey) =
builder.nodeKey = some(nodeKey)
proc withNetworkConfiguration*(builder: var WakuNodeBuilder, config: NetConfig) =
builder.netConfig = some(config)
proc withNetworkConfigurationDetails*(builder: var WakuNodeBuilder,
bindIp: ValidIpAddress,
bindPort: Port,
extIp = none(ValidIpAddress),
extPort = none(Port),
extMultiAddrs = newSeq[MultiAddress](),
wsBindPort: Port = Port(8000),
wsEnabled: bool = false,
wssEnabled: bool = false,
wakuFlags = none(CapabilitiesBitfield),
dns4DomainName = none(string),
discv5UdpPort = none(Port)): WakuNodeBuilderResult {.
deprecated: "use 'builder.withNetworkConfiguration()' instead".} =
let netConfig = ? NetConfig.init(
bindIp = bindIp,
bindPort = bindPort,
extIp = extIp,
extPort = extPort,
extMultiAddrs = extMultiAddrs,
wsBindPort = wsBindPort,
wsEnabled = wsEnabled,
wssEnabled = wssEnabled,
wakuFlags = wakuFlags,
dns4DomainName = dns4DomainName,
discv5UdpPort = discv5UdpPort,
)
builder.withNetworkConfiguration(netConfig)
ok()
## Peer storage and peer manager
proc withPeerStorage*(builder: var WakuNodeBuilder, peerStorage: PeerStorage, capacity = none(int)) =
if not peerStorage.isNil():
builder.peerStorage = some(peerStorage)
builder.peerStorageCapacity = capacity
proc withPeerManager*(builder: var WakuNodeBuilder, peerManager: PeerManager) =
builder.peerManager = some(peerManager)
## Waku switch
proc withSwitchConfiguration*(builder: var WakuNodeBuilder,
maxConnections = none(int),
nameResolver: NameResolver = nil,
sendSignedPeerRecord = false,
secureKey = none(string),
secureCert = none(string),
agentString = none(string)) =
builder.switchMaxConnections = maxConnections
builder.switchSendSignedPeerRecord = some(sendSignedPeerRecord)
builder.switchSslSecureKey = secureKey
builder.switchSslSecureCert = secureCert
builder.switchAgentString = agentString
if not nameResolver.isNil():
builder.switchNameResolver = some(nameResolver)
## Waku discv5
proc withWakuDiscv5*(builder: var WakuNodeBuilder, instance: WakuDiscoveryV5) =
if not instance.isNil():
builder.wakuDiscv5 = some(instance)
## Build
proc build*(builder: WakuNodeBuilder): Result[WakuNode, string] =
var rng: ref crypto.HmacDrbgContext
if builder.nodeRng.isNone():
rng = crypto.newRng()
else:
rng = builder.nodeRng.get()
if builder.nodeKey.isNone():
return err("node key is required")
if builder.netConfig.isNone():
return err("network configuration is required")
var node: WakuNode
try:
node = WakuNode.new(
rng = rng,
nodeKey = builder.nodeKey.get(),
netConfig = builder.netConfig.get(),
peerStorage = builder.peerStorage.get(nil),
peerStoreCapacity = builder.peerStorageCapacity,
maxConnections = builder.switchMaxConnections.get(builders.MaxConnections),
nameResolver = builder.switchNameResolver.get(nil),
agentString = builder.switchAgentString,
secureKey = builder.switchSslSecureKey.get(""),
secureCert = builder.switchSslSecureCert.get(""),
sendSignedPeerRecord = builder.switchSendSignedPeerRecord.get(false),
wakuDiscv5 = builder.wakuDiscv5,
)
except Exception:
return err("failed to build WakuNode instance: " & getCurrentExceptionMsg())
ok(node)

View File

@ -5,7 +5,7 @@ else:
# Collection of utilities related to Waku peers
import
std/[options, sequtils, strutils, times],
std/[options, sequtils, strutils],
chronos,
stew/results,
stew/shims/net,

View File

@ -1,9 +1,11 @@
import
./node/config,
./node/builder,
./node/waku_switch as switch,
./node/waku_node as node
export
config,
builder,
switch,
node