Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: discv5 re-org clean-up #1823

Merged
merged 3 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 69 additions & 30 deletions apps/networkmonitor/networkmonitor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,18 @@ proc populateInfoFromIp(allPeersRef: CustomPeersTableRef,
# crawls the network discovering peers and trying to connect to them
# metrics are processed and exposed
proc crawlNetwork(node: WakuNode,
wakuDiscv5: WakuDiscoveryV5,
restClient: RestClientRef,
conf: NetworkMonitorConf,
allPeersRef: CustomPeersTableRef) {.async.} =

let crawlInterval = conf.refreshInterval * 1000
while true:
# discover new random nodes
let discoveredNodes = await node.wakuDiscv5.protocol.queryRandom()
let discoveredNodes = await wakuDiscv5.protocol.queryRandom()

# nodes are nested into bucket, flat it
let flatNodes = node.wakuDiscv5.protocol.routingTable.buckets.mapIt(it.nodes).flatten()
let flatNodes = wakuDiscv5.protocol.routingTable.buckets.mapIt(it.nodes).flatten()

# populate metrics related to capabilities as advertised by the ENR (see waku field)
setDiscoveredPeersCapabilities(flatNodes)
Expand Down Expand Up @@ -242,44 +243,82 @@ proc getBootstrapFromDiscDns(conf: NetworkMonitorConf): Result[seq[enr.Record],
except CatchableError:
error("failed discovering peers from DNS")

proc initAndStartNode(conf: NetworkMonitorConf): Result[WakuNode, string] =
proc initAndStartApp(conf: NetworkMonitorConf): Result[(WakuNode, WakuDiscoveryV5), string] =
let bindIp = try:
ValidIpAddress.init("0.0.0.0")
except CatchableError:
return err("could not start node: " & getCurrentExceptionMsg())

let extIp = try:
ValidIpAddress.init("127.0.0.1")
except CatchableError:
return err("could not start node: " & getCurrentExceptionMsg())

let
# some hardcoded parameters
rng = keys.newRng()
nodeKey = crypto.PrivateKey.random(Secp256k1, rng[])[]
key = crypto.PrivateKey.random(Secp256k1, rng[])[]
nodeTcpPort = Port(60000)
nodeUdpPort = Port(9000)
flags = CapabilitiesBitfield.init(lightpush = false, filter = false, store = false, relay = true)

try:
let
bindIp = ValidIpAddress.init("0.0.0.0")
extIp = ValidIpAddress.init("127.0.0.1")
var builder = EnrBuilder.init(key)

var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodeKey)
? builder.withNetworkConfigurationDetails(bindIp, nodeTcpPort)
let node = ? builder.build()
builder.withIpAddressAndPorts(
ipAddr = some(extIp),
tcpPort = some(nodeTcpPort),
udpPort = some(nodeUdpPort),
)
builder.withWakuCapabilities(flags)
#builder.withMultiaddrs(???)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal but I'd delete this comment


var discv5BootstrapEnrsRes = getBootstrapFromDiscDns(conf)
if not discv5BootstrapEnrsRes.isOk():
error("failed discovering peers from DNS")
var discv5BootstrapEnrs = discv5BootstrapEnrsRes.get()
let recordRes = builder.build()
let record =
if recordRes.isErr():
return err("cannot build record: " & $recordRes.error)
else: recordRes.get()

# parse enrURIs from the configuration and add the resulting ENRs to the discv5BootstrapEnrs seq
for enrUri in conf.bootstrapNodes:
addBootstrapNode(enrUri, discv5BootstrapEnrs)
var nodeBuilder = WakuNodeBuilder.init()

nodeBuilder.withNodeKey(key)
nodeBuilder.withRecord(record)
let res = nodeBuilder.withNetworkConfigurationDetails(bindIp, nodeTcpPort)
if res.isErr():
return err("node building error" & $ res.error)

# mount discv5
node.wakuDiscv5 = WakuDiscoveryV5.new(
some(extIp), some(nodeTcpPort), some(nodeUdpPort),
bindIp, nodeUdpPort, discv5BootstrapEnrs, false,
keys.PrivateKey(nodeKey.skkey), flags, @[], node.rng, @[])
let nodeRes = nodeBuilder.build()
let node =
if nodeRes.isErr():
return err("node building error" & $ res.error)
else: nodeRes.get()

node.wakuDiscv5.protocol.open()
return ok(node)
var discv5BootstrapEnrsRes = getBootstrapFromDiscDns(conf)
if not discv5BootstrapEnrsRes.isOk():
error("failed discovering peers from DNS")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not discv5BootstrapEnrsRes.isOk():
error("failed discovering peers from DNS")
if discv5BootstrapEnrsRes.isErr():
error("failed discovering peers from DNS: " & discv5BootstrapEnrsRes.error)

var discv5BootstrapEnrs = discv5BootstrapEnrsRes.get()

# parse enrURIs from the configuration and add the resulting ENRs to the discv5BootstrapEnrs seq
for enrUri in conf.bootstrapNodes:
addBootstrapNode(enrUri, discv5BootstrapEnrs)

# discv5
let discv5Conf = WakuDiscoveryV5Config(
discv5Config: none(DiscoveryConfig),
address: bindIp,
port: nodeUdpPort,
privateKey: keys.PrivateKey(key.skkey),
bootstrapRecords: discv5BootstrapEnrs,
autoupdateRecord: false
)

let wakuDiscv5 = WakuDiscoveryV5.new(node.rng, discv5Conf, some(record))

try:
wakuDiscv5.protocol.open()
except CatchableError:
error("could not start node")
return err("could not start node: " & getCurrentExceptionMsg())

ok((node, wakuDiscv5))

proc startRestApiServer(conf: NetworkMonitorConf,
allPeersInfo: CustomPeersTableRef,
Expand Down Expand Up @@ -366,12 +405,12 @@ when isMainModule:
let restClient = clientRest.get()

# start waku node
let nodeRes = initAndStartNode(conf)
let nodeRes = initAndStartApp(conf)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we change this we'd need to change the previous comment and the next error message

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's exactly the kind of errors I wish the tooling would catch... :(

if nodeRes.isErr():
error "could not start node"
quit 1

let node = nodeRes.get()
let (node, discv5) = nodeRes.get()

waitFor node.mountRelay()

Expand All @@ -380,6 +419,6 @@ when isMainModule:

# spawn the routine that crawls the network
# TODO: split into 3 routines (discovery, connections, ip2location)
asyncSpawn crawlNetwork(node, restClient, conf, allPeersInfo)
asyncSpawn crawlNetwork(node, discv5, restClient, conf, allPeersInfo)

runForever()
6 changes: 6 additions & 0 deletions apps/wakubridge/wakubridge.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import
# Waku v2 imports
libp2p/crypto/crypto,
libp2p/nameresolving/nameresolver,
../../waku/v2/waku_enr,
../../waku/v2/waku_core,
../../waku/v2/waku_store,
../../waku/v2/waku_filter,
Expand Down Expand Up @@ -228,10 +229,15 @@ proc new*(T: type WakuBridge,
topics: topicInterest)
nodev1.configureWaku(wakuConfig)

var builder = EnrBuilder.init(nodev2Key)
builder.withIpAddressAndPorts(nodev2ExtIp, nodev2ExtPort, none(Port))
let record = builder.build().tryGet()

# Setup Waku v2 node
let nodev2 = block:
var builder = WakuNodeBuilder.init()
builder.withNodeKey(nodev2Key)
builder.withRecord(record)
builder.withNetworkConfigurationDetails(nodev2BindIp, nodev2BindPort, nodev2ExtIp, nodev2ExtPort).tryGet()
builder.withSwitchConfiguration(nameResolver=nameResolver)
builder.build().tryGet()
Expand Down
4 changes: 2 additions & 2 deletions apps/wakunode2/app.nim
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ proc setupDiscoveryV5*(app: App): WakuDiscoveryV5 =

let discv5Conf = WakuDiscoveryV5Config(
discv5Config: some(discv5Config),
address: app.netConf.bindIp,
address: app.conf.listenAddress,
port: discv5UdpPort,
privateKey: keys.PrivateKey(app.key.skkey),
bootstrapRecords: discv5BootstrapEnrs,
Expand Down Expand Up @@ -504,7 +504,7 @@ proc startApp*(app: App): Future[AppResult[void]] {.async.} =
let res = app.wakuDiscv5.get().start()

if res.isErr():
return err("failed to start waku discovery v5: " & res.error)
return err("failed to start waku discovery v5: " & $res.error)

asyncSpawn app.wakuDiscv5.get().searchLoop(app.node.peerManager, some(app.record))

Expand Down
4 changes: 2 additions & 2 deletions apps/wakunode2/internal_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ proc createRecord*(conf: WakuNodeConf, netConf: NetConfig, key: crypto.PrivateKe
var builder = EnrBuilder.init(key)

builder.withIpAddressAndPorts(
ipAddr = netConf.extIp,
tcpPort = netConf.extPort,
ipAddr = netConf.enrIp,
tcpPort = netConf.enrPort,
udpPort = netConf.discv5UdpPort,
)

Expand Down
26 changes: 24 additions & 2 deletions tests/v2/testlib/wakunode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,34 @@ proc newTestWakuNode*(nodeKey: crypto.PrivateKey,
dns4DomainName = dns4DomainName,
discv5UdpPort = discv5UdpPort,
)
if netConfigRes.isErr():
raise newException(Defect, "Invalid network configuration: " & $netConfigRes.error)
let netConf =
if netConfigRes.isErr():
raise newException(Defect, "Invalid network configuration: " & $netConfigRes.error)
else:
netConfigRes.get()

var enrBuilder = EnrBuilder.init(nodeKey)

enrBuilder.withIpAddressAndPorts(
ipAddr = netConf.enrIp,
tcpPort = netConf.enrPort,
udpPort = netConf.discv5UdpPort,
)
if netConf.wakuFlags.isSome():
enrBuilder.withWakuCapabilities(netConf.wakuFlags.get())
enrBuilder.withMultiaddrs(netConf.enrMultiaddrs)

let recordRes = enrBuilder.build()
let record =
if recordRes.isErr():
raise newException(Defect, "Invalid record: " & $recordRes.error)
else:
recordRes.get()

var builder = WakuNodeBuilder.init()
builder.withRng(rng())
builder.withNodeKey(nodeKey)
builder.withRecord(record)
builder.withNetworkConfiguration(netConfigRes.get())
builder.withPeerStorage(peerStorage, capacity = peerStoreCapacity)
builder.withSwitchConfiguration(
Expand Down
8 changes: 8 additions & 0 deletions tests/wakubridge/test_wakubridge.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import
../../waku/v1/protocol/waku_protocol,
../../waku/v2/waku_core,
../../waku/v2/waku_node,
../../waku/v2/waku_enr,
../../waku/v2/utils/compat,
../test_helpers

Expand Down Expand Up @@ -54,9 +55,16 @@ procSuite "WakuBridge":

# Waku v2 node
v2NodeKey = crypto.PrivateKey.random(Secp256k1, cryptoRng[])[]

var builder = EnrBuilder.init(v2NodeKey)
builder.withIpAddressAndPorts(none(ValidIpAddress), none(Port), none(Port))
let record = builder.build().tryGet()

let
v2Node = block:
var builder = WakuNodeBuilder.init()
builder.withNodeKey(v2NodeKey)
builder.withRecord(record)
builder.withNetworkConfigurationDetails(ValidIpAddress.init("0.0.0.0"), Port(62203)).tryGet()
builder.build().tryGet()

Expand Down
10 changes: 5 additions & 5 deletions waku/v2/node/builder.nim
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ proc withNetworkConfigurationDetails*(builder: var WakuNodeBuilder,
wsEnabled: bool = false,
wssEnabled: bool = false,
wakuFlags = none(CapabilitiesBitfield),
dns4DomainName = none(string),
discv5UdpPort = none(Port)): WakuNodeBuilderResult {.
dns4DomainName = none(string)): WakuNodeBuilderResult {.
deprecated: "use 'builder.withNetworkConfiguration()' instead".} =
let netConfig = ? NetConfig.init(
bindIp = bindIp,
Expand All @@ -91,7 +90,6 @@ proc withNetworkConfigurationDetails*(builder: var WakuNodeBuilder,
wssEnabled = wssEnabled,
wakuFlags = wakuFlags,
dns4DomainName = dns4DomainName,
discv5UdpPort = discv5UdpPort,
)
builder.withNetworkConfiguration(netConfig)
ok()
Expand Down Expand Up @@ -144,6 +142,9 @@ proc build*(builder: WakuNodeBuilder): Result[WakuNode, string] =
if builder.netConfig.isNone():
return err("network configuration is required")

if builder.record.isNone():
return err("node record is required")

# fallbck to max connections if not set
var maxRelayPeers: int
if builder.maxRelayPeers.isNone():
Expand Down Expand Up @@ -181,9 +182,8 @@ proc build*(builder: WakuNodeBuilder): Result[WakuNode, string] =
var node: WakuNode
try:
node = WakuNode.new(
nodeKey = builder.nodeKey.get(),
netConfig = builder.netConfig.get(),
enr = builder.record,
enr = builder.record.get(),
switch = switch,
peerManager = peerManager,
rng = rng,
Expand Down
43 changes: 1 addition & 42 deletions waku/v2/node/waku_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import
../waku_lightpush/client as lightpush_client,
../waku_enr,
../waku_dnsdisc,
../waku_discv5,
../waku_peer_exchange,
./config,
./peer_manager,
Expand Down Expand Up @@ -101,37 +100,10 @@ type
enr*: enr.Record
libp2pPing*: Ping
rng*: ref rand.HmacDrbgContext
wakuDiscv5*: WakuDiscoveryV5
rendezvous*: RendezVous
announcedAddresses* : seq[MultiAddress]
started*: bool # Indicates that node has started listening

proc getEnr*(netConfig: NetConfig,
wakuDiscV5 = none(WakuDiscoveryV5),
nodeKey: crypto.PrivateKey): Result[enr.Record, string] =
if wakuDiscV5.isSome():
return ok(wakuDiscV5.get().protocol.getRecord())

var builder = EnrBuilder.init(nodeKey, seqNum = 1)

builder.withIpAddressAndPorts(
ipAddr = netConfig.enrIp,
tcpPort = netConfig.enrPort,
udpPort = netConfig.discv5UdpPort
)

if netConfig.wakuFlags.isSome():
builder.withWakuCapabilities(netConfig.wakuFlags.get())

if netConfig.enrMultiAddrs.len > 0:
builder.withMultiaddrs(netConfig.enrMultiAddrs)

let recordRes = builder.build()
if recordRes.isErr():
return err($recordRes.error)

return ok(recordRes.get())

proc getAutonatService*(rng: ref HmacDrbgContext): AutonatService =
## AutonatService request other peers to dial us back
## flagging us as Reachable or NotReachable.
Expand All @@ -156,11 +128,9 @@ proc getAutonatService*(rng: ref HmacDrbgContext): AutonatService =
return autonatService

proc new*(T: type WakuNode,
nodeKey: crypto.PrivateKey,
netConfig: NetConfig,
enr: Option[enr.Record],
enr: enr.Record,
switch: Switch,
wakuDiscv5 = none(WakuDiscoveryV5),
peerManager: PeerManager,
# TODO: make this argument required after tests are updated
rng: ref HmacDrbgContext = crypto.newRng()
Expand All @@ -169,23 +139,12 @@ proc new*(T: type WakuNode,

info "Initializing networking", addrs= $netConfig.announcedAddresses

let enr =
if enr.isNone():
let nodeEnrRes = getEnr(netConfig, wakuDiscv5, nodekey)

if nodeEnrRes.isErr():
raise newException(Defect, "failed to generate the node ENR record: " & $nodeEnrRes.error)

nodeEnrRes.get()
else: enr.get()

return WakuNode(
peerManager: peerManager,
switch: switch,
rng: rng,
enr: enr,
announcedAddresses: netConfig.announcedAddresses,
wakuDiscv5: if wakuDiscV5.isSome(): wakuDiscV5.get() else: nil,
)

proc peerInfo*(node: WakuNode): PeerInfo =
Expand Down