libp2p 0.35.6 → 0.35.9-rc.1

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 (92) hide show
  1. package/README.md +2 -2
  2. package/dist/src/circuit/auto-relay.d.ts +8 -10
  3. package/dist/src/circuit/auto-relay.d.ts.map +1 -1
  4. package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
  5. package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
  6. package/dist/src/connection-manager/index.d.ts +1 -2
  7. package/dist/src/connection-manager/index.d.ts.map +1 -1
  8. package/dist/src/content-routing/utils.d.ts +3 -3
  9. package/dist/src/content-routing/utils.d.ts.map +1 -1
  10. package/dist/src/dht/dht-peer-routing.d.ts.map +1 -1
  11. package/dist/src/dialer/dial-request.d.ts.map +1 -1
  12. package/dist/src/dialer/index.d.ts +20 -16
  13. package/dist/src/dialer/index.d.ts.map +1 -1
  14. package/dist/src/identify/index.d.ts +4 -4
  15. package/dist/src/identify/index.d.ts.map +1 -1
  16. package/dist/src/index.d.ts +14 -9
  17. package/dist/src/index.d.ts.map +1 -1
  18. package/dist/src/metrics/index.d.ts +9 -4
  19. package/dist/src/metrics/index.d.ts.map +1 -1
  20. package/dist/src/metrics/stats.d.ts +3 -1
  21. package/dist/src/metrics/stats.d.ts.map +1 -1
  22. package/dist/src/metrics/tracked-map.d.ts +8 -0
  23. package/dist/src/metrics/tracked-map.d.ts.map +1 -0
  24. package/dist/src/peer-routing.d.ts +1 -1
  25. package/dist/src/peer-routing.d.ts.map +1 -1
  26. package/dist/src/peer-store/address-book.d.ts +28 -84
  27. package/dist/src/peer-store/address-book.d.ts.map +1 -1
  28. package/dist/src/peer-store/index.d.ts +25 -94
  29. package/dist/src/peer-store/index.d.ts.map +1 -1
  30. package/dist/src/peer-store/key-book.d.ts +31 -15
  31. package/dist/src/peer-store/key-book.d.ts.map +1 -1
  32. package/dist/src/peer-store/metadata-book.d.ts +33 -29
  33. package/dist/src/peer-store/metadata-book.d.ts.map +1 -1
  34. package/dist/src/peer-store/pb/peer.d.ts +222 -0
  35. package/dist/src/peer-store/proto-book.d.ts +27 -28
  36. package/dist/src/peer-store/proto-book.d.ts.map +1 -1
  37. package/dist/src/peer-store/store.d.ts +73 -0
  38. package/dist/src/peer-store/store.d.ts.map +1 -0
  39. package/dist/src/peer-store/types.d.ts +202 -0
  40. package/dist/src/peer-store/types.d.ts.map +1 -0
  41. package/dist/src/ping/index.d.ts.map +1 -1
  42. package/dist/src/record/peer-record/index.d.ts +2 -2
  43. package/dist/src/record/peer-record/index.d.ts.map +1 -1
  44. package/dist/src/registrar.d.ts +5 -5
  45. package/dist/src/registrar.d.ts.map +1 -1
  46. package/dist/src/upgrader.d.ts.map +1 -1
  47. package/package.json +22 -22
  48. package/src/circuit/auto-relay.js +19 -19
  49. package/src/connection-manager/auto-dialler.js +9 -4
  50. package/src/connection-manager/index.js +41 -31
  51. package/src/content-routing/utils.js +4 -4
  52. package/src/dht/dht-peer-routing.js +2 -6
  53. package/src/dialer/dial-request.js +4 -1
  54. package/src/dialer/index.js +29 -22
  55. package/src/identify/index.js +28 -23
  56. package/src/index.js +43 -35
  57. package/src/metrics/index.js +15 -8
  58. package/src/metrics/stats.js +1 -0
  59. package/src/metrics/tracked-map.js +94 -0
  60. package/src/peer-routing.js +4 -1
  61. package/src/peer-store/address-book.js +242 -227
  62. package/src/peer-store/index.js +77 -110
  63. package/src/peer-store/key-book.js +99 -54
  64. package/src/peer-store/metadata-book.js +171 -101
  65. package/src/peer-store/pb/peer.d.ts +222 -0
  66. package/src/peer-store/pb/peer.js +643 -0
  67. package/src/peer-store/pb/peer.proto +31 -0
  68. package/src/peer-store/proto-book.js +171 -105
  69. package/src/peer-store/store.js +250 -0
  70. package/src/peer-store/types.ts +245 -0
  71. package/src/ping/index.js +6 -0
  72. package/src/record/peer-record/index.js +1 -1
  73. package/src/record/utils.js +1 -1
  74. package/src/registrar.js +4 -4
  75. package/src/upgrader.js +3 -1
  76. package/dist/src/peer-store/book.d.ts +0 -81
  77. package/dist/src/peer-store/book.d.ts.map +0 -1
  78. package/dist/src/peer-store/persistent/consts.d.ts +0 -6
  79. package/dist/src/peer-store/persistent/consts.d.ts.map +0 -1
  80. package/dist/src/peer-store/persistent/index.d.ts +0 -129
  81. package/dist/src/peer-store/persistent/index.d.ts.map +0 -1
  82. package/dist/src/peer-store/persistent/pb/address-book.d.ts +0 -198
  83. package/dist/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
  84. package/src/peer-store/book.js +0 -124
  85. package/src/peer-store/persistent/consts.js +0 -15
  86. package/src/peer-store/persistent/index.js +0 -408
  87. package/src/peer-store/persistent/pb/address-book.d.ts +0 -198
  88. package/src/peer-store/persistent/pb/address-book.js +0 -522
  89. package/src/peer-store/persistent/pb/address-book.proto +0 -27
  90. package/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
  91. package/src/peer-store/persistent/pb/proto-book.js +0 -157
  92. package/src/peer-store/persistent/pb/proto-book.proto +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libp2p",
3
- "version": "0.35.6",
3
+ "version": "0.35.9-rc.1",
4
4
  "description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
5
5
  "leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
6
6
  "main": "src/index.js",
@@ -20,20 +20,18 @@
20
20
  "scripts": {
21
21
  "lint": "aegir lint",
22
22
  "build": "aegir build",
23
- "build:proto": "npm run build:proto:circuit && npm run build:proto:identify && npm run build:proto:plaintext && npm run build:proto:address-book && npm run build:proto:proto-book && npm run build:proto:peer-record && npm run build:proto:envelope",
23
+ "build:proto": "npm run build:proto:circuit && npm run build:proto:identify && npm run build:proto:plaintext && npm run build:proto:address-book && npm run build:proto:proto-book && npm run build:proto:peer && npm run build:proto:peer-record && npm run build:proto:envelope",
24
24
  "build:proto:circuit": "pbjs -t static-module -w commonjs -r libp2p-circuit --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/circuit/protocol/index.js ./src/circuit/protocol/index.proto",
25
25
  "build:proto:identify": "pbjs -t static-module -w commonjs -r libp2p-identify --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/identify/message.js ./src/identify/message.proto",
26
26
  "build:proto:plaintext": "pbjs -t static-module -w commonjs -r libp2p-plaintext --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/insecure/proto.js ./src/insecure/proto.proto",
27
- "build:proto:address-book": "pbjs -t static-module -w commonjs -r libp2p-address-book --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/peer-store/persistent/pb/address-book.js ./src/peer-store/persistent/pb/address-book.proto",
28
- "build:proto:proto-book": "pbjs -t static-module -w commonjs -r libp2p-proto-book --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/peer-store/persistent/pb/proto-book.js ./src/peer-store/persistent/pb/proto-book.proto",
27
+ "build:proto:peer": "pbjs -t static-module -w commonjs -r libp2p-peer --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/peer-store/pb/peer.js ./src/peer-store/pb/peer.proto",
29
28
  "build:proto:peer-record": "pbjs -t static-module -w commonjs -r libp2p-peer-record --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/record/peer-record/peer-record.js ./src/record/peer-record/peer-record.proto",
30
29
  "build:proto:envelope": "pbjs -t static-module -w commonjs -r libp2p-envelope --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/record/envelope/envelope.js ./src/record/envelope/envelope.proto",
31
- "build:proto-types": "npm run build:proto-types:circuit && npm run build:proto-types:identify && npm run build:proto-types:plaintext && npm run build:proto-types:address-book && npm run build:proto-types:proto-book && npm run build:proto-types:peer-record && npm run build:proto-types:envelope",
30
+ "build:proto-types": "npm run build:proto-types:circuit && npm run build:proto-types:identify && npm run build:proto-types:plaintext && npm run build:proto-types:address-book && npm run build:proto-types:proto-book && npm run build:proto-types:peer && npm run build:proto-types:peer-record && npm run build:proto-types:envelope",
32
31
  "build:proto-types:circuit": "pbts -o src/circuit/protocol/index.d.ts src/circuit/protocol/index.js",
33
32
  "build:proto-types:identify": "pbts -o src/identify/message.d.ts src/identify/message.js",
34
33
  "build:proto-types:plaintext": "pbts -o src/insecure/proto.d.ts src/insecure/proto.js",
35
- "build:proto-types:address-book": "pbts -o src/peer-store/persistent/pb/address-book.d.ts src/peer-store/persistent/pb/address-book.js",
36
- "build:proto-types:proto-book": "pbts -o src/peer-store/persistent/pb/proto-book.d.ts src/peer-store/persistent/pb/proto-book.js",
34
+ "build:proto-types:peer": "pbts -o src/peer-store/pb/peer.d.ts src/peer-store/pb/peer.js",
37
35
  "build:proto-types:peer-record": "pbts -o src/record/peer-record/peer-record.d.ts src/record/peer-record/peer-record.js",
38
36
  "build:proto-types:envelope": "pbts -o src/record/envelope/envelope.d.ts src/record/envelope/envelope.js",
39
37
  "test": "aegir test",
@@ -87,6 +85,7 @@
87
85
  "any-signal": "^2.1.1",
88
86
  "bignumber.js": "^9.0.1",
89
87
  "class-is": "^1.1.0",
88
+ "datastore-core": "^6.0.7",
90
89
  "debug": "^4.3.1",
91
90
  "err-code": "^3.0.0",
92
91
  "es6-promisify": "^7.0.0",
@@ -105,10 +104,11 @@
105
104
  "it-pipe": "^1.1.0",
106
105
  "it-take": "^1.0.0",
107
106
  "libp2p-crypto": "^0.21.0",
108
- "libp2p-interfaces": "^2.0.1",
107
+ "libp2p-interfaces": "^4.0.0",
109
108
  "libp2p-utils": "^0.4.0",
110
109
  "mafmt": "^10.0.0",
111
110
  "merge-options": "^3.0.4",
111
+ "mortice": "^2.0.1",
112
112
  "multiaddr": "^10.0.0",
113
113
  "multiformats": "^9.0.0",
114
114
  "multistream-select": "^2.0.0",
@@ -141,7 +141,6 @@
141
141
  "@types/varint": "^6.0.0",
142
142
  "aegir": "^36.0.0",
143
143
  "buffer": "^6.0.3",
144
- "datastore-core": "^6.0.7",
145
144
  "delay": "^5.0.0",
146
145
  "into-stream": "^6.0.0",
147
146
  "ipfs-http-client": "^54.0.2",
@@ -152,13 +151,11 @@
152
151
  "libp2p-bootstrap": "^0.14.0",
153
152
  "libp2p-delegated-content-routing": "^0.11.0",
154
153
  "libp2p-delegated-peer-routing": "^0.11.1",
155
- "libp2p-floodsub": "^0.28.0",
156
- "libp2p-gossipsub": "^0.12.1",
157
- "libp2p-interfaces-compliance-tests": "^2.0.1",
158
- "libp2p-interop": "^0.5.0",
159
- "libp2p-kad-dht": "^0.27.1",
154
+ "libp2p-interfaces-compliance-tests": "^4.0.8",
155
+ "libp2p-interop": "^0.7.1",
156
+ "libp2p-kad-dht": "^0.28.4",
160
157
  "libp2p-mdns": "^0.18.0",
161
- "libp2p-mplex": "^0.10.1",
158
+ "libp2p-mplex": "^0.10.4",
162
159
  "libp2p-tcp": "^0.17.0",
163
160
  "libp2p-webrtc-star": "^0.25.0",
164
161
  "libp2p-websockets": "^0.16.0",
@@ -182,33 +179,34 @@
182
179
  "Maciej Krüger <mkg20001@gmail.com>",
183
180
  "Hugo Dias <mail@hugodias.me>",
184
181
  "dirkmc <dirkmdev@gmail.com>",
185
- "Chris Dostert <chrisdostert@users.noreply.github.com>",
186
182
  "Volker Mische <volker.mische@gmail.com>",
183
+ "Chris Dostert <chrisdostert@users.noreply.github.com>",
184
+ "zeim839 <50573884+zeim839@users.noreply.github.com>",
187
185
  "Robert Kiel <robert.kiel@hoprnet.org>",
188
186
  "Richard Littauer <richard.littauer@gmail.com>",
189
- "zeim839 <50573884+zeim839@users.noreply.github.com>",
190
187
  "a1300 <matthias-knopp@gmx.net>",
191
188
  "Ryan Bell <ryan@piing.net>",
192
189
  "ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>",
193
190
  "Andrew Nesbitt <andrewnez@gmail.com>",
194
191
  "Franck Royer <franck@royer.one>",
195
192
  "Thomas Eizinger <thomas@eizinger.io>",
193
+ "Vít Habada <vithabada93@gmail.com>",
196
194
  "Giovanni T. Parra <fiatjaf@gmail.com>",
197
195
  "acolytec3 <17355484+acolytec3@users.noreply.github.com>",
198
196
  "Alan Smithee <ggnore.alan.smithee@gmail.com>",
199
197
  "Elven <mon.samuel@qq.com>",
200
198
  "Samlior <samlior@foxmail.com>",
201
199
  "Didrik Nordström <didrik.nordstrom@gmail.com>",
202
- "Soeren <nikorpoulsen@gmail.com>",
203
- "Sönke Hahn <soenkehahn@gmail.com>",
200
+ "Aditya Bose <13054902+adbose@users.noreply.github.com>",
204
201
  "TJKoury <TJKoury@gmail.com>",
205
202
  "TheStarBoys <41286328+TheStarBoys@users.noreply.github.com>",
206
203
  "Tiago Alves <alvesjtiago@gmail.com>",
204
+ "Tim Daubenschütz <tim@daubenschuetz.de>",
207
205
  "XiaoZhang <zxinmyth@gmail.com>",
208
206
  "Yusef Napora <yusef@napora.org>",
209
207
  "Zane Starr <zcstarr@gmail.com>",
210
208
  "ebinks <elizabethjbinks@gmail.com>",
211
- "Aditya Bose <13054902+adbose@users.noreply.github.com>",
209
+ "greenSnot <greenSnot@users.noreply.github.com>",
212
210
  "isan_rivkin <isanrivkin@gmail.com>",
213
211
  "mayerwin <mayerwin@users.noreply.github.com>",
214
212
  "mcclure <andi.m.mcclure@gmail.com>",
@@ -217,7 +215,8 @@
217
215
  "robertkiel <robert.kiel@validitylabs.org>",
218
216
  "shresthagrawal <34920931+shresthagrawal@users.noreply.github.com>",
219
217
  "swedneck <40505480+swedneck@users.noreply.github.com>",
220
- "greenSnot <greenSnot@users.noreply.github.com>",
218
+ "tuyennhv <vutuyen2636@gmail.com>",
219
+ "Sönke Hahn <soenkehahn@gmail.com>",
221
220
  "Aleksei <vozhdb@gmail.com>",
222
221
  "Bernd Strehl <bernd.strehl@gmail.com>",
223
222
  "Chris Bratlien <chrisbratlien@gmail.com>",
@@ -248,6 +247,7 @@
248
247
  "Nuno Nogueira <nunofmn@gmail.com>",
249
248
  "Philipp Muens <raute1337@gmx.de>",
250
249
  "RasmusErik Voel Jensen <github@solsort.com>",
251
- "Smite Chow <xiaopengyou@live.com>"
250
+ "Smite Chow <xiaopengyou@live.com>",
251
+ "Soeren <nikorpoulsen@gmail.com>"
252
252
  ]
253
253
  }
@@ -8,7 +8,6 @@ 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')
12
11
 
13
12
  const { relay: multicodec } = require('./multicodec')
14
13
  const { canHop } = require('./circuit/hop')
@@ -22,7 +21,8 @@ const {
22
21
 
23
22
  /**
24
23
  * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
25
- * @typedef {import('../peer-store/address-book').Address} Address
24
+ * @typedef {import('../peer-store/types').Address} Address
25
+ * @typedef {import('peer-id')} PeerId
26
26
  */
27
27
 
28
28
  /**
@@ -91,7 +91,7 @@ class AutoRelay {
91
91
 
92
92
  // If no protocol, check if we were keeping the peer before as a listenRelay
93
93
  if (!hasProtocol && this._listenRelays.has(id)) {
94
- this._removeListenRelay(id)
94
+ await this._removeListenRelay(id)
95
95
  return
96
96
  } else if (!hasProtocol || this._listenRelays.has(id)) {
97
97
  return
@@ -113,7 +113,7 @@ class AutoRelay {
113
113
  const supportsHop = await canHop({ connection })
114
114
 
115
115
  if (supportsHop) {
116
- this._peerStore.metadataBook.set(peerId, HOP_METADATA_KEY, uint8ArrayFromString(HOP_METADATA_VALUE))
116
+ await this._peerStore.metadataBook.setValue(peerId, HOP_METADATA_KEY, uint8ArrayFromString(HOP_METADATA_VALUE))
117
117
  await this._addListenRelay(connection, id)
118
118
  }
119
119
  } catch (/** @type {any} */ err) {
@@ -125,7 +125,6 @@ class AutoRelay {
125
125
  * Peer disconnects.
126
126
  *
127
127
  * @param {Connection} connection - connection to the peer
128
- * @returns {void}
129
128
  */
130
129
  _onPeerDisconnected (connection) {
131
130
  const peerId = connection.remotePeer
@@ -136,7 +135,9 @@ class AutoRelay {
136
135
  return
137
136
  }
138
137
 
139
- this._removeListenRelay(id)
138
+ this._removeListenRelay(id).catch(err => {
139
+ log.error(err)
140
+ })
140
141
  }
141
142
 
142
143
  /**
@@ -154,7 +155,7 @@ class AutoRelay {
154
155
  }
155
156
 
156
157
  // Get peer known addresses and sort them per public addresses first
157
- const remoteAddrs = this._peerStore.addressBook.getMultiaddrsForPeer(
158
+ const remoteAddrs = await this._peerStore.addressBook.getMultiaddrsForPeer(
158
159
  connection.remotePeer, this._addressSorter
159
160
  )
160
161
 
@@ -180,12 +181,11 @@ class AutoRelay {
180
181
  *
181
182
  * @private
182
183
  * @param {string} id - peer identifier string.
183
- * @returns {void}
184
184
  */
185
- _removeListenRelay (id) {
185
+ async _removeListenRelay (id) {
186
186
  if (this._listenRelays.delete(id)) {
187
187
  // TODO: this should be responsibility of the connMgr
188
- this._listenOnAvailableHopRelays([id])
188
+ await this._listenOnAvailableHopRelays([id])
189
189
  }
190
190
  }
191
191
 
@@ -197,7 +197,6 @@ class AutoRelay {
197
197
  * 3. Search the network.
198
198
  *
199
199
  * @param {string[]} [peersToIgnore]
200
- * @returns {Promise<void>}
201
200
  */
202
201
  async _listenOnAvailableHopRelays (peersToIgnore = []) {
203
202
  // TODO: The peer redial issue on disconnect should be handled by connection gating
@@ -209,29 +208,30 @@ class AutoRelay {
209
208
  const knownHopsToDial = []
210
209
 
211
210
  // 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()) {
211
+ for await (const { id, metadata } of this._peerStore.getPeers()) {
212
+ const idStr = id.toB58String()
213
+
213
214
  // Continue to next if listening on this or peer to ignore
214
- if (this._listenRelays.has(id) || peersToIgnore.includes(id)) {
215
+ if (this._listenRelays.has(idStr) || peersToIgnore.includes(idStr)) {
215
216
  continue
216
217
  }
217
218
 
218
- const supportsHop = metadataMap.get(HOP_METADATA_KEY)
219
+ const supportsHop = metadata.get(HOP_METADATA_KEY)
219
220
 
220
221
  // Continue to next if it does not support Hop
221
222
  if (!supportsHop || uint8ArrayToString(supportsHop) !== HOP_METADATA_VALUE) {
222
223
  continue
223
224
  }
224
225
 
225
- const peerId = PeerId.createFromB58String(id)
226
- const connection = this._connectionManager.get(peerId)
226
+ const connection = this._connectionManager.get(id)
227
227
 
228
228
  // If not connected, store for possible later use.
229
229
  if (!connection) {
230
- knownHopsToDial.push(peerId)
230
+ knownHopsToDial.push(id)
231
231
  continue
232
232
  }
233
233
 
234
- await this._addListenRelay(connection, id)
234
+ await this._addListenRelay(connection, idStr)
235
235
 
236
236
  // Check if already listening on enough relays
237
237
  if (this._listenRelays.size >= this.maxListeners) {
@@ -258,7 +258,7 @@ class AutoRelay {
258
258
  }
259
259
 
260
260
  const peerId = provider.id
261
- this._peerStore.addressBook.add(peerId, provider.multiaddrs)
261
+ await this._peerStore.addressBook.add(peerId, provider.multiaddrs)
262
262
 
263
263
  await this._tryToListenOnRelay(peerId)
264
264
 
@@ -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
@@ -164,8 +172,6 @@ class ConnectionManager extends EventEmitter {
164
172
 
165
173
  await Promise.all(tasks)
166
174
  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
175
  }
170
176
 
171
177
  /**
@@ -189,19 +195,22 @@ class ConnectionManager extends EventEmitter {
189
195
  *
190
196
  * @private
191
197
  */
192
- _checkMetrics () {
198
+ async _checkMetrics () {
193
199
  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)
200
+ try {
201
+ const movingAverages = this._libp2p.metrics.global.movingAverages
202
+ // @ts-ignore moving averages object types
203
+ const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage()
204
+ await this._checkMaxLimit('maxReceivedData', received)
205
+ // @ts-ignore moving averages object types
206
+ const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage()
207
+ await this._checkMaxLimit('maxSentData', sent)
208
+ const total = received + sent
209
+ await this._checkMaxLimit('maxData', total)
210
+ log('metrics update', total)
211
+ } finally {
212
+ this._timer = retimer(this._checkMetrics, this._options.pollInterval)
213
+ }
205
214
  }
206
215
  }
207
216
 
@@ -209,9 +218,8 @@ class ConnectionManager extends EventEmitter {
209
218
  * Tracks the incoming connection and check the connection limit
210
219
  *
211
220
  * @param {Connection} connection
212
- * @returns {void}
213
221
  */
214
- onConnect (connection) {
222
+ async onConnect (connection) {
215
223
  const peerId = connection.remotePeer
216
224
  const peerIdStr = peerId.toB58String()
217
225
  const storedConn = this.connections.get(peerIdStr)
@@ -222,17 +230,15 @@ class ConnectionManager extends EventEmitter {
222
230
  storedConn.push(connection)
223
231
  } else {
224
232
  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
233
  }
228
234
 
229
- this._libp2p.peerStore.keyBook.set(peerId, peerId.pubKey)
235
+ await this._libp2p.peerStore.keyBook.set(peerId, peerId.pubKey)
230
236
 
231
237
  if (!this._peerValues.has(peerIdStr)) {
232
238
  this._peerValues.set(peerIdStr, this._options.defaultPeerValue)
233
239
  }
234
240
 
235
- this._checkMaxLimit('maxConnections', this.size)
241
+ await this._checkMaxLimit('maxConnections', this.size)
236
242
  }
237
243
 
238
244
  /**
@@ -255,9 +261,6 @@ class ConnectionManager extends EventEmitter {
255
261
 
256
262
  this._libp2p.metrics && this._libp2p.metrics.onPeerDisconnected(connection.remotePeer)
257
263
  }
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
264
  }
262
265
 
263
266
  /**
@@ -303,6 +306,9 @@ class ConnectionManager extends EventEmitter {
303
306
  */
304
307
  _onLatencyMeasure (summary) {
305
308
  this._checkMaxLimit('maxEventLoopDelay', summary.avgMs)
309
+ .catch(err => {
310
+ log.error(err)
311
+ })
306
312
  }
307
313
 
308
314
  /**
@@ -312,12 +318,12 @@ class ConnectionManager extends EventEmitter {
312
318
  * @param {string} name - The name of the field to check limits for
313
319
  * @param {number} value - The current value of the field
314
320
  */
315
- _checkMaxLimit (name, value) {
321
+ async _checkMaxLimit (name, value) {
316
322
  const limit = this._options[name]
317
323
  log('checking limit of %s. current value: %d of %d', name, value, limit)
318
324
  if (value > limit) {
319
325
  log('%s: limit exceeded: %s, %d', this._peerId, name, value)
320
- this._maybeDisconnectOne()
326
+ await this._maybeDisconnectOne()
321
327
  }
322
328
  }
323
329
 
@@ -327,7 +333,7 @@ class ConnectionManager extends EventEmitter {
327
333
  *
328
334
  * @private
329
335
  */
330
- _maybeDisconnectOne () {
336
+ async _maybeDisconnectOne () {
331
337
  if (this._options.minConnections < this.connections.size) {
332
338
  const peerValues = Array.from(new Map([...this._peerValues.entries()].sort((a, b) => a[1] - b[1])))
333
339
  log('%s: sorted peer values: %j', this._peerId, peerValues)
@@ -338,7 +344,11 @@ class ConnectionManager extends EventEmitter {
338
344
  log('%s: closing a connection to %j', this._peerId, peerId)
339
345
  for (const connections of this.connections.values()) {
340
346
  if (connections[0].remotePeer.toB58String() === peerId) {
341
- connections[0].close()
347
+ connections[0].close().catch(err => {
348
+ log.error(err)
349
+ })
350
+ // TODO: should not need to invoke this manually
351
+ this.onDisconnect(connections[0])
342
352
  break
343
353
  }
344
354
  }
@@ -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
  })
@@ -14,7 +14,7 @@ const { setMaxListeners } = require('events')
14
14
  const DialRequest = require('./dial-request')
15
15
  const { publicAddressesFirst } = require('libp2p-utils/src/address-sort')
16
16
  const getPeer = require('../get-peer')
17
-
17
+ const trackedMap = require('../metrics/tracked-map')
18
18
  const { codes } = require('../errors')
19
19
  const {
20
20
  DIAL_TIMEOUT,
@@ -30,8 +30,8 @@ const METRICS_PENDING_DIAL_TARGETS = 'pending-dial-targets'
30
30
  /**
31
31
  * @typedef {import('libp2p-interfaces/src/connection').Connection} Connection
32
32
  * @typedef {import('peer-id')} PeerId
33
- * @typedef {import('../peer-store')} PeerStore
34
- * @typedef {import('../peer-store/address-book').Address} Address
33
+ * @typedef {import('../peer-store/types').PeerStore} PeerStore
34
+ * @typedef {import('../peer-store/types').Address} Address
35
35
  * @typedef {import('../transport-manager')} TransportManager
36
36
  */
37
37
 
@@ -56,8 +56,8 @@ const METRICS_PENDING_DIAL_TARGETS = 'pending-dial-targets'
56
56
  * @property {Multiaddr[]} addrs
57
57
  *
58
58
  * @typedef PendingDial
59
- * @property {DialRequest} dialRequest
60
- * @property {TimeoutController} controller
59
+ * @property {import('./dial-request')} dialRequest
60
+ * @property {import('timeout-abort-controller').TimeoutController} controller
61
61
  * @property {Promise<Connection>} promise
62
62
  * @property {function():void} destroy
63
63
  */
@@ -86,9 +86,20 @@ class Dialer {
86
86
  this.timeout = dialTimeout
87
87
  this.maxDialsPerPeer = maxDialsPerPeer
88
88
  this.tokens = [...new Array(maxParallelDials)].map((_, index) => index)
89
- this._pendingDials = new Map()
90
- this._pendingDialTargets = new Map()
91
- 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
+ })
92
103
 
93
104
  for (const [key, value] of Object.entries(resolvers)) {
94
105
  Multiaddr.resolvers.set(key, value)
@@ -112,9 +123,6 @@ class Dialer {
112
123
  pendingTarget.reject(new AbortError('Dialer was destroyed'))
113
124
  }
114
125
  this._pendingDialTargets.clear()
115
-
116
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIALS, 0)
117
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIAL_TARGETS, 0)
118
126
  }
119
127
 
120
128
  /**
@@ -164,7 +172,6 @@ class Dialer {
164
172
  const id = `${(parseInt(String(Math.random() * 1e9), 10)).toString() + Date.now()}`
165
173
  const cancellablePromise = new Promise((resolve, reject) => {
166
174
  this._pendingDialTargets.set(id, { resolve, reject })
167
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIAL_TARGETS, this._pendingDialTargets.size)
168
175
  })
169
176
 
170
177
  try {
@@ -176,7 +183,6 @@ class Dialer {
176
183
  return dialTarget
177
184
  } finally {
178
185
  this._pendingDialTargets.delete(id)
179
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIAL_TARGETS, this._pendingDialTargets.size)
180
186
  }
181
187
  }
182
188
 
@@ -194,10 +200,10 @@ class Dialer {
194
200
  const { id, multiaddrs } = getPeer(peer)
195
201
 
196
202
  if (multiaddrs) {
197
- this.peerStore.addressBook.add(id, multiaddrs)
203
+ await this.peerStore.addressBook.add(id, multiaddrs)
198
204
  }
199
205
 
200
- let knownAddrs = this.peerStore.addressBook.getMultiaddrsForPeer(id, this.addressSorter) || []
206
+ let knownAddrs = await this.peerStore.addressBook.getMultiaddrsForPeer(id, this.addressSorter) || []
201
207
 
202
208
  // If received a multiaddr to dial, it should be the first to use
203
209
  // But, if we know other multiaddrs for the peer, we should try them too.
@@ -217,7 +223,7 @@ class Dialer {
217
223
  const supportedAddrs = addrs.filter(a => this.transportManager.transportForMultiaddr(a))
218
224
 
219
225
  if (supportedAddrs.length > this.maxAddrsToDial) {
220
- this.peerStore.delete(id)
226
+ await this.peerStore.delete(id)
221
227
  throw errCode(new Error('dial with more addresses than allowed'), codes.ERR_TOO_MANY_ADDRESSES)
222
228
  }
223
229
 
@@ -254,14 +260,18 @@ class Dialer {
254
260
 
255
261
  // Combine the timeout signal and options.signal, if provided
256
262
  const timeoutController = new TimeoutController(this.timeout)
257
- // this controller will potentially be used while dialing lots of
258
- // peers so prevent MaxListenersExceededWarning appearing in the console
259
- setMaxListeners && setMaxListeners(Infinity, timeoutController.signal)
260
263
 
261
264
  const signals = [timeoutController.signal]
262
265
  options.signal && signals.push(options.signal)
263
266
  const signal = anySignal(signals)
264
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
+
265
275
  const pendingDial = {
266
276
  dialRequest,
267
277
  controller: timeoutController,
@@ -269,13 +279,10 @@ class Dialer {
269
279
  destroy: () => {
270
280
  timeoutController.clear()
271
281
  this._pendingDials.delete(dialTarget.id)
272
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIALS, this._pendingDials.size)
273
282
  }
274
283
  }
275
284
  this._pendingDials.set(dialTarget.id, pendingDial)
276
285
 
277
- this._metrics && this._metrics.updateComponentMetric(METRICS_COMPONENT, METRICS_PENDING_DIALS, this._pendingDials.size)
278
-
279
286
  return pendingDial
280
287
  }
281
288