libp2p 0.35.4 → 0.35.8-bf1fc32
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 +26 -30
- package/src/circuit/auto-relay.js +19 -19
- package/src/connection-manager/auto-dialler.js +9 -4
- package/src/connection-manager/index.js +41 -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 +33 -21
- package/src/identify/index.js +28 -23
- 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,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/
|
|
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.
|
|
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
|
|
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(
|
|
215
|
+
if (this._listenRelays.has(idStr) || peersToIgnore.includes(idStr)) {
|
|
215
216
|
continue
|
|
216
217
|
}
|
|
217
218
|
|
|
218
|
-
const supportsHop =
|
|
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
|
|
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(
|
|
230
|
+
knownHopsToDial.push(id)
|
|
231
231
|
continue
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
await this._addListenRelay(connection,
|
|
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
|
|
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
|
|
@@ -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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
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,
|
|
@@ -24,13 +25,13 @@ const {
|
|
|
24
25
|
|
|
25
26
|
const METRICS_COMPONENT = 'dialler'
|
|
26
27
|
const METRICS_PENDING_DIALS = 'pending-dials'
|
|
27
|
-
const METRICS_PENDING_DIAL_TARGETS = 'pending-
|
|
28
|
+
const METRICS_PENDING_DIAL_TARGETS = 'pending-dial-targets'
|
|
28
29
|
|
|
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-dials-targers'
|
|
|
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
|
|
package/src/identify/index.js
CHANGED
|
@@ -77,8 +77,6 @@ class IdentifyService {
|
|
|
77
77
|
...libp2p._options.host
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
this.peerStore.metadataBook.set(this.peerId, 'AgentVersion', uint8ArrayFromString(this._host.agentVersion))
|
|
81
|
-
this.peerStore.metadataBook.set(this.peerId, 'ProtocolVersion', uint8ArrayFromString(this._host.protocolVersion))
|
|
82
80
|
// When a new connection happens, trigger identify
|
|
83
81
|
this.connectionManager.on('peer:connect', (connection) => {
|
|
84
82
|
this.identify(connection).catch(log.error)
|
|
@@ -87,18 +85,27 @@ class IdentifyService {
|
|
|
87
85
|
// When self multiaddrs change, trigger identify-push
|
|
88
86
|
this.peerStore.on('change:multiaddrs', ({ peerId }) => {
|
|
89
87
|
if (peerId.toString() === this.peerId.toString()) {
|
|
90
|
-
this.pushToPeerStore()
|
|
88
|
+
this.pushToPeerStore().catch(err => log.error(err))
|
|
91
89
|
}
|
|
92
90
|
})
|
|
93
91
|
|
|
94
92
|
// When self protocols change, trigger identify-push
|
|
95
93
|
this.peerStore.on('change:protocols', ({ peerId }) => {
|
|
96
94
|
if (peerId.toString() === this.peerId.toString()) {
|
|
97
|
-
this.pushToPeerStore()
|
|
95
|
+
this.pushToPeerStore().catch(err => log.error(err))
|
|
98
96
|
}
|
|
99
97
|
})
|
|
100
98
|
}
|
|
101
99
|
|
|
100
|
+
async start () {
|
|
101
|
+
await this.peerStore.metadataBook.setValue(this.peerId, 'AgentVersion', uint8ArrayFromString(this._host.agentVersion))
|
|
102
|
+
await this.peerStore.metadataBook.setValue(this.peerId, 'ProtocolVersion', uint8ArrayFromString(this._host.protocolVersion))
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async stop () {
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
102
109
|
/**
|
|
103
110
|
* Send an Identify Push update to the list of connections
|
|
104
111
|
*
|
|
@@ -108,7 +115,7 @@ class IdentifyService {
|
|
|
108
115
|
async push (connections) {
|
|
109
116
|
const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId)
|
|
110
117
|
const listenAddrs = this._libp2p.multiaddrs.map((ma) => ma.bytes)
|
|
111
|
-
const protocols = this.peerStore.protoBook.get(this.peerId)
|
|
118
|
+
const protocols = await this.peerStore.protoBook.get(this.peerId)
|
|
112
119
|
|
|
113
120
|
const pushes = connections.map(async connection => {
|
|
114
121
|
try {
|
|
@@ -135,10 +142,8 @@ class IdentifyService {
|
|
|
135
142
|
|
|
136
143
|
/**
|
|
137
144
|
* Calls `push` for all peers in the `peerStore` that are connected
|
|
138
|
-
*
|
|
139
|
-
* @returns {void}
|
|
140
145
|
*/
|
|
141
|
-
pushToPeerStore () {
|
|
146
|
+
async pushToPeerStore () {
|
|
142
147
|
// Do not try to push if libp2p node is not running
|
|
143
148
|
if (!this._libp2p.isStarted()) {
|
|
144
149
|
return
|
|
@@ -146,13 +151,13 @@ class IdentifyService {
|
|
|
146
151
|
|
|
147
152
|
const connections = []
|
|
148
153
|
let connection
|
|
149
|
-
for (const peer of this.peerStore.
|
|
154
|
+
for await (const peer of this.peerStore.getPeers()) {
|
|
150
155
|
if (peer.protocols.includes(this.identifyPushProtocolStr) && (connection = this.connectionManager.get(peer.id))) {
|
|
151
156
|
connections.push(connection)
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
159
|
|
|
155
|
-
this.push(connections)
|
|
160
|
+
await this.push(connections)
|
|
156
161
|
}
|
|
157
162
|
|
|
158
163
|
/**
|
|
@@ -205,10 +210,10 @@ class IdentifyService {
|
|
|
205
210
|
|
|
206
211
|
try {
|
|
207
212
|
const envelope = await Envelope.openAndCertify(signedPeerRecord, PeerRecord.DOMAIN)
|
|
208
|
-
if (this.peerStore.addressBook.consumePeerRecord(envelope)) {
|
|
209
|
-
this.peerStore.protoBook.set(id, protocols)
|
|
210
|
-
this.peerStore.metadataBook.
|
|
211
|
-
this.peerStore.metadataBook.
|
|
213
|
+
if (await this.peerStore.addressBook.consumePeerRecord(envelope)) {
|
|
214
|
+
await this.peerStore.protoBook.set(id, protocols)
|
|
215
|
+
await this.peerStore.metadataBook.setValue(id, 'AgentVersion', uint8ArrayFromString(message.agentVersion))
|
|
216
|
+
await this.peerStore.metadataBook.setValue(id, 'ProtocolVersion', uint8ArrayFromString(message.protocolVersion))
|
|
212
217
|
return
|
|
213
218
|
}
|
|
214
219
|
} catch (/** @type {any} */ err) {
|
|
@@ -217,14 +222,14 @@ class IdentifyService {
|
|
|
217
222
|
|
|
218
223
|
// LEGACY: Update peers data in PeerStore
|
|
219
224
|
try {
|
|
220
|
-
this.peerStore.addressBook.set(id, listenAddrs.map((addr) => new Multiaddr(addr)))
|
|
225
|
+
await this.peerStore.addressBook.set(id, listenAddrs.map((addr) => new Multiaddr(addr)))
|
|
221
226
|
} catch (/** @type {any} */ err) {
|
|
222
227
|
log.error('received invalid addrs', err)
|
|
223
228
|
}
|
|
224
229
|
|
|
225
|
-
this.peerStore.protoBook.set(id, protocols)
|
|
226
|
-
this.peerStore.metadataBook.
|
|
227
|
-
this.peerStore.metadataBook.
|
|
230
|
+
await this.peerStore.protoBook.set(id, protocols)
|
|
231
|
+
await this.peerStore.metadataBook.setValue(id, 'AgentVersion', uint8ArrayFromString(message.agentVersion))
|
|
232
|
+
await this.peerStore.metadataBook.setValue(id, 'ProtocolVersion', uint8ArrayFromString(message.protocolVersion))
|
|
228
233
|
|
|
229
234
|
// TODO: Add and score our observed addr
|
|
230
235
|
log('received observed address of %s', cleanObservedAddr)
|
|
@@ -268,7 +273,7 @@ class IdentifyService {
|
|
|
268
273
|
}
|
|
269
274
|
|
|
270
275
|
const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId)
|
|
271
|
-
const protocols = this.peerStore.protoBook.get(this.peerId)
|
|
276
|
+
const protocols = await this.peerStore.protoBook.get(this.peerId)
|
|
272
277
|
|
|
273
278
|
const message = Message.Identify.encode({
|
|
274
279
|
protocolVersion: this._host.protocolVersion,
|
|
@@ -321,8 +326,8 @@ class IdentifyService {
|
|
|
321
326
|
|
|
322
327
|
try {
|
|
323
328
|
const envelope = await Envelope.openAndCertify(message.signedPeerRecord, PeerRecord.DOMAIN)
|
|
324
|
-
if (this.peerStore.addressBook.consumePeerRecord(envelope)) {
|
|
325
|
-
this.peerStore.protoBook.set(id, message.protocols)
|
|
329
|
+
if (await this.peerStore.addressBook.consumePeerRecord(envelope)) {
|
|
330
|
+
await this.peerStore.protoBook.set(id, message.protocols)
|
|
326
331
|
return
|
|
327
332
|
}
|
|
328
333
|
} catch (/** @type {any} */ err) {
|
|
@@ -331,14 +336,14 @@ class IdentifyService {
|
|
|
331
336
|
|
|
332
337
|
// LEGACY: Update peers data in PeerStore
|
|
333
338
|
try {
|
|
334
|
-
this.peerStore.addressBook.set(id,
|
|
339
|
+
await this.peerStore.addressBook.set(id,
|
|
335
340
|
message.listenAddrs.map((addr) => new Multiaddr(addr)))
|
|
336
341
|
} catch (/** @type {any} */ err) {
|
|
337
342
|
log.error('received invalid addrs', err)
|
|
338
343
|
}
|
|
339
344
|
|
|
340
345
|
// Update the protocols
|
|
341
|
-
this.peerStore.protoBook.set(id, message.protocols)
|
|
346
|
+
await this.peerStore.protoBook.set(id, message.protocols)
|
|
342
347
|
}
|
|
343
348
|
|
|
344
349
|
/**
|