libp2p 0.35.7 → 0.35.8-9b22c6e

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 (100) hide show
  1. package/dist/index.min.js +55 -0
  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 +5 -5
  13. package/dist/src/dialer/index.d.ts.map +1 -1
  14. package/dist/src/fetch/constants.d.ts +2 -0
  15. package/dist/src/fetch/constants.d.ts.map +1 -0
  16. package/dist/src/fetch/index.d.ts +76 -0
  17. package/dist/src/fetch/index.d.ts.map +1 -0
  18. package/dist/src/fetch/proto.d.ts +134 -0
  19. package/dist/src/identify/index.d.ts +4 -4
  20. package/dist/src/identify/index.d.ts.map +1 -1
  21. package/dist/src/index.d.ts +16 -6
  22. package/dist/src/index.d.ts.map +1 -1
  23. package/dist/src/metrics/index.d.ts +9 -4
  24. package/dist/src/metrics/index.d.ts.map +1 -1
  25. package/dist/src/metrics/tracked-map.d.ts +6 -1
  26. package/dist/src/metrics/tracked-map.d.ts.map +1 -1
  27. package/dist/src/peer-routing.d.ts +1 -1
  28. package/dist/src/peer-routing.d.ts.map +1 -1
  29. package/dist/src/peer-store/address-book.d.ts +28 -84
  30. package/dist/src/peer-store/address-book.d.ts.map +1 -1
  31. package/dist/src/peer-store/index.d.ts +25 -94
  32. package/dist/src/peer-store/index.d.ts.map +1 -1
  33. package/dist/src/peer-store/key-book.d.ts +31 -15
  34. package/dist/src/peer-store/key-book.d.ts.map +1 -1
  35. package/dist/src/peer-store/metadata-book.d.ts +33 -29
  36. package/dist/src/peer-store/metadata-book.d.ts.map +1 -1
  37. package/dist/src/peer-store/pb/peer.d.ts +222 -0
  38. package/dist/src/peer-store/proto-book.d.ts +27 -28
  39. package/dist/src/peer-store/proto-book.d.ts.map +1 -1
  40. package/dist/src/peer-store/store.d.ts +73 -0
  41. package/dist/src/peer-store/store.d.ts.map +1 -0
  42. package/dist/src/peer-store/types.d.ts +202 -0
  43. package/dist/src/peer-store/types.d.ts.map +1 -0
  44. package/dist/src/ping/index.d.ts.map +1 -1
  45. package/dist/src/record/peer-record/index.d.ts +2 -2
  46. package/dist/src/record/peer-record/index.d.ts.map +1 -1
  47. package/dist/src/registrar.d.ts +5 -5
  48. package/dist/src/registrar.d.ts.map +1 -1
  49. package/dist/src/upgrader.d.ts.map +1 -1
  50. package/package.json +24 -28
  51. package/src/circuit/auto-relay.js +52 -38
  52. package/src/connection-manager/auto-dialler.js +23 -9
  53. package/src/connection-manager/index.js +42 -22
  54. package/src/content-routing/utils.js +4 -4
  55. package/src/dht/dht-peer-routing.js +2 -6
  56. package/src/dialer/dial-request.js +4 -1
  57. package/src/dialer/index.js +22 -10
  58. package/src/fetch/README.md +36 -0
  59. package/src/fetch/constants.js +6 -0
  60. package/src/fetch/index.js +159 -0
  61. package/src/fetch/proto.d.ts +134 -0
  62. package/src/fetch/proto.js +333 -0
  63. package/src/fetch/proto.proto +15 -0
  64. package/src/identify/index.js +47 -38
  65. package/src/index.js +53 -27
  66. package/src/metrics/index.js +15 -8
  67. package/src/metrics/tracked-map.js +45 -13
  68. package/src/peer-routing.js +4 -1
  69. package/src/peer-store/address-book.js +242 -227
  70. package/src/peer-store/index.js +77 -110
  71. package/src/peer-store/key-book.js +99 -54
  72. package/src/peer-store/metadata-book.js +171 -101
  73. package/src/peer-store/pb/peer.d.ts +222 -0
  74. package/src/peer-store/pb/peer.js +643 -0
  75. package/src/peer-store/pb/peer.proto +31 -0
  76. package/src/peer-store/proto-book.js +171 -105
  77. package/src/peer-store/store.js +250 -0
  78. package/src/peer-store/types.ts +245 -0
  79. package/src/ping/index.js +6 -0
  80. package/src/record/peer-record/index.js +1 -1
  81. package/src/record/utils.js +1 -1
  82. package/src/registrar.js +4 -4
  83. package/src/upgrader.js +3 -2
  84. package/dist/src/peer-store/book.d.ts +0 -81
  85. package/dist/src/peer-store/book.d.ts.map +0 -1
  86. package/dist/src/peer-store/persistent/consts.d.ts +0 -6
  87. package/dist/src/peer-store/persistent/consts.d.ts.map +0 -1
  88. package/dist/src/peer-store/persistent/index.d.ts +0 -129
  89. package/dist/src/peer-store/persistent/index.d.ts.map +0 -1
  90. package/dist/src/peer-store/persistent/pb/address-book.d.ts +0 -198
  91. package/dist/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
  92. package/src/peer-store/book.js +0 -124
  93. package/src/peer-store/persistent/consts.js +0 -15
  94. package/src/peer-store/persistent/index.js +0 -408
  95. package/src/peer-store/persistent/pb/address-book.d.ts +0 -198
  96. package/src/peer-store/persistent/pb/address-book.js +0 -522
  97. package/src/peer-store/persistent/pb/address-book.proto +0 -27
  98. package/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
  99. package/src/peer-store/persistent/pb/proto-book.js +0 -157
  100. 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.7",
