Skip to content

fix(libp2p): emit peer:discovered event on internal event bus #2019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions packages/libp2p/src/connection-manager/auto-dial.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { logger } from '@libp2p/logger'
import { PeerMap, PeerSet } from '@libp2p/peer-collections'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
import { PeerJobQueue } from '../utils/peer-job-queue.js'
import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_INTERVAL, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PEER_RETRY_THRESHOLD, AUTO_DIAL_PRIORITY, LAST_DIAL_FAILURE_KEY, MIN_CONNECTIONS } from './constants.js'
import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE, AUTO_DIAL_INTERVAL, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PEER_RETRY_THRESHOLD, AUTO_DIAL_PRIORITY, LAST_DIAL_FAILURE_KEY, MIN_CONNECTIONS } from './constants.js'
import type { Libp2pEvents } from '@libp2p/interface'
import type { EventEmitter } from '@libp2p/interface/events'
import type { PeerStore } from '@libp2p/interface/peer-store'
@@ -18,6 +18,7 @@ interface AutoDialInit {
autoDialPriority?: number
autoDialInterval?: number
autoDialPeerRetryThreshold?: number
autoDialDiscoveredPeersDebounce?: number
}

interface AutoDialComponents {
@@ -32,7 +33,8 @@ const defaultOptions = {
autoDialConcurrency: AUTO_DIAL_CONCURRENCY,
autoDialPriority: AUTO_DIAL_PRIORITY,
autoDialInterval: AUTO_DIAL_INTERVAL,
autoDialPeerRetryThreshold: AUTO_DIAL_PEER_RETRY_THRESHOLD
autoDialPeerRetryThreshold: AUTO_DIAL_PEER_RETRY_THRESHOLD,
autoDialDiscoveredPeersDebounce: AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE
}

export class AutoDial implements Startable {
@@ -44,6 +46,7 @@ export class AutoDial implements Startable {
private readonly autoDialIntervalMs: number
private readonly autoDialMaxQueueLength: number
private readonly autoDialPeerRetryThresholdMs: number
private readonly autoDialDiscoveredPeersDebounce: number
private autoDialInterval?: ReturnType<typeof setInterval>
private started: boolean
private running: boolean
@@ -61,6 +64,7 @@ export class AutoDial implements Startable {
this.autoDialIntervalMs = init.autoDialInterval ?? defaultOptions.autoDialInterval
this.autoDialMaxQueueLength = init.maxQueueLength ?? defaultOptions.maxQueueLength
this.autoDialPeerRetryThresholdMs = init.autoDialPeerRetryThreshold ?? defaultOptions.autoDialPeerRetryThreshold
this.autoDialDiscoveredPeersDebounce = init.autoDialDiscoveredPeersDebounce ?? defaultOptions.autoDialDiscoveredPeersDebounce
this.started = false
this.running = false
this.queue = new PeerJobQueue({
@@ -77,6 +81,22 @@ export class AutoDial implements Startable {
log.error(err)
})
})

// sometimes peers are discovered in quick succession so add a small
// debounce to ensure all eligible peers are autodialed
let debounce: ReturnType<typeof setTimeout>

// when new peers are discovered, dial them if we don't have
// enough connections
components.events.addEventListener('peer:discovery', () => {
clearTimeout(debounce)
debounce = setTimeout(() => {
this.autoDial()
.catch(err => {
log.error(err)
})
}, this.autoDialDiscoveredPeersDebounce)
})
}

isStarted (): boolean {
5 changes: 5 additions & 0 deletions packages/libp2p/src/connection-manager/constants.defaults.ts
Original file line number Diff line number Diff line change
@@ -38,6 +38,11 @@ export const AUTO_DIAL_MAX_QUEUE_LENGTH = 100
*/
export const AUTO_DIAL_PEER_RETRY_THRESHOLD = 1000 * 60

/**
* @see https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.unknown.ConnectionManagerInit.html#autoDialDiscoveredPeersDebounce
*/
export const AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE = 10

/**
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#inboundConnectionThreshold
*/
8 changes: 8 additions & 0 deletions packages/libp2p/src/connection-manager/index.ts
Original file line number Diff line number Diff line change
@@ -72,6 +72,14 @@ export interface ConnectionManagerInit {
*/
autoDialPeerRetryThreshold?: number

/**
* Newly discovered peers may be auto-dialed to increase the number of open
* connections, but they can be discovered in quick succession so add a small
* delay before attempting to dial them in case more peers have been
* discovered. (default: 10ms)
*/
autoDialDiscoveredPeersDebounce?: number

/**
* Sort the known addresses of a peer before trying to dial, By default public
* addresses will be dialled before private (e.g. loopback or LAN) addresses.
2 changes: 1 addition & 1 deletion packages/libp2p/src/libp2p.ts
Original file line number Diff line number Diff line change
@@ -105,7 +105,7 @@ export class Libp2pNode<T extends ServiceMap = Record<string, unknown>> extends
protocols: evt.detail.peer.protocols
}

this.safeDispatchEvent('peer:discovery', { detail: peerInfo })
components.events.safeDispatchEvent('peer:discovery', { detail: peerInfo })
}
})