diff --git a/libp2p/protocols/pubsub/gossipsub.nim b/libp2p/protocols/pubsub/gossipsub.nim index b2266b497..77887a842 100644 --- a/libp2p/protocols/pubsub/gossipsub.nim +++ b/libp2p/protocols/pubsub/gossipsub.nim @@ -510,17 +510,15 @@ method publish*(g: GossipSub, trace "publish: including flood/high score peer", peer peers.incl(peer) - if peers.len < g.parameters.dLow: - # not subscribed or bad mesh, send to fanout peers - # + if peers.len < g.parameters.dLow and topic notin g.topics: + # not subscribed send, to fanout peers var fanoutPeers = g.fanout.getOrDefault(topic).toSeq() if fanoutPeers.len < g.parameters.dLow: g.replenishFanout(topic) fanoutPeers = g.fanout.getOrDefault(topic).toSeq() g.rng.shuffle(fanoutPeers) - if fanoutPeers.len + peers.len > g.parameters.d: - fanoutPeers.setLen(g.parameters.d - peers.len) + fanoutPeers.capLen(g.parameters.d - peers.len) for fanPeer in fanoutPeers: peers.incl(fanPeer) @@ -533,6 +531,19 @@ method publish*(g: GossipSub, # time g.lastFanoutPubSub[topic] = Moment.fromNow(g.parameters.fanoutTTL) + if peers.len < g.parameters.dLow: + # Bad mesh, just send to whoever + var allPeers = toSeq(g.gossipsub.getOrDefault(topic)) + g.rng.shuffle(allPeers) + for peer in allPeers: + if peers.len >= g.parameters.dLow: break + if peer.score >= g.parameters.publishThreshold: + peers.incl(peer) + + for peer in allPeers: + if peers.len >= g.parameters.dLow: break + peers.incl(peer) + if peers.len == 0: let topicPeers = g.gossipsub.getOrDefault(topic).toSeq() debug "No peers for topic, skipping publish", peersOnTopic = topicPeers.len, diff --git a/libp2p/utility.nim b/libp2p/utility.nim index 09c1fac15..ca7e1f83c 100644 --- a/libp2p/utility.nim +++ b/libp2p/utility.nim @@ -70,6 +70,10 @@ template safeConvert*[T: SomeInteger, S: Ordinal](value: S): T = else: {.error: "Source and target types have an incompatible range low..high".} +proc capLen*[T](s: var seq[T], length: Natural) = + if s.len > length: + s.setLen(length) + template exceptionToAssert*(body: untyped): untyped = block: var res: type(body)