Bridge improvements (#875)

This commit is contained in:
Hanno Cornelius 2022-03-08 11:48:17 +01:00 committed by GitHub
parent 2f73667a96
commit 9165720f63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 4 deletions

View File

@ -1,3 +1,17 @@
## Next version
### Features
### Changes
- Waku v1 <> v2 bridge now supports DNS `multiaddrs`
- Waku v1 <> v2 bridge now validates content topics before attempting to bridge a message from Waku v2 to Waku v1
### Fixes
### Docs
## 2021-03-03 v0.8
Release highlights:
@ -23,6 +37,7 @@ The full list of changes is below.
- Metrics: improved default fleet monitoring dashboard
- Introduced a `Timestamp` type (currently an alias for int64).
- All timestamps changed to nanosecond resolution.
- `timestamp` field number in WakuMessage object changed from `4` to `10`
- [`13/WAKU2-STORE`](https://rfc.vac.dev/spec/13/) identifier updated to `/vac/waku/store/2.0.0-beta4`
- `toy-chat` application now uses DNS discovery to connect to existing fleets

View File

@ -98,6 +98,19 @@ procSuite "WakuBridge":
expect ValueError:
# Content topic name not hex
discard toV1Topic(ContentTopic("/waku/1/my-content/rfc26"))
asyncTest "Verify that WakuMessages are on bridgeable content topics":
let
validCT = ContentTopic("/waku/1/my-content/rfc26")
unnamespacedCT = ContentTopic("just_a_bunch_of_words")
invalidAppCT = ContentTopic("/facebook/1/my-content/rfc26")
invalidVersionCT = ContentTopic("/waku/2/my-content/rfc26")
check:
WakuMessage(contentTopic: validCT).isBridgeable() == true
WakuMessage(contentTopic: unnamespacedCT).isBridgeable() == false
WakuMessage(contentTopic: invalidAppCT).isBridgeable() == false
WakuMessage(contentTopic: invalidVersionCT).isBridgeable() == false
asyncTest "Messages are bridged between Waku v1 and Waku v2":
# Setup test

View File

@ -134,6 +134,16 @@ type
defaultValue: ""
name: "filternode" }: string
dnsAddrs* {.
desc: "Enable resolution of `dnsaddr`, `dns4` or `dns6` multiaddrs"
defaultValue: true
name: "dns-addrs" }: bool
dnsAddrsNameServers* {.
desc: "DNS name server IPs to query for DNS multiaddrs resolution. Argument may be repeated."
defaultValue: @[ValidIpAddress.init("1.1.1.1"), ValidIpAddress.init("1.0.0.1")]
name: "dns-addrs-name-server" }: seq[ValidIpAddress]
### Bridge options
bridgePubsubTopic* {.

View File

@ -12,6 +12,7 @@ import
../v1/protocol/waku_protocol,
# Waku v2 imports
libp2p/crypto/crypto,
libp2p/nameresolving/nameresolver,
../v2/utils/namespacing,
../v2/utils/time,
../v2/node/wakunode2,
@ -32,6 +33,9 @@ const
ClientIdV1 = "nim-waku v1 node"
DefaultTTL = 5'u32
DeduplQSize = 20 # Maximum number of seen messages to keep in deduplication queue
ContentTopicApplication = "waku"
ContentTopicAppVersion = "1"
#########
# Types #
@ -48,6 +52,18 @@ type
# Helper funtions #
###################
# Validity
proc isBridgeable*(msg: WakuMessage): bool =
## Determines if a Waku v2 msg is on a bridgeable content topic
let ns = NamespacedTopic.fromString(msg.contentTopic)
if ns.isOk():
if ns.get().application == ContentTopicApplication and ns.get().version == ContentTopicAppVersion:
return true
return false
# Deduplication
proc containsOrAdd(sequence: var seq[hashes.Hash], hash: hashes.Hash): bool =
@ -72,8 +88,8 @@ proc toV2ContentTopic*(v1Topic: waku_protocol.Topic): ContentTopic =
var namespacedTopic = NamespacedTopic()
namespacedTopic.application = "waku"
namespacedTopic.version = "1"
namespacedTopic.application = ContentTopicApplication
namespacedTopic.version = ContentTopicAppVersion
namespacedTopic.topicName = "0x" & v1Topic.toHex()
namespacedTopic.encoding = "rfc26"
@ -149,6 +165,7 @@ proc new*(T: type WakuBridge,
nodev2Key: crypto.PrivateKey,
nodev2BindIp: ValidIpAddress, nodev2BindPort: Port,
nodev2ExtIp = none[ValidIpAddress](), nodev2ExtPort = none[Port](),
nameResolver: NameResolver = nil,
# Bridge configuration
nodev2PubsubTopic: wakunode2.Topic): T
{.raises: [Defect,IOError, TLSStreamProtocolError, LPError].} =
@ -177,7 +194,8 @@ proc new*(T: type WakuBridge,
let
nodev2 = WakuNode.new(nodev2Key,
nodev2BindIp, nodev2BindPort,
nodev2ExtIp, nodev2ExtPort)
nodev2ExtIp, nodev2ExtPort,
nameResolver = nameResolver)
return WakuBridge(nodev1: nodev1, nodev2: nodev2, nodev2PubsubTopic: nodev2PubsubTopic)
@ -215,7 +233,7 @@ proc start*(bridge: WakuBridge) {.async.} =
# Handle messages on Waku v2 and bridge to Waku v1
proc relayHandler(pubsubTopic: string, data: seq[byte]) {.async, gcsafe.} =
let msg = WakuMessage.init(data)
if msg.isOk():
if msg.isOk() and msg.get().isBridgeable():
try:
trace "Bridging message from V2 to V1", msg=msg.tryGet()
bridge.toWakuV1(msg.tryGet())
@ -232,6 +250,7 @@ proc stop*(bridge: WakuBridge) {.async.} =
when isMainModule:
import
eth/p2p/whispernodes,
libp2p/nameresolving/dnsresolver,
./utils/nat,
../v1/node/rpc/wakusim,
../v1/node/rpc/waku,
@ -299,6 +318,16 @@ when isMainModule:
else:
bloom = some(fullBloom())
# DNS resolution
var dnsReslvr: DnsResolver
if conf.dnsAddrs:
# Support for DNS multiaddrs
var nameServers: seq[TransportAddress]
for ip in conf.dnsAddrsNameServers:
nameServers.add(initTAddress(ip, Port(53))) # Assume all servers use port 53
dnsReslvr = DnsResolver.new(nameServers)
let
bridge = WakuBridge.new(nodev1Key = conf.nodekeyV1,
nodev1Address = nodev1Address,
@ -309,6 +338,7 @@ when isMainModule:
nodev2Key = conf.nodekeyV2,
nodev2BindIp = conf.listenAddress, nodev2BindPort = Port(uint16(conf.libp2pTcpPort) + conf.portsShift),
nodev2ExtIp = nodev2ExtIp, nodev2ExtPort = nodev2ExtPort,
nameResolver = dnsReslvr,
nodev2PubsubTopic = conf.bridgePubsubTopic)
waitFor bridge.start()