libp2p 0.35.5 → 0.35.8-63aa480

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 (93) hide show
  1. package/README.md +2 -2
  2. package/dist/index.min.js +55 -0
  3. package/dist/src/circuit/auto-relay.d.ts +8 -10
  4. package/dist/src/circuit/auto-relay.d.ts.map +1 -1
  5. package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
  6. package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
  7. package/dist/src/connection-manager/index.d.ts +1 -2
  8. package/dist/src/connection-manager/index.d.ts.map +1 -1
  9. package/dist/src/content-routing/utils.d.ts +3 -3
  10. package/dist/src/content-routing/utils.d.ts.map +1 -1
  11. package/dist/src/dht/dht-peer-routing.d.ts.map +1 -1
  12. package/dist/src/dialer/dial-request.d.ts.map +1 -1
  13. package/dist/src/dialer/index.d.ts +20 -16
  14. package/dist/src/dialer/index.d.ts.map +1 -1
  15. package/dist/src/identify/index.d.ts +4 -4
  16. package/dist/src/identify/index.d.ts.map +1 -1
  17. package/dist/src/index.d.ts +14 -9
  18. package/dist/src/index.d.ts.map +1 -1
  19. package/dist/src/metrics/index.d.ts +9 -4
  20. package/dist/src/metrics/index.d.ts.map +1 -1
  21. package/dist/src/metrics/stats.d.ts +3 -1
  22. package/dist/src/metrics/stats.d.ts.map +1 -1
  23. package/dist/src/metrics/tracked-map.d.ts +8 -0
  24. package/dist/src/metrics/tracked-map.d.ts.map +1 -0
  25. package/dist/src/peer-routing.d.ts +1 -1
  26. package/dist/src/peer-routing.d.ts.map +1 -1
  27. package/dist/src/peer-store/address-book.d.ts +28 -84
  28. package/dist/src/peer-store/address-book.d.ts.map +1 -1
  29. package/dist/src/peer-store/index.d.ts +25 -94
  30. package/dist/src/peer-store/index.d.ts.map +1 -1
  31. package/dist/src/peer-store/key-book.d.ts +31 -15
  32. package/dist/src/peer-store/key-book.d.ts.map +1 -1
  33. package/dist/src/peer-store/metadata-book.d.ts +33 -29
  34. package/dist/src/peer-store/metadata-book.d.ts.map +1 -1
  35. package/dist/src/peer-store/pb/peer.d.ts +222 -0
  36. package/dist/src/peer-store/proto-book.d.ts +27 -28
  37. package/dist/src/peer-store/proto-book.d.ts.map +1 -1
  38. package/dist/src/peer-store/store.d.ts +73 -0
  39. package/dist/src/peer-store/store.d.ts.map +1 -0
  40. package/dist/src/peer-store/types.d.ts +202 -0
  41. package/dist/src/peer-store/types.d.ts.map +1 -0
  42. package/dist/src/ping/index.d.ts.map +1 -1
  43. package/dist/src/record/peer-record/index.d.ts +2 -2
  44. package/dist/src/record/peer-record/index.d.ts.map +1 -1
  45. package/dist/src/registrar.d.ts +5 -5
  46. package/dist/src/registrar.d.ts.map +1 -1
  47. package/dist/src/upgrader.d.ts.map +1 -1
  48. package/package.json +28 -32
  49. package/src/circuit/auto-relay.js +52 -38
  50. package/src/connection-manager/auto-dialler.js +9 -4
  51. package/src/connection-manager/index.js +44 -31
  52. package/src/content-routing/utils.js +4 -4
  53. package/src/dht/dht-peer-routing.js +2 -6
  54. package/src/dialer/dial-request.js +4 -1
  55. package/src/dialer/index.js +32 -20
  56. package/src/identify/index.js +47 -38
  57. package/src/index.js +43 -35
  58. package/src/metrics/index.js +15 -8
  59. package/src/metrics/stats.js +1 -0
  60. package/src/metrics/tracked-map.js +94 -0
  61. package/src/peer-routing.js +11 -1
  62. package/src/peer-store/address-book.js +242 -227
  63. package/src/peer-store/index.js +77 -110
  64. package/src/peer-store/key-book.js +99 -54
  65. package/src/peer-store/metadata-book.js +171 -101
  66. package/src/peer-store/pb/peer.d.ts +222 -0
  67. package/src/peer-store/pb/peer.js +643 -0
  68. package/src/peer-store/pb/peer.proto +31 -0
  69. package/src/peer-store/proto-book.js +171 -105
  70. package/src/peer-store/store.js +250 -0
  71. package/src/peer-store/types.ts +245 -0
  72. package/src/ping/index.js +6 -0
  73. package/src/record/peer-record/index.js +1 -1
  74. package/src/record/utils.js +1 -1
  75. package/src/registrar.js +4 -4
  76. package/src/upgrader.js +3 -1
  77. package/dist/src/peer-store/book.d.ts +0 -81
  78. package/dist/src/peer-store/book.d.ts.map +0 -1
  79. package/dist/src/peer-store/persistent/consts.d.ts +0 -6
  80. package/dist/src/peer-store/persistent/consts.d.ts.map +0 -1
  81. package/dist/src/peer-store/persistent/index.d.ts +0 -129
  82. package/dist/src/peer-store/persistent/index.d.ts.map +0 -1
  83. package/dist/src/peer-store/persistent/pb/address-book.d.ts +0 -198
  84. package/dist/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
  85. package/src/peer-store/book.js +0 -124
  86. package/src/peer-store/persistent/consts.js +0 -15
  87. package/src/peer-store/persistent/index.js +0 -408
  88. package/src/peer-store/persistent/pb/address-book.d.ts +0 -198
  89. package/src/peer-store/persistent/pb/address-book.js +0 -522
  90. package/src/peer-store/persistent/pb/address-book.proto +0 -27
  91. package/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
  92. package/src/peer-store/persistent/pb/proto-book.js +0 -157
  93. package/src/peer-store/persistent/pb/proto-book.proto +0 -5
