libp2p 0.44.0-e3deaa40 → 0.44.0-ed2fa794

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/index.min.js +17 -17
  2. package/dist/src/autonat/constants.d.ts +16 -2
  3. package/dist/src/autonat/constants.d.ts.map +1 -1
  4. package/dist/src/autonat/constants.js +16 -2
  5. package/dist/src/autonat/constants.js.map +1 -1
  6. package/dist/src/autonat/index.d.ts +9 -30
  7. package/dist/src/autonat/index.d.ts.map +1 -1
  8. package/dist/src/autonat/index.js +22 -18
  9. package/dist/src/autonat/index.js.map +1 -1
  10. package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
  11. package/dist/src/circuit-relay/server/index.js +3 -0
  12. package/dist/src/circuit-relay/server/index.js.map +1 -1
  13. package/dist/src/circuit-relay/transport/discovery.js +2 -2
  14. package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
  15. package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
  16. package/dist/src/circuit-relay/transport/index.js +4 -6
  17. package/dist/src/circuit-relay/transport/index.js.map +1 -1
  18. package/dist/src/circuit-relay/transport/listener.d.ts +0 -3
  19. package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
  20. package/dist/src/circuit-relay/transport/listener.js +27 -24
  21. package/dist/src/circuit-relay/transport/listener.js.map +1 -1
  22. package/dist/src/circuit-relay/transport/reservation-store.d.ts +2 -4
  23. package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
  24. package/dist/src/circuit-relay/transport/reservation-store.js +28 -26
  25. package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
  26. package/dist/src/config.d.ts.map +1 -1
  27. package/dist/src/config.js +0 -55
  28. package/dist/src/config.js.map +1 -1
  29. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  30. package/dist/src/connection-manager/dial-queue.js +11 -0
  31. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  32. package/dist/src/index.d.ts +2 -6
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +2 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/libp2p.d.ts.map +1 -1
  37. package/dist/src/libp2p.js +0 -1
  38. package/dist/src/libp2p.js.map +1 -1
  39. package/dist/src/peer-routing.d.ts +1 -38
  40. package/dist/src/peer-routing.d.ts.map +1 -1
  41. package/dist/src/peer-routing.js +0 -60
  42. package/dist/src/peer-routing.js.map +1 -1
  43. package/dist/src/transport-manager.d.ts +5 -1
  44. package/dist/src/transport-manager.d.ts.map +1 -1
  45. package/dist/src/transport-manager.js +10 -1
  46. package/dist/src/transport-manager.js.map +1 -1
  47. package/dist/src/upgrader.d.ts.map +1 -1
  48. package/dist/src/upgrader.js +3 -2
  49. package/dist/src/upgrader.js.map +1 -1
  50. package/dist/src/upnp-nat/index.d.ts +2 -2
  51. package/dist/src/upnp-nat/index.d.ts.map +1 -1
  52. package/dist/src/upnp-nat/index.js +1 -1
  53. package/dist/src/upnp-nat/index.js.map +1 -1
  54. package/package.json +2 -2
  55. package/src/autonat/constants.ts +17 -2
  56. package/src/autonat/index.ts +37 -30
  57. package/src/circuit-relay/server/index.ts +4 -0
  58. package/src/circuit-relay/transport/discovery.ts +2 -2
  59. package/src/circuit-relay/transport/index.ts +4 -7
  60. package/src/circuit-relay/transport/listener.ts +35 -29
  61. package/src/circuit-relay/transport/reservation-store.ts +21 -15
  62. package/src/config.ts +0 -55
  63. package/src/connection-manager/dial-queue.ts +11 -0
  64. package/src/index.ts +2 -7
  65. package/src/libp2p.ts +0 -1
  66. package/src/peer-routing.ts +1 -103
  67. package/src/transport-manager.ts +13 -1
  68. package/src/upgrader.ts +3 -3
  69. package/src/upnp-nat/index.ts +2 -2
  70. package/src/version.ts +1 -1
