fix: remove returned Futures from switch.start (#662)

* fix: remove returned Futures from switch.start

The proc `start` returned a seq of futures that was mean to be awaited by the caller. However, the start proc itself awaited each Future before returning it, so the ceremony requiring the caller to await the Future, and returning the Futures themselves was just used to handle errors. But we'll give a better way to handle errors in a future revision

Remove `switch.start` return type (implicit `Future[void]`)

Update tutorials and examples to reflect the change.

* Raise error during failed transport

Replaces logging of error, and adds comment that it should be replaced with a callback in a future PR.
This commit is contained in:
Eric Mastro 2021-12-04 05:23:12 +11:00 committed by GitHub
parent 6893bd9dbb
commit fffa7e8cc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 168 deletions

View File

@ -181,7 +181,7 @@ proc main() {.async.} =
switch.mount(ChatProto.new(chat)) switch.mount(ChatProto.new(chat))
let libp2pFuts = await switch.start() await switch.start()
let id = $switch.peerInfo.peerId let id = $switch.peerInfo.peerId
echo "PeerID: " & id echo "PeerID: " & id
@ -190,7 +190,6 @@ proc main() {.async.} =
echo &"{a}/p2p/{id}" echo &"{a}/p2p/{id}"
await chat.readLoop() await chat.readLoop()
await allFuturesThrowing(libp2pFuts)
quit(0) quit(0)
waitFor(main()) waitFor(main())

View File

@ -65,9 +65,8 @@ proc main() {.async, gcsafe.} =
# Start the nodes. This will start the transports # Start the nodes. This will start the transports
# and listen on each local addresses # and listen on each local addresses
let await switch1.start()
switch1Fut = await switch1.start() await switch2.start()
switch2Fut = await switch2.start()
# the node addrs is populated with it's # the node addrs is populated with it's
# actual port during the start # actual port during the start
@ -87,6 +86,5 @@ proc main() {.async, gcsafe.} =
await conn.close() await conn.close()
await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports
await allFutures(switch1Fut & switch2Fut) # wait for all transports to shutdown
waitFor(main()) waitFor(main())

View File

@ -73,9 +73,8 @@ We can now create our two switches:
switch1.mount(pingProtocol) switch1.mount(pingProtocol)
let await switch1.start()
switch1Fut = await switch1.start() await switch2.start()
switch2Fut = await switch2.start()
``` ```
We've **mounted** the `pingProtocol` on our first switch. This means that the first switch will actually listen for any ping requests coming in, and handle them accordingly. We've **mounted** the `pingProtocol` on our first switch. This means that the first switch will actually listen for any ping requests coming in, and handle them accordingly.
@ -98,7 +97,6 @@ We now have a `Ping` connection setup between the second and the first switch, w
And that's it! Just a little bit of cleanup: shutting down the switches, waiting for them to stop, and we'll call our `main` procedure: And that's it! Just a little bit of cleanup: shutting down the switches, waiting for them to stop, and we'll call our `main` procedure:
```nim ```nim
await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports
await allFutures(switch1Fut & switch2Fut) # wait for all transports to shutdown
waitFor(main()) waitFor(main())
``` ```

View File

@ -57,11 +57,10 @@ proc main() {.async, gcsafe.} =
switch1.mount(testProto) switch1.mount(testProto)
let await switch1.start()
switch1Fut = await switch1.start() await switch2.start()
switch2Fut = await switch2.start()
conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
await testProto.hello(conn) await testProto.hello(conn)
@ -69,7 +68,6 @@ proc main() {.async, gcsafe.} =
await conn.close() await conn.close()
await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports await allFutures(switch1.stop(), switch2.stop()) # close connections and shutdown all transports
await allFutures(switch1Fut & switch2Fut) # wait for all transports to shutdown
``` ```
This is very similar to the first tutorial's `main`, the only noteworthy difference is that we use `newStandardSwitch`, which is similar to `createSwitch` but is bundled directly in libp2p This is very similar to the first tutorial's `main`, the only noteworthy difference is that we use `newStandardSwitch`, which is similar to `createSwitch` but is bundled directly in libp2p

View File

@ -234,7 +234,7 @@ proc stop*(s: Switch) {.async.} =
trace "Switch stopped" trace "Switch stopped"
proc start*(s: Switch): Future[seq[Future[void]]] {.async, gcsafe.} = proc start*(s: Switch) {.async, gcsafe.} =
trace "starting switch for peer", peerInfo = s.peerInfo trace "starting switch for peer", peerInfo = s.peerInfo
var startFuts: seq[Future[void]] var startFuts: seq[Future[void]]
for t in s.transports: for t in s.transports:
@ -253,7 +253,10 @@ proc start*(s: Switch): Future[seq[Future[void]]] {.async, gcsafe.} =
for s in startFuts: for s in startFuts:
if s.failed: if s.failed:
info "Failed to start one transport", error=s.error.msg # TODO: replace this exception with a `listenError` callback. See
# https://github.com/status-im/nim-libp2p/pull/662 for more info.
raise newException(transport.TransportError,
"Failed to start one transport", s.error)
for t in s.transports: # for each transport for t in s.transports: # for each transport
if t.addrs.len > 0: if t.addrs.len > 0:
@ -261,8 +264,6 @@ proc start*(s: Switch): Future[seq[Future[void]]] {.async, gcsafe.} =
s.peerInfo.addrs &= t.addrs s.peerInfo.addrs &= t.addrs
debug "Started libp2p node", peer = s.peerInfo debug "Started libp2p node", peer = s.peerInfo
return startFuts # listen for incoming connections
proc newSwitch*(peerInfo: PeerInfo, proc newSwitch*(peerInfo: PeerInfo,
transports: seq[Transport], transports: seq[Transport],

View File

@ -129,7 +129,6 @@ suite "Identify":
switch2 {.threadvar.}: Switch switch2 {.threadvar.}: Switch
identifyPush1 {.threadvar.}: IdentifyPush identifyPush1 {.threadvar.}: IdentifyPush
identifyPush2 {.threadvar.}: IdentifyPush identifyPush2 {.threadvar.}: IdentifyPush
awaiters {.threadvar.}: seq[Future[void]]
conn {.threadvar.}: Connection conn {.threadvar.}: Connection
asyncSetup: asyncSetup:
switch1 = newStandardSwitch() switch1 = newStandardSwitch()
@ -146,8 +145,8 @@ suite "Identify":
switch1.mount(identifyPush1) switch1.mount(identifyPush1)
switch2.mount(identifyPush2) switch2.mount(identifyPush2)
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
conn = await switch2.dial( conn = await switch2.dial(
switch1.peerInfo.peerId, switch1.peerInfo.peerId,
@ -167,9 +166,6 @@ suite "Identify":
await switch1.stop() await switch1.stop()
await switch2.stop() await switch2.stop()
# this needs to go at end
await allFuturesThrowing(awaiters)
asyncTest "simple push identify": asyncTest "simple push identify":
switch2.peerInfo.protocols.add("/newprotocol/") switch2.peerInfo.protocols.add("/newprotocol/")
switch2.peerInfo.addrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet()) switch2.peerInfo.addrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet())

View File

@ -54,7 +54,7 @@ proc testPubSubDaemonPublish(gossip: bool = false, count: int = 1) {.async.} =
nativeNode.mount(pubsub) nativeNode.mount(pubsub)
let awaiters = nativeNode.start() await nativeNode.start()
await pubsub.start() await pubsub.start()
let nativePeer = nativeNode.peerInfo let nativePeer = nativeNode.peerInfo
@ -90,7 +90,6 @@ proc testPubSubDaemonPublish(gossip: bool = false, count: int = 1) {.async.} =
await nativeNode.stop() await nativeNode.stop()
await pubsub.stop() await pubsub.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
proc testPubSubNodePublish(gossip: bool = false, count: int = 1) {.async.} = proc testPubSubNodePublish(gossip: bool = false, count: int = 1) {.async.} =
@ -115,7 +114,7 @@ proc testPubSubNodePublish(gossip: bool = false, count: int = 1) {.async.} =
nativeNode.mount(pubsub) nativeNode.mount(pubsub)
let awaiters = nativeNode.start() await nativeNode.start()
await pubsub.start() await pubsub.start()
let nativePeer = nativeNode.peerInfo let nativePeer = nativeNode.peerInfo
@ -151,7 +150,6 @@ proc testPubSubNodePublish(gossip: bool = false, count: int = 1) {.async.} =
check finished check finished
await nativeNode.stop() await nativeNode.stop()
await pubsub.stop() await pubsub.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
suite "Interop": suite "Interop":
@ -171,7 +169,7 @@ suite "Interop":
secureManagers = [SecureProtocol.Noise], secureManagers = [SecureProtocol.Noise],
outTimeout = 5.minutes) outTimeout = 5.minutes)
let awaiters = await nativeNode.start() await nativeNode.start()
let daemonNode = await newDaemonApi() let daemonNode = await newDaemonApi()
let daemonPeer = await daemonNode.identity() let daemonPeer = await daemonNode.identity()
@ -195,7 +193,6 @@ suite "Interop":
await nativeNode.stop() await nativeNode.stop()
await daemonNode.close() await daemonNode.close()
await allFutures(awaiters)
await sleepAsync(1.seconds) await sleepAsync(1.seconds)
@ -215,7 +212,7 @@ suite "Interop":
secureManagers = [SecureProtocol.Noise], secureManagers = [SecureProtocol.Noise],
outTimeout = 5.minutes) outTimeout = 5.minutes)
let awaiters = await nativeNode.start() await nativeNode.start()
let daemonNode = await newDaemonApi() let daemonNode = await newDaemonApi()
let daemonPeer = await daemonNode.identity() let daemonPeer = await daemonNode.identity()
@ -236,7 +233,6 @@ suite "Interop":
await conn.close() await conn.close()
await nativeNode.stop() await nativeNode.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
asyncTest "daemon -> native connection": asyncTest "daemon -> native connection":
@ -260,7 +256,7 @@ suite "Interop":
nativeNode.mount(proto) nativeNode.mount(proto)
let awaiters = await nativeNode.start() await nativeNode.start()
let nativePeer = nativeNode.peerInfo let nativePeer = nativeNode.peerInfo
let daemonNode = await newDaemonApi() let daemonNode = await newDaemonApi()
@ -272,7 +268,6 @@ suite "Interop":
await stream.close() await stream.close()
await nativeNode.stop() await nativeNode.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
await sleepAsync(1.seconds) await sleepAsync(1.seconds)
@ -305,7 +300,7 @@ suite "Interop":
nativeNode.mount(proto) nativeNode.mount(proto)
let awaiters = await nativeNode.start() await nativeNode.start()
let nativePeer = nativeNode.peerInfo let nativePeer = nativeNode.peerInfo
let daemonNode = await newDaemonApi(hostAddresses = @[wsAddress]) let daemonNode = await newDaemonApi(hostAddresses = @[wsAddress])
@ -317,7 +312,6 @@ suite "Interop":
await stream.close() await stream.close()
await nativeNode.stop() await nativeNode.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
await sleepAsync(1.seconds) await sleepAsync(1.seconds)
@ -343,7 +337,7 @@ suite "Interop":
.withNoise() .withNoise()
.build() .build()
let awaiters = await nativeNode.start() await nativeNode.start()
let daemonNode = await newDaemonApi(hostAddresses = @[wsAddress]) let daemonNode = await newDaemonApi(hostAddresses = @[wsAddress])
let daemonPeer = await daemonNode.identity() let daemonPeer = await daemonNode.identity()
@ -364,7 +358,6 @@ suite "Interop":
await conn.close() await conn.close()
await nativeNode.stop() await nativeNode.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
asyncTest "daemon -> multiple reads and writes": asyncTest "daemon -> multiple reads and writes":
@ -391,7 +384,7 @@ suite "Interop":
nativeNode.mount(proto) nativeNode.mount(proto)
let awaiters = await nativeNode.start() await nativeNode.start()
let nativePeer = nativeNode.peerInfo let nativePeer = nativeNode.peerInfo
let daemonNode = await newDaemonApi() let daemonNode = await newDaemonApi()
@ -408,7 +401,6 @@ suite "Interop":
await stream.close() await stream.close()
await nativeNode.stop() await nativeNode.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
asyncTest "read write multiple": asyncTest "read write multiple":
@ -437,7 +429,7 @@ suite "Interop":
nativeNode.mount(proto) nativeNode.mount(proto)
let awaiters = await nativeNode.start() await nativeNode.start()
let nativePeer = nativeNode.peerInfo let nativePeer = nativeNode.peerInfo
let daemonNode = await newDaemonApi() let daemonNode = await newDaemonApi()
@ -454,7 +446,6 @@ suite "Interop":
check 10 == (await wait(testFuture, 1.minutes)) check 10 == (await wait(testFuture, 1.minutes))
await stream.close() await stream.close()
await nativeNode.stop() await nativeNode.stop()
await allFutures(awaiters)
await daemonNode.close() await daemonNode.close()
asyncTest "floodsub: daemon publish one": asyncTest "floodsub: daemon publish one":

