libp2p 0.44.0 → 0.45.0

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 (188) hide show
  1. package/dist/index.min.js +30 -30
  2. package/dist/src/address-manager/index.d.ts +8 -4
  3. package/dist/src/address-manager/index.d.ts.map +1 -1
  4. package/dist/src/address-manager/index.js +37 -6
  5. package/dist/src/address-manager/index.js.map +1 -1
  6. package/dist/src/address-manager/utils.d.ts +2 -0
  7. package/dist/src/address-manager/utils.d.ts.map +1 -0
  8. package/dist/src/address-manager/utils.js +12 -0
  9. package/dist/src/address-manager/utils.js.map +1 -0
  10. package/dist/src/autonat/constants.d.ts +16 -2
  11. package/dist/src/autonat/constants.d.ts.map +1 -1
  12. package/dist/src/autonat/constants.js +16 -2
  13. package/dist/src/autonat/constants.js.map +1 -1
  14. package/dist/src/autonat/index.d.ts +12 -33
  15. package/dist/src/autonat/index.d.ts.map +1 -1
  16. package/dist/src/autonat/index.js +36 -30
  17. package/dist/src/autonat/index.js.map +1 -1
  18. package/dist/src/circuit-relay/server/advert-service.d.ts.map +1 -1
  19. package/dist/src/circuit-relay/server/advert-service.js +2 -2
  20. package/dist/src/circuit-relay/server/advert-service.js.map +1 -1
  21. package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
  22. package/dist/src/circuit-relay/server/index.js +10 -3
  23. package/dist/src/circuit-relay/server/index.js.map +1 -1
  24. package/dist/src/circuit-relay/transport/discovery.d.ts.map +1 -1
  25. package/dist/src/circuit-relay/transport/discovery.js +4 -2
  26. package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
  27. package/dist/src/circuit-relay/transport/index.d.ts +3 -0
  28. package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
  29. package/dist/src/circuit-relay/transport/index.js +6 -4
  30. package/dist/src/circuit-relay/transport/index.js.map +1 -1
  31. package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
  32. package/dist/src/circuit-relay/transport/listener.js +30 -26
  33. package/dist/src/circuit-relay/transport/listener.js.map +1 -1
  34. package/dist/src/circuit-relay/transport/reservation-store.d.ts +5 -4
  35. package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
  36. package/dist/src/circuit-relay/transport/reservation-store.js +37 -30
  37. package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
  38. package/dist/src/components.d.ts +6 -63
  39. package/dist/src/components.d.ts.map +1 -1
  40. package/dist/src/components.js +60 -164
  41. package/dist/src/components.js.map +1 -1
  42. package/dist/src/config/connection-gater.browser.d.ts +8 -0
  43. package/dist/src/config/connection-gater.browser.d.ts.map +1 -0
  44. package/dist/src/config/connection-gater.browser.js +27 -0
  45. package/dist/src/config/connection-gater.browser.js.map +1 -0
  46. package/dist/src/config/connection-gater.d.ts +6 -0
  47. package/dist/src/config/connection-gater.d.ts.map +1 -0
  48. package/dist/src/config/connection-gater.js +18 -0
  49. package/dist/src/config/connection-gater.js.map +1 -0
  50. package/dist/src/config.d.ts +2 -1
  51. package/dist/src/config.d.ts.map +1 -1
  52. package/dist/src/config.js +0 -62
  53. package/dist/src/config.js.map +1 -1
  54. package/dist/src/connection-manager/auto-dial.d.ts +3 -0
  55. package/dist/src/connection-manager/auto-dial.d.ts.map +1 -1
  56. package/dist/src/connection-manager/auto-dial.js +36 -13
  57. package/dist/src/connection-manager/auto-dial.js.map +1 -1
  58. package/dist/src/connection-manager/connection-pruner.d.ts +4 -0
  59. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  60. package/dist/src/connection-manager/connection-pruner.js +23 -8
  61. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  62. package/dist/src/connection-manager/dial-queue.d.ts +2 -1
  63. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  64. package/dist/src/connection-manager/dial-queue.js +36 -14
  65. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  66. package/dist/src/connection-manager/index.d.ts +8 -7
  67. package/dist/src/connection-manager/index.d.ts.map +1 -1
  68. package/dist/src/connection-manager/index.js +23 -34
  69. package/dist/src/connection-manager/index.js.map +1 -1
  70. package/dist/src/content-routing/index.d.ts +0 -10
  71. package/dist/src/content-routing/index.d.ts.map +1 -1
  72. package/dist/src/content-routing/index.js +7 -42
  73. package/dist/src/content-routing/index.js.map +1 -1
  74. package/dist/src/content-routing/utils.d.ts.map +1 -1
  75. package/dist/src/content-routing/utils.js +3 -1
  76. package/dist/src/content-routing/utils.js.map +1 -1
  77. package/dist/src/fetch/index.d.ts +13 -35
  78. package/dist/src/fetch/index.d.ts.map +1 -1
  79. package/dist/src/fetch/index.js +7 -9
  80. package/dist/src/fetch/index.js.map +1 -1
  81. package/dist/src/identify/identify.d.ts +53 -0
  82. package/dist/src/identify/identify.d.ts.map +1 -0
  83. package/dist/src/identify/identify.js +405 -0
  84. package/dist/src/identify/identify.js.map +1 -0
  85. package/dist/src/identify/index.d.ts +12 -58
  86. package/dist/src/identify/index.d.ts.map +1 -1
  87. package/dist/src/identify/index.js +5 -388
  88. package/dist/src/identify/index.js.map +1 -1
  89. package/dist/src/index.d.ts +13 -68
  90. package/dist/src/index.d.ts.map +1 -1
  91. package/dist/src/index.js +2 -1
  92. package/dist/src/index.js.map +1 -1
  93. package/dist/src/insecure/index.js.map +1 -1
  94. package/dist/src/libp2p.d.ts +11 -42
  95. package/dist/src/libp2p.d.ts.map +1 -1
  96. package/dist/src/libp2p.js +137 -196
  97. package/dist/src/libp2p.js.map +1 -1
  98. package/dist/src/peer-routing.d.ts +1 -38
  99. package/dist/src/peer-routing.d.ts.map +1 -1
  100. package/dist/src/peer-routing.js +0 -59
  101. package/dist/src/peer-routing.js.map +1 -1
  102. package/dist/src/ping/constants.d.ts +4 -0
  103. package/dist/src/ping/constants.d.ts.map +1 -1
  104. package/dist/src/ping/constants.js +10 -0
  105. package/dist/src/ping/constants.js.map +1 -1
  106. package/dist/src/ping/index.d.ts +10 -27
  107. package/dist/src/ping/index.d.ts.map +1 -1
  108. package/dist/src/ping/index.js +18 -21
  109. package/dist/src/ping/index.js.map +1 -1
  110. package/dist/src/registrar.d.ts +5 -2
  111. package/dist/src/registrar.d.ts.map +1 -1
  112. package/dist/src/registrar.js +27 -25
  113. package/dist/src/registrar.js.map +1 -1
  114. package/dist/src/transport-manager.d.ts +11 -4
  115. package/dist/src/transport-manager.d.ts.map +1 -1
  116. package/dist/src/transport-manager.js +19 -10
  117. package/dist/src/transport-manager.js.map +1 -1
  118. package/dist/src/upgrader.d.ts +15 -10
  119. package/dist/src/upgrader.d.ts.map +1 -1
  120. package/dist/src/upgrader.js +39 -48
  121. package/dist/src/upgrader.js.map +1 -1
  122. package/dist/src/upnp-nat/index.d.ts +42 -0
  123. package/dist/src/upnp-nat/index.d.ts.map +1 -0
  124. package/dist/src/{nat-manager.js → upnp-nat/index.js} +11 -7
  125. package/dist/src/upnp-nat/index.js.map +1 -0
  126. package/dist/src/version.d.ts +1 -1
  127. package/dist/src/version.d.ts.map +1 -1
  128. package/dist/src/version.js +1 -1
  129. package/dist/src/version.js.map +1 -1
  130. package/dist/typedoc-urls.json +25 -10
  131. package/package.json +61 -45
  132. package/src/address-manager/index.ts +50 -8
  133. package/src/address-manager/utils.ts +14 -0
  134. package/src/autonat/constants.ts +17 -2
  135. package/src/autonat/index.ts +53 -45
  136. package/src/circuit-relay/server/advert-service.ts +2 -2
  137. package/src/circuit-relay/server/index.ts +11 -3
  138. package/src/circuit-relay/transport/discovery.ts +5 -3
  139. package/src/circuit-relay/transport/index.ts +9 -4
  140. package/src/circuit-relay/transport/listener.ts +38 -28
  141. package/src/circuit-relay/transport/reservation-store.ts +34 -20
  142. package/src/components.ts +71 -234
  143. package/src/config/connection-gater.browser.ts +31 -0
  144. package/src/config/connection-gater.ts +19 -0
  145. package/src/config.ts +3 -64
  146. package/src/connection-manager/auto-dial.ts +44 -15
  147. package/src/connection-manager/connection-pruner.ts +28 -8
  148. package/src/connection-manager/dial-queue.ts +41 -21
  149. package/src/connection-manager/index.ts +31 -43
  150. package/src/content-routing/index.ts +7 -55
  151. package/src/content-routing/utils.ts +3 -1
  152. package/src/fetch/index.ts +51 -14
  153. package/src/identify/identify.ts +518 -0
  154. package/src/identify/index.ts +17 -507
  155. package/src/index.ts +14 -77
  156. package/src/insecure/index.ts +4 -4
  157. package/src/libp2p.ts +139 -260
  158. package/src/peer-routing.ts +1 -101
  159. package/src/ping/constants.ts +11 -0
  160. package/src/ping/index.ts +32 -28
  161. package/src/registrar.ts +31 -27
  162. package/src/transport-manager.ts +27 -13
  163. package/src/upgrader.ts +62 -58
  164. package/src/{nat-manager.ts → upnp-nat/index.ts} +16 -17
  165. package/src/version.ts +1 -1
  166. package/dist/src/dht/dht-content-routing.d.ts +0 -17
  167. package/dist/src/dht/dht-content-routing.d.ts.map +0 -1
  168. package/dist/src/dht/dht-content-routing.js +0 -32
  169. package/dist/src/dht/dht-content-routing.js.map +0 -1
  170. package/dist/src/dht/dht-peer-routing.d.ts +0 -15
  171. package/dist/src/dht/dht-peer-routing.d.ts.map +0 -1
  172. package/dist/src/dht/dht-peer-routing.js +0 -26
  173. package/dist/src/dht/dht-peer-routing.js.map +0 -1
  174. package/dist/src/dht/dummy-dht.d.ts +0 -20
  175. package/dist/src/dht/dummy-dht.d.ts.map +0 -1
  176. package/dist/src/dht/dummy-dht.js +0 -46
  177. package/dist/src/dht/dummy-dht.js.map +0 -1
  178. package/dist/src/nat-manager.d.ts +0 -74
  179. package/dist/src/nat-manager.d.ts.map +0 -1
  180. package/dist/src/nat-manager.js.map +0 -1
  181. package/dist/src/peer-record-updater.d.ts +0 -24
  182. package/dist/src/peer-record-updater.d.ts.map +0 -1
  183. package/dist/src/peer-record-updater.js +0 -44
  184. package/dist/src/peer-record-updater.js.map +0 -1
  185. package/src/dht/dht-content-routing.ts +0 -44
  186. package/src/dht/dht-peer-routing.ts +0 -36
  187. package/src/dht/dummy-dht.ts +0 -60
  188. package/src/peer-record-updater.ts +0 -65