@@ -91,7 +91,7 @@ export class RelayDiscovery extends EventEmitter<RelayDiscoveryEvents> implement
91
91
  log('searching peer store for relays')
92
92
  const peers = (await this.peerStore.all())
93
93
  // filter by a list of peers supporting RELAY_V2_HOP and ones we are not listening on
94
- .filter(({ id, protocols }) => protocols.includes(RELAY_V2_HOP_CODEC))
94
+ .filter(({ protocols }) => protocols.includes(RELAY_V2_HOP_CODEC))
95
95
  .sort(() => Math.random() - 0.5)
96
96
 
97
97
  for (const peer of peers) {
@@ -112,11 +112,11 @@ export class RelayDiscovery extends EventEmitter<RelayDiscoveryEvents> implement
112
112
  const peerId = provider.id
113
113
 
114
114
  found++
115
- log('found relay peer %p in content routing', peerId)
116
115
  await this.peerStore.merge(peerId, {
117
116
  multiaddrs: provider.multiaddrs
118
117
  })
119
118
 
119
+ log('found relay peer %p in content routing', peerId)
120
120
  this.safeDispatchEvent('relay:discover', { detail: peerId })
121
121
  }
122
122
  }
@@ -84,7 +84,6 @@ class CircuitRelayTransport implements Transport {
84
84
  private readonly upgrader: Upgrader
85
85
  private readonly addressManager: AddressManager
86
86
  private readonly connectionGater: ConnectionGater
87
- private readonly events: EventEmitter<Libp2pEvents>
88
87
  private readonly reservationStore: ReservationStore
89
88
  private started: boolean
90
89
 
@@ -96,7 +95,6 @@ class CircuitRelayTransport implements Transport {
96
95
  this.upgrader = components.upgrader
97
96
  this.addressManager = components.addressManager
98
97
  this.connectionGater = components.connectionGater
99
- this.events = components.events
100
98
 
101
99
  if (init.discoverRelays != null && init.discoverRelays > 0) {
102
100
  this.discovery = new RelayDiscovery(components)
@@ -170,7 +168,7 @@ class CircuitRelayTransport implements Transport {
170
168
  const destinationId = destinationAddr.getPeerId()
171
169
 
172
170
  if (relayId == null || destinationId == null) {
173
- const errMsg = 'Circuit relay dial failed as addresses did not have peer id'
171
+ const errMsg = `Circuit relay dial to ${ma.toString()} failed as address did not have peer ids`
174
172
  log.error(errMsg)
175
173
  throw new CodeError(errMsg, codes.ERR_RELAYED_DIAL)
176
174
  }
@@ -203,7 +201,7 @@ class CircuitRelayTransport implements Transport {
203
201
  disconnectOnFailure
204
202
  })
205
203
  } catch (err: any) {
206
- log.error('Circuit relay dial failed', err)
204
+ log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${relayPeer.toString()} failed`, err)
207
205
  disconnectOnFailure && await relayConnection.close()
208
206
  throw err
209
207
  }
@@ -244,7 +242,7 @@ class CircuitRelayTransport implements Transport {
244
242
  log('new outbound connection %s', maConn.remoteAddr)
245
243
  return await this.upgrader.upgradeOutbound(maConn)
246
244
  } catch (err) {
247
- log.error('Circuit relay dial failed', err)
245
+ log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${connection.remotePeer.toString()} failed`, err)
248
246
  disconnectOnFailure && await connection.close()
249
247
  throw err
250
248
  }
@@ -256,8 +254,7 @@ class CircuitRelayTransport implements Transport {
256
254
  createListener (options: CreateListenerOptions): Listener {
257
255
  return createListener({
258
256
  connectionManager: this.connectionManager,
259
- relayStore: this.reservationStore,
260
- events: this.events
257
+ relayStore: this.reservationStore
261
258
  })
262
259
  }
263
260
 
@@ -7,47 +7,57 @@ import type { ReservationStore } from './reservation-store.js'
7
7
  import type { PeerId } from '@libp2p/interface-peer-id'
8
8
  import { PeerMap } from '@libp2p/peer-collections'
9
9
  import { logger } from '@libp2p/logger'
10
- import type { Libp2pEvents } from '@libp2p/interface-libp2p'
10
+ import { peerIdFromString } from '@libp2p/peer-id'
11
+ import type { Connection } from '@libp2p/interface-connection'
12
+ import { CodeError } from '@libp2p/interfaces/errors'
11
13
 
12
14
  const log = logger('libp2p:circuit-relay:transport:listener')
13
15
 
14
16
  export interface CircuitRelayTransportListenerComponents {
15
17
  connectionManager: ConnectionManager
16
18
  relayStore: ReservationStore
17
- events: EventEmitter<Libp2pEvents>
18
19
  }
19
20
 
20
21
  class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> implements Listener {
21
22
  private readonly connectionManager: ConnectionManager
22
23
  private readonly relayStore: ReservationStore
23
- private readonly listeningAddrs: PeerMap<Multiaddr>
24
- private readonly events: EventEmitter<Libp2pEvents>
24
+ private readonly listeningAddrs: PeerMap<Multiaddr[]>
25
25
 
26
26
  constructor (components: CircuitRelayTransportListenerComponents) {
27
27
  super()
28
28
 
29
29
  this.connectionManager = components.connectionManager
30
30
  this.relayStore = components.relayStore
31
- this.events = components.events
32
31
  this.listeningAddrs = new PeerMap()
33
32
 
34
33
  // remove listening addrs when a relay is removed
35
34
  this.relayStore.addEventListener('relay:removed', (evt) => {
36
35
  this.#removeRelayPeer(evt.detail)
37
36
  })
38
-
39
- // remove listening addrs when a peer disconnects
40
- this.events.addEventListener('connection:close', (evt) => {
41
- this.#removeRelayPeer(evt.detail.remotePeer)
42
- })
43
37
  }
44
38
 
45
39
  async listen (addr: Multiaddr): Promise<void> {
46
40
  log('listen on %s', addr)
47
41
 
48
- const addrString = addr.toString().split('/p2p-circuit').find(a => a !== '')
49
- const ma = multiaddr(addrString)
50
- const relayConn = await this.connectionManager.openConnection(ma)
42
+ const relayPeerStr = addr.getPeerId()
43
+ let relayConn: Connection | undefined
44
+
45
+ // check if we already have a connection to the relay
46
+ if (relayPeerStr != null) {
47
+ const relayPeer = peerIdFromString(relayPeerStr)
48
+ const connections = this.connectionManager.getConnectionsMap().get(relayPeer) ?? []
49
+
50
+ if (connections.length > 0) {
51
+ relayConn = connections[0]
52
+ }
53
+ }
54
+
55
+ // open a new connection as we don't already have one
56
+ if (relayConn == null) {
57
+ const addrString = addr.toString().split('/p2p-circuit').find(a => a !== '')
58
+ const ma = multiaddr(addrString)
59
+ relayConn = await this.connectionManager.openConnection(ma)
60
+ }
51
61
 
52
62
  if (!this.relayStore.hasReservation(relayConn.remotePeer)) {
53
63
  // addRelay calls transportManager.listen which calls this listen method
@@ -55,31 +65,27 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
55
65
  return
56
66
  }
57
67
 
68
+ const reservation = this.relayStore.getReservation(relayConn.remotePeer)
69
+
70
+ if (reservation == null) {
71
+ throw new CodeError('Did not have reservation after making reservation', 'ERR_NO_RESERVATION')
72
+ }
73
+
58
74
  if (this.listeningAddrs.has(relayConn.remotePeer)) {
59
75
  log('already listening on relay %p', relayConn.remotePeer)
60
76
  return
61
77
  }
62
78
 
63
- this.listeningAddrs.set(relayConn.remotePeer, addr)
79
+ // add all addresses from the relay reservation
80
+ this.listeningAddrs.set(relayConn.remotePeer, reservation.addrs.map(buf => {
81
+ return multiaddr(buf).encapsulate('/p2p-circuit')
82
+ }))
83
+
64
84
  this.safeDispatchEvent('listening', {})
65
85
  }
66
86
 
67
- /**
68
- * Get fixed up multiaddrs
69
- *
70
- * NOTE: This method will grab the peers multiaddrs and expand them such that:
71
- *
72
- * a) If it's an existing /p2p-circuit address for a specific relay i.e.
73
- * `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit` this method will expand the
74
- * address to `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit/ipfs/QmPeer` where
75
- * `QmPeer` is this peers id
76
- * b) If it's not a /p2p-circuit address, it will encapsulate the address as a /p2p-circuit
77
- * addr, such when dialing over a relay with this address, it will create the circuit using
78
- * the encapsulated transport address. This is useful when for example, a peer should only
79
- * be dialed over TCP rather than any other transport
80
- */
81
87
  getAddrs (): Multiaddr[] {
82
- return [...this.listeningAddrs.values()]
88
+ return [...this.listeningAddrs.values()].flat()
83
89
  }
84
90
 
85
91
  async close (): Promise<void> {
@@ -96,8 +96,8 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
96
96
  // When a peer disconnects, if we had a reservation on that peer
97
97
  // remove the reservation and multiaddr and maybe trigger search
98
98
  // for new relays
99
- this.events.addEventListener('connection:close', (evt) => {
100
- this.removeRelay(evt.detail.remotePeer)
99
+ this.events.addEventListener('peer:disconnect', (evt) => {
100
+ this.#removeRelay(evt.detail)
101
101
  })
102
102
  }
103
103
 
@@ -125,15 +125,15 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
125
125
  * on the remote peer
126
126
  */
127
127
  async addRelay (peerId: PeerId, type: RelayType): Promise<void> {
128
- log('add relay', this.reserveQueue.size)
128
+ if (this.peerId.equals(peerId)) {
129
+ log('not trying to use self as relay')
130
+ return
131
+ }
132
+
133
+ log('add relay %p', peerId)
129
134
 
130
135
  await this.reserveQueue.add(async () => {
131
136
  try {
132
- if (this.peerId.equals(peerId)) {
133
- log('not trying to use self as relay')
134
- return
135
- }
136
-
137
137
  // allow refresh of an existing reservation if it is about to expire
138
138
  const existingReservation = this.reservations.get(peerId)
139
139
 
@@ -181,6 +181,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
181
181
  })
182
182
  }, timeoutDuration)
183
183
 
184
+ // we've managed to create a reservation successfully
184
185
  this.reservations.set(peerId, {
185
186
  timeout,
186
187
  reservation,
@@ -197,13 +198,13 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
197
198
  }
198
199
  })
199
200
 
200
- await this.transportManager.listen(
201
- reservation.addrs.map(ma => {
202
- return multiaddr(ma).encapsulate('/p2p-circuit')
203
- })
204
- )
201
+ // listen on multiaddr that only the circuit transport is listening for
202
+ await this.transportManager.listen([multiaddr(`/p2p/${peerId.toString()}/p2p-circuit`)])
205
203
  } catch (err) {
206
204
  log.error('could not reserve slot on %p', peerId, err)
205
+
206
+ // if listening failed, remove the reservation
207
+ this.reservations.delete(peerId)
207
208
  }
208
209
  })
209
210
  }
