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.
- package/README.md +2 -2
- package/dist/index.min.js +55 -0
- package/dist/src/circuit/auto-relay.d.ts +8 -10
- package/dist/src/circuit/auto-relay.d.ts.map +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
- package/dist/src/connection-manager/index.d.ts +1 -2
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/content-routing/utils.d.ts +3 -3
- package/dist/src/content-routing/utils.d.ts.map +1 -1
- package/dist/src/dht/dht-peer-routing.d.ts.map +1 -1
- package/dist/src/dialer/dial-request.d.ts.map +1 -1
- package/dist/src/dialer/index.d.ts +20 -16
- package/dist/src/dialer/index.d.ts.map +1 -1
- package/dist/src/identify/index.d.ts +4 -4
- package/dist/src/identify/index.d.ts.map +1 -1
- package/dist/src/index.d.ts +14 -9
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/metrics/index.d.ts +9 -4
- package/dist/src/metrics/index.d.ts.map +1 -1
- package/dist/src/metrics/stats.d.ts +3 -1
- package/dist/src/metrics/stats.d.ts.map +1 -1
- package/dist/src/metrics/tracked-map.d.ts +8 -0
- package/dist/src/metrics/tracked-map.d.ts.map +1 -0
- package/dist/src/peer-routing.d.ts +1 -1
- package/dist/src/peer-routing.d.ts.map +1 -1
- package/dist/src/peer-store/address-book.d.ts +28 -84
- package/dist/src/peer-store/address-book.d.ts.map +1 -1
- package/dist/src/peer-store/index.d.ts +25 -94
- package/dist/src/peer-store/index.d.ts.map +1 -1
- package/dist/src/peer-store/key-book.d.ts +31 -15
- package/dist/src/peer-store/key-book.d.ts.map +1 -1
- package/dist/src/peer-store/metadata-book.d.ts +33 -29
- package/dist/src/peer-store/metadata-book.d.ts.map +1 -1
- package/dist/src/peer-store/pb/peer.d.ts +222 -0
- package/dist/src/peer-store/proto-book.d.ts +27 -28
- package/dist/src/peer-store/proto-book.d.ts.map +1 -1
- package/dist/src/peer-store/store.d.ts +73 -0
- package/dist/src/peer-store/store.d.ts.map +1 -0
- package/dist/src/peer-store/types.d.ts +202 -0
- package/dist/src/peer-store/types.d.ts.map +1 -0
- package/dist/src/ping/index.d.ts.map +1 -1
- package/dist/src/record/peer-record/index.d.ts +2 -2
- package/dist/src/record/peer-record/index.d.ts.map +1 -1
- package/dist/src/registrar.d.ts +5 -5
- package/dist/src/registrar.d.ts.map +1 -1
- package/dist/src/upgrader.d.ts.map +1 -1
- package/package.json +28 -32
- package/src/circuit/auto-relay.js +52 -38
- package/src/connection-manager/auto-dialler.js +9 -4
- package/src/connection-manager/index.js +44 -31
- package/src/content-routing/utils.js +4 -4
- package/src/dht/dht-peer-routing.js +2 -6
- package/src/dialer/dial-request.js +4 -1
- package/src/dialer/index.js +32 -20
- package/src/identify/index.js +47 -38
- package/src/index.js +43 -35
- package/src/metrics/index.js +15 -8
- package/src/metrics/stats.js +1 -0
- package/src/metrics/tracked-map.js +94 -0
- package/src/peer-routing.js +11 -1
- package/src/peer-store/address-book.js +242 -227
- package/src/peer-store/index.js +77 -110
- package/src/peer-store/key-book.js +99 -54
- package/src/peer-store/metadata-book.js +171 -101
- package/src/peer-store/pb/peer.d.ts +222 -0
- package/src/peer-store/pb/peer.js +643 -0
- package/src/peer-store/pb/peer.proto +31 -0
- package/src/peer-store/proto-book.js +171 -105
- package/src/peer-store/store.js +250 -0
- package/src/peer-store/types.ts +245 -0
- package/src/ping/index.js +6 -0
- package/src/record/peer-record/index.js +1 -1
- package/src/record/utils.js +1 -1
- package/src/registrar.js +4 -4
- package/src/upgrader.js +3 -1
- package/dist/src/peer-store/book.d.ts +0 -81
- package/dist/src/peer-store/book.d.ts.map +0 -1
- package/dist/src/peer-store/persistent/consts.d.ts +0 -6
- package/dist/src/peer-store/persistent/consts.d.ts.map +0 -1
- package/dist/src/peer-store/persistent/index.d.ts +0 -129
- package/dist/src/peer-store/persistent/index.d.ts.map +0 -1
- package/dist/src/peer-store/persistent/pb/address-book.d.ts +0 -198
- package/dist/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
- package/src/peer-store/book.js +0 -124
- package/src/peer-store/persistent/consts.js +0 -15
- package/src/peer-store/persistent/index.js +0 -408
- package/src/peer-store/persistent/pb/address-book.d.ts +0 -198
- package/src/peer-store/persistent/pb/address-book.js +0 -522
- package/src/peer-store/persistent/pb/address-book.proto +0 -27
- package/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
- package/src/peer-store/persistent/pb/proto-book.js +0 -157
- 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
|
|
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/
|
|
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.
|
|
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
|
-
|
|
171
|
-
|
|
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
|
|
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(
|
|
225
|
+
if (this._listenRelays.has(idStr)) {
|
|
215
226
|
continue
|
|
216
227
|
}
|
|
217
228
|
|
|
218
|
-
|
|
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
|
|
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(
|
|
244
|
+
knownHopsToDial.push(id)
|
|
231
245
|
continue
|
|
232
246
|
}
|
|
233
247
|
|
|
234
|
-
await this._addListenRelay(connection,
|
|
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
|
|
88
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
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 === '
|
|
31
|
-
|
|
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
|
-
|
|
66
|
+
try {
|
|
67
|
+
// fails on node < 15.4
|
|
68
|
+
setMaxListeners && setMaxListeners(Infinity, controller.signal)
|
|
69
|
+
} catch {}
|
|
67
70
|
|
|
68
71
|
return controller
|
|
69
72
|
})
|
package/src/dialer/index.js
CHANGED
|
@@ -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/
|
|
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 {
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
this.
|
|
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
|
|