Skip to content

Commit ab2c1f6

Browse files
maschadachingbrain
andauthored
fix: remove relay:removed event listener after relay is removed (#1998)
When a relay is removed, also remove the event listener Closes #1944 Closes #2106 --------- Co-authored-by: Alex Potsides <[email protected]>
1 parent ce0e38d commit ab2c1f6

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

packages/libp2p/src/circuit-relay/transport/listener.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
3131
this.listeningAddrs = new PeerMap()
3232

3333
// remove listening addrs when a relay is removed
34-
this.relayStore.addEventListener('relay:removed', (evt) => {
35-
this.#removeRelayPeer(evt.detail)
36-
})
34+
this.relayStore.addEventListener('relay:removed', this._onRemoveRelayPeer)
35+
}
36+
37+
_onRemoveRelayPeer = (evt: CustomEvent<PeerId>): void => {
38+
this.#removeRelayPeer(evt.detail)
3739
}
3840

3941
async listen (addr: Multiaddr): Promise<void> {
@@ -100,6 +102,8 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
100102
this.listeningAddrs.delete(peerId)
101103

102104
if (had) {
105+
log.trace('removing relay event listener for peer %p', peerId)
106+
this.relayStore.removeEventListener('relay:removed', this._onRemoveRelayPeer)
103107
// Announce listen addresses change
104108
this.safeDispatchEvent('close', {})
105109
}

packages/libp2p/test/circuit-relay/relay.node.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { HopMessage, Status } from '../../src/circuit-relay/pb/index.js'
2121
import { identifyService } from '../../src/identify/index.js'
2222
import { createLibp2p, type Libp2pOptions } from '../../src/index.js'
2323
import { plaintext } from '../../src/insecure/index.js'
24-
import { discoveredRelayConfig, doesNotHaveRelay, getRelayAddress, hasRelay, usingAsRelay } from './utils.js'
24+
import { discoveredRelayConfig, doesNotHaveRelay, getRelayAddress, hasRelay, notUsingAsRelay, usingAsRelay, usingAsRelayCount } from './utils.js'
2525
import type { Components } from '../../src/components.js'
2626
import type { Libp2p } from '@libp2p/interface'
2727
import type { Connection } from '@libp2p/interface/connection'
@@ -354,7 +354,7 @@ describe('circuit-relay', () => {
354354
transports: [
355355
tcp(),
356356
circuitRelayTransport({
357-
discoverRelays: 1
357+
discoverRelays: 3
358358
})
359359
]
360360
}),
@@ -603,6 +603,35 @@ describe('circuit-relay', () => {
603603
expect(events[1].detail.remotePeer.toString()).to.equal(relay1.peerId.toString())
604604
})
605605

606+
it('should remove the relay event listener when the relay stops', async () => {
607+
// discover relay and make reservation
608+
await local.dial(relay1.getMultiaddrs()[0])
609+
await local.dial(relay2.getMultiaddrs()[0])
610+
611+
await usingAsRelayCount(local, [relay1, relay2], 2)
612+
613+
// expect 2 listeners
614+
// @ts-expect-error these are private fields
615+
const listeners = local.components.transportManager.getListeners()
616+
617+
// @ts-expect-error as a result these will have any types
618+
const circuitListener = listeners.filter(listener => {
619+
// @ts-expect-error as a result these will have any types
620+
const circuitMultiaddrs = listener.getAddrs().filter(ma => Circuit.matches(ma))
621+
return circuitMultiaddrs.length > 0
622+
})
623+
624+
expect(circuitListener[0].relayStore.listenerCount('relay:removed')).to.equal(2)
625+
626+
// remove one listener
627+
await local.hangUp(relay1.peerId)
628+
629+
await notUsingAsRelay(local, relay1)
630+
631+
// expect 1 listener
632+
expect(circuitListener[0].relayStore.listenerCount('relay:removed')).to.equal(1)
633+
})
634+
606635
it('should mark a relayed connection as transient', async () => {
607636
// discover relay and make reservation
608637
const connectionToRelay = await remote.dial(relay1.getMultiaddrs()[0])

packages/libp2p/test/circuit-relay/utils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@ export async function usingAsRelay (node: Libp2p, relay: Libp2p, opts?: PWaitFor
3030
}, opts)
3131
}
3232

33+
export async function usingAsRelayCount (node: Libp2p, relays: Libp2p[], count: number): Promise<void> {
34+
// Wait for peer to be used as a relay
35+
await pWaitFor(async () => {
36+
let relayCount = 0
37+
38+
for (const relay of relays) {
39+
for (const addr of node.getMultiaddrs()) {
40+
const search = `${relay.peerId.toString()}/p2p-circuit`
41+
if (addr.toString().includes(search)) {
42+
relayCount++
43+
}
44+
}
45+
}
46+
return relayCount === count
47+
})
48+
}
49+
3350
export async function notUsingAsRelay (node: Libp2p, relay: Libp2p, opts?: PWaitForOptions<boolean>): Promise<void> {
3451
// Wait for peer to be used as a relay
3552
await pWaitFor(() => {

0 commit comments

Comments
 (0)