3
+ "version": "0.35.8-9b22c6e",
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,20 @@
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:fetch && 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
+ "build:proto:fetch": "pbjs -t static-module -w commonjs -r libp2p-fetch --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/fetch/proto.js ./src/fetch/proto.proto",
25
26
  "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
27
  "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",
28
+ "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
29
  "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
30
  "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",
31
+ "build:proto-types": "npm run build:proto-types:circuit && npm run build:proto-types:fetch && 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
32
  "build:proto-types:circuit": "pbts -o src/circuit/protocol/index.d.ts src/circuit/protocol/index.js",
33
+ "build:proto-types:fetch": "pbts -o src/fetch/proto.d.ts src/fetch/proto.js",
33
34
  "build:proto-types:identify": "pbts -o src/identify/message.d.ts src/identify/message.js",
34
35
  "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",
36
+ "build:proto-types:peer": "pbts -o src/peer-store/pb/peer.d.ts src/peer-store/pb/peer.js",
37
37
  "build:proto-types:peer-record": "pbts -o src/record/peer-record/peer-record.d.ts src/record/peer-record/peer-record.js",
38
38
  "build:proto-types:envelope": "pbts -o src/record/envelope/envelope.d.ts src/record/envelope/envelope.js",
39
39
  "test": "aegir test",
@@ -42,10 +42,7 @@
42
42
  "test:browser": "aegir test -t browser",
43
43
  "test:examples": "cd examples && npm run test:all",
44
44
  "test:interop": "LIBP2P_JS=$PWD npx aegir test -t node -f ./node_modules/libp2p-interop/test/*",
45
- "prepare": "aegir build --no-bundle",
46
- "release": "aegir release -t node -t browser",
47
- "release-minor": "aegir release --type minor -t node -t browser",
48
- "release-major": "aegir release --type major -t node -t browser",
45
+ "prepare": "npm run build",
49
46
  "coverage": "nyc --reporter=text --reporter=lcov npm run test:node"
50
47
  },
51
48
  "repository": {
@@ -81,12 +78,12 @@
81
78
  },