@@ -212,6 +213,10 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
212
213
  return this.reservations.has(peerId)
213
214
  }
214
215
 
216
+ getReservation (peerId: PeerId): Reservation | undefined {
217
+ return this.reservations.get(peerId)?.reservation
218
+ }
219
+
215
220
  async #createReservation (connection: Connection): Promise<Reservation> {
216
221
  log('requesting reservation from %s', connection.remotePeer)
217
222
  const stream = await connection.newStream(RELAY_V2_HOP_CODEC)
@@ -243,14 +248,14 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
243
248
  /**
244
249
  * Remove listen relay
245
250
  */
246
- removeRelay (peerId: PeerId): void {
251
+ #removeRelay (peerId: PeerId): void {
247
252
  const existingReservation = this.reservations.get(peerId)
248
253
 
249
254
  if (existingReservation == null) {
250
255
  return
251
256
  }
252
257
 
253
- log('removing relay %p', peerId)
258
+ log('connection to relay %p closed, removing reservation from local store', peerId)
254
259
 
255
260
  clearTimeout(existingReservation.timeout)
256
261
  this.reservations.delete(peerId)
@@ -258,6 +263,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
258
263
  this.safeDispatchEvent('relay:removed', { detail: peerId })
259
264
 
260
265
  if (this.reservations.size < this.maxDiscoveredRelays) {
266
+ log('not enough relays %d/%d', this.reservations.size, this.maxDiscoveredRelays)
261
267
  this.safeDispatchEvent('relay:not-enough-relays', {})
262
268
  }
263
269
  }
