From 3c8dd5bbfc57489a0b10b555c81e773058a58156 Mon Sep 17 00:00:00 2001 From: Joel Gustafson Date: Fri, 16 Aug 2024 13:36:14 -0400 Subject: [PATCH] fix: accept custom ping protocol prefix in connection monitor (#2667) The new connection monitor currently uses the hard-coded default ping protocol `'/ipfs/ping/1.0.0'`. The ping service lets the developer override the `ipfs` component with a custom protocol prefix, and some apps are already doing this. This PR adds support for a `protocolPrefix` option in `ConnectionMonitorInit` that matches the option in `PingServiceInit`. --------- Co-authored-by: Alex Potsides --- packages/libp2p/src/connection-monitor.ts | 14 ++++++++++++- .../test/connection-monitor/index.spec.ts | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/packages/libp2p/src/connection-monitor.ts b/packages/libp2p/src/connection-monitor.ts index 7dcf9176f5..5e93d85251 100644 --- a/packages/libp2p/src/connection-monitor.ts +++ b/packages/libp2p/src/connection-monitor.ts @@ -6,6 +6,9 @@ import type { ConnectionManager } from '@libp2p/interface-internal' import type { AdaptiveTimeoutInit } from '@libp2p/utils/adaptive-timeout' const DEFAULT_PING_INTERVAL_MS = 10000 +const PROTOCOL_VERSION = '1.0.0' +const PROTOCOL_NAME = 'ping' +const PROTOCOL_PREFIX = 'ipfs' export interface ConnectionMonitorInit { /** @@ -37,6 +40,13 @@ export interface ConnectionMonitorInit { * @default true */ abortConnectionOnPingFailure?: boolean + + /** + * Override the ping protocol prefix + * + * @default 'ipfs' + */ + protocolPrefix?: string } export interface ConnectionMonitorComponents { @@ -46,6 +56,7 @@ export interface ConnectionMonitorComponents { } export class ConnectionMonitor implements Startable { + private readonly protocol: string private readonly components: ConnectionMonitorComponents private readonly log: Logger private heartbeatInterval?: ReturnType @@ -55,6 +66,7 @@ export class ConnectionMonitor implements Startable { constructor (components: ConnectionMonitorComponents, init: ConnectionMonitorInit = {}) { this.components = components + this.protocol = `/${init.protocolPrefix ?? PROTOCOL_PREFIX}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}` this.log = components.logger.forComponent('libp2p:connection-monitor') this.pingIntervalMs = init.pingInterval ?? DEFAULT_PING_INTERVAL_MS @@ -83,7 +95,7 @@ export class ConnectionMonitor implements Startable { const signal = this.timeout.getTimeoutSignal({ signal: this.abortController?.signal }) - const stream = await conn.newStream('/ipfs/ping/1.0.0', { + const stream = await conn.newStream(this.protocol, { signal, runOnTransientConnection: true }) diff --git a/packages/libp2p/test/connection-monitor/index.spec.ts b/packages/libp2p/test/connection-monitor/index.spec.ts index d3d920c353..633a1c4121 100644 --- a/packages/libp2p/test/connection-monitor/index.spec.ts +++ b/packages/libp2p/test/connection-monitor/index.spec.ts @@ -50,6 +50,27 @@ describe('connection monitor', () => { expect(connection.rtt).to.be.gte(0) }) + it('should monitor the liveness of a connection with a custom ping protocol prefix', async () => { + monitor = new ConnectionMonitor(components, { + pingInterval: 10, + protocolPrefix: 'foobar' + }) + + await start(monitor) + + const connection = stubInterface() + const stream = stubInterface({ + ...pair() + }) + connection.newStream.withArgs('/foobar/ping/1.0.0').resolves(stream) + + components.connectionManager.getConnections.returns([connection]) + + await delay(100) + + expect(connection.rtt).to.be.gte(0) + }) + it('should monitor the liveness of a connection that does not support ping', async () => { monitor = new ConnectionMonitor(components, { pingInterval: 10