View File

@ -257,7 +257,6 @@ suite "Noise":
var peerInfo1, peerInfo2: PeerInfo var peerInfo1, peerInfo2: PeerInfo
var switch1, switch2: Switch var switch1, switch2: Switch
var awaiters: seq[Future[void]]
(switch1, peerInfo1) = createSwitch(ma1, false) (switch1, peerInfo1) = createSwitch(ma1, false)
@ -266,8 +265,8 @@ suite "Noise":
testProto.codec = TestCodec testProto.codec = TestCodec
switch1.mount(testProto) switch1.mount(testProto)
(switch2, peerInfo2) = createSwitch(ma2, true) (switch2, peerInfo2) = createSwitch(ma2, true)
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
await conn.writeLp("Hello!") await conn.writeLp("Hello!")
let msg = string.fromBytes(await conn.readLp(1024)) let msg = string.fromBytes(await conn.readLp(1024))
@ -277,7 +276,6 @@ suite "Noise":
await allFuturesThrowing( await allFuturesThrowing(
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
await allFuturesThrowing(awaiters)
asyncTest "e2e test wrong secure negotiation": asyncTest "e2e test wrong secure negotiation":
let ma1 = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet() let ma1 = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
@ -285,7 +283,6 @@ suite "Noise":
var peerInfo1, peerInfo2: PeerInfo var peerInfo1, peerInfo2: PeerInfo
var switch1, switch2: Switch var switch1, switch2: Switch
var awaiters: seq[Future[void]]
(switch1, peerInfo1) = createSwitch(ma1, false) (switch1, peerInfo1) = createSwitch(ma1, false)
@ -294,13 +291,11 @@ suite "Noise":
testProto.codec = TestCodec testProto.codec = TestCodec
switch1.mount(testProto) switch1.mount(testProto)
(switch2, peerInfo2) = createSwitch(ma2, true, true) # secio, we want to fail (switch2, peerInfo2) = createSwitch(ma2, true, true) # secio, we want to fail
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
expect(UpgradeFailedError): expect(UpgradeFailedError):
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
await allFuturesThrowing( await allFuturesThrowing(
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
await allFuturesThrowing(awaiters)

View File

@ -54,9 +54,8 @@ suite "Switch":
switch1.mount(testProto) switch1.mount(testProto)
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
var awaiters: seq[Future[void]] await switch1.start()
awaiters.add(await switch1.start()) await switch2.start()
awaiters.add(await switch2.start())
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
@ -73,9 +72,6 @@ suite "Switch":
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
# this needs to go at end
await allFuturesThrowing(awaiters)
check not switch1.isConnected(switch2.peerInfo.peerId) check not switch1.isConnected(switch2.peerInfo.peerId)
check not switch2.isConnected(switch1.peerInfo.peerId) check not switch2.isConnected(switch1.peerInfo.peerId)
@ -103,9 +99,8 @@ suite "Switch":
switch1.mount(testProto, match) switch1.mount(testProto, match)
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise]) let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
var awaiters: seq[Future[void]] await switch1.start()
awaiters.add(await switch1.start()) await switch2.start()
awaiters.add(await switch2.start())
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, callProto) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, callProto)
@ -122,9 +117,6 @@ suite "Switch":
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
# this needs to go at end
await allFuturesThrowing(awaiters)
check not switch1.isConnected(switch2.peerInfo.peerId) check not switch1.isConnected(switch2.peerInfo.peerId)
check not switch2.isConnected(switch1.peerInfo.peerId) check not switch2.isConnected(switch1.peerInfo.peerId)
@ -147,9 +139,8 @@ suite "Switch":
switch1.mount(testProto) switch1.mount(testProto)
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
var awaiters: seq[Future[void]] await switch1.start()
awaiters.add(await switch1.start()) await switch2.start()
awaiters.add(await switch2.start())
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
@ -167,15 +158,10 @@ suite "Switch":
switch2.stop(), switch2.stop(),
) )
# this needs to go at end
await allFuturesThrowing(awaiters)
check not switch1.isConnected(switch2.peerInfo.peerId) check not switch1.isConnected(switch2.peerInfo.peerId)
check not switch2.isConnected(switch1.peerInfo.peerId) check not switch2.isConnected(switch1.peerInfo.peerId)
asyncTest "e2e use connect then dial": asyncTest "e2e use connect then dial":
var awaiters: seq[Future[void]]
proc handle(conn: Connection, proto: string) {.async, gcsafe.} = proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
try: try:
let msg = string.fromBytes(await conn.readLp(1024)) let msg = string.fromBytes(await conn.readLp(1024))
@ -192,8 +178,8 @@ suite "Switch":
switch1.mount(testProto) switch1.mount(testProto)
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise]) let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
@ -210,18 +196,15 @@ suite "Switch":
switch1.stop(), switch1.stop(),
switch2.stop() switch2.stop()
) )
await allFuturesThrowing(awaiters)
check not switch1.isConnected(switch2.peerInfo.peerId) check not switch1.isConnected(switch2.peerInfo.peerId)
check not switch2.isConnected(switch1.peerInfo.peerId) check not switch2.isConnected(switch1.peerInfo.peerId)
asyncTest "e2e should not leak on peer disconnect": asyncTest "e2e should not leak on peer disconnect":
var awaiters: seq[Future[void]]
let switch1 = newStandardSwitch() let switch1 = newStandardSwitch()
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
@ -239,11 +222,8 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
await allFuturesThrowing(awaiters)
asyncTest "e2e should trigger connection events (remote)": asyncTest "e2e should trigger connection events (remote)":
var awaiters: seq[Future[void]]
let switch1 = newStandardSwitch() let switch1 = newStandardSwitch()
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
@ -269,8 +249,8 @@ suite "Switch":
switch2.addConnEventHandler(hook, ConnEventKind.Connected) switch2.addConnEventHandler(hook, ConnEventKind.Connected)
switch2.addConnEventHandler(hook, ConnEventKind.Disconnected) switch2.addConnEventHandler(hook, ConnEventKind.Disconnected)
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
@ -294,11 +274,8 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
await allFuturesThrowing(awaiters)
asyncTest "e2e should trigger connection events (local)": asyncTest "e2e should trigger connection events (local)":
var awaiters: seq[Future[void]]
let switch1 = newStandardSwitch() let switch1 = newStandardSwitch()
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
@ -324,8 +301,8 @@ suite "Switch":
switch1.addConnEventHandler(hook, ConnEventKind.Connected) switch1.addConnEventHandler(hook, ConnEventKind.Connected)
switch1.addConnEventHandler(hook, ConnEventKind.Disconnected) switch1.addConnEventHandler(hook, ConnEventKind.Disconnected)
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
@ -349,11 +326,8 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
await allFuturesThrowing(awaiters)
asyncTest "e2e should trigger peer events (remote)": asyncTest "e2e should trigger peer events (remote)":
var awaiters: seq[Future[void]]
let switch1 = newStandardSwitch() let switch1 = newStandardSwitch()
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
@ -378,8 +352,8 @@ suite "Switch":
switch1.addPeerEventHandler(handler, PeerEventKind.Joined) switch1.addPeerEventHandler(handler, PeerEventKind.Joined)
switch1.addPeerEventHandler(handler, PeerEventKind.Left) switch1.addPeerEventHandler(handler, PeerEventKind.Left)
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
@ -403,11 +377,8 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
await allFuturesThrowing(awaiters)
asyncTest "e2e should trigger peer events (local)": asyncTest "e2e should trigger peer events (local)":
var awaiters: seq[Future[void]]
let switch1 = newStandardSwitch() let switch1 = newStandardSwitch()
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
@ -432,8 +403,8 @@ suite "Switch":
switch2.addPeerEventHandler(handler, PeerEventKind.Joined) switch2.addPeerEventHandler(handler, PeerEventKind.Joined)
switch2.addPeerEventHandler(handler, PeerEventKind.Left) switch2.addPeerEventHandler(handler, PeerEventKind.Left)
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs)
@ -457,11 +428,8 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
await allFuturesThrowing(awaiters)
asyncTest "e2e should trigger peer events only once per peer": asyncTest "e2e should trigger peer events only once per peer":
var awaiters: seq[Future[void]]
let switch1 = newStandardSwitch() let switch1 = newStandardSwitch()
let rng = crypto.newRng() let rng = crypto.newRng()
@ -494,9 +462,9 @@ suite "Switch":
switch1.addPeerEventHandler(handler, PeerEventKind.Joined) switch1.addPeerEventHandler(handler, PeerEventKind.Joined)
switch1.addPeerEventHandler(handler, PeerEventKind.Left) switch1.addPeerEventHandler(handler, PeerEventKind.Left)
awaiters.add(await switch1.start()) await switch1.start()
awaiters.add(await switch2.start()) await switch2.start()
awaiters.add(await switch3.start()) await switch3.start()
await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) # should trigger 1st Join event await switch2.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) # should trigger 1st Join event
await switch3.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) # should trigger 2nd Join event await switch3.connect(switch1.peerInfo.peerId, switch1.peerInfo.addrs) # should trigger 2nd Join event
@ -526,11 +494,8 @@ suite "Switch":
switch1.stop(), switch1.stop(),
switch2.stop(), switch2.stop(),
switch3.stop()) switch3.stop())
await allFuturesThrowing(awaiters)
asyncTest "e2e should allow dropping peer from connection events": asyncTest "e2e should allow dropping peer from connection events":
var awaiters: seq[Future[void]]
let rng = crypto.newRng() let rng = crypto.newRng()
# use same private keys to emulate two connection from same peer # use same private keys to emulate two connection from same peer
let let
@ -555,7 +520,7 @@ suite "Switch":
switches[0].addConnEventHandler(hook, ConnEventKind.Connected) switches[0].addConnEventHandler(hook, ConnEventKind.Connected)
switches[0].addConnEventHandler(hook, ConnEventKind.Disconnected) switches[0].addConnEventHandler(hook, ConnEventKind.Disconnected)
awaiters.add(await switches[0].start()) await switches[0].start()
switches.add(newStandardSwitch( switches.add(newStandardSwitch(
privKey = some(privateKey), privKey = some(privateKey),
@ -569,11 +534,8 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
switches.mapIt( it.stop() )) switches.mapIt( it.stop() ))
await allFuturesThrowing(awaiters)
asyncTest "e2e should allow dropping multiple connections for peer from connection events": asyncTest "e2e should allow dropping multiple connections for peer from connection events":
var awaiters: seq[Future[void]]
let rng = crypto.newRng() let rng = crypto.newRng()
# use same private keys to emulate two connection from same peer # use same private keys to emulate two connection from same peer
let let
@ -603,7 +565,7 @@ suite "Switch":
rng = rng)) rng = rng))
switches[0].addConnEventHandler(hook, ConnEventKind.Connected) switches[0].addConnEventHandler(hook, ConnEventKind.Connected)
awaiters.add(await switches[0].start()) await switches[0].start()
for i in 1..5: for i in 1..5:
switches.add(newStandardSwitch( switches.add(newStandardSwitch(
@ -619,7 +581,6 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
switches.mapIt( it.stop() )) switches.mapIt( it.stop() ))
await allFuturesThrowing(awaiters)
# TODO: we should be able to test cancellation # TODO: we should be able to test cancellation
# for most of the steps in the upgrade flow - # for most of the steps in the upgrade flow -
@ -641,8 +602,7 @@ suite "Switch":
let handlerWait = acceptHandler() let handlerWait = acceptHandler()
let switch = newStandardSwitch(secureManagers = [SecureProtocol.Noise]) let switch = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
var awaiters: seq[Future[void]] await switch.start()
awaiters.add(await switch.start())
var peerId = PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get() var peerId = PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get()
let connectFut = switch.connect(peerId, transport.addrs) let connectFut = switch.connect(peerId, transport.addrs)
@ -658,9 +618,6 @@ suite "Switch":
transport.stop(), transport.stop(),
switch.stop()) switch.stop())
# this needs to go at end
await allFuturesThrowing(awaiters)
asyncTest "e2e closing remote conn should not leak": asyncTest "e2e closing remote conn should not leak":
let ma = @[Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()] let ma = @[Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()]
@ -674,8 +631,7 @@ suite "Switch":
let handlerWait = acceptHandler() let handlerWait = acceptHandler()
let switch = newStandardSwitch(secureManagers = [SecureProtocol.Noise]) let switch = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
var awaiters: seq[Future[void]] await switch.start()
awaiters.add(await switch.start())
var peerId = PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get() var peerId = PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get()
expect LPStreamClosedError: expect LPStreamClosedError:
@ -691,9 +647,6 @@ suite "Switch":
transport.stop(), transport.stop(),
switch.stop()) switch.stop())
# this needs to go at end
await allFuturesThrowing(awaiters)
asyncTest "e2e calling closeWithEOF on the same stream should not assert": asyncTest "e2e calling closeWithEOF on the same stream should not assert":
proc handle(conn: Connection, proto: string) {.async, gcsafe.} = proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
discard await conn.readLp(100) discard await conn.readLp(100)
@ -707,8 +660,7 @@ suite "Switch":
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise]) let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
var awaiters: seq[Future[void]] await switch1.start()
awaiters.add(await switch1.start())
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
@ -729,12 +681,9 @@ suite "Switch":
await switch1.stop() await switch1.stop()
# this needs to go at end
await allFuturesThrowing(awaiters)
asyncTest "connect to inexistent peer": asyncTest "connect to inexistent peer":
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise]) let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
discard await switch2.start() await switch2.start()
let someAddr = MultiAddress.init("/ip4/127.128.0.99").get() let someAddr = MultiAddress.init("/ip4/127.128.0.99").get()
let seckey = PrivateKey.random(ECDSA, rng[]).get() let seckey = PrivateKey.random(ECDSA, rng[]).get()
let somePeer = PeerInfo.new(secKey, [someAddr]) let somePeer = PeerInfo.new(secKey, [someAddr])
@ -743,46 +692,41 @@ suite "Switch":
await switch2.stop() await switch2.stop()
asyncTest "e2e total connection limits on incoming connections": asyncTest "e2e total connection limits on incoming connections":
var awaiters: seq[Future[void]]
var switches: seq[Switch] var switches: seq[Switch]
let destSwitch = newStandardSwitch(maxConnections = 3) let destSwitch = newStandardSwitch(maxConnections = 3)
switches.add(destSwitch) switches.add(destSwitch)
awaiters.add(await destSwitch.start()) await destSwitch.start()
let destPeerInfo = destSwitch.peerInfo let destPeerInfo = destSwitch.peerInfo
for i in 0..<3: for i in 0..<3:
let switch = newStandardSwitch() let switch = newStandardSwitch()
switches.add(switch) switches.add(switch)
awaiters.add(await switch.start()) await switch.start()
check await switch.connect(destPeerInfo.peerId, destPeerInfo.addrs) check await switch.connect(destPeerInfo.peerId, destPeerInfo.addrs)
.withTimeout(1000.millis) .withTimeout(1000.millis)
let switchFail = newStandardSwitch() let switchFail = newStandardSwitch()
switches.add(switchFail) switches.add(switchFail)
awaiters.add(await switchFail.start()) await switchFail.start()
check not(await switchFail.connect(destPeerInfo.peerId, destPeerInfo.addrs) check not(await switchFail.connect(destPeerInfo.peerId, destPeerInfo.addrs)
.withTimeout(1000.millis)) .withTimeout(1000.millis))
await allFuturesThrowing( await allFuturesThrowing(
allFutures(switches.mapIt( it.stop() ))) allFutures(switches.mapIt( it.stop() )))
await allFuturesThrowing(awaiters)
asyncTest "e2e total connection limits on incoming connections": asyncTest "e2e total connection limits on incoming connections":
var awaiters: seq[Future[void]]
var switches: seq[Switch] var switches: seq[Switch]
for i in 0..<3: for i in 0..<3:
switches.add(newStandardSwitch()) switches.add(newStandardSwitch())
awaiters.add(await switches[i].start()) await switches[i].start()
let srcSwitch = newStandardSwitch(maxConnections = 3) let srcSwitch = newStandardSwitch(maxConnections = 3)
awaiters.add(await srcSwitch.start()) await srcSwitch.start()
let dstSwitch = newStandardSwitch() let dstSwitch = newStandardSwitch()
awaiters.add(await dstSwitch.start()) await dstSwitch.start()
for s in switches: for s in switches:
check await srcSwitch.connect(s.peerInfo.peerId, s.peerInfo.addrs) check await srcSwitch.connect(s.peerInfo.peerId, s.peerInfo.addrs)
@ -796,49 +740,44 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
allFutures(switches.mapIt( it.stop() ))) allFutures(switches.mapIt( it.stop() )))
await allFuturesThrowing(awaiters)
asyncTest "e2e max incoming connection limits": asyncTest "e2e max incoming connection limits":
var awaiters: seq[Future[void]]
var switches: seq[Switch] var switches: seq[Switch]
let destSwitch = newStandardSwitch(maxIn = 3) let destSwitch = newStandardSwitch(maxIn = 3)
switches.add(destSwitch) switches.add(destSwitch)
awaiters.add(await destSwitch.start()) await destSwitch.start()
let destPeerInfo = destSwitch.peerInfo let destPeerInfo = destSwitch.peerInfo
for i in 0..<3: for i in 0..<3:
let switch = newStandardSwitch() let switch = newStandardSwitch()
switches.add(switch) switches.add(switch)
awaiters.add(await switch.start()) await switch.start()
check await switch.connect(destPeerInfo.peerId, destPeerInfo.addrs) check await switch.connect(destPeerInfo.peerId, destPeerInfo.addrs)
.withTimeout(1000.millis) .withTimeout(1000.millis)
let switchFail = newStandardSwitch() let switchFail = newStandardSwitch()
switches.add(switchFail) switches.add(switchFail)
awaiters.add(await switchFail.start()) await switchFail.start()
check not(await switchFail.connect(destPeerInfo.peerId, destPeerInfo.addrs) check not(await switchFail.connect(destPeerInfo.peerId, destPeerInfo.addrs)
.withTimeout(1000.millis)) .withTimeout(1000.millis))
await allFuturesThrowing( await allFuturesThrowing(
allFutures(switches.mapIt( it.stop() ))) allFutures(switches.mapIt( it.stop() )))
await allFuturesThrowing(awaiters)
asyncTest "e2e max outgoing connection limits": asyncTest "e2e max outgoing connection limits":
var awaiters: seq[Future[void]]
var switches: seq[Switch] var switches: seq[Switch]
for i in 0..<3: for i in 0..<3:
switches.add(newStandardSwitch()) switches.add(newStandardSwitch())
awaiters.add(await switches[i].start()) await switches[i].start()
let srcSwitch = newStandardSwitch(maxOut = 3) let srcSwitch = newStandardSwitch(maxOut = 3)
awaiters.add(await srcSwitch.start()) await srcSwitch.start()
let dstSwitch = newStandardSwitch() let dstSwitch = newStandardSwitch()
awaiters.add(await dstSwitch.start()) await dstSwitch.start()
for s in switches: for s in switches:
check await srcSwitch.connect(s.peerInfo.peerId, s.peerInfo.addrs) check await srcSwitch.connect(s.peerInfo.peerId, s.peerInfo.addrs)
@ -852,7 +791,6 @@ suite "Switch":
await allFuturesThrowing( await allFuturesThrowing(
allFutures(switches.mapIt( it.stop() ))) allFutures(switches.mapIt( it.stop() )))
await allFuturesThrowing(awaiters)
asyncTest "e2e peer store": asyncTest "e2e peer store":
let done = newFuture[void]() let done = newFuture[void]()
@ -873,9 +811,8 @@ suite "Switch":
switch1.mount(testProto) switch1.mount(testProto)
let switch2 = newStandardSwitch() let switch2 = newStandardSwitch()
var awaiters: seq[Future[void]] await switch1.start()
awaiters.add(await switch1.start()) await switch2.start()
awaiters.add(await switch2.start())
let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec) let conn = await switch2.dial(switch1.peerInfo.peerId, switch1.peerInfo.addrs, TestCodec)
@ -892,9 +829,6 @@ suite "Switch":
switch1.stop(), switch1.stop(),
switch2.stop()) switch2.stop())
# this needs to go at end
await allFuturesThrowing(awaiters)
check not switch1.isConnected(switch2.peerInfo.peerId) check not switch1.isConnected(switch2.peerInfo.peerId)
check not switch2.isConnected(switch1.peerInfo.peerId) check not switch2.isConnected(switch1.peerInfo.peerId)
@ -973,7 +907,6 @@ suite "Switch":
check not switch2.isConnected(switch1.peerInfo.peerId) check not switch2.isConnected(switch1.peerInfo.peerId)
asyncTest "e2e dial dns4 address": asyncTest "e2e dial dns4 address":
var awaiters: seq[Future[void]]
let resolver = MockResolver.new() let resolver = MockResolver.new()
resolver.ipResponses[("localhost", false)] = @["127.0.0.1"] resolver.ipResponses[("localhost", false)] = @["127.0.0.1"]
resolver.ipResponses[("localhost", true)] = @["::1"] resolver.ipResponses[("localhost", true)] = @["::1"]
@ -982,9 +915,8 @@ suite "Switch":
srcSwitch = newStandardSwitch(nameResolver = resolver) srcSwitch = newStandardSwitch(nameResolver = resolver)
destSwitch = newStandardSwitch() destSwitch = newStandardSwitch()
awaiters.add(await destSwitch.start()) await destSwitch.start()
awaiters.add(await srcSwitch.start()) await srcSwitch.start()
await allFuturesThrowing(awaiters)
let testAddr = MultiAddress.init("/dns4/localhost/").tryGet() & let testAddr = MultiAddress.init("/dns4/localhost/").tryGet() &
destSwitch.peerInfo.addrs[0][1].tryGet() destSwitch.peerInfo.addrs[0][1].tryGet()
@ -996,7 +928,6 @@ suite "Switch":
await srcSwitch.stop() await srcSwitch.stop()
asyncTest "e2e dial dnsaddr with multiple transports": asyncTest "e2e dial dnsaddr with multiple transports":
var awaiters: seq[Future[void]]
let resolver = MockResolver.new() let resolver = MockResolver.new()
let let
@ -1024,10 +955,8 @@ suite "Switch":
.withNoise() .withNoise()
.build() .build()
awaiters.add(await destSwitch.start()) await destSwitch.start()
awaiters.add(await srcTcpSwitch.start()) await srcWsSwitch.start()
awaiters.add(await srcWsSwitch.start())
await allFuturesThrowing(awaiters)
resolver.txtResponses["_dnsaddr.test.io"] = @[ resolver.txtResponses["_dnsaddr.test.io"] = @[
"dnsaddr=" & $destSwitch.peerInfo.addrs[0], "dnsaddr=" & $destSwitch.peerInfo.addrs[0],