@@ -360,11 +360,6 @@ func getNode*(p: PortalProtocol, id: NodeId): Opt[Node] =
360360func localNode * (p: PortalProtocol ): Node =
361361 p.baseProtocol.localNode
362362
363- template neighbours * (
364- p: PortalProtocol , id: NodeId , k: int = BUCKET_SIZE , seenOnly = false
365- ): seq [Node ] =
366- p.routingTable.neighbours (id, k, seenOnly)
367-
368363func distance (p: PortalProtocol , a, b: NodeId ): UInt256 =
369364 p.routingTable.distance (a, b)
370365
@@ -380,6 +375,34 @@ func inRange(
380375template inRange * (p: PortalProtocol , contentId: ContentId ): bool =
381376 p.inRange (p.localNode.id, p.dataRadius (), contentId)
382377
378+ func neighbours * (
379+ p: PortalProtocol ,
380+ id: NodeId ,
381+ k: int = BUCKET_SIZE ,
382+ seenOnly = false ,
383+ excluding = initHashSet [NodeId ](),
384+ ): seq [Node ] =
385+ func nodeNotExcluded (nodeId: NodeId ): bool =
386+ not excluding.contains (nodeId)
387+
388+ p.routingTable.neighbours (id, k, seenOnly, nodeNotExcluded)
389+
390+ func neighboursInRange * (
391+ p: PortalProtocol ,
392+ id: ContentId ,
393+ k: int = BUCKET_SIZE ,
394+ seenOnly = false ,
395+ excluding = initHashSet [NodeId ](),
396+ ): seq [Node ] =
397+ func nodeNotExcludedAndInRange (nodeId: NodeId ): bool =
398+ if excluding.contains (nodeId):
399+ return false
400+ let radius = p.radiusCache.get (nodeId).valueOr:
401+ return false
402+ p.inRange (nodeId, radius, id)
403+
404+ p.routingTable.neighbours (id, k, seenOnly, nodeNotExcludedAndInRange)
405+
383406func truncateEnrs (
384407 nodes: seq [Node ], maxSize: int , enrOverhead: int
385408): List [ByteList [2048 ], 32 ] =
@@ -542,8 +565,10 @@ proc handleFindContent(
542565
543566 # Node does not have the content, or content is not even in radius,
544567 # send closest neighbours to the requested content id.
568+
545569 let
546- closestNodes = p.neighbours (NodeId (contentId), seenOnly = true )
570+ closestNodes =
571+ p.neighbours (contentId, seenOnly = true , excluding = toHashSet ([srcId]))
547572 enrs = truncateEnrs (closestNodes, maxPayloadSize, enrOverhead)
548573 portal_content_enrs_packed.observe (enrs.len ().int64 , labelValues = [$ p.protocolId])
549574
@@ -1751,28 +1776,24 @@ proc neighborhoodGossip*(
17511776 # table, but at the same time avoid unnecessary node lookups.
17521777 # It might still cause issues in data getting propagated in a wider id range.
17531778
1779+ var excluding: HashSet [NodeId ]
1780+ if srcNodeId.isSome ():
1781+ excluding.incl (srcNodeId.get ())
1782+
17541783 var closestLocalNodes =
1755- p.routingTable. neighbours ( NodeId ( contentId) , BUCKET_SIZE , seenOnly = true )
1784+ p.neighboursInRange ( contentId, BUCKET_SIZE , seenOnly = true , excluding )
17561785
17571786 # Shuffling the order of the nodes in order to not always hit the same node
17581787 # first for the same request.
17591788 p.baseProtocol.rng[].shuffle (closestLocalNodes)
17601789
1761- var gossipNodes: seq [Node ]
1762- for node in closestLocalNodes:
1763- let radius = p.radiusCache.get (node.id).valueOr:
1764- continue
1765- if p.inRange (node.id, radius, contentId):
1766- if srcNodeId.isNone () or node.id != srcNodeId.get ():
1767- gossipNodes.add (node)
1768-
17691790 var numberOfGossipedNodes = 0
17701791
1771- if not enableNodeLookup or gossipNodes .len () >= p.config.maxGossipNodes:
1792+ if not enableNodeLookup or closestLocalNodes .len () >= p.config.maxGossipNodes:
17721793 # use local nodes for gossip
17731794 portal_gossip_without_lookup.inc (labelValues = [$ p.protocolId])
17741795
1775- for node in gossipNodes :
1796+ for node in closestLocalNodes :
17761797 let req = OfferRequest (dst: node, kind: Direct , contentList: contentList)
17771798 await p.offerQueue.addLast (req)
17781799 inc numberOfGossipedNodes
0 commit comments