82
79
  "dependencies": {
83
80
  "@vascosantos/moving-average": "^1.1.0",
84
- "abort-controller": "^3.0.0",
85
81
  "abortable-iterator": "^3.0.0",
86
82
  "aggregate-error": "^3.1.0",
87
- "any-signal": "^2.1.1",
83
+ "any-signal": "^3.0.0",
88
84
  "bignumber.js": "^9.0.1",
89
85
  "class-is": "^1.1.0",
86
+ "datastore-core": "^7.0.0",
90
87
  "debug": "^4.3.1",
91
88
  "err-code": "^3.0.0",
92
89
  "es6-promisify": "^7.0.0",
@@ -103,18 +100,20 @@
103
100
  "it-map": "^1.0.4",
104
101
  "it-merge": "^1.0.0",
105
102
  "it-pipe": "^1.1.0",
103
+ "it-sort": "^1.0.1",
106
104
  "it-take": "^1.0.0",
107
- "libp2p-crypto": "^0.21.0",
108
- "libp2p-interfaces": "^2.0.1",
105
+ "libp2p-crypto": "^0.21.2",
106
+ "libp2p-interfaces": "^4.0.0",
109
107
  "libp2p-utils": "^0.4.0",
110
108
  "mafmt": "^10.0.0",
111
109
  "merge-options": "^3.0.4",
110
+ "mortice": "^2.0.1",
112
111
  "multiaddr": "^10.0.0",
113
112
  "multiformats": "^9.0.0",
114
- "multistream-select": "^2.0.0",
113
+ "multistream-select": "^3.0.0",
115
114
  "mutable-proxy": "^1.0.0",
116
115
  "nat-api": "^0.3.1",
117
- "node-forge": "^0.10.0",
116
+ "node-forge": "^1.2.1",
118
117
  "p-any": "^3.0.0",
119
118
  "p-fifo": "^1.0.0",
120
119
  "p-retry": "^4.4.0",
@@ -126,7 +125,7 @@
126
125
  "sanitize-filename": "^1.6.3",
127
126
  "set-delayed-interval": "^1.0.0",
128
127
  "streaming-iterables": "^6.0.0",
129
- "timeout-abort-controller": "^2.0.0",
128
+ "timeout-abort-controller": "^3.0.0",
130
129
  "uint8arrays": "^3.0.0",
131
130
  "varint": "^6.0.0",
132
131
  "wherearewe": "^1.0.0",
@@ -137,11 +136,10 @@
137
136
  "@nodeutils/defaults-deep": "^1.1.0",
138
137
  "@types/es6-promisify": "^6.0.0",
139
138
  "@types/node": "^16.0.1",
140
- "@types/node-forge": "^0.10.1",
139
+ "@types/node-forge": "^1.0.0",
141
140
  "@types/varint": "^6.0.0",
142
141
  "aegir": "^36.0.0",
143
142
  "buffer": "^6.0.3",
144
- "datastore-core": "^6.0.7",
145
143
  "delay": "^5.0.0",
146
144
  "into-stream": "^6.0.0",
147
145
  "ipfs-http-client": "^54.0.2",
@@ -152,13 +150,11 @@
152
150
  "libp2p-bootstrap": "^0.14.0",
153
151
  "libp2p-delegated-content-routing": "^0.11.0",
154
152
  "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",
153
+ "libp2p-interfaces-compliance-tests": "^4.0.8",
154
+ "libp2p-interop": "^0.7.1",
155
+ "libp2p-kad-dht": "^0.28.6",
160
156
  "libp2p-mdns": "^0.18.0",
161
- "libp2p-mplex": "^0.10.1",
157
+ "libp2p-mplex": "^0.10.4",
162
158
  "libp2p-tcp": "^0.17.0",
163
159
  "libp2p-webrtc-star": "^0.25.0",
164
160
  "libp2p-websockets": "^0.16.0",
@@ -181,12 +177,12 @@
181
177
  "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
182
178
  "Maciej Krüger <mkg20001@gmail.com>",
183
179
  "Hugo Dias <mail@hugodias.me>",
180
+ "dirkmc <dirkmdev@gmail.com>",
184
181
  "Volker Mische <volker.mische@gmail.com>",
185
182
  "Chris Dostert <chrisdostert@users.noreply.github.com>",
186
- "dirkmc <dirkmdev@gmail.com>",
183
+ "zeim839 <50573884+zeim839@users.noreply.github.com>",
187
184
  "Robert Kiel <robert.kiel@hoprnet.org>",
188
185
  "Richard Littauer <richard.littauer@gmail.com>",
189
- "zeim839 <50573884+zeim839@users.noreply.github.com>",
190
186
  "a1300 <matthias-knopp@gmx.net>",
191
187
  "Ryan Bell <ryan@piing.net>",
192
188
  "ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>",
@@ -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,10 @@ 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')
8
+ const { pipe } = require('it-pipe')
9
+ const filter = require('it-filter')
10
+ const sort = require('it-sort')
7
11
 
8
12
  const log = Object.assign(debug('libp2p:connection-manager:auto-dialler'), {
9
13
  error: debug('libp2p:connection-manager:auto-dialler:err')
@@ -50,14 +54,16 @@ class AutoDialler {
50
54
  /**
51
55
  * Starts the auto dialer
52
56
  */
53
- start () {
57
+ async start () {
54
58
  if (!this._options.enabled) {
55
59
  log('not enabled')
56
60
  return
57
61
  }
58
62
 
59
63
  this._running = true
60
- this._autoDial()
64
+ this._autoDial().catch(err => {
65
+ log.error('could start autodial', err)
66
+ })
61
67
  log('started')
62
68
  }
63
69
 
@@ -84,22 +90,30 @@ class AutoDialler {
84
90
  return
85
91
  }
86
92
 
87
- // Sort peers on wether we know protocols of public keys for them
88
- const peers = Array.from(this._libp2p.peerStore.peers.values())
89
- .sort((a, b) => {
93
+ // Sort peers on whether we know protocols of public keys for them
94
+ // TODO: assuming the `peerStore.getPeers()` order is stable this will mean
95
+ // we keep trying to connect to the same peers?
96
+ const peers = await pipe(
97
+ this._libp2p.peerStore.getPeers(),
98
+ (source) => filter(source, (peer) => !peer.id.equals(this._libp2p.peerId)),
99
+ (source) => sort(source, (a, b) => {
90
100
  if (b.protocols && b.protocols.length && (!a.protocols || !a.protocols.length)) {
91
101
  return 1
92
102
  } else if (b.id.pubKey && !a.id.pubKey) {
93
103
  return 1
94
104
  }
95
105
  return -1
96
- })
106
+ }),
107
+ (source) => all(source)
108
+ )
97
109
 
98
110
  for (let i = 0; this._running && i < peers.length && this._libp2p.connections.size < minConnections; i++) {
99
- if (!this._libp2p.connectionManager.get(peers[i].id)) {
100
- log('connecting to a peerStore stored peer %s', peers[i].id.toB58String())
111
+ const peer = peers[i]
112
+
113
+ if (!this._libp2p.connectionManager.get(peer.id)) {
114
+ log('connecting to a peerStore stored peer %s', peer.id.toB58String())
101
115
  try {
102
- await this._libp2p.dialer.connectToPeer(peers[i].id)
116
+ await this._libp2p.dialer.connectToPeer(peer.id)
103
117
  } catch (/** @type {any} */ err) {
104
118
  log.error('could not connect to peerStore stored peer', err)
105
119
  }
@@ -87,14 +87,22 @@ class ConnectionManager extends EventEmitter {
87
87
  *
88
88
  * @type {Map<string, number>}
89
89
  */
90
- this._peerValues = trackedMap(METRICS_COMPONENT, METRICS_PEER_VALUES, this._libp2p.metrics)
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 = trackedMap(METRICS_COMPONENT, METRICS_PEER_CONNECTIONS, this._libp2p.metrics)
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
  /**
@@ -187,19 +198,22 @@ class ConnectionManager extends EventEmitter {
187
198
  *
188
199
  * @private
189
200
  */
190
- _checkMetrics () {
201
+ async _checkMetrics () {
191
202
  if (this._libp2p.metrics) {
192
- const movingAverages = this._libp2p.metrics.global.movingAverages
193
- // @ts-ignore moving averages object types
194
- const received = movingAverages.dataReceived[this._options.movingAverageInterval].movingAverage()
195
- this._checkMaxLimit('maxReceivedData', received)
196
- // @ts-ignore moving averages object types
197
- const sent = movingAverages.dataSent[this._options.movingAverageInterval].movingAverage()
198
- this._checkMaxLimit('maxSentData', sent)
199
- const total = received + sent
200
- this._checkMaxLimit('maxData', total)
201
- log('metrics update', total)
202
- 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
+ }
203
217
  }
204
218
  }
205
219
 
@@ -207,9 +221,8 @@ class ConnectionManager extends EventEmitter {
207
221
  * Tracks the incoming connection and check the connection limit
208
222
  *
209
223
  * @param {Connection} connection
210
- * @returns {void}
211
224
  */
212
- onConnect (connection) {
225
+ async onConnect (connection) {
213
226
  const peerId = connection.remotePeer
214
227
  const peerIdStr = peerId.toB58String()
215
228
  const storedConn = this.connections.get(peerIdStr)
@@ -222,13 +235,13 @@ class ConnectionManager extends EventEmitter {
222
235
  this.connections.set(peerIdStr, [connection])
223
236
  }
224
237
 
225
- this._libp2p.peerStore.keyBook.set(peerId, peerId.pubKey)
238
+ await this._libp2p.peerStore.keyBook.set(peerId, peerId.pubKey)
226
239
 
227
240
  if (!this._peerValues.has(peerIdStr)) {
228
241
  this._peerValues.set(peerIdStr, this._options.defaultPeerValue)
229
242
  }
230
243
 
231
- this._checkMaxLimit('maxConnections', this.size)
244
+ await this._checkMaxLimit('maxConnections', this.size)
232
245
  }
233
246
 
234
247
  /**
@@ -296,6 +309,9 @@ class ConnectionManager extends EventEmitter {
296
309
  */
297
310
  _onLatencyMeasure (summary) {
298
311
  this._checkMaxLimit('maxEventLoopDelay', summary.avgMs)
312
+ .catch(err => {
313
+ log.error(err)
314
+ })
299
315
  }
300
316
 
301
317
  /**
@@ -305,12 +321,12 @@ class ConnectionManager extends EventEmitter {
305
321
  * @param {string} name - The name of the field to check limits for
306
322
  * @param {number} value - The current value of the field
307
323
  */
308
- _checkMaxLimit (name, value) {
324
+ async _checkMaxLimit (name, value) {
309
325
  const limit = this._options[name]
310
326
  log('checking limit of %s. current value: %d of %d', name, value, limit)
311
327
  if (value > limit) {
312
328
  log('%s: limit exceeded: %s, %d', this._peerId, name, value)
313
- this._maybeDisconnectOne()
329
+ await this._maybeDisconnectOne()
314
330
  }
315
331
  }
316
332
 
@@ -320,7 +336,7 @@ class ConnectionManager extends EventEmitter {
320
336
  *
321
337
  * @private
322
338
  */
323
- _maybeDisconnectOne () {
339
+ async _maybeDisconnectOne () {
324
340
  if (this._options.minConnections < this.connections.size) {
325
341
  const peerValues = Array.from(new Map([...this._peerValues.entries()].sort((a, b) => a[1] - b[1])))
326
342
  log('%s: sorted peer values: %j', this._peerId, peerValues)
@@ -331,7 +347,11 @@ class ConnectionManager extends EventEmitter {
331
347
  log('%s: closing a connection to %j', this._peerId, peerId)
332
348
  for (const connections of this.connections.values()) {
333
349
  if (connections[0].remotePeer.toB58String() === peerId) {
334
- 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])
335
355
  break
336
356
  }
337
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
  })
@@ -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
 
@@ -88,10 +88,18 @@ class Dialer {
88
88
  this.tokens = [...new Array(maxParallelDials)].map((_, index) => index)
89
89
 
90
90
  /** @type {Map<string, PendingDial>} */
91
- this._pendingDials = trackedMap(METRICS_COMPONENT, METRICS_PENDING_DIALS, metrics)
91
+ this._pendingDials = trackedMap({
92
+ component: METRICS_COMPONENT,
93
+ metric: METRICS_PENDING_DIALS,
94
+ metrics
95
+ })
92
96
 
93
97
  /** @type {Map<string, { resolve: (value: any) => void, reject: (err: Error) => void}>} */
94
- this._pendingDialTargets = trackedMap(METRICS_COMPONENT, METRICS_PENDING_DIAL_TARGETS, metrics)
98
+ this._pendingDialTargets = trackedMap({
99
+ component: METRICS_COMPONENT,
100
+ metric: METRICS_PENDING_DIAL_TARGETS,
101
+ metrics
102
+ })
95
103
 
96
104
  for (const [key, value] of Object.entries(resolvers)) {
97
105
  Multiaddr.resolvers.set(key, value)
@@ -192,10 +200,10 @@ class Dialer {
192
200
  const { id, multiaddrs } = getPeer(peer)
193
201
 
194
202
  if (multiaddrs) {
195
- this.peerStore.addressBook.add(id, multiaddrs)
203
+ await this.peerStore.addressBook.add(id, multiaddrs)
196
204
  }
197
205
 
198
- let knownAddrs = this.peerStore.addressBook.getMultiaddrsForPeer(id, this.addressSorter) || []
206
+ let knownAddrs = await this.peerStore.addressBook.getMultiaddrsForPeer(id, this.addressSorter) || []
199
207
 
200
208
  // If received a multiaddr to dial, it should be the first to use
201
209
  // But, if we know other multiaddrs for the peer, we should try them too.
@@ -215,7 +223,7 @@ class Dialer {
215
223
  const supportedAddrs = addrs.filter(a => this.transportManager.transportForMultiaddr(a))
216
224
 
217
225
  if (supportedAddrs.length > this.maxAddrsToDial) {
218
- this.peerStore.delete(id)
226
+ await this.peerStore.delete(id)
219
227
  throw errCode(new Error('dial with more addresses than allowed'), codes.ERR_TOO_MANY_ADDRESSES)
220
228
  }
221
229
 
@@ -252,14 +260,18 @@ class Dialer {
252
260
 
253
261
  // Combine the timeout signal and options.signal, if provided
254
262
  const timeoutController = new TimeoutController(this.timeout)
255
- // this controller will potentially be used while dialing lots of
256
- // peers so prevent MaxListenersExceededWarning appearing in the console
257
- setMaxListeners && setMaxListeners(Infinity, timeoutController.signal)
258
263
 
259
264
  const signals = [timeoutController.signal]
260
265
  options.signal && signals.push(options.signal)
261
266
  const signal = anySignal(signals)
262
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
+
263
275
  const pendingDial = {
264
276
  dialRequest,
265
277
  controller: timeoutController,