@@ -24,7 +24,7 @@ import { ReservationVoucherRecord } from './reservation-voucher.js'
24
24
  import type { AddressManager } from '@libp2p/interface-address-manager'
25
25
  import type { ConnectionManager } from '@libp2p/interface-connection-manager'
26
26
  import type { CircuitRelayService, RelayReservation } from '../index.js'
27
- import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
27
+ import { EventEmitter } from '@libp2p/interfaces/events'
28
28
  import { setMaxListeners } from 'events'
29
29
  import type { PeerMap } from '@libp2p/peer-collections'
30
30
 
@@ -128,7 +128,7 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
128
128
  if (init.advertise != null && init.advertise !== false) {
129
129
  this.advertService = new AdvertService(components, init.advertise === true ? undefined : init.advertise)
130
130
  this.advertService.addEventListener('advert:success', () => {
131
- this.dispatchEvent(new CustomEvent('relay:advert:success'))
131
+ this.safeDispatchEvent('relay:advert:success', {})
132
132
  })
133
133
  this.advertService.addEventListener('advert:error', (evt) => {
134
134
  this.safeDispatchEvent('relay:advert:error', { detail: evt.detail })
@@ -260,7 +260,11 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
260
260
  // result.expire is non-null if `ReservationStore.reserve` returns with status == OK
261
261
  if (result.expire != null) {
262
262
  const ttl = (result.expire * 1000) - Date.now()
263
- await this.peerStore.tagPeer(connection.remotePeer, RELAY_SOURCE_TAG, { value: 1, ttl })
263
+ await this.peerStore.merge(connection.remotePeer, {
264
+ tags: {
265
+ [RELAY_SOURCE_TAG]: { value: 1, ttl }
266
+ }
267
+ })
264
268
  }
265
269
 
266
270
  hopstr.write({
@@ -283,6 +287,10 @@ class CircuitRelayServer extends EventEmitter<RelayServerEvents> implements Star
283
287
  const addrs = []
284
288
 
285
289
  for (const relayAddr of this.addressManager.getAddresses()) {
290
+ if (relayAddr.toString().includes('/p2p-circuit')) {
291
+ continue
292
+ }
293
+
286
294
  addrs.push(relayAddr.bytes)
287
295
  }
288
296
 
@@ -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,9 +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
- await this.peerStore.addressBook.add(peerId, provider.multiaddrs)
115
+ await this.peerStore.merge(peerId, {
116
+ multiaddrs: provider.multiaddrs
117
+ })
117
118
 
119
+ log('found relay peer %p in content routing', peerId)
118
120
  this.safeDispatchEvent('relay:discover', { detail: peerId })
119
121
  }
120
122
  }
@@ -23,6 +23,8 @@ import { CIRCUIT_PROTO_CODE, RELAY_V2_HOP_CODEC, RELAY_V2_STOP_CODEC } from '../
23
23
  import { RelayStoreInit, ReservationStore } from './reservation-store.js'
24
24
  import { RelayDiscovery, RelayDiscoveryComponents } from './discovery.js'
25
25
  import { CodeError } from '@libp2p/interfaces/errors'
26
+ import type { EventEmitter } from '@libp2p/interfaces/events'
27
+ import type { Libp2pEvents } from '@libp2p/interface-libp2p'
26
28
 
27
29
  const log = logger('libp2p:circuit-relay:transport')
28
30
 
@@ -49,6 +51,7 @@ export interface CircuitRelayTransportComponents extends RelayDiscoveryComponent
49
51
  addressManager: AddressManager
50
52
  contentRouting: ContentRouting
51
53
  connectionGater: ConnectionGater
54
+ events: EventEmitter<Libp2pEvents>
52
55
  }
53
56
 
54
57
  interface ConnectOptions {
@@ -165,7 +168,7 @@ class CircuitRelayTransport implements Transport {
165
168
  const destinationId = destinationAddr.getPeerId()
166
169
 
167
170
  if (relayId == null || destinationId == null) {
168
- 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`
169
172
  log.error(errMsg)
170
173
  throw new CodeError(errMsg, codes.ERR_RELAYED_DIAL)
171
174
  }
@@ -178,7 +181,9 @@ class CircuitRelayTransport implements Transport {
178
181
  let relayConnection = relayConnections[0]
179
182
 
180
183
  if (relayConnection == null) {
181
- await this.peerStore.addressBook.add(relayPeer, [relayAddr])
184
+ await this.peerStore.merge(relayPeer, {
185
+ multiaddrs: [relayAddr]
186
+ })
182
187
  relayConnection = await this.connectionManager.openConnection(relayPeer, options)
183
188
  disconnectOnFailure = true
184
189
  }
@@ -196,7 +201,7 @@ class CircuitRelayTransport implements Transport {
196
201
  disconnectOnFailure
197
202
  })
198
203
  } catch (err: any) {
199
- log.error('Circuit relay dial failed', err)
204
+ log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${relayPeer.toString()} failed`, err)
200
205
  disconnectOnFailure && await relayConnection.close()
201
206
  throw err
202
207
  }
@@ -237,7 +242,7 @@ class CircuitRelayTransport implements Transport {
237
242
  log('new outbound connection %s', maConn.remoteAddr)
238
243
  return await this.upgrader.upgradeOutbound(maConn)
239
244
  } catch (err) {
240
- log.error('Circuit relay dial failed', err)
245
+ log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${connection.remotePeer.toString()} failed`, err)
241
246
  disconnectOnFailure && await connection.close()
242
247
  throw err
243
248
  }
@@ -1,4 +1,4 @@
1
- import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
1
+ import { EventEmitter } from '@libp2p/interfaces/events'
2
2
  import type { ConnectionManager } from '@libp2p/interface-connection-manager'
3
3
  import type { Listener, ListenerEvents } from '@libp2p/interface-transport'
4
4
  import type { Multiaddr } from '@multiformats/multiaddr'
@@ -7,6 +7,9 @@ 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 { peerIdFromString } from '@libp2p/peer-id'
11
+ import type { Connection } from '@libp2p/interface-connection'
12
+ import { CodeError } from '@libp2p/interfaces/errors'
10
13
 
11
14
  const log = logger('libp2p:circuit-relay:transport:listener')
12
15
 
@@ -18,7 +21,7 @@ export interface CircuitRelayTransportListenerComponents {
18
21
  class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> implements Listener {
19
22
  private readonly connectionManager: ConnectionManager
20
23
  private readonly relayStore: ReservationStore
21
- private readonly listeningAddrs: PeerMap<Multiaddr>
24
+ private readonly listeningAddrs: PeerMap<Multiaddr[]>
22
25
 
23
26
  constructor (components: CircuitRelayTransportListenerComponents) {
24
27
  super()
@@ -31,19 +34,30 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
31
34
  this.relayStore.addEventListener('relay:removed', (evt) => {
32
35
  this.#removeRelayPeer(evt.detail)
33
36
  })
34
-
35
- // remove listening addrs when a peer disconnects
36
- this.connectionManager.addEventListener('peer:disconnect', (evt) => {
37
- this.#removeRelayPeer(evt.detail.remotePeer)
38
- })
39
37
  }
40
38
 
41
39
  async listen (addr: Multiaddr): Promise<void> {
42
40
  log('listen on %s', addr)
43
41
 
44
- const addrString = addr.toString().split('/p2p-circuit').find(a => a !== '')
45
- const ma = multiaddr(addrString)
46
- 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
+ }
47
61
 
48
62
  if (!this.relayStore.hasReservation(relayConn.remotePeer)) {
49
63
  // addRelay calls transportManager.listen which calls this listen method
@@ -51,31 +65,27 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
51
65
  return
52
66
  }
53
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
+
54
74
  if (this.listeningAddrs.has(relayConn.remotePeer)) {
55
75
  log('already listening on relay %p', relayConn.remotePeer)
56
76
  return
57
77
  }
58
78
 
59
- this.listeningAddrs.set(relayConn.remotePeer, addr)
60
- this.dispatchEvent(new CustomEvent('listening'))
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
+
84
+ this.safeDispatchEvent('listening', {})
61
85
  }
62
86
 
63
- /**
64
- * Get fixed up multiaddrs
65
- *
66
- * NOTE: This method will grab the peers multiaddrs and expand them such that:
67
- *
68
- * a) If it's an existing /p2p-circuit address for a specific relay i.e.
69
- * `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit` this method will expand the
70
- * address to `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit/ipfs/QmPeer` where
71
- * `QmPeer` is this peers id
72
- * b) If it's not a /p2p-circuit address, it will encapsulate the address as a /p2p-circuit
73
- * addr, such when dialing over a relay with this address, it will create the circuit using
74
- * the encapsulated transport address. This is useful when for example, a peer should only
75
- * be dialed over TCP rather than any other transport
76
- */
77
87
  getAddrs (): Multiaddr[] {
78
- return [...this.listeningAddrs.values()]
88
+ return [...this.listeningAddrs.values()].flat()
79
89
  }
80
90
 
81
91
  async close (): Promise<void> {
@@ -89,7 +99,7 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
89
99
 
90
100
  if (had) {
91
101
  // Announce listen addresses change
92
- this.dispatchEvent(new CustomEvent('close'))
102
+ this.safeDispatchEvent('close', {})
93
103
  }
94
104
  }
95
105
  }
@@ -11,9 +11,10 @@ import { HopMessage, Status } from '../pb/index.js'
11
11
  import { getExpirationMilliseconds } from '../utils.js'
12
12
  import type { TransportManager } from '@libp2p/interface-transport'
13
13
  import type { Startable } from '@libp2p/interfaces/startable'
14
- import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
14
+ import { EventEmitter } from '@libp2p/interfaces/events'
15
15
  import type { PeerStore } from '@libp2p/interface-peer-store'
16
16
  import { multiaddr } from '@multiformats/multiaddr'
17
+ import type { Libp2pEvents } from '@libp2p/interface-libp2p'
17
18
 
18
19
  const log = logger('libp2p:circuit-relay:transport:reservation-store')
19
20
 
@@ -31,6 +32,7 @@ export interface RelayStoreComponents {
31
32
  connectionManager: ConnectionManager
32
33
  transportManager: TransportManager
33
34
  peerStore: PeerStore
35
+ events: EventEmitter<Libp2pEvents>
34
36
  }
35
37
 
36
38
  export interface RelayStoreInit {
@@ -68,6 +70,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
68
70
  private readonly connectionManager: ConnectionManager
69
71
  private readonly transportManager: TransportManager
70
72
  private readonly peerStore: PeerStore
73
+ private readonly events: EventEmitter<Libp2pEvents>
71
74
  private readonly reserveQueue: PQueue
72
75
  private readonly reservations: PeerMap<RelayEntry>
73
76
  private readonly maxDiscoveredRelays: number
@@ -80,6 +83,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
80
83
  this.connectionManager = components.connectionManager
81
84
  this.transportManager = components.transportManager
82
85
  this.peerStore = components.peerStore
86
+ this.events = components.events
83
87
  this.reservations = new PeerMap()
84
88
  this.maxDiscoveredRelays = init?.discoverRelays ?? 0
85
89
  this.started = false
@@ -92,8 +96,8 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
92
96
  // When a peer disconnects, if we had a reservation on that peer
93
97
  // remove the reservation and multiaddr and maybe trigger search
94
98
  // for new relays
95
- this.connectionManager.addEventListener('peer:disconnect', (evt) => {
96
- this.removeRelay(evt.detail.remotePeer)
99
+ this.events.addEventListener('peer:disconnect', (evt) => {
100
+ this.#removeRelay(evt.detail)
97
101
  })
98
102
  }
99
103
 
@@ -121,15 +125,15 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
121
125
  * on the remote peer
122
126
  */
123
127
  async addRelay (peerId: PeerId, type: RelayType): Promise<void> {
124
- 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)
125
134
 
126
135
  await this.reserveQueue.add(async () => {
127
136
  try {
128
- if (this.peerId.equals(peerId)) {
129
- log('not trying to use self as relay')
130
- return
131
- }
132
-
133
137
  // allow refresh of an existing reservation if it is about to expire
134
138
  const existingReservation = this.reservations.get(peerId)
135
139
 
@@ -177,6 +181,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
177
181
  })
178
182
  }, timeoutDuration)
179
183
 
184
+ // we've managed to create a reservation successfully
180
185
  this.reservations.set(peerId, {
181
186
  timeout,
182
187
  reservation,
@@ -184,18 +189,22 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
184
189
  })
185
190
 
186
191
  // ensure we don't close the connection to the relay
187
- await this.peerStore.tagPeer(peerId, RELAY_TAG, {
188
- value: 1,
189
- ttl: expiration
192
+ await this.peerStore.merge(peerId, {
193
+ tags: {
194
+ [RELAY_TAG]: {
195
+ value: 1,
196
+ ttl: expiration
197
+ }
198
+ }
190
199
  })
191
200
 
192
- await this.transportManager.listen(
193
- reservation.addrs.map(ma => {
194
- return multiaddr(ma).encapsulate('/p2p-circuit')
195
- })
196
- )
201
+ // listen on multiaddr that only the circuit transport is listening for
202
+ await this.transportManager.listen([multiaddr(`/p2p/${peerId.toString()}/p2p-circuit`)])
197
203
  } catch (err) {
198
204
  log.error('could not reserve slot on %p', peerId, err)
205
+
206
+ // if listening failed, remove the reservation
207
+ this.reservations.delete(peerId)
199
208
  }
200
209
  })
201
210
  }
@@ -204,6 +213,10 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
204
213
  return this.reservations.has(peerId)
205
214
  }
206
215
 
216
+ getReservation (peerId: PeerId): Reservation | undefined {
217
+ return this.reservations.get(peerId)?.reservation
218
+ }
219
+
207
220
  async #createReservation (connection: Connection): Promise<Reservation> {
208
221
  log('requesting reservation from %s', connection.remotePeer)
209
222
  const stream = await connection.newStream(RELAY_V2_HOP_CODEC)
@@ -235,14 +248,14 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
235
248
  /**
236
249
  * Remove listen relay
237
250
  */
238
- removeRelay (peerId: PeerId): void {
251
+ #removeRelay (peerId: PeerId): void {
239
252
  const existingReservation = this.reservations.get(peerId)
240
253
 
241
254
  if (existingReservation == null) {
242
255
  return
243
256
  }
244
257
 
245
- log('removing relay %p', peerId)
258
+ log('connection to relay %p closed, removing reservation from local store', peerId)
246
259
 
247
260
  clearTimeout(existingReservation.timeout)
248
261
  this.reservations.delete(peerId)
@@ -250,7 +263,8 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
250
263
  this.safeDispatchEvent('relay:removed', { detail: peerId })
251
264
 
252
265
  if (this.reservations.size < this.maxDiscoveredRelays) {
253
- this.dispatchEvent(new CustomEvent('relay:not-enough-relays'))
266
+ log('not enough relays %d/%d', this.reservations.size, this.maxDiscoveredRelays)
267
+ this.safeDispatchEvent('relay:not-enough-relays', {})
254
268
  }
255
269
  }
256
270
  }