Fluffy: Prioritize nodes that have radius in range of target content in lookup (#2841)

* Prioritize nodes that have radius in range of target content in content lookup.
This commit is contained in:
bhartnett 2024-11-07 16:59:59 +08:00 committed by GitHub
parent 70a1f768f7
commit 9dceb58ad0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 3 deletions

View File

@ -47,7 +47,7 @@ declareHistogram portal_lookup_node_requests,
labels = ["protocol_id"], labels = ["protocol_id"],
buckets = requestBuckets buckets = requestBuckets
declareHistogram portal_lookup_content_requests, declareHistogram portal_lookup_content_requests,
"Portal wire protocol amount of requests per node lookup", "Portal wire protocol amount of requests per content lookup",
labels = ["protocol_id"], labels = ["protocol_id"],
buckets = requestBuckets buckets = requestBuckets
declareCounter portal_lookup_content_failures, declareCounter portal_lookup_content_failures,
@ -1139,14 +1139,31 @@ proc contentLookup*(
p: PortalProtocol, target: ContentKeyByteList, targetId: UInt256 p: PortalProtocol, target: ContentKeyByteList, targetId: UInt256
): Future[Opt[ContentLookupResult]] {.async: (raises: [CancelledError]).} = ): Future[Opt[ContentLookupResult]] {.async: (raises: [CancelledError]).} =
## Perform a lookup for the given target, return the closest n nodes to the ## Perform a lookup for the given target, return the closest n nodes to the
## target. Maximum value for n is `BUCKET_SIZE`. ## target.
# `closestNodes` holds the k closest nodes to target found, sorted by distance # `closestNodes` holds the k closest nodes to target found, sorted by distance
# Unvalidated nodes are used for requests as a form of validation. # Unvalidated nodes are used for requests as a form of validation.
var closestNodes = p.routingTable.neighbours(targetId, BUCKET_SIZE, seenOnly = false) var closestNodes = p.routingTable.neighbours(targetId, BUCKET_SIZE, seenOnly = false)
# Shuffling the order of the nodes in order to not always hit the same node # Shuffling the order of the nodes in order to not always hit the same node
# first for the same request. # first for the same request.
p.baseProtocol.rng[].shuffle(closestNodes) p.baseProtocol.rng[].shuffle(closestNodes)
# Sort closestNodes so that nodes that are in range of the target content
# are queried first
proc nodesCmp(x, y: Node): int =
let
xRadius = p.radiusCache.get(x.id)
yRadius = p.radiusCache.get(y.id)
if xRadius.isSome() and p.inRange(x.id, xRadius.unsafeGet(), targetId):
-1
elif yRadius.isSome() and p.inRange(y.id, yRadius.unsafeGet(), targetId):
1
else:
0
closestNodes.sort(nodesCmp)
var asked, seen = HashSet[NodeId]() var asked, seen = HashSet[NodeId]()
asked.incl(p.localNode.id) # No need to ask our own node asked.incl(p.localNode.id) # No need to ask our own node
seen.incl(p.localNode.id) # No need to discover our own node seen.incl(p.localNode.id) # No need to discover our own node

View File

@ -336,7 +336,7 @@ proc runBackfillGossipBlockOffersLoop(
break break
except CatchableError as e: except CatchableError as e:
warn "Failed to find content with key: ", warn "Failed to find content with key: ",
contentKey = k, error = e.msg, workerId contentKey = k.to0xHex(), error = e.msg, workerId
retryGossip = true retryGossip = true
break break
@ -349,6 +349,9 @@ proc runBackfillGossipBlockOffersLoop(
if blockOffers.blockNumber mod 1000 == 0: if blockOffers.blockNumber mod 1000 == 0:
info "Finished gossiping offers for block number: ", info "Finished gossiping offers for block number: ",
workerId, blockNumber = blockOffers.blockNumber, offerCount = offersMap.len() workerId, blockNumber = blockOffers.blockNumber, offerCount = offersMap.len()
else:
debug "Finished gossiping offers for block number: ",
workerId, blockNumber = blockOffers.blockNumber, offerCount = offersMap.len()
blockOffers = await blockOffersQueue.popFirst() blockOffers = await blockOffersQueue.popFirst()