2023-11-15 15:11:36 +00:00
{. used . }
import
2024-07-09 15:36:12 +00:00
std / [ options , sequtils , strutils , strformat ] ,
2023-11-15 15:11:36 +00:00
stew / shims / net as stewNet ,
testutils / unittests ,
chronicles ,
chronos ,
2024-03-15 23:08:47 +00:00
libp2p / protocols / pubsub / [ pubsub , gossipsub ] ,
libp2p / [ multihash , stream / connection , switch ] ,
2023-11-15 15:11:36 +00:00
. / crypto_utils ,
std / json
import
2024-07-05 22:03:38 +00:00
waku / [
2023-11-15 15:11:36 +00:00
node / peer_manager ,
waku_relay / protocol ,
waku_relay ,
2024-01-03 12:11:50 +00:00
waku_core ,
2024-03-15 23:08:47 +00:00
waku_core / message / codec ,
2023-11-15 15:11:36 +00:00
] ,
2024-03-15 23:08:47 +00:00
.. / testlib / [ wakucore , testasync , testutils , futures , sequtils ] ,
2023-11-15 15:11:36 +00:00
. / utils ,
.. / resources / payloads
suite " Waku Relay " :
var messageSeq {. threadvar . } : seq [ ( PubsubTopic , WakuMessage ) ]
var handlerFuture {. threadvar . } : Future [ ( PubsubTopic , WakuMessage ) ]
var simpleFutureHandler {. threadvar . } : WakuRelayHandler
2023-11-15 15:15:38 +00:00
2023-11-15 15:11:36 +00:00
var switch {. threadvar . } : Switch
var peerManager {. threadvar . } : PeerManager
var node {. threadvar . } : WakuRelay
2023-11-15 15:15:38 +00:00
2023-11-15 15:11:36 +00:00
var remotePeerInfo {. threadvar . } : RemotePeerInfo
var peerId {. threadvar . } : PeerId
2023-11-15 15:15:38 +00:00
2023-11-15 15:11:36 +00:00
var contentTopic {. threadvar . } : ContentTopic
var pubsubTopic {. threadvar . } : PubsubTopic
var pubsubTopicSeq {. threadvar . } : seq [ PubsubTopic ]
var testMessage {. threadvar . } : string
var wakuMessage {. threadvar . } : WakuMessage
asyncSetup :
messageSeq = @ [ ]
handlerFuture = newPushHandlerFuture ( )
simpleFutureHandler = proc (
2024-03-15 23:08:47 +00:00
topic : PubsubTopic , msg : WakuMessage
2023-11-15 15:11:36 +00:00
) : Future [ void ] {. async , closure , gcsafe . } =
messageSeq . add ( ( topic , msg ) )
handlerFuture . complete ( ( topic , msg ) )
switch = newTestSwitch ( )
peerManager = PeerManager . new ( switch )
node = await newTestWakuRelay ( switch )
testMessage = " test-message "
contentTopic = DefaultContentTopic
pubsubTopic = DefaultPubsubTopic
pubsubTopicSeq = @ [ pubsubTopic ]
wakuMessage = fakeWakuMessage ( testMessage , pubsubTopic )
2024-04-18 09:20:39 +00:00
await allFutures ( switch . start ( ) )
2023-11-15 15:11:36 +00:00
remotePeerInfo = switch . peerInfo . toRemotePeerInfo ( )
peerId = remotePeerInfo . peerId
asyncTeardown :
2024-04-18 09:20:39 +00:00
await allFutures ( switch . stop ( ) )
2023-11-15 15:11:36 +00:00
suite " Subscribe " :
asyncTest " Publish without Subscription " :
# When publishing a message without being subscribed
discard await node . publish ( pubsubTopic , wakuMessage )
# Then the message is not published
check :
2023-11-15 15:15:38 +00:00
not await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
asyncTest " Publish with Subscription (Network Size: 1) " :
# When subscribing to a Pubsub Topic
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
# Then the node is subscribed
check :
node . isSubscribed ( pubsubTopic )
node . subscribedTopics = = pubsubTopicSeq
# When publishing a message
discard await node . publish ( pubsubTopic , wakuMessage )
# Then the message is published
2023-11-15 15:15:38 +00:00
assert ( await handlerFuture . withTimeout ( FUTURE_TIMEOUT ) )
2023-11-15 15:11:36 +00:00
let ( topic , msg ) = handlerFuture . read ( )
check :
topic = = pubsubTopic
msg = = wakuMessage
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
asyncTest " Pubsub Topic Subscription (Network Size: 2, only one subscribed) " :
# Given a second node connected to the first one
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
let otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
# When subscribing the second node to the Pubsub Topic
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
# Then the second node is subscribed, but not the first one
check :
not node . isSubscribed ( pubsubTopic )
node . subscribedTopics ! = pubsubTopicSeq
otherNode . isSubscribed ( pubsubTopic )
otherNode . subscribedTopics = = pubsubTopicSeq
await sleepAsync ( 500 . millis )
# When publishing a message in the subscribed node
let fromOtherWakuMessage = fakeWakuMessage ( " fromOther " )
discard await otherNode . publish ( pubsubTopic , fromOtherWakuMessage )
# Then the message is published only in the subscribed node
check :
2023-11-15 15:15:38 +00:00
not await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
let ( otherTopic1 , otherMessage1 ) = otherHandlerFuture . read ( )
check :
otherTopic1 = = pubsubTopic
otherMessage1 = = fromOtherWakuMessage
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# When publishing a message in the other node
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
let fromNodeWakuMessage = fakeWakuMessage ( " fromNode " )
discard await node . publish ( pubsubTopic , fromNodeWakuMessage )
# Then the message is published only in the subscribed node
check :
2023-11-15 15:15:38 +00:00
not await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
let ( otherTopic2 , otherMessage2 ) = otherHandlerFuture . read ( )
check :
otherTopic2 = = pubsubTopic
otherMessage2 = = fromNodeWakuMessage
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
asyncTest " Pubsub Topic Subscription (Network Size: 2, both subscribed to same pubsub topic) " :
# Given a second node connected to the first one
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
let otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
# When subscribing both nodes to the same Pubsub Topic
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
# Then both nodes are subscribed
check :
node . isSubscribed ( pubsubTopic )
node . subscribedTopics = = pubsubTopicSeq
otherNode . isSubscribed ( pubsubTopic )
otherNode . subscribedTopics = = pubsubTopicSeq
await sleepAsync ( 500 . millis )
# When publishing a message in node
let fromOtherWakuMessage = fakeWakuMessage ( " fromOther " )
discard await node . publish ( pubsubTopic , fromOtherWakuMessage )
# Then the message is published in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
( topic1 , message1 ) = handlerFuture . read ( )
( otherTopic1 , otherMessage1 ) = otherHandlerFuture . read ( )
check :
topic1 = = pubsubTopic
message1 = = fromOtherWakuMessage
otherTopic1 = = pubsubTopic
otherMessage1 = = fromOtherWakuMessage
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# When publishing a message in the other node
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
let fromNodeWakuMessage = fakeWakuMessage ( " fromNode " )
discard await node . publish ( pubsubTopic , fromNodeWakuMessage )
discard await otherNode . publish ( pubsubTopic , fromNodeWakuMessage )
# Then the message is published in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
( topic2 , message2 ) = handlerFuture . read ( )
( otherTopic2 , otherMessage2 ) = otherHandlerFuture . read ( )
check :
topic2 = = pubsubTopic
message2 = = fromNodeWakuMessage
otherTopic2 = = pubsubTopic
otherMessage2 = = fromNodeWakuMessage
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
asyncTest " Refreshing subscription " :
# Given a subscribed node
2023-11-15 17:10:10 +00:00
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
2023-11-15 15:11:36 +00:00
check :
node . isSubscribed ( pubsubTopic )
node . subscribedTopics = = pubsubTopicSeq
let otherWakuMessage = fakeWakuMessage ( " fromOther " )
discard await node . publish ( pubsubTopic , otherWakuMessage )
check :
messageSeq = = @ [ ( pubsubTopic , otherWakuMessage ) ]
# Given the subscription is refreshed
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
2024-03-15 23:08:47 +00:00
2023-11-15 17:10:10 +00:00
discard node . subscribe ( pubsubTopic , otherSimpleFutureHandler )
2023-11-15 15:11:36 +00:00
check :
node . isSubscribed ( pubsubTopic )
node . subscribedTopics = = pubsubTopicSeq
messageSeq = = @ [ ( pubsubTopic , otherWakuMessage ) ]
# When publishing a message with the refreshed subscription
handlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , wakuMessage )
# Then the message is published
2023-11-15 15:15:38 +00:00
check ( await handlerFuture . withTimeout ( FUTURE_TIMEOUT ) )
2023-11-15 15:11:36 +00:00
let ( topic , msg ) = handlerFuture . read ( )
check :
topic = = pubsubTopic
msg = = wakuMessage
messageSeq = = @ [ ( pubsubTopic , otherWakuMessage ) , ( pubsubTopic , wakuMessage ) ]
asyncTest " With additional validator " :
# Given a simple validator
var validatorFuture = newBoolFuture ( )
let len4Validator = proc (
2024-03-15 23:08:47 +00:00
pubsubTopic : string , message : WakuMessage
2023-11-15 15:11:36 +00:00
) : Future [ ValidationResult ] {. async . } =
if message . payload . len ( ) = = 8 :
validatorFuture . complete ( true )
return ValidationResult . Accept
else :
validatorFuture . complete ( false )
return ValidationResult . Reject
# And a second node connected to the first one
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
let otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
2024-02-01 17:16:10 +00:00
otherNode . addValidator ( len4Validator )
2023-11-15 17:10:10 +00:00
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
2023-11-15 15:11:36 +00:00
await sleepAsync ( 500 . millis )
check :
otherNode . isSubscribed ( pubsubTopic )
# Given a subscribed node with a validator
2024-02-01 17:16:10 +00:00
node . addValidator ( len4Validator )
2023-11-15 17:10:10 +00:00
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
2023-11-15 15:11:36 +00:00
await sleepAsync ( 500 . millis )
check :
node . isSubscribed ( pubsubTopic )
node . subscribedTopics = = pubsubTopicSeq
otherNode . isSubscribed ( pubsubTopic )
otherNode . subscribedTopics = = pubsubTopicSeq
# When publishing a message that doesn't match the validator
discard await node . publish ( pubsubTopic , wakuMessage )
# Then the validator is ran in the other node, and fails
# Not run in the self node
2024-03-15 23:08:47 +00:00
check :
2023-11-15 15:15:38 +00:00
await validatorFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
validatorFuture . read ( ) = = false
# And the message is published in the self node, but not in the other node,
# because it doesn't pass the validator check.
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
not await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
let ( topic1 , msg1 ) = handlerFuture . read ( )
# let (otherTopic1, otherMsg1) = otherHandlerFuture.read()
check :
topic1 = = pubsubTopic
msg1 = = wakuMessage
# otherTopic1 == pubsubTopic
# otherMsg1 == wakuMessage
# When publishing a message that matches the validator
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
validatorFuture = newBoolFuture ( )
let wakuMessage2 = fakeWakuMessage ( " 12345678 " , pubsubTopic )
discard await node . publish ( pubsubTopic , wakuMessage2 )
# Then the validator is ran in the other node, and succeeds
# Not run in the self node
2024-03-15 23:08:47 +00:00
check :
2023-11-15 15:15:38 +00:00
await validatorFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
validatorFuture . read ( ) = = true
# And the message is published in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
let ( topic2 , msg2 ) = handlerFuture . read ( )
let ( otherTopic2 , otherMsg2 ) = otherHandlerFuture . read ( )
check :
topic2 = = pubsubTopic
msg2 = = wakuMessage2
otherTopic2 = = pubsubTopic
otherMsg2 = = wakuMessage2
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
asyncTest " Max Topic Size " :
# NOT FOUND
discard
asyncTest " Max subscriptions " :
# NOT FOUND
discard
asyncTest " Message encryption/decryption " :
# Given a second node connected to the first one, both subscribed to the same Pubsub Topic
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
let otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
check :
node . isSubscribed ( pubsubTopic )
node . subscribedTopics = = pubsubTopicSeq
otherNode . isSubscribed ( pubsubTopic )
otherNode . subscribedTopics = = pubsubTopicSeq
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
await sleepAsync ( 500 . millis )
# Given some crypto info
var key = " My fancy key "
var data = " Hello, Crypto! "
var iv = " 0123456789ABCDEF "
# When publishing an encrypted message
let encodedText = cfbEncode ( key , iv , data )
let encodedWakuMessage = fakeWakuMessage ( encodedText , pubsubTopic )
discard await node . publish ( pubsubTopic , encodedWakuMessage )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the message is published in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
let ( topic1 , msg1 ) = handlerFuture . read ( )
let ( otherTopic1 , otherMsg1 ) = otherHandlerFuture . read ( )
check :
topic1 = = pubsubTopic
msg1 = = encodedWakuMessage
otherTopic1 = = pubsubTopic
otherMsg1 = = encodedWakuMessage
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# When decoding the message
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
decodedText = cfbDecode ( key , iv , msg1 . payload )
otherDecodedText = cfbDecode ( key , iv , otherMsg1 . payload )
# Then the message is decrypted in both nodes
check :
decodedText . toString ( ) = = data
otherDecodedText . toString ( ) = = data
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
asyncTest " How multiple interconnected nodes work " :
# Given two other pubsub topics
let
2024-07-09 15:36:12 +00:00
pubsubTopicB = " /waku/2/rs/0/1 "
pubsubTopicC = " /waku/2/rs/0/2 "
2023-11-15 15:11:36 +00:00
# Given two other nodes connected to the first one
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherSwitch = newTestSwitch ( )
otherPeerManager = PeerManager . new ( otherSwitch )
otherNode = await newTestWakuRelay ( otherSwitch )
anotherSwitch = newTestSwitch ( )
anotherPeerManager = PeerManager . new ( anotherSwitch )
anotherNode = await newTestWakuRelay ( anotherSwitch )
2024-03-15 23:08:47 +00:00
await allFutures (
otherSwitch . start ( ) ,
otherNode . start ( ) ,
anotherSwitch . start ( ) ,
anotherNode . start ( ) ,
)
2023-11-15 15:11:36 +00:00
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
otherPeerId = otherRemotePeerInfo . peerId
anotherRemotePeerInfo = anotherSwitch . peerInfo . toRemotePeerInfo ( )
anotherPeerId = anotherRemotePeerInfo . peerId
check :
await peerManager . connectRelay ( otherRemotePeerInfo )
await peerManager . connectRelay ( anotherRemotePeerInfo )
# Given the first node is subscribed to two pubsub topics
var handlerFuture2 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc simpleFutureHandler2 (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
handlerFuture2 . complete ( ( topic , message ) )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
discard node . subscribe ( pubsubTopicB , simpleFutureHandler2 )
# Given the other nodes are subscribed to two pubsub topics
var otherHandlerFuture1 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler1 (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture1 . complete ( ( topic , message ) )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
var otherHandlerFuture2 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler2 (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture2 . complete ( ( topic , message ) )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
var anotherHandlerFuture1 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc anotherSimpleFutureHandler1 (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
anotherHandlerFuture1 . complete ( ( topic , message ) )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
var anotherHandlerFuture2 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc anotherSimpleFutureHandler2 (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
anotherHandlerFuture2 . complete ( ( topic , message ) )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler1 )
discard otherNode . subscribe ( pubsubTopicC , otherSimpleFutureHandler2 )
discard anotherNode . subscribe ( pubsubTopicB , anotherSimpleFutureHandler1 )
discard anotherNode . subscribe ( pubsubTopicC , anotherSimpleFutureHandler2 )
await sleepAsync ( 500 . millis )
# When publishing a message in node for each of the pubsub topics
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
fromNodeWakuMessage1 = fakeWakuMessage ( " fromNode1 " )
fromNodeWakuMessage2 = fakeWakuMessage ( " fromNode2 " )
fromNodeWakuMessage3 = fakeWakuMessage ( " fromNode3 " )
discard await node . publish ( pubsubTopic , fromNodeWakuMessage1 )
discard await node . publish ( pubsubTopicB , fromNodeWakuMessage2 )
discard await node . publish ( pubsubTopicC , fromNodeWakuMessage3 )
# Then the messages are published in all nodes (because it's published in the center node)
# Center meaning that all other nodes are connected to this one
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await handlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
await anotherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
await anotherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
let
( topic1 , msg1 ) = handlerFuture . read ( )
( topic2 , msg2 ) = handlerFuture2 . read ( )
( otherTopic1 , otherMsg1 ) = otherHandlerFuture1 . read ( )
( otherTopic2 , otherMsg2 ) = otherHandlerFuture2 . read ( )
( anotherTopic1 , anotherMsg1 ) = anotherHandlerFuture1 . read ( )
( anotherTopic2 , anotherMsg2 ) = anotherHandlerFuture2 . read ( )
check :
topic1 = = pubsubTopic
msg1 = = fromNodeWakuMessage1
topic2 = = pubsubTopicB
msg2 = = fromNodeWakuMessage2
otherTopic1 = = pubsubTopic
otherMsg1 = = fromNodeWakuMessage1
otherTopic2 = = pubsubTopicC
otherMsg2 = = fromNodeWakuMessage3
anotherTopic1 = = pubsubTopicB
anotherMsg1 = = fromNodeWakuMessage2
anotherTopic2 = = pubsubTopicC
anotherMsg2 = = fromNodeWakuMessage3
# Given anotherNode is completely disconnected from the first one
await anotherPeerManager . switch . disconnect ( peerId )
await peerManager . switch . disconnect ( anotherPeerId )
check :
not anotherPeerManager . switch . isConnected ( peerId )
not peerManager . switch . isConnected ( anotherPeerId )
# When publishing a message in node for each of the pubsub topics
handlerFuture = newPushHandlerFuture ( )
handlerFuture2 = newPushHandlerFuture ( )
otherHandlerFuture1 = newPushHandlerFuture ( )
otherHandlerFuture2 = newPushHandlerFuture ( )
anotherHandlerFuture1 = newPushHandlerFuture ( )
anotherHandlerFuture2 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
fromNodeWakuMessage4 = fakeWakuMessage ( " fromNode4 " )
fromNodeWakuMessage5 = fakeWakuMessage ( " fromNode5 " )
fromNodeWakuMessage6 = fakeWakuMessage ( " fromNode6 " )
discard await node . publish ( pubsubTopic , fromNodeWakuMessage4 )
discard await node . publish ( pubsubTopicB , fromNodeWakuMessage5 )
discard await node . publish ( pubsubTopicC , fromNodeWakuMessage6 )
# Then the message is published in node and otherNode,
# but not in anotherNode because it is not connected anymore
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await handlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
not await anotherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
not await anotherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
let
( topic3 , msg3 ) = handlerFuture . read ( )
( topic4 , msg4 ) = handlerFuture2 . read ( )
( otherTopic3 , otherMsg3 ) = otherHandlerFuture1 . read ( )
( otherTopic4 , otherMsg4 ) = otherHandlerFuture2 . read ( )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
check :
topic3 = = pubsubTopic
msg3 = = fromNodeWakuMessage4
topic4 = = pubsubTopicB
msg4 = = fromNodeWakuMessage5
otherTopic3 = = pubsubTopic
otherMsg3 = = fromNodeWakuMessage4
otherTopic4 = = pubsubTopicC
otherMsg4 = = fromNodeWakuMessage6
# When publishing a message in anotherNode for each of the pubsub topics
handlerFuture = newPushHandlerFuture ( )
handlerFuture2 = newPushHandlerFuture ( )
otherHandlerFuture1 = newPushHandlerFuture ( )
otherHandlerFuture2 = newPushHandlerFuture ( )
anotherHandlerFuture1 = newPushHandlerFuture ( )
anotherHandlerFuture2 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
fromAnotherNodeWakuMessage1 = fakeWakuMessage ( " fromAnotherNode1 " )
fromAnotherNodeWakuMessage2 = fakeWakuMessage ( " fromAnotherNode2 " )
fromAnotherNodeWakuMessage3 = fakeWakuMessage ( " fromAnotherNode3 " )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
discard await anotherNode . publish ( pubsubTopic , fromAnotherNodeWakuMessage1 )
discard await anotherNode . publish ( pubsubTopicB , fromAnotherNodeWakuMessage2 )
discard await anotherNode . publish ( pubsubTopicC , fromAnotherNodeWakuMessage3 )
# Then the messages are only published in anotherNode because it's disconnected from
# the rest of the network
check :
2023-11-15 15:15:38 +00:00
not await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
not await handlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
not await otherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
not await otherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
await anotherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
await anotherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
let
( anotherTopic3 , anotherMsg3 ) = anotherHandlerFuture1 . read ( )
( anotherTopic4 , anotherMsg4 ) = anotherHandlerFuture2 . read ( )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
check :
anotherTopic3 = = pubsubTopicB
anotherMsg3 = = fromAnotherNodeWakuMessage2
anotherTopic4 = = pubsubTopicC
anotherMsg4 = = fromAnotherNodeWakuMessage3
# When publishing a message in otherNode for each of the pubsub topics
handlerFuture = newPushHandlerFuture ( )
handlerFuture2 = newPushHandlerFuture ( )
otherHandlerFuture1 = newPushHandlerFuture ( )
otherHandlerFuture2 = newPushHandlerFuture ( )
anotherHandlerFuture1 = newPushHandlerFuture ( )
anotherHandlerFuture2 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
fromOtherNodeWakuMessage1 = fakeWakuMessage ( " fromOtherNode1 " )
fromOtherNodeWakuMessage2 = fakeWakuMessage ( " fromOtherNode2 " )
fromOtherNodeWakuMessage3 = fakeWakuMessage ( " fromOtherNode3 " )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
discard await otherNode . publish ( pubsubTopic , fromOtherNodeWakuMessage1 )
discard await otherNode . publish ( pubsubTopicB , fromOtherNodeWakuMessage2 )
discard await otherNode . publish ( pubsubTopicC , fromOtherNodeWakuMessage3 )
# Then the messages are only published in otherNode and node, but not in anotherNode
# because it's disconnected from the rest of the network
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await handlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
not await anotherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
not await anotherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
let
( topic5 , msg5 ) = handlerFuture . read ( )
( topic6 , msg6 ) = handlerFuture2 . read ( )
( otherTopic5 , otherMsg5 ) = otherHandlerFuture1 . read ( )
( otherTopic6 , otherMsg6 ) = otherHandlerFuture2 . read ( )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
check :
topic5 = = pubsubTopic
msg5 = = fromOtherNodeWakuMessage1
topic6 = = pubsubTopicB
msg6 = = fromOtherNodeWakuMessage2
otherTopic5 = = pubsubTopic
otherMsg5 = = fromOtherNodeWakuMessage1
otherTopic6 = = pubsubTopicC
otherMsg6 = = fromOtherNodeWakuMessage3
# Given anotherNode is reconnected, but to otherNode
check await anotherPeerManager . connectRelay ( otherRemotePeerInfo )
check :
anotherPeerManager . switch . isConnected ( otherPeerId )
otherPeerManager . switch . isConnected ( anotherPeerId )
# When publishing a message in anotherNode for each of the pubsub topics
handlerFuture = newPushHandlerFuture ( )
handlerFuture2 = newPushHandlerFuture ( )
otherHandlerFuture1 = newPushHandlerFuture ( )
otherHandlerFuture2 = newPushHandlerFuture ( )
anotherHandlerFuture1 = newPushHandlerFuture ( )
anotherHandlerFuture2 = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
fromAnotherNodeWakuMessage4 = fakeWakuMessage ( " fromAnotherNode4 " )
fromAnotherNodeWakuMessage5 = fakeWakuMessage ( " fromAnotherNode5 " )
fromAnotherNodeWakuMessage6 = fakeWakuMessage ( " fromAnotherNode6 " )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
discard await anotherNode . publish ( pubsubTopic , fromAnotherNodeWakuMessage4 )
discard await anotherNode . publish ( pubsubTopicB , fromAnotherNodeWakuMessage5 )
discard await anotherNode . publish ( pubsubTopicC , fromAnotherNodeWakuMessage6 )
# Then the messages are published in all nodes except in node's B topic, because
# even if they're connected like so AnotherNode <-> OtherNode <-> Node,
# otherNode doesn't broadcast B topic messages because it's not subscribed to it
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
not await handlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
await anotherHandlerFuture1 . withTimeout ( FUTURE_TIMEOUT )
await anotherHandlerFuture2 . withTimeout ( FUTURE_TIMEOUT )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
let
( topic7 , msg7 ) = handlerFuture . read ( )
( otherTopic7 , otherMsg7 ) = otherHandlerFuture1 . read ( )
( otherTopic8 , otherMsg8 ) = otherHandlerFuture2 . read ( )
( anotherTopic7 , anotherMsg7 ) = anotherHandlerFuture1 . read ( )
( anotherTopic8 , anotherMsg8 ) = anotherHandlerFuture2 . read ( )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
check :
topic7 = = pubsubTopic
msg7 = = fromAnotherNodeWakuMessage4
otherTopic7 = = pubsubTopic
otherMsg7 = = fromAnotherNodeWakuMessage4
otherTopic8 = = pubsubTopicC
otherMsg8 = = fromAnotherNodeWakuMessage6
anotherTopic7 = = pubsubTopicB
anotherMsg7 = = fromAnotherNodeWakuMessage5
anotherTopic8 = = pubsubTopicC
anotherMsg8 = = fromAnotherNodeWakuMessage6
# Finally stop the other nodes
2024-03-15 23:08:47 +00:00
await allFutures (
otherSwitch . stop ( ) , otherNode . stop ( ) , anotherSwitch . stop ( ) , anotherNode . stop ( )
)
2023-11-15 15:11:36 +00:00
suite " Unsubscribe " :
asyncTest " Without Subscription " :
# Given an external topic handler
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
2024-03-15 23:08:47 +00:00
let otherTopicHandler : TopicHandler =
otherNode . subscribe ( pubsubTopic , simpleFutureHandler )
2023-11-15 15:11:36 +00:00
# Given a node without a subscription
check :
node . subscribedTopics = = [ ]
# When unsubscribing from a pubsub topic from an unsubscribed topic handler
node . unsubscribe ( pubsubTopic , otherTopicHandler )
# Then the node is still not subscribed
check :
node . subscribedTopics = = [ ]
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
asyncTest " Single Node with Single Pubsub Topic " :
# Given a node subscribed to a pubsub topic
let topicHandler = node . subscribe ( pubsubTopic , simpleFutureHandler )
check node . subscribedTopics = = pubsubTopicSeq
# When unsubscribing from the pubsub topic
node . unsubscribe ( pubsubTopic , topicHandler )
# Then the node is not subscribed anymore
check node . subscribedTopics = = [ ]
asyncTest " Single Node with Multiple Pubsub Topics " :
# Given other pubsub topic
2024-07-09 15:36:12 +00:00
let pubsubTopicB = " /waku/2/rs/0/1 "
2023-11-15 15:11:36 +00:00
# Given a node subscribed to multiple pubsub topics
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
topicHandler = node . subscribe ( pubsubTopic , simpleFutureHandler )
topicHandlerB = node . subscribe ( pubsubTopicB , simpleFutureHandler )
2024-07-09 15:36:12 +00:00
assert pubsubTopic in node . subscribedTopics ,
fmt" Node is not subscribed to {pubsubTopic} "
assert pubsubTopicB in node . subscribedTopics ,
fmt" Node is not subscribed to {pubsubTopicB} "
2023-11-15 15:11:36 +00:00
# When unsubscribing from one of the pubsub topics
node . unsubscribe ( pubsubTopic , topicHandler )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the node is still subscribed to the other pubsub topic
check node . subscribedTopics = = @ [ pubsubTopicB ]
# When unsubscribing from the other pubsub topic
node . unsubscribe ( pubsubTopicB , topicHandlerB )
# Then the node is not subscribed anymore
check node . subscribedTopics = = [ ]
suite " Unsubscribe All " :
asyncTest " Without subscriptions " :
# Given a node without subscriptions
check node . subscribedTopics = = [ ]
# When unsubscribing from all pubsub topics
node . unsubscribeAll ( pubsubTopic )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the node is still not subscribed
check node . subscribedTopics = = [ ]
asyncTest " Single Node with Single Pubsub Topic " :
# Given a node subscribed to a pubsub topic
2023-11-15 17:10:10 +00:00
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
2023-11-15 15:11:36 +00:00
check node . subscribedTopics = = pubsubTopicSeq
# When unsubscribing from all pubsub topics
node . unsubscribeAll ( pubsubTopic )
# Then the node is not subscribed anymore
check node . subscribedTopics = = [ ]
asyncTest " Single Node with Multiple Pubsub Topics " :
# Given other pubsub topic
2024-07-09 15:36:12 +00:00
let pubsubTopicB = " /waku/2/rs/0/1 "
2023-11-15 15:11:36 +00:00
# Given a node subscribed to multiple pubsub topics
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
discard node . subscribe ( pubsubTopicB , simpleFutureHandler )
2024-03-15 23:08:47 +00:00
2024-07-09 15:36:12 +00:00
assert pubsubTopic in node . subscribedTopics ,
fmt" Node is not subscribed to {pubsubTopic} "
assert pubsubTopicB in node . subscribedTopics ,
fmt" Node is not subscribed to {pubsubTopicB} "
2023-11-15 15:11:36 +00:00
# When unsubscribing all handlers from pubsubTopic
node . unsubscribeAll ( pubsubTopic )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the node doesn't have pubsubTopic handlers
check node . subscribedTopics = = @ [ pubsubTopicB ]
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# When unsubscribing all handlers from pubsubTopicB
node . unsubscribeAll ( pubsubTopicB )
# Then the node is not subscribed to anything
check node . subscribedTopics = = [ ]
suite " Send & Retrieve Messages " :
asyncTest " Valid Payload Types " :
# Given a second node connected to the first one
let
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
let otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
# Given both are subscribed to the same pubsub topic
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
check :
node . subscribedTopics = = pubsubTopicSeq
otherNode . subscribedTopics = = pubsubTopicSeq
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
await sleepAsync ( 500 . millis )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Given some payloads
let
JSON_DICTIONARY = getSampleJsonDictionary ( )
JSON_LIST = getSampleJsonList ( )
# Given some valid messages
2024-03-15 23:08:47 +00:00
let
msg1 = fakeWakuMessage ( contentTopic = contentTopic , payload = ALPHABETIC )
msg2 = fakeWakuMessage ( contentTopic = contentTopic , payload = ALPHANUMERIC )
msg3 =
fakeWakuMessage ( contentTopic = contentTopic , payload = ALPHANUMERIC_SPECIAL )
msg4 = fakeWakuMessage ( contentTopic = contentTopic , payload = EMOJI )
msg5 = fakeWakuMessage ( contentTopic = contentTopic , payload = CODE )
msg6 = fakeWakuMessage ( contentTopic = contentTopic , payload = QUERY )
msg7 =
fakeWakuMessage ( contentTopic = contentTopic , payload = ( $ JSON_DICTIONARY ) )
msg8 = fakeWakuMessage ( contentTopic = contentTopic , payload = ( $ JSON_LIST ) )
msg9 = fakeWakuMessage ( contentTopic = contentTopic , payload = TEXT_SMALL )
msg10 = fakeWakuMessage ( contentTopic = contentTopic , payload = TEXT_LARGE )
2023-11-15 15:11:36 +00:00
# When sending the alphabetic message
discard await node . publish ( pubsubTopic , msg1 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg1 ) = = handlerFuture . read ( )
( pubsubTopic , msg1 ) = = otherHandlerFuture . read ( )
# When sending the alphanumeric message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg2 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg2 ) = = handlerFuture . read ( )
( pubsubTopic , msg2 ) = = otherHandlerFuture . read ( )
# When sending the alphanumeric special message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg3 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg3 ) = = handlerFuture . read ( )
( pubsubTopic , msg3 ) = = otherHandlerFuture . read ( )
# When sending the emoji message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg4 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg4 ) = = handlerFuture . read ( )
( pubsubTopic , msg4 ) = = otherHandlerFuture . read ( )
# When sending the code message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg5 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg5 ) = = handlerFuture . read ( )
( pubsubTopic , msg5 ) = = otherHandlerFuture . read ( )
# When sending the query message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg6 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg6 ) = = handlerFuture . read ( )
( pubsubTopic , msg6 ) = = otherHandlerFuture . read ( )
# When sending the JSON dictionary message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg7 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg7 ) = = handlerFuture . read ( )
( pubsubTopic , msg7 ) = = otherHandlerFuture . read ( )
# When sending the JSON list message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg8 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg8 ) = = handlerFuture . read ( )
( pubsubTopic , msg8 ) = = otherHandlerFuture . read ( )
# When sending the small text message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg9 )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg9 ) = = handlerFuture . read ( )
( pubsubTopic , msg9 ) = = otherHandlerFuture . read ( )
# When sending the large text message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg10 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg10 ) = = handlerFuture . read ( )
( pubsubTopic , msg10 ) = = otherHandlerFuture . read ( )
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
asyncTest " Valid Payload Sizes " :
# Given a second node connected to the first one
let
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
let otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
# Given both are subscribed to the same pubsub topic
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
check :
node . subscribedTopics = = pubsubTopicSeq
otherNode . subscribedTopics = = pubsubTopicSeq
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
await sleepAsync ( 500 . millis )
# Given some valid payloads
2024-01-03 12:11:50 +00:00
let
msgWithoutPayload =
2024-03-15 23:08:47 +00:00
fakeWakuMessage ( contentTopic = contentTopic , payload = getByteSequence ( 0 ) )
2024-01-03 12:11:50 +00:00
sizeEmptyMsg = uint64 ( msgWithoutPayload . encode ( ) . buffer . len )
2023-11-15 15:11:36 +00:00
let
2024-03-15 23:08:47 +00:00
msg1 =
fakeWakuMessage ( contentTopic = contentTopic , payload = getByteSequence ( 1024 ) )
# 1KiB
msg2 = fakeWakuMessage (
contentTopic = contentTopic , payload = getByteSequence ( 10 * 1024 )
) # 10KiB
msg3 = fakeWakuMessage (
contentTopic = contentTopic , payload = getByteSequence ( 100 * 1024 )
) # 100KiB
msg4 = fakeWakuMessage (
contentTopic = contentTopic ,
2024-07-09 15:36:12 +00:00
payload = getByteSequence ( DefaultMaxWakuMessageSize - sizeEmptyMsg - 26 ) ,
2024-03-15 23:08:47 +00:00
) # Max Size (Inclusive Limit)
msg5 = fakeWakuMessage (
contentTopic = contentTopic ,
2024-07-09 15:36:12 +00:00
payload = getByteSequence ( DefaultMaxWakuMessageSize - sizeEmptyMsg - 25 ) ,
2024-03-15 23:08:47 +00:00
) # Max Size (Exclusive Limit)
msg6 = fakeWakuMessage (
2024-04-20 03:40:52 +00:00
contentTopic = contentTopic ,
payload = getByteSequence ( DefaultMaxWakuMessageSize ) ,
2024-03-15 23:08:47 +00:00
) # MaxWakuMessageSize -> Out of Max Size
2024-01-03 12:11:50 +00:00
# Notice that the message is wrapped with more data in https://github.com/status-im/nim-libp2p/blob/3011ba4326fa55220a758838835797ff322619fc/libp2p/protocols/pubsub/gossipsub.nim#L627-L632
# And therefore, we need to substract a hard-coded values above (for msg4 & msg5), obtained empirically,
# running the tests with 'TRACE' level: nim c -r -d:chronicles_log_level=DEBUG -d:release -d:postgres -d:rln --passL:librln_v0.3.4.a --passL:-lm -d:nimDebugDlOpen tests/waku_relay/test_protocol.nim test "Valid Payload Sizes"
2023-11-16 15:18:50 +00:00
2023-11-15 15:11:36 +00:00
# When sending the 1KiB message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg1 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg1 ) = = handlerFuture . read ( )
( pubsubTopic , msg1 ) = = otherHandlerFuture . read ( )
2023-11-15 15:15:38 +00:00
2023-11-15 15:11:36 +00:00
# When sending the 10KiB message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg2 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg2 ) = = handlerFuture . read ( )
( pubsubTopic , msg2 ) = = otherHandlerFuture . read ( )
2023-11-15 15:15:38 +00:00
2023-11-15 15:11:36 +00:00
# When sending the 100KiB message
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg3 )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg3 ) = = handlerFuture . read ( )
( pubsubTopic , msg3 ) = = otherHandlerFuture . read ( )
2023-11-15 15:15:38 +00:00
2024-04-20 03:40:52 +00:00
# When sending the 'DefaultMaxWakuMessageSize - sizeEmptyMsg - 38' message
2023-11-15 15:11:36 +00:00
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg4 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg4 ) = = handlerFuture . read ( )
( pubsubTopic , msg4 ) = = otherHandlerFuture . read ( )
2024-04-20 03:40:52 +00:00
# When sending the 'DefaultMaxWakuMessageSize - sizeEmptyMsg - 37' message
2023-11-15 15:11:36 +00:00
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg5 )
# Then the message is received in self, because there's no checking, but not in other node
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
not await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg5 ) = = handlerFuture . read ( )
2024-04-20 03:40:52 +00:00
# When sending the 'DefaultMaxWakuMessageSize' message
2023-11-15 15:11:36 +00:00
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg6 )
# Then the message is received in self, because there's no checking, but not in other node
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
not await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg6 ) = = handlerFuture . read ( )
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
asyncTest " Multiple messages at once " :
# Given a second node connected to the first one
let
otherSwitch = newTestSwitch ( )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
let otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
# Given both are subscribed to the same pubsub topic
# Create a different handler than the default to include messages in a seq
var thisHandlerFuture = newPushHandlerFuture ( )
var thisMessageSeq : seq [ ( PubsubTopic , WakuMessage ) ] = @ [ ]
2024-03-15 23:08:47 +00:00
proc thisSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
thisMessageSeq . add ( ( topic , message ) )
thisHandlerFuture . complete ( ( topic , message ) )
var otherHandlerFuture = newPushHandlerFuture ( )
var otherMessageSeq : seq [ ( PubsubTopic , WakuMessage ) ] = @ [ ]
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherMessageSeq . add ( ( topic , message ) )
otherHandlerFuture . complete ( ( topic , message ) )
discard node . subscribe ( pubsubTopic , thisSimpleFutureHandler )
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
check :
node . subscribedTopics = = pubsubTopicSeq
otherNode . subscribedTopics = = pubsubTopicSeq
await sleepAsync ( 500 . millis )
# When sending multiple messages from node
let
msg1 = fakeWakuMessage ( " msg1 " , pubsubTopic )
msg2 = fakeWakuMessage ( " msg2 " , pubsubTopic )
msg3 = fakeWakuMessage ( " msg3 " , pubsubTopic )
msg4 = fakeWakuMessage ( " msg4 " , pubsubTopic )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
discard await node . publish ( pubsubTopic , msg1 )
2023-11-15 15:15:38 +00:00
check await thisHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
check await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
thisHandlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg2 )
2023-11-15 15:15:38 +00:00
check await thisHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
check await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
thisHandlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg3 )
2023-11-15 15:15:38 +00:00
check await thisHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
check await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
thisHandlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
discard await node . publish ( pubsubTopic , msg4 )
check :
2023-11-15 15:15:38 +00:00
await thisHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2024-03-15 23:08:47 +00:00
thisMessageSeq = =
@ [
( pubsubTopic , msg1 ) ,
( pubsubTopic , msg2 ) ,
( pubsubTopic , msg3 ) ,
( pubsubTopic , msg4 ) ,
]
2023-11-15 15:15:38 +00:00
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2024-03-15 23:08:47 +00:00
otherMessageSeq = =
@ [
( pubsubTopic , msg1 ) ,
( pubsubTopic , msg2 ) ,
( pubsubTopic , msg3 ) ,
( pubsubTopic , msg4 ) ,
]
2023-11-15 15:11:36 +00:00
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
suite " Security and Privacy " :
2024-04-18 09:20:39 +00:00
asyncTest " Relay can receive messages after reboot and reconnect " :
2023-11-15 15:11:36 +00:00
# Given a second node connected to the first one
let
otherSwitch = newTestSwitch ( )
otherPeerManager = PeerManager . new ( otherSwitch )
otherNode = await newTestWakuRelay ( otherSwitch )
2024-04-18 09:20:39 +00:00
await otherSwitch . start ( )
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
otherPeerId = otherRemotePeerInfo . peerId
check await peerManager . connectRelay ( otherRemotePeerInfo )
# Given both are subscribed to the same pubsub topic
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
check :
node . subscribedTopics = = pubsubTopicSeq
otherNode . subscribedTopics = = pubsubTopicSeq
await sleepAsync ( 500 . millis )
# Given other node is stopped and restarted
2024-04-18 09:20:39 +00:00
await otherSwitch . stop ( )
await otherSwitch . start ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
2023-11-15 15:11:36 +00:00
# FIXME: Once stopped and started, nodes are not considered connected, nor do they reconnect after running connectRelay, as below
# check await otherPeerManager.connectRelay(otherRemotePeerInfo)
# When sending a message from node
let msg1 = fakeWakuMessage ( testMessage , pubsubTopic )
discard await node . publish ( pubsubTopic , msg1 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg1 ) = = handlerFuture . read ( )
( pubsubTopic , msg1 ) = = otherHandlerFuture . read ( )
# When sending a message from other node
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
let msg2 = fakeWakuMessage ( testMessage , pubsubTopic )
discard await otherNode . publish ( pubsubTopic , msg2 )
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg2 ) = = handlerFuture . read ( )
( pubsubTopic , msg2 ) = = otherHandlerFuture . read ( )
# Given node is stopped and restarted
2024-04-18 09:20:39 +00:00
await switch . stop ( )
await switch . start ( )
check await peerManager . connectRelay ( otherRemotePeerInfo )
2023-11-15 15:11:36 +00:00
# When sending a message from node
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
let msg3 = fakeWakuMessage ( testMessage , pubsubTopic )
discard await node . publish ( pubsubTopic , msg3 )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg3 ) = = handlerFuture . read ( )
( pubsubTopic , msg3 ) = = otherHandlerFuture . read ( )
# When sending a message from other node
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
let msg4 = fakeWakuMessage ( testMessage , pubsubTopic )
discard await otherNode . publish ( pubsubTopic , msg4 )
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg4 ) = = handlerFuture . read ( )
( pubsubTopic , msg4 ) = = otherHandlerFuture . read ( )
# Finally stop the other node
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
2023-11-15 15:15:38 +00:00
asyncTest " Relay can ' t receive messages after subscribing and stopping without unsubscribing " :
2023-11-15 15:11:36 +00:00
# Given a second node connected to the first one
let
otherSwitch = newTestSwitch ( )
otherPeerManager = PeerManager . new ( otherSwitch )
otherNode = await newTestWakuRelay ( otherSwitch )
await allFutures ( otherSwitch . start ( ) , otherNode . start ( ) )
2024-03-15 23:08:47 +00:00
let
2023-11-15 15:11:36 +00:00
otherRemotePeerInfo = otherSwitch . peerInfo . toRemotePeerInfo ( )
otherPeerId = otherRemotePeerInfo . peerId
check await peerManager . connectRelay ( otherRemotePeerInfo )
# Given both are subscribed to the same pubsub topic
var otherHandlerFuture = newPushHandlerFuture ( )
2024-03-15 23:08:47 +00:00
proc otherSimpleFutureHandler (
topic : PubsubTopic , message : WakuMessage
) {. async , gcsafe . } =
2023-11-15 15:11:36 +00:00
otherHandlerFuture . complete ( ( topic , message ) )
discard otherNode . subscribe ( pubsubTopic , otherSimpleFutureHandler )
discard node . subscribe ( pubsubTopic , simpleFutureHandler )
check :
node . subscribedTopics = = pubsubTopicSeq
otherNode . subscribedTopics = = pubsubTopicSeq
2024-03-15 23:08:47 +00:00
2023-11-15 15:11:36 +00:00
await sleepAsync ( 500 . millis )
# Given other node is stopped without unsubscribing
await allFutures ( otherSwitch . stop ( ) , otherNode . stop ( ) )
# When sending a message from node
let msg1 = fakeWakuMessage ( testMessage , pubsubTopic )
discard await node . publish ( pubsubTopic , msg1 )
2023-11-15 15:15:38 +00:00
# Then the message is not received in any node
2023-11-15 15:11:36 +00:00
check :
2023-11-15 15:15:38 +00:00
await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
not await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg1 ) = = handlerFuture . read ( )
2023-11-15 15:15:38 +00:00
2023-11-15 15:11:36 +00:00
# When sending a message from other node
handlerFuture = newPushHandlerFuture ( )
otherHandlerFuture = newPushHandlerFuture ( )
let msg2 = fakeWakuMessage ( testMessage , pubsubTopic )
discard await otherNode . publish ( pubsubTopic , msg2 )
2023-11-15 15:15:38 +00:00
2023-11-15 15:11:36 +00:00
# Then the message is received in both nodes
check :
2023-11-15 15:15:38 +00:00
not await handlerFuture . withTimeout ( FUTURE_TIMEOUT )
await otherHandlerFuture . withTimeout ( FUTURE_TIMEOUT )
2023-11-15 15:11:36 +00:00
( pubsubTopic , msg2 ) = = otherHandlerFuture . read ( )