Merge pull request #35 from status-im/bootstrap-retry-fix

Fixed discovery busyloop when no bootnodes provided
This commit is contained in:
Yuriy Glukhov 2019-04-10 20:20:04 +03:00 committed by GitHub
commit a6be6426ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 17 deletions

View File

@ -46,7 +46,7 @@ type
const const
BUCKET_SIZE = 16 BUCKET_SIZE = 16
BITS_PER_HOP = 8 BITS_PER_HOP = 8
REQUEST_TIMEOUT = 900 # timeout of message round trips REQUEST_TIMEOUT = chronos.milliseconds(900) # timeout of message round trips
FIND_CONCURRENCY = 3 # parallel find node lookups FIND_CONCURRENCY = 3 # parallel find node lookups
ID_SIZE = 256 ID_SIZE = 256
@ -419,19 +419,25 @@ proc resolve*(k: KademliaProtocol, id: NodeId): Future[Node] {.async.} =
proc bootstrap*(k: KademliaProtocol, bootstrapNodes: seq[Node], retries = 0) {.async.} = proc bootstrap*(k: KademliaProtocol, bootstrapNodes: seq[Node], retries = 0) {.async.} =
## Bond with bootstrap nodes and do initial lookup. Retry `retries` times ## Bond with bootstrap nodes and do initial lookup. Retry `retries` times
## in case of failure, or indefinitely if `retries` is 0. ## in case of failure, or indefinitely if `retries` is 0.
var retryInterval = chronos.milliseconds(2)
var numTries = 0 var numTries = 0
if bootstrapNodes.len != 0:
while true: while true:
let bonded = await all(bootstrapNodes.mapIt(k.bond(it))) let bonded = await all(bootstrapNodes.mapIt(k.bond(it)))
if true notin bonded: if true notin bonded:
info "Failed to bond with bootstrap nodes"
inc numTries inc numTries
if retries == 0 or numTries < retries: if retries == 0 or numTries < retries:
info "Retrying" info "Failed to bond with bootstrap nodes, retrying"
retryInterval = min(chronos.seconds(10), retryInterval * 2)
await sleepAsync(retryInterval)
else: else:
info "Failed to bond with bootstrap nodes"
return return
else: else:
break break
discard await k.lookupRandom() discard await k.lookupRandom() # Prepopulate the routing table
else:
info "Skipping discovery bootstrap, no bootnodes provided"
proc recvPong*(k: KademliaProtocol, n: Node, token: seq[byte]) = proc recvPong*(k: KademliaProtocol, n: Node, token: seq[byte]) =
trace "<<< pong from ", n trace "<<< pong from ", n

View File

@ -61,6 +61,6 @@ proc verifyStateType(t: NimNode): NimNode =
if result.kind != nnkBracketExpr or $result[0] != "ref": if result.kind != nnkBracketExpr or $result[0] != "ref":
macros.error($result & " must be a ref type") macros.error($result & " must be a ref type")
proc newFuture[T](location: var Future[T]) = proc initFuture[T](loc: var Future[T]) =
location = newFuture[T]() loc = newFuture[T]()

View File

@ -500,7 +500,7 @@ proc nextMsg*(peer: Peer, MsgType: type): Future[MsgType] =
if not f.isNil: if not f.isNil:
return Future[MsgType](f) return Future[MsgType](f)
newFuture result initFuture result
peer.awaitedMessages[wantedId] = result peer.awaitedMessages[wantedId] = result
# Known fatal errors are handled inside dispatchMessages. # Known fatal errors are handled inside dispatchMessages.
@ -776,12 +776,12 @@ macro p2pProtocolImpl(name: static[string],
responseMsgId) responseMsgId)
if hasReqIds: if hasReqIds:
appendParams.add quote do: appendParams.add quote do:
newFuture `resultIdent` initFuture `resultIdent`
let `reqId` = `registerRequestCall` let `reqId` = `registerRequestCall`
paramsToWrite.add reqId paramsToWrite.add reqId
else: else:
appendParams.add quote do: appendParams.add quote do:
newFuture `resultIdent` initFuture `resultIdent`
discard `registerRequestCall` discard `registerRequestCall`
of rlpxResponse: of rlpxResponse: