Skip to content

Commit

Permalink
workaround for 1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
diegomrsantos committed Apr 6, 2023
1 parent cb235e3 commit 5686243
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
22 changes: 17 additions & 5 deletions libp2p/protocols/connectivity/dcutr/client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,25 @@ type
connectTimeout: Duration
maxDialableAddrs: int

AnyCompletedBoolProc = proc (futs: seq[Future[bool]]): Future[Future[bool]] {.async.}

logScope:
topics = "libp2p dcutrclient"

proc new*(T: typedesc[DcutrClient], connectTimeout = 15.seconds, maxDialableAddrs = 8): T =
return T(connectTimeout: connectTimeout, maxDialableAddrs: maxDialableAddrs)

proc startSync*(self: DcutrClient, switch: Switch, remotePeerId: PeerId, addrs: seq[MultiAddress], anyCompletedProc: AnyCompletedProc = anyCompleted) {.async.} =
#FIXME: This is a workaround for 1.2 as we can't use anyCompleted as proc param.
proc anyCompletedBool(futs: seq[Future[bool]]): Future[Future[bool]] =
return anyCompleted(futs)

proc startSync*(self: DcutrClient, switch: Switch, remotePeerId: PeerId, addrs: seq[MultiAddress], anyCompletedBoolProc: AnyCompletedBoolProc = anyCompletedBool) {.async.} =
#FIXME: This is a workaround for 1.2 as we can't use anyCompleted as proc param.
proc connectWrapper(peerId: PeerId, addrs: MultiAddress): Future[bool] {.async.} =
let fut = switch.connect(peerId, @[addrs], forceDial = true, reuseConnection = false, upgradeDir = Direction.In)
await fut
if fut.completed(): return true else: return false

logScope:
peerId = switch.peerInfo.peerId

Expand Down Expand Up @@ -67,10 +79,10 @@ proc startSync*(self: DcutrClient, switch: Switch, remotePeerId: PeerId, addrs:

if peerDialableAddrs.len > self.maxDialableAddrs:
peerDialableAddrs = peerDialableAddrs[0..<self.maxDialableAddrs]
var futs = peerDialableAddrs.mapIt(switch.connect(stream.peerId, @[it], forceDial = true, reuseConnection = false, upgradeDir = Direction.In))
let fut = await anyCompletedProc(futs).wait(self.connectTimeout)
await fut
if fut.completed():
var futs = peerDialableAddrs.mapIt(connectWrapper(stream.peerId, it))
let fut = await anyCompletedBoolProc(futs).wait(self.connectTimeout)
let connected = await fut
if connected:
debug "Dcutr initiator has directly connected to the remote peer."
else:
debug "Dcutr initiator could not connect to the remote peer.", msg = fut.error.msg
Expand Down
1 change: 0 additions & 1 deletion libp2p/utils/future.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import chronos

type
AllFuturesFailedError* = object of CatchableError
AnyCompletedProc* = proc (futs: seq[Future[void]]): Future[Future[void]] {.async.}

proc anyCompleted*[T](futs: seq[Future[T]]): Future[Future[T]] {.async.} =
## Returns a future that will complete with the first future that completes.
Expand Down
4 changes: 2 additions & 2 deletions tests/testdcutr.nim
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ suite "Dcutr":

asyncTest "Client connect timeout":

proc anyCompletedTimeout[T](futs: seq[Future[T]]): Future[Future[T]] {.async.} =
proc anyCompletedTimeout(futs: seq[Future[bool]]): Future[Future[bool]] {.async.} =
await sleepAsync(10.millis)

let behindNATSwitch = newStandardSwitch()
Expand All @@ -85,7 +85,7 @@ suite "Dcutr":

asyncTest "All client connect attempts fail":

proc anyCompletedTimeout[T](futs: seq[Future[T]]): Future[Future[T]] {.async.} =
proc anyCompletedTimeout(futs: seq[Future[bool]]): Future[Future[bool]] {.async.} =
raise newException(AllFuturesFailedError, "None of the futures completed successfully")

let behindNATSwitch = newStandardSwitch()
Expand Down

0 comments on commit 5686243

Please sign in to comment.