diff --git a/src/constants.ts b/src/constants.ts index 23a6d64f..cff4a16c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -246,3 +246,6 @@ export const ACCEPT_FROM_WHITELIST_DURATION_MS = 1000 * The default MeshMessageDeliveriesWindow to be used in metrics. */ export const DEFAULT_METRIC_MESH_MESSAGE_DELIVERIES_WINDOWS = 1000 + +/** Wait for 1 more heartbeats before clearing a backoff */ +export const BACKOFF_SLACK = 1 diff --git a/src/index.ts b/src/index.ts index 9ef5520d..74c545f2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,7 +23,8 @@ import { SimpleTimeCache } from './utils/time-cache.js' import { ACCEPT_FROM_WHITELIST_DURATION_MS, ACCEPT_FROM_WHITELIST_MAX_MESSAGES, - ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE + ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE, + BACKOFF_SLACK } from './constants.js' import { ChurnReason, @@ -1648,7 +1649,8 @@ export class GossipSub extends EventEmitter implements PubSub { backoff.forEach((expire, id) => { - if (expire < now) { + // add some slack time to the expiration, see https://github.com/libp2p/specs/pull/289 + if (expire + BACKOFF_SLACK * this.opts.heartbeatInterval < now) { backoff.delete(id) } }) @@ -1793,6 +1795,7 @@ export class GossipSub extends EventEmitter implements PubSub() + const backoff = this.backoff.get(topic) // check if we have mesh_n peers in fanout[topic] and add them to the mesh if we do, // removing the fanout entry. @@ -1804,8 +1807,7 @@ export class GossipSub extends EventEmitter implements PubSub { - // TODO:rust-libp2p checks `self.backoffs.is_backoff_with_slack()` - if (!this.direct.has(id) && this.score.score(id) >= 0) { + if (!this.direct.has(id) && this.score.score(id) >= 0 && (!backoff || !backoff.has(id))) { toAdd.add(id) } }) @@ -1821,7 +1823,7 @@ export class GossipSub extends EventEmitter implements PubSub // filter direct peers and peers with negative score - !toAdd.has(id) && !this.direct.has(id) && this.score.score(id) >= 0 + !toAdd.has(id) && !this.direct.has(id) && this.score.score(id) >= 0 && (!backoff || !backoff.has(id)) ) newPeers.forEach((peer) => {