@@ -8,7 +8,7 @@ const log = Object.assign(debug('libp2p:auto-relay'), {
8
8
  const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string')
9
9
  const { toString: uint8ArrayToString } = require('uint8arrays/to-string')
10
10
  const { Multiaddr } = require('multiaddr')
11
- const PeerId = require('peer-id')
11
+ const all = require('it-all')
12
12
 
13
13
  const { relay: multicodec } = require('./multicodec')
14
14
  const { canHop } = require('./circuit/hop')
@@ -22,7 +22,8 @@ const {
22
22
 
23
23
  /**
24
24
  * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
25
- * @typedef {import('../peer-store/address-book').Address} Address
25
+ * @typedef {import('../peer-store/types').Address} Address
26
+ * @typedef {import('peer-id')} PeerId
26
27
  */
27
28
 
28
29
  /**
@@ -91,7 +92,7 @@ class AutoRelay {
91
92
 
92
93
  // If no protocol, check if we were keeping the peer before as a listenRelay
93
94
  if (!hasProtocol && this._listenRelays.has(id)) {
94
- this._removeListenRelay(id)
95
+ await this._removeListenRelay(id)
95
96
  return
96
97
  } else if (!hasProtocol || this._listenRelays.has(id)) {
97
98
  return
@@ -113,7 +114,7 @@ class AutoRelay {
113
114
  const supportsHop = await canHop({ connection })
114
115
 
115
116
  if (supportsHop) {
116
- this._peerStore.metadataBook.set(peerId, HOP_METADATA_KEY, uint8ArrayFromString(HOP_METADATA_VALUE))
117
+ await this._peerStore.metadataBook.setValue(peerId, HOP_METADATA_KEY, uint8ArrayFromString(HOP_METADATA_VALUE))
117
118
  await this._addListenRelay(connection, id)
118
119
  }
119
120
  } catch (/** @type {any} */ err) {
@@ -125,7 +126,6 @@ class AutoRelay {
125
126
  * Peer disconnects.
126
127
  *
127
128
  * @param {Connection} connection - connection to the peer
128
- * @returns {void}
129
129
  */
130
130
  _onPeerDisconnected (connection) {
131
131
  const peerId = connection.remotePeer
@@ -136,7 +136,9 @@ class AutoRelay {
136
136
  return
137
137
  }
138
138
 
139
- this._removeListenRelay(id)
139
+ this._removeListenRelay(id).catch(err => {
140
+ log.error(err)
141
+ })
140
142
  }
141
143
 
142
144
  /**
@@ -148,27 +150,35 @@ class AutoRelay {
148
150
  * @returns {Promise<void>}
149
151
  */
150
152
  async _addListenRelay (connection, id) {
151
- // Check if already listening on enough relays
152
- if (this._listenRelays.size >= this.maxListeners) {
153
- return
154
- }
155
-
156
- // Get peer known addresses and sort them per public addresses first
157
- const remoteAddrs = this._peerStore.addressBook.getMultiaddrsForPeer(
158
- connection.remotePeer, this._addressSorter
159
- )
160
-
161
- if (!remoteAddrs || !remoteAddrs.length) {
162
- return
163
- }
164
-
165
- const listenAddr = `${remoteAddrs[0].toString()}/p2p-circuit`
166
- this._listenRelays.add(id)
167
-
168
- // Attempt to listen on relay
169
153
  try {
170
- await this._transportManager.listen([new Multiaddr(listenAddr)])
171
- // Announce multiaddrs will update on listen success by TransportManager event being triggered
154
+ // Check if already listening on enough relays
155
+ if (this._listenRelays.size >= this.maxListeners) {
156
+ return
157
+ }
158
+
159
+ // Get peer known addresses and sort them per public addresses first
160
+ const remoteAddrs = await this._peerStore.addressBook.getMultiaddrsForPeer(
161
+ connection.remotePeer, this._addressSorter
162
+ )
163
+
164
+ // Attempt to listen on relay
165
+ const result = await Promise.all(
166
+ remoteAddrs.map(async addr => {
167
+ try {
168
+ // Announce multiaddrs will update on listen success by TransportManager event being triggered
169
+ await this._transportManager.listen([new Multiaddr(`${addr.toString()}/p2p-circuit`)])
170
+ return true
171
+ } catch (/** @type {any} */ err) {
172
+ this._onError(err)
173
+ }
174
+
175
+ return false
176
+ })
177
+ )
178
+
179
+ if (result.includes(true)) {
180
+ this._listenRelays.add(id)
181
+ }
172
182
  } catch (/** @type {any} */ err) {
173
183
  this._onError(err)
174
184
  this._listenRelays.delete(id)
@@ -180,12 +190,11 @@ class AutoRelay {
180
190
  *
181
191
  * @private
182
192
  * @param {string} id - peer identifier string.
183
- * @returns {void}
184
193
  */
185
- _removeListenRelay (id) {
194
+ async _removeListenRelay (id) {
186
195
  if (this._listenRelays.delete(id)) {
187
196
  // TODO: this should be responsibility of the connMgr
188
- this._listenOnAvailableHopRelays([id])
197
+ await this._listenOnAvailableHopRelays([id])
189
198
  }
190
199
  }
191
200
 
@@ -197,7 +206,6 @@ class AutoRelay {
197
206
  * 3. Search the network.
198
207
  *
199
208
  * @param {string[]} [peersToIgnore]
200
- * @returns {Promise<void>}
201
209
  */
202
210
  async _listenOnAvailableHopRelays (peersToIgnore = []) {
203
211
  // TODO: The peer redial issue on disconnect should be handled by connection gating
@@ -207,31 +215,37 @@ class AutoRelay {
207
215
  }
208
216
 
209
217
  const knownHopsToDial = []
218
+ const peers = await all(this._peerStore.getPeers())
210
219
 
211
220
  // Check if we have known hop peers to use and attempt to listen on the already connected
212
- for (const [id, metadataMap] of this._peerStore.metadataBook.data.entries()) {
221
+ for await (const { id, metadata } of peers) {
222
+ const idStr = id.toB58String()
223
+
213
224
  // Continue to next if listening on this or peer to ignore
214
- if (this._listenRelays.has(id) || peersToIgnore.includes(id)) {
225
+ if (this._listenRelays.has(idStr)) {
215
226
  continue
216
227
  }
217
228
 
218
- const supportsHop = metadataMap.get(HOP_METADATA_KEY)
229
+ if (peersToIgnore.includes(idStr)) {
230
+ continue
231
+ }
232
+
233
+ const supportsHop = metadata.get(HOP_METADATA_KEY)
219
234
 
220
235
  // Continue to next if it does not support Hop
221
236
  if (!supportsHop || uint8ArrayToString(supportsHop) !== HOP_METADATA_VALUE) {
222
237
  continue
223
238
  }
224
239
 
225
- const peerId = PeerId.createFromB58String(id)
226
- const connection = this._connectionManager.get(peerId)
240
+ const connection = this._connectionManager.get(id)
227
241
 
228
242
  // If not connected, store for possible later use.
229
243
  if (!connection) {
230
- knownHopsToDial.push(peerId)
244
+ knownHopsToDial.push(id)
231
245
  continue
232
246
  }
233
247
 
234
- await this._addListenRelay(connection, id)
248
+ await this._addListenRelay(connection, idStr)
235
249
 
236
250
  // Check if already listening on enough relays
237
251
  if (this._listenRelays.size >= this.maxListeners) {
@@ -258,7 +272,7 @@ class AutoRelay {
258
272
  }
259
273
 
260
274
  const peerId = provider.id
261
- this._peerStore.addressBook.add(peerId, provider.multiaddrs)
275
+ await this._peerStore.addressBook.add(peerId, provider.multiaddrs)
262
276
 
263
277
  await this._tryToListenOnRelay(peerId)
264
278
 
@@ -4,6 +4,7 @@ const debug = require('debug')
4
4
  const mergeOptions = require('merge-options')
5
5
  // @ts-ignore retimer does not have types
6
6
  const retimer = require('retimer')
7
+ const all = require('it-all')
7
8
 
8
9
  const log = Object.assign(debug('libp2p:connection-manager:auto-dialler'), {
9
10
  error: debug('libp2p:connection-manager:auto-dialler:err')
@@ -50,14 +51,16 @@ class AutoDialler {
50
51
  /**
51
52
  * Starts the auto dialer
52
53
  */
53
- start () {
54
+ async start () {
54
55
  if (!this._options.enabled) {
55
56
  log('not enabled')
56
57
  return
57
58
  }
58
59
 
59
60
  this._running = true
60
- this._autoDial()
61
+ this._autoDial().catch(err => {
62
+ log.error('could start autodial', err)
63
+ })
61
64
  log('started')
62
65
  }
63
66
 
@@ -84,8 +87,10 @@ class AutoDialler {
84
87
  return
85
88
  }
86
89
 
87
- // Sort peers on wether we know protocols of public keys for them
88
- const peers = Array.from(this._libp2p.peerStore.peers.values())
90
+ // Sort peers on whether we know protocols of public keys for them
91
+ // TODO: assuming the `peerStore.getPeers()` order is stable this will mean
92
+ // we keep trying to connect to the same peers?
93
+ const peers = (await all(this._libp2p.peerStore.getPeers()))
89
94
  .sort((a, b) => {
90
95
  if (b.protocols && b.protocols.length && (!a.protocols || !a.protocols.length)) {
91
96
  return 1
@@ -12,7 +12,7 @@ const LatencyMonitor = require('./latency-monitor')
12
12
  const retimer = require('retimer')
13
13
 
14
14
  const { EventEmitter } = require('events')
15
-
15
+ const trackedMap = require('../metrics/tracked-map')
16
16
  const PeerId = require('peer-id')
17
17
 
18
18
  const {
@@ -34,7 +34,7 @@ const defaultOptions = {
34
34
 
35
35
  const METRICS_COMPONENT = 'connection-manager'
36
36
  const METRICS_PEER_CONNECTIONS = 'peer-connections'
37
- const METRICS_ALL_CONNECTIONS = 'all-connections'
37
+ const METRICS_PEER_VALUES = 'peer-values'
38
38
 
39
39
  /**
40
40
  * @typedef {import('../')} Libp2p
@@ -87,14 +87,22 @@ class ConnectionManager extends EventEmitter {
87
87
  *
88
88
  * @type {Map<string, number>}
89
89
  */
90
- this._peerValues = new Map()
90
+ this._peerValues = trackedMap({
91
+ component: METRICS_COMPONENT,
92
+ metric: METRICS_PEER_VALUES,
93
+ metrics: this._libp2p.metrics
94
+ })
91
95
 
92
96
  /**
93
97
  * Map of connections per peer
94
98
  *
95
99
  * @type {Map<string, Connection[]>}
96
100
  */
97
- this.connections = new Map()
101
+ this.connections = trackedMap({
102
+ component: METRICS_COMPONENT,
103
+ metric: METRICS_PEER_CONNECTIONS,
104
+ metrics: this._libp2p.metrics
105
+ })
98
106
 
99
107
  this._started = false
100
108
  this._timer = null
@@ -104,6 +112,9 @@ class ConnectionManager extends EventEmitter {
104
112
  latencyCheckIntervalMs: this._options.pollInterval,
105
113
  dataEmitIntervalMs: this._options.pollInterval
106
114
  })
115
+
116
+ // This emitter gets listened to a lot
117
+ this.setMaxListeners(Infinity)
107
118
  }
108
119
 
109
120
  /**
@@ -164,8 +175,6 @@ class ConnectionManager extends EventEmitter {
164
175
 
165
176
  await Promise.all(tasks)
166
177
  this.connections.clear()
167
- this._libp2p.metrics && this._libp2p.metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PEER_CONNECTIONS, 0)
168
- this._libp2p.metrics && this._libp2p.metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_ALL_CONNECTIONS, 0)
169
178
  }
170
179
 
171
180
  /**
@@ -189,19 +198,22 @@ class ConnectionManager extends EventEmitter {
189
198
  *
190
199
  * @private
191
200
  */
192
- _checkMetrics () {
201
+ async _checkMetrics () {
193
202
  if (this._libp2p.metrics) {
194
- const movingAverages = this._libp2p.metrics.global.movingAverages
195
- // @ts-ignore moving averages object types
196
- const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage()
197
- this._checkMaxLimit('maxReceivedData', received)
198
- // @ts-ignore moving averages object types
199
- const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage()
200
- this._checkMaxLimit('maxSentData', sent)
201
- const total = received + sent
202
- this._checkMaxLimit('maxData', total)
203
- log('metrics update', total)
204
- this._timer = retimer(this._checkMetrics, this._options.pollInterval)
203
+ try {
204
+ const movingAverages = this._libp2p.metrics.global.movingAverages
205
+ // @ts-ignore moving averages object types
206
+ const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage()
207
+ await this._checkMaxLimit('maxReceivedData', received)
208
+ // @ts-ignore moving averages object types
209
+ const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage()
210
+ await this._checkMaxLimit('maxSentData', sent)
211
+ const total = received + sent
212
+ await this._checkMaxLimit('maxData', total)
213
+ log('metrics update', total)
214
+ } finally {
215
+ this._timer = retimer(this._checkMetrics, this._options.pollInterval)
216
+ }
205
217
  }
206
218
  }
207
219
 
@@ -209,9 +221,8 @@ class ConnectionManager extends EventEmitter {
209
221
  * Tracks the incoming connection and check the connection limit
210
222
  *
211
223
  * @param {Connection} connection
212
- * @returns {void}
213
224
  */
214
- onConnect (connection) {
225
+ async onConnect (connection) {
215
226
  const peerId = connection.remotePeer
216
227
  const peerIdStr = peerId.toB58String()
217
228
  const storedConn = this.connections.get(peerIdStr)
@@ -222,17 +233,15 @@ class ConnectionManager extends EventEmitter {
222
233
  storedConn.push(connection)
223
234
  } else {
224
235
  this.connections.set(peerIdStr, [connection])
225
- this._libp2p.metrics && this._libp2p.metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PEER_CONNECTIONS, this.connections.size)
226
- this._libp2p.metrics && this._libp2p.metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_ALL_CONNECTIONS, this.size)
227
236
  }
228
237
 
229
- this._libp2p.peerStore.keyBook.set(peerId, peerId.pubKey)
238
+ await this._libp2p.peerStore.keyBook.set(peerId, peerId.pubKey)
230
239
 
231
240
  if (!this._peerValues.has(peerIdStr)) {
232
241
  this._peerValues.set(peerIdStr, this._options.defaultPeerValue)
233
242
  }
234
243
 
235
- this._checkMaxLimit('maxConnections', this.size)
244
+ await this._checkMaxLimit('maxConnections', this.size)
236
245
  }
237
246
 
238
247
  /**
@@ -255,9 +264,6 @@ class ConnectionManager extends EventEmitter {
255
264
 
256
265
  this._libp2p.metrics && this._libp2p.metrics.onPeerDisconnected(connection.remotePeer)
257
266
  }
258
-
259
- this._libp2p.metrics && this._libp2p.metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PEER_CONNECTIONS, this.connections.size)
260
- this._libp2p.metrics && this._libp2p.metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_ALL_CONNECTIONS, this.size)
261
267
  }
262
268
 
263
269
  /**
@@ -303,6 +309,9 @@ class ConnectionManager extends EventEmitter {
303
309
  */
304
310
  _onLatencyMeasure (summary) {
305
311
  this._checkMaxLimit('maxEventLoopDelay', summary.avgMs)
312
+ .catch(err => {
313
+ log.error(err)
314
+ })
306
315
  }
307
316
 
308
317
  /**
@@ -312,12 +321,12 @@ class ConnectionManager extends EventEmitter {
312
321
  * @param {string} name - The name of the field to check limits for
313
322
  * @param {number} value - The current value of the field
314
323
  */
315
- _checkMaxLimit (name, value) {
324
+ async _checkMaxLimit (name, value) {
316
325
  const limit = this._options[name]
317
326
  log('checking limit of %s. current value: %d of %d', name, value, limit)
318
327
  if (value > limit) {
319
328
  log('%s: limit exceeded: %s, %d', this._peerId, name, value)
320
- this._maybeDisconnectOne()
329
+ await this._maybeDisconnectOne()
321
330
  }
322
331
  }
323
332
 
@@ -327,7 +336,7 @@ class ConnectionManager extends EventEmitter {
327
336
  *
328
337
  * @private
329
338
  */
330
- _maybeDisconnectOne () {
339
+ async _maybeDisconnectOne () {
331
340
  if (this._options.minConnections < this.connections.size) {
332
341
  const peerValues = Array.from(new Map([...this._peerValues.entries()].sort((a, b) => a[1] - b[1])))
333
342
  log('%s: sorted peer values: %j', this._peerId, peerValues)
@@ -338,7 +347,11 @@ class ConnectionManager extends EventEmitter {
338
347
  log('%s: closing a connection to %j', this._peerId, peerId)
339
348
  for (const connections of this.connections.values()) {
340
349
  if (connections[0].remotePeer.toB58String() === peerId) {
341
- connections[0].close()
350
+ connections[0].close().catch(err => {
351
+ log.error(err)
352
+ })
353
+ // TODO: should not need to invoke this manually
354
+ this.onDisconnect(connections[0])
342
355
  break
343
356
  }
344
357
  }
@@ -14,12 +14,12 @@ const take = require('it-take')
14
14
  * Store the multiaddrs from every peer in the passed peer store
15
15
  *
16
16
  * @param {AsyncIterable<{ id: PeerId, multiaddrs: Multiaddr[] }>} source
17
- * @param {import('../peer-store')} peerStore
17
+ * @param {import('../peer-store/types').PeerStore} peerStore
18
18
  */
19
- function storeAddresses (source, peerStore) {
20
- return map(source, (peer) => {
19
+ async function * storeAddresses (source, peerStore) {
20
+ yield * map(source, async (peer) => {
21
21
  // ensure we have the addresses for a given peer
22
- peerStore.addressBook.add(peer.id, peer.multiaddrs)
22
+ await peerStore.addressBook.add(peer.id, peer.multiaddrs)
23
23
 
24
24
  return peer
25
25
  })
@@ -27,12 +27,8 @@ class DHTPeerRouting {
27
27
  */
28
28
  async findPeer (peerId, options = {}) {
29
29
  for await (const event of this._dht.findPeer(peerId, options)) {
30
- if (event.name === 'PEER_RESPONSE') {
31
- const peer = event.closer.find(peerData => peerData.id.equals(peerId))
32
-
33
- if (peer) {
34
- return peer
35
- }
30
+ if (event.name === 'FINAL_PEER') {
31
+ return event.peer
36
32
  }
37
33
  }
38
34
 
@@ -63,7 +63,10 @@ class DialRequest {
63
63
  tokens.forEach(token => tokenHolder.push(token))
64
64
  const dialAbortControllers = this.addrs.map(() => {
65
65
  const controller = new AbortController()
66
- setMaxListeners && setMaxListeners(Infinity, controller.signal)
66
+ try {
67
+ // fails on node < 15.4
68
+ setMaxListeners && setMaxListeners(Infinity, controller.signal)
69
+ } catch {}
67
70
 
68
71
  return controller
69
72
  })
@@ -9,11 +9,12 @@ const { Multiaddr } = require('multiaddr')
9
9
  const { TimeoutController } = require('timeout-abort-controller')
10
10
  const { AbortError } = require('abortable-iterator')
11
11
  const { anySignal } = require('any-signal')
12
-
12
+ // @ts-expect-error setMaxListeners is missing from the types
13
+ const { setMaxListeners } = require('events')
13
14
  const DialRequest = require('./dial-request')
14
15
  const { publicAddressesFirst } = require('libp2p-utils/src/address-sort')
15
16
  const getPeer = require('../get-peer')
16
-
17
+ const trackedMap = require('../metrics/tracked-map')
17
18
  const { codes } = require('../errors')
18
19
  const {
19
20
  DIAL_TIMEOUT,
@@ -29,8 +30,8 @@ const METRICS_PENDING_DIAL_TARGETS = 'pending-dial-targets'
29
30
  /**
30
31
  * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
31
32
  * @typedef {import('peer-id')} PeerId
32
- * @typedef {import('../peer-store')} PeerStore
33
- * @typedef {import('../peer-store/address-book').Address} Address
33
+ * @typedef {import('../peer-store/types').PeerStore} PeerStore
34
+ * @typedef {import('../peer-store/types').Address} Address
34
35
  * @typedef {import('../transport-manager')} TransportManager
35
36
  */
36
37
 
@@ -55,8 +56,8 @@ const METRICS_PENDING_DIAL_TARGETS = 'pending-dial-targets'
55
56
  * @property {Multiaddr[]} addrs
56
57
  *
57
58
  * @typedef PendingDial
58
- * @property {DialRequest} dialRequest
59
- * @property {TimeoutController} controller
59
+ * @property {import('./dial-request')} dialRequest
60
+ * @property {import('timeout-abort-controller').TimeoutController} controller
60
61
  * @property {Promise<Connection>} promise
61
62
  * @property {function():void} destroy
62
63
  */
@@ -85,9 +86,20 @@ class Dialer {
85
86
  this.timeout = dialTimeout
86
87
  this.maxDialsPerPeer = maxDialsPerPeer
87
88
  this.tokens = [...new Array(maxParallelDials)].map((_, index) => index)
88
- this._pendingDials = new Map()
89
- this._pendingDialTargets = new Map()
90
- this._metrics = metrics
89
+
90
+ /** @type {Map<string, PendingDial>} */
91
+ this._pendingDials = trackedMap({
92
+ component: METRICS_COMPONENT,
93
+ metric: METRICS_PENDING_DIALS,
94
+ metrics
95
+ })
96
+
97
+ /** @type {Map<string, { resolve: (value: any) => void, reject: (err: Error) => void}>} */
98
+ this._pendingDialTargets = trackedMap({
99
+ component: METRICS_COMPONENT,
100
+ metric: METRICS_PENDING_DIAL_TARGETS,
101
+ metrics
102
+ })
91
103
 
92
104
  for (const [key, value] of Object.entries(resolvers)) {
93
105
  Multiaddr.resolvers.set(key, value)
@@ -111,9 +123,6 @@ class Dialer {
111
123
  pendingTarget.reject(new AbortError('Dialer was destroyed'))
112
124
  }
113
125
  this._pendingDialTargets.clear()
114
-
115
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIALS, 0)
116
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIAL_TARGETS, 0)
117
126
  }
118
127
 
119
128
  /**
@@ -163,7 +172,6 @@ class Dialer {
163
172
  const id = `${(parseInt(String(Math.random() * 1e9), 10)).toString() + Date.now()}`
164
173
  const cancellablePromise = new Promise((resolve, reject) => {
165
174
  this._pendingDialTargets.set(id, { resolve, reject })
166
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIAL_TARGETS, this._pendingDialTargets.size)
167
175
  })
168
176
 
169
177
  try {
@@ -175,7 +183,6 @@ class Dialer {
175
183
  return dialTarget
176
184
  } finally {
177
185
  this._pendingDialTargets.delete(id)
178
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIAL_TARGETS, this._pendingDialTargets.size)
179
186
  }
180
187
  }
181
188
 
@@ -193,10 +200,10 @@ class Dialer {
193
200
  const { id, multiaddrs } = getPeer(peer)
194
201
 
195
202
  if (multiaddrs) {
196
- this.peerStore.addressBook.add(id, multiaddrs)
203
+ await this.peerStore.addressBook.add(id, multiaddrs)
197
204
  }
198
205
 
199
- let knownAddrs = this.peerStore.addressBook.getMultiaddrsForPeer(id, this.addressSorter) || []
206
+ let knownAddrs = await this.peerStore.addressBook.getMultiaddrsForPeer(id, this.addressSorter) || []
200
207
 
201
208
  // If received a multiaddr to dial, it should be the first to use
202
209
  // But, if we know other multiaddrs for the peer, we should try them too.
@@ -216,7 +223,7 @@ class Dialer {
216
223
  const supportedAddrs = addrs.filter(a => this.transportManager.transportForMultiaddr(a))
217
224
 
218
225
  if (supportedAddrs.length > this.maxAddrsToDial) {
219
- this.peerStore.delete(id)
226
+ await this.peerStore.delete(id)
220
227
  throw errCode(new Error('dial with more addresses than allowed'), codes.ERR_TOO_MANY_ADDRESSES)
221
228
  }
222
229
 
@@ -253,10 +260,18 @@ class Dialer {
253
260
 
254
261
  // Combine the timeout signal and options.signal, if provided
255
262
  const timeoutController = new TimeoutController(this.timeout)
263
+
256
264
  const signals = [timeoutController.signal]
257
265
  options.signal && signals.push(options.signal)
258
266
  const signal = anySignal(signals)
259
267
 
268
+ // this signal will potentially be used while dialing lots of
269
+ // peers so prevent MaxListenersExceededWarning appearing in the console
270
+ try {
271
+ // fails on node < 15.4
272
+ setMaxListeners && setMaxListeners(Infinity, signal)
273
+ } catch {}
274
+
260
275
  const pendingDial = {
261
276
  dialRequest,
262
277
  controller: timeoutController,
@@ -264,13 +279,10 @@ class Dialer {
264
279
  destroy: () => {
265
280
  timeoutController.clear()
266
281
  this._pendingDials.delete(dialTarget.id)
267
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIALS, this._pendingDials.size)
268
282
  }
269
283
  }
270
284
  this._pendingDials.set(dialTarget.id, pendingDial)
271
285
 
272
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIALS, this._pendingDials.size)
273
-
274
286
  return pendingDial
275
287
  }
276
288