package/src/config.ts CHANGED
@@ -24,62 +24,7 @@ const DefaultConfig: Partial<Libp2pInit> = {
24
24
  },
25
25
  transportManager: {
26
26
  faultTolerance: FaultTolerance.FATAL_ALL
27
- },
28
- peerRouting: {
29
- refreshManager: {
30
- enabled: true,
31
- interval: 6e5,
32
- bootDelay: 10e3
33
- }
34
27
  }
35
- /*
36
-
37
- nat: {
38
- enabled: true,
39
- ttl: 7200,
40
- keepAlive: true
41
- },
42
- identify: {
43
- protocolPrefix: 'ipfs',
44
- host: {
45
- agentVersion: AGENT_VERSION
46
- },
47
- // https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L48
48
- timeout: 60000,
49
- maxInboundStreams: 1,
50
- maxOutboundStreams: 1,
51
- maxPushIncomingStreams: 1,
52
- maxPushOutgoingStreams: 1,
53
- maxObservedAddresses: 10
54
- },
55
- ping: {
56
- protocolPrefix: 'ipfs',
57
- // See https://github.com/libp2p/specs/blob/d4b5fb0152a6bb86cfd9ea/ping/ping.md?plain=1#L38-L43
58
- // The dialing peer MUST NOT keep more than one outbound stream for the ping protocol per peer.
59
- // The listening peer SHOULD accept at most two streams per peer since cross-stream behavior is
60
- // non-linear and stream writes occur asynchronously. The listening peer may perceive the
61
- // dialing peer closing and opening the wrong streams (for instance, closing stream B and
62
- // opening stream A even though the dialing peer is opening stream B and closing stream A).
63
- maxInboundStreams: 2,
64
- maxOutboundStreams: 1,
65
- timeout: 10000
66
- },
67
- fetch: {
68
- protocolPrefix: 'libp2p',
69
- maxInboundStreams: 1,
70
- maxOutboundStreams: 1,
71
- timeout: 10000
72
- },
73
- autonat: {
74
- protocolPrefix: 'libp2p',
75
- maxInboundStreams: 1,
76
- maxOutboundStreams: 1,
77
- timeout: 30000,
78
- startupDelay: 5000,
79
- refreshInterval: 60000
80
- }
81
-
82
- */
83
28
  }
