Fixed occasional assertion failure on bonding

This commit is contained in:
Yuriy Glukhov 2018-09-06 19:52:56 +03:00 committed by zah
parent 892467b5a8
commit 573ca08643

View File

@ -251,8 +251,10 @@ template onTimeout(b: untyped) =
asyncCheck doSleep() do(): asyncCheck doSleep() do():
b b
proc waitPong(k: KademliaProtocol, n: Node, token: seq[byte]): Future[bool] = proc pingId(n: Node, token: seq[byte]): seq[byte] {.inline.} =
let pingid = token & @(n.node.pubkey.data) result = token & @(n.node.pubkey.data)
proc waitPong(k: KademliaProtocol, n: Node, pingid: seq[byte]): Future[bool] =
assert(pingid notin k.pongFutures, "Already waiting for pong from " & $n) assert(pingid notin k.pongFutures, "Already waiting for pong from " & $n)
result = newFuture[bool]("waitPong") result = newFuture[bool]("waitPong")
let fut = result let fut = result
@ -316,8 +318,12 @@ proc bond(k: KademliaProtocol, n: Node): Future[bool] {.async.} =
if n in k.routing: if n in k.routing:
return true return true
let token = k.ping(n) let pid = pingId(n, k.ping(n))
let gotPong = await k.waitPong(n, token) if pid in k.pongFutures:
debug "Binding failed, already waiting for pong ", n
return false
let gotPong = await k.waitPong(n, pid)
if not gotPong: if not gotPong:
debug "bonding failed, didn't receive pong from ", n debug "bonding failed, didn't receive pong from ", n
# Drop the failing node and schedule a populateNotFullBuckets() call to try and # Drop the failing node and schedule a populateNotFullBuckets() call to try and
@ -329,6 +335,10 @@ proc bond(k: KademliaProtocol, n: Node): Future[bool] {.async.} =
# Give the remote node a chance to ping us before we move on and start sending findNode # Give the remote node a chance to ping us before we move on and start sending findNode
# requests. It is ok for waitPing() to timeout and return false here as that just means # requests. It is ok for waitPing() to timeout and return false here as that just means
# the remote remembers us. # the remote remembers us.
if n in k.pingFutures:
debug "Bonding failed, already waiting for ping ", n
return false
discard await k.waitPing(n) discard await k.waitPing(n)
debug "bonding completed successfully with ", n debug "bonding completed successfully with ", n