84
29
 
85
30
  export function validateConfig <T extends ServiceMap = {}> (opts: RecursivePartial<Libp2pInit<T>>): Libp2pInit<T> {
@@ -23,6 +23,7 @@ import { combineSignals, resolveMultiaddrs } from './utils.js'
23
23
  import pDefer from 'p-defer'
24
24
  import { ClearableSignal, anySignal } from 'any-signal'
25
25
  import type { AddressSorter } from '@libp2p/interface-libp2p'
26
+ import { setMaxListeners } from 'events'
26
27
 
27
28
  const log = logger('libp2p:connection-manager:dial-queue')
28
29
 
@@ -100,6 +101,11 @@ export class DialQueue {
100
101
  this.transportManager = components.transportManager
101
102
  this.shutDownController = new AbortController()
102
103
 
104
+ try {
105
+ // This emitter gets listened to a lot
106
+ setMaxListeners?.(Infinity, this.shutDownController.signal)
107
+ } catch {}
108
+
103
109
  this.pendingDialCount = components.metrics?.registerMetric('libp2p_dialler_pending_dials')
104
110
  this.inProgressDialCount = components.metrics?.registerMetric('libp2p_dialler_in_progress_dials')
105
111
  this.pendingDials = []
@@ -258,6 +264,11 @@ export class DialQueue {
258
264
  ]
259
265
  )
260
266
 
267
+ try {
268
+ // This emitter gets listened to a lot
269
+ setMaxListeners?.(Infinity, signal)
270
+ } catch {}
271
+
261
272
  return signal
262
273
  }
263
274
 
package/src/index.ts CHANGED
@@ -32,7 +32,6 @@ import type { Components } from './components.js'
32
32
  import type { Libp2p, ServiceMap } from '@libp2p/interface-libp2p'
33
33
  import type { KeyChainInit } from '@libp2p/keychain'
34
34
  import type { AddressManagerInit } from './address-manager/index.js'
35
- import type { PeerRoutingInit } from './peer-routing.js'
36
35
  import type { ConnectionManagerInit } from './connection-manager/index.js'
37
36
  import type { PersistentPeerStoreInit } from '@libp2p/peer-store'
38
37
 
@@ -81,11 +80,6 @@ export interface Libp2pInit<T extends ServiceMap = {}> {
81
80
  */
82
81
  peerStore: PersistentPeerStoreInit
83
82
 
84
- /**
85
- * libp2p Peer routing service configuration
86
- */
87
- peerRouting: PeerRoutingInit
88
-
89
83
  /**
90
84
  * keychain configuration
91
85
  */
@@ -134,11 +128,12 @@ export type Libp2pOptions<T extends ServiceMap = {}> = RecursivePartial<Libp2pIn
134
128
  * import { tcp } from '@libp2p/tcp'
135
129
  * import { mplex } from '@libp2p/mplex'
136
130
  * import { noise } from '@chainsafe/libp2p-noise'
131
+ * import { yamux } from '@chainsafe/libp2p-yamux'
137
132
  *
138
133
  * // specify options
139
134
  * const options = {
140
135
  * transports: [tcp()],
141
- * streamMuxers: [mplex()],
136
+ * streamMuxers: [yamux(), mplex()],
142
137
  * connectionEncryption: [noise()]
143
138
  * }
144
139
  *
package/src/libp2p.ts CHANGED
@@ -137,7 +137,6 @@ export class Libp2pNode<T extends ServiceMap = {}> extends EventEmitter<Libp2pEv
137
137
  // Peer routers
138
138
  const peerRouters: PeerRouting[] = (init.peerRouters ?? []).map((fn, index) => this.configureComponent(`peer-router-${index}`, fn(this.components)))
139
139
  this.peerRouting = this.components.peerRouting = this.configureComponent('peerRouting', new DefaultPeerRouting(this.components, {
140
- ...init.peerRouting,
141
140
  routers: peerRouters
142
141
  }))
143
142
 
@@ -9,49 +9,17 @@ import {
9
9
  import merge from 'it-merge'
10
10
  import { pipe } from 'it-pipe'
11
11
  import first from 'it-first'
12
- import drain from 'it-drain'
13
12
  import filter from 'it-filter'
14
- import {
15
- setDelayedInterval,
16
- clearDelayedInterval
17
- // @ts-expect-error module with no types
18
- } from 'set-delayed-interval'
19
- import { setMaxListeners } from 'events'
20
13
  import type { PeerId } from '@libp2p/interface-peer-id'
21
14
  import type { PeerRouting } from '@libp2p/interface-peer-routing'
22
15
  import type { AbortOptions } from '@libp2p/interfaces'
23
- import type { Startable } from '@libp2p/interfaces/startable'
24
16
  import type { PeerInfo } from '@libp2p/interface-peer-info'
25
17
  import type { PeerStore } from '@libp2p/interface-peer-store'
26
- import { anySignal } from 'any-signal'
27
18
 
28
19
  const log = logger('libp2p:peer-routing')
29
20
 
30
- export interface RefreshManagerInit {
31
- /**
32
- * Whether to enable the Refresh manager
33
- */
34
- enabled?: boolean
35
-
36
- /**
37
- * Boot delay to start the Refresh Manager (in ms)
38
- */
39
- bootDelay?: number
40
-
41
- /**
42
- * Interval between each Refresh Manager run (in ms)
43
- */
44
- interval?: number
45
-
46
- /**
47
- * How long to let each refresh run (in ms)
48
- */
49
- timeout?: number
50
- }
51
-
52
21
  export interface PeerRoutingInit {
53
22
  routers?: PeerRouting[]
54
- refreshManager?: RefreshManagerInit
55
23
  }
56
24
 
57
25
  export interface DefaultPeerRoutingComponents {
@@ -59,83 +27,13 @@ export interface DefaultPeerRoutingComponents {
59
27
  peerStore: PeerStore
60
28
  }
61
29
 
62
- export class DefaultPeerRouting implements PeerRouting, Startable {
30
+ export class DefaultPeerRouting implements PeerRouting {
63
31
  private readonly components: DefaultPeerRoutingComponents
64
32
  private readonly routers: PeerRouting[]
65
- private readonly refreshManagerInit: RefreshManagerInit
66
- private timeoutId?: ReturnType<typeof setTimeout>
67
- private started: boolean
68
- private abortController?: AbortController
69
33
 
70
34
  constructor (components: DefaultPeerRoutingComponents, init: PeerRoutingInit) {
71
35
  this.components = components
72
36
  this.routers = init.routers ?? []
73
- this.refreshManagerInit = init.refreshManager ?? {}
74
- this.started = false
75
-
76
- this._findClosestPeersTask = this._findClosestPeersTask.bind(this)
77
- }
78
-
79
- isStarted (): boolean {
80
- return this.started
81
- }
82
-
83
- /**
84
- * Start peer routing service.
85
- */
86
- async start (): Promise<void> {
87
- if (this.started || this.routers.length === 0 || this.timeoutId != null || this.refreshManagerInit.enabled === false) {
88
- return
89
- }
90
-
91
- this.timeoutId = setDelayedInterval(
92
- this._findClosestPeersTask, this.refreshManagerInit.interval, this.refreshManagerInit.bootDelay
93
- )
94
-
95
- this.started = true
96
- }
97
-
98
- /**
99
- * Recurrent task to find closest peers and add their addresses to the Address Book.
100
- */
101
- async _findClosestPeersTask (): Promise<void> {
102
- if (this.abortController != null) {
103
- // we are already running the query
104
- return
105
- }
106
-
107
- this.abortController = new AbortController()
108
-
109
- const signal = anySignal([this.abortController.signal, AbortSignal.timeout(this.refreshManagerInit.timeout ?? 10e3)])
110
-
111
- try {
112
- // this controller may be used while dialing lots of peers so prevent MaxListenersExceededWarning
113
- // appearing in the console
114
- try {
115
- setMaxListeners?.(Infinity, signal)
116
- } catch {}
117
-
118
- // nb getClosestPeers adds the addresses to the address book
119
- await drain(this.getClosestPeers(this.components.peerId.toBytes(), { signal }))
120
- } catch (err: any) {
121
- log.error(err)
122
- } finally {
123
- this.abortController?.abort()
124
- this.abortController = undefined
125
- signal.clear()
126
- }
127
- }
128
-
129
- /**
130
- * Stop peer routing service.
131
- */
132
- async stop (): Promise<void> {
133
- clearDelayedInterval(this.timeoutId)
134
-
135
- // abort query if it is in-flight
136
- this.abortController?.abort()
137
-
138
- this.started = false
139
37
  }
140
38
 
141
39
  /**
@@ -157,6 +157,13 @@ export class DefaultTransportManager implements TransportManager, Startable {
157
157
  return Array.of(...this.transports.values())
158
158
  }
159
159
 
160
+ /**
161
+ * Returns all the listener instances
162
+ */
163
+ getListeners (): Listener[] {
164
+ return Array.of(...this.listeners.values()).flat()
165
+ }
166
+
160
167
  /**
161
168
  * Finds a transport that matches the given Multiaddr
162
169
  */
@@ -192,7 +199,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
192
199
  upgrader: this.components.upgrader
193
200
  })
194
201
 
195
- let listeners = this.listeners.get(key)
202
+ let listeners: Listener[] = this.listeners.get(key) ?? []
196
203
 
197
204
  if (listeners == null) {
198
205
  listeners = []
@@ -216,6 +223,11 @@ export class DefaultTransportManager implements TransportManager, Startable {
216
223
  })
217
224
  })
218
225
  listener.addEventListener('close', () => {
226
+ const index = listeners.findIndex(l => l === listener)
227
+
228
+ // remove the listener
229
+ listeners.splice(index, 1)
230
+
219
231
  this.components.peerStore.patch(this.components.peerId, {
220
232
  multiaddrs: this.getAddrs()
221
233
  })
package/src/upgrader.ts CHANGED
@@ -73,7 +73,6 @@ function findIncomingStreamLimit (protocol: string, registrar: Registrar): numbe
73
73
  function findOutgoingStreamLimit (protocol: string, registrar: Registrar): number | undefined {
74
74
  try {
75
75
  const { options } = registrar.getHandler(protocol)
76
-
77
76
  return options.maxOutboundStreams
78
77
  } catch (err: any) {
79
78
  if (err.code !== codes.ERR_NO_HANDLER_FOR_PROTOCOL) {
@@ -392,9 +391,10 @@ export class DefaultUpgrader implements Upgrader {
392
391
  const streamCount = countStreams(protocol, 'inbound', connection)
393
392
 
394
393
  if (streamCount === incomingLimit) {
395
- muxedStream.abort(new CodeError(`Too many inbound protocol streams for protocol "${protocol}" - limit ${incomingLimit}`, codes.ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS))
394
+ const err = new CodeError(`Too many inbound protocol streams for protocol "${protocol}" - limit ${incomingLimit}`, codes.ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS)
395
+ muxedStream.abort(err)
396
396
 
397
- return
397
+ throw err
398
398
  }
399
399
 
400
400
  // after the handshake the returned stream can have early data so override
@@ -50,7 +50,7 @@ export interface UPnPNATInit {
50
50
  /**
51
51
  * Whether to automatically refresh UPnP port mappings when their TTL is reached
52
52
  */
53
- keepAlive: boolean
53
+ keepAlive?: boolean
54
54
 
55
55
  /**
56
56
  * Pass a value to use instead of auto-detection
@@ -205,7 +205,7 @@ class UPnPNAT implements Startable {
205
205
  }
206
206
  }
207
207
 
208
- export function uPnPNAT (init: UPnPNATInit): (components: UPnPNATComponents) => {} {
208
+ export function uPnPNATService (init: UPnPNATInit = {}): (components: UPnPNATComponents) => {} {
209
209
  return (components: UPnPNATComponents) => {
210
210
  return new UPnPNAT(components, init)
211
211
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '0.44.0-e3deaa40'
1
+ export const version = '0.44.0-ed2fa794'
2
2
  export const name = 'libp2p'