libp2p 0.36.2-fab4f13 → 0.37.0-d5386df

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 (180) hide show
  1. package/dist/src/address-manager/index.d.ts +2 -1
  2. package/dist/src/address-manager/index.d.ts.map +1 -1
  3. package/dist/src/address-manager/index.js +1 -1
  4. package/dist/src/address-manager/index.js.map +1 -1
  5. package/dist/src/circuit/auto-relay.d.ts.map +1 -1
  6. package/dist/src/circuit/auto-relay.js +7 -6
  7. package/dist/src/circuit/auto-relay.js.map +1 -1
  8. package/dist/src/circuit/circuit/hop.d.ts +1 -1
  9. package/dist/src/circuit/circuit/hop.d.ts.map +1 -1
  10. package/dist/src/circuit/circuit/hop.js +4 -4
  11. package/dist/src/circuit/circuit/hop.js.map +1 -1
  12. package/dist/src/circuit/index.d.ts +1 -1
  13. package/dist/src/circuit/index.d.ts.map +1 -1
  14. package/dist/src/circuit/listener.d.ts +3 -3
  15. package/dist/src/circuit/listener.d.ts.map +1 -1
  16. package/dist/src/circuit/listener.js +10 -2
  17. package/dist/src/circuit/listener.js.map +1 -1
  18. package/dist/src/circuit/pb/index.d.ts +5 -4
  19. package/dist/src/circuit/pb/index.d.ts.map +1 -1
  20. package/dist/src/circuit/pb/index.js +28 -2
  21. package/dist/src/circuit/pb/index.js.map +1 -1
  22. package/dist/src/circuit/transport.d.ts.map +1 -1
  23. package/dist/src/circuit/transport.js +7 -5
  24. package/dist/src/circuit/transport.js.map +1 -1
  25. package/dist/src/config.d.ts.map +1 -1
  26. package/dist/src/config.js +5 -7
  27. package/dist/src/config.js.map +1 -1
  28. package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
  29. package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
  30. package/dist/src/connection-manager/auto-dialler.js +4 -4
  31. package/dist/src/connection-manager/auto-dialler.js.map +1 -1
  32. package/dist/src/{dialer → connection-manager/dialer}/auto-dialer.d.ts +2 -0
  33. package/dist/src/connection-manager/dialer/auto-dialer.d.ts.map +1 -0
  34. package/dist/src/connection-manager/dialer/auto-dialer.js +37 -0
  35. package/dist/src/connection-manager/dialer/auto-dialer.js.map +1 -0
  36. package/dist/src/{dialer → connection-manager/dialer}/dial-request.d.ts +2 -2
  37. package/dist/src/connection-manager/dialer/dial-request.d.ts.map +1 -0
  38. package/dist/src/{dialer → connection-manager/dialer}/dial-request.js +1 -1
  39. package/dist/src/connection-manager/dialer/dial-request.js.map +1 -0
  40. package/dist/src/{dialer → connection-manager/dialer}/index.d.ts +37 -8
  41. package/dist/src/connection-manager/dialer/index.d.ts.map +1 -0
  42. package/dist/src/{dialer → connection-manager/dialer}/index.js +10 -23
  43. package/dist/src/connection-manager/dialer/index.js.map +1 -0
  44. package/dist/src/connection-manager/index.d.ts +57 -26
  45. package/dist/src/connection-manager/index.d.ts.map +1 -1
  46. package/dist/src/connection-manager/index.js +80 -42
  47. package/dist/src/connection-manager/index.js.map +1 -1
  48. package/dist/src/connection-manager/latency-monitor.d.ts +1 -1
  49. package/dist/src/connection-manager/latency-monitor.d.ts.map +1 -1
  50. package/dist/src/connection-manager/latency-monitor.js +1 -1
  51. package/dist/src/connection-manager/latency-monitor.js.map +1 -1
  52. package/dist/src/connection-manager/visibility-change-emitter.d.ts +1 -1
  53. package/dist/src/connection-manager/visibility-change-emitter.d.ts.map +1 -1
  54. package/dist/src/connection-manager/visibility-change-emitter.js +1 -1
  55. package/dist/src/connection-manager/visibility-change-emitter.js.map +1 -1
  56. package/dist/src/content-routing/index.d.ts +2 -1
  57. package/dist/src/content-routing/index.d.ts.map +1 -1
  58. package/dist/src/content-routing/index.js.map +1 -1
  59. package/dist/src/dht/dummy-dht.d.ts +4 -1
  60. package/dist/src/dht/dummy-dht.d.ts.map +1 -1
  61. package/dist/src/dht/dummy-dht.js +8 -1
  62. package/dist/src/dht/dummy-dht.js.map +1 -1
  63. package/dist/src/fetch/index.d.ts +1 -1
  64. package/dist/src/fetch/index.d.ts.map +1 -1
  65. package/dist/src/fetch/index.js +1 -1
  66. package/dist/src/fetch/index.js.map +1 -1
  67. package/dist/src/fetch/pb/proto.d.ts +4 -3
  68. package/dist/src/fetch/pb/proto.d.ts.map +1 -1
  69. package/dist/src/fetch/pb/proto.js +7 -1
  70. package/dist/src/fetch/pb/proto.js.map +1 -1
  71. package/dist/src/identify/index.d.ts +1 -1
  72. package/dist/src/identify/index.d.ts.map +1 -1
  73. package/dist/src/identify/index.js +4 -4
  74. package/dist/src/identify/index.js.map +1 -1
  75. package/dist/src/identify/pb/message.d.ts +2 -1
  76. package/dist/src/identify/pb/message.d.ts.map +1 -1
  77. package/dist/src/identify/pb/message.js.map +1 -1
  78. package/dist/src/index.d.ts +7 -24
  79. package/dist/src/index.d.ts.map +1 -1
  80. package/dist/src/index.js.map +1 -1
  81. package/dist/src/insecure/pb/proto.d.ts +4 -3
  82. package/dist/src/insecure/pb/proto.d.ts.map +1 -1
  83. package/dist/src/insecure/pb/proto.js +8 -1
  84. package/dist/src/insecure/pb/proto.js.map +1 -1
  85. package/dist/src/keychain/index.d.ts +0 -1
  86. package/dist/src/keychain/index.d.ts.map +1 -1
  87. package/dist/src/keychain/index.js +0 -1
  88. package/dist/src/keychain/index.js.map +1 -1
  89. package/dist/src/libp2p.d.ts +4 -2
  90. package/dist/src/libp2p.d.ts.map +1 -1
  91. package/dist/src/libp2p.js +57 -43
  92. package/dist/src/libp2p.js.map +1 -1
  93. package/dist/src/metrics/index.d.ts +1 -1
  94. package/dist/src/metrics/index.d.ts.map +1 -1
  95. package/dist/src/metrics/stats.d.ts +1 -1
  96. package/dist/src/metrics/stats.d.ts.map +1 -1
  97. package/dist/src/metrics/stats.js +1 -1
  98. package/dist/src/metrics/stats.js.map +1 -1
  99. package/dist/src/nat-manager.d.ts +6 -3
  100. package/dist/src/nat-manager.d.ts.map +1 -1
  101. package/dist/src/nat-manager.js +6 -3
  102. package/dist/src/nat-manager.js.map +1 -1
  103. package/dist/src/peer-record-updater.d.ts +1 -1
  104. package/dist/src/peer-record-updater.d.ts.map +1 -1
  105. package/dist/src/peer-routing.d.ts +2 -1
  106. package/dist/src/peer-routing.d.ts.map +1 -1
  107. package/dist/src/peer-routing.js.map +1 -1
  108. package/dist/src/ping/index.d.ts +1 -1
  109. package/dist/src/ping/index.d.ts.map +1 -1
  110. package/dist/src/ping/index.js +2 -1
  111. package/dist/src/ping/index.js.map +1 -1
  112. package/dist/src/pnet/index.d.ts +1 -0
  113. package/dist/src/pnet/index.d.ts.map +1 -1
  114. package/dist/src/pnet/index.js +1 -0
  115. package/dist/src/pnet/index.js.map +1 -1
  116. package/dist/src/pnet/key-generator.d.ts +1 -1
  117. package/dist/src/pnet/key-generator.d.ts.map +1 -1
  118. package/dist/src/pnet/key-generator.js +1 -1
  119. package/dist/src/pnet/key-generator.js.map +1 -1
  120. package/dist/src/pubsub/dummy-pubsub.d.ts +1 -1
  121. package/dist/src/pubsub/dummy-pubsub.d.ts.map +1 -1
  122. package/dist/src/pubsub/dummy-pubsub.js +1 -1
  123. package/dist/src/pubsub/dummy-pubsub.js.map +1 -1
  124. package/dist/src/registrar.d.ts +0 -1
  125. package/dist/src/registrar.d.ts.map +1 -1
  126. package/dist/src/registrar.js +2 -17
  127. package/dist/src/registrar.js.map +1 -1
  128. package/dist/src/transport-manager.d.ts +3 -1
  129. package/dist/src/transport-manager.d.ts.map +1 -1
  130. package/dist/src/transport-manager.js +1 -1
  131. package/dist/src/transport-manager.js.map +1 -1
  132. package/dist/src/upgrader.d.ts +1 -1
  133. package/dist/src/upgrader.d.ts.map +1 -1
  134. package/dist/src/upgrader.js +1 -1
  135. package/dist/src/upgrader.js.map +1 -1
  136. package/package.json +16 -25
  137. package/src/address-manager/index.ts +2 -1
  138. package/src/circuit/auto-relay.ts +8 -6
  139. package/src/circuit/circuit/hop.ts +5 -5
  140. package/src/circuit/index.ts +1 -1
  141. package/src/circuit/listener.ts +18 -5
  142. package/src/circuit/pb/index.ts +33 -4
  143. package/src/circuit/transport.ts +8 -5
  144. package/src/config.ts +5 -7
  145. package/src/connection-manager/auto-dialler.ts +5 -5
  146. package/src/{dialer → connection-manager/dialer}/auto-dialer.ts +23 -4
  147. package/src/{dialer → connection-manager/dialer}/dial-request.ts +4 -4
  148. package/src/{dialer → connection-manager/dialer}/index.ts +48 -37
  149. package/src/connection-manager/index.ts +146 -60
  150. package/src/connection-manager/latency-monitor.ts +1 -1
  151. package/src/connection-manager/visibility-change-emitter.ts +1 -1
  152. package/src/content-routing/index.ts +2 -1
  153. package/src/dht/dummy-dht.ts +10 -1
  154. package/src/fetch/index.ts +2 -2
  155. package/src/fetch/pb/proto.ts +10 -3
  156. package/src/identify/index.ts +5 -5
  157. package/src/identify/pb/message.ts +2 -1
  158. package/src/index.ts +7 -28
  159. package/src/insecure/pb/proto.ts +11 -4
  160. package/src/keychain/index.ts +0 -1
  161. package/src/libp2p.ts +68 -49
  162. package/src/metrics/index.ts +1 -1
  163. package/src/metrics/stats.ts +1 -1
  164. package/src/nat-manager.ts +8 -4
  165. package/src/peer-record-updater.ts +1 -1
  166. package/src/peer-routing.ts +2 -1
  167. package/src/ping/index.ts +3 -2
  168. package/src/pnet/index.ts +2 -0
  169. package/src/pnet/key-generator.ts +1 -1
  170. package/src/pubsub/dummy-pubsub.ts +1 -1
  171. package/src/registrar.ts +3 -19
  172. package/src/transport-manager.ts +3 -1
  173. package/src/upgrader.ts +1 -1
  174. package/dist/src/dialer/auto-dialer.d.ts.map +0 -1
  175. package/dist/src/dialer/auto-dialer.js +0 -24
  176. package/dist/src/dialer/auto-dialer.js.map +0 -1
  177. package/dist/src/dialer/dial-request.d.ts.map +0 -1
  178. package/dist/src/dialer/dial-request.js.map +0 -1
  179. package/dist/src/dialer/index.d.ts.map +0 -1
  180. package/dist/src/dialer/index.js.map +0 -1
@@ -4,16 +4,21 @@ import mergeOptions from 'merge-options'
4
4
  import { LatencyMonitor, SummaryObject } from './latency-monitor.js'
5
5
  // @ts-expect-error retimer does not have types
6
6
  import retimer from 'retimer'
7
- import { CustomEvent, EventEmitter, Startable } from '@libp2p/interfaces'
7
+ import type { AbortOptions } from '@libp2p/interfaces'
8
+ import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
9
+ import type { Startable } from '@libp2p/interfaces/startable'
8
10
  import { trackedMap } from '@libp2p/tracked-map'
9
11
  import { codes } from '../errors.js'
10
12
  import { isPeerId, PeerId } from '@libp2p/interfaces/peer-id'
11
13
  // @ts-expect-error setMaxListeners is missing from the node 16 types
12
14
  import { setMaxListeners } from 'events'
13
15
  import type { Connection } from '@libp2p/interfaces/connection'
14
- import type { ConnectionManager } from '@libp2p/interfaces/registrar'
15
- import type { Components } from '@libp2p/interfaces/components'
16
+ import type { ConnectionManager } from '@libp2p/interfaces/connection-manager'
17
+ import { Components, Initializable } from '@libp2p/interfaces/components'
16
18
  import * as STATUS from '@libp2p/interfaces/connection/status'
19
+ import { Dialer } from './dialer/index.js'
20
+ import type { AddressSorter } from '@libp2p/interfaces/peer-store'
21
+ import type { Resolver } from '@multiformats/multiaddr'
17
22
 
18
23
  const log = logger('libp2p:connection-manager')
19
24
 
@@ -34,21 +39,16 @@ const METRICS_COMPONENT = 'connection-manager'
34
39
  const METRICS_PEER_CONNECTIONS = 'peer-connections'
35
40
  const METRICS_PEER_VALUES = 'peer-values'
36
41
 
37
- export interface ConnectionManagerEvents {
38
- 'peer:connect': CustomEvent<PeerId>
39
- 'peer:disconnect': CustomEvent<PeerId>
40
- }
41
-
42
42
  export interface ConnectionManagerInit {
43
43
  /**
44
- * The maximum number of connections allowed
44
+ * The maximum number of connections to keep open
45
45
  */
46
- maxConnections?: number
46
+ maxConnections: number
47
47
 
48
48
  /**
49
- * The minimum number of connections to avoid pruning
49
+ * The minimum number of connections to keep open
50
50
  */
51
- minConnections?: number
51
+ minConnections: number
52
52
 
53
53
  /**
54
54
  * The max data (in and out), per average interval to allow
@@ -86,39 +86,75 @@ export interface ConnectionManagerInit {
86
86
  defaultPeerValue?: number
87
87
 
88
88
  /**
89
- * Should preemptively guarantee connections are above the low watermark
89
+ * If true, try to connect to all discovered peers up to the connection manager limit
90
90
  */
91
91
  autoDial?: boolean
92
92
 
93
93
  /**
94
- * How often, in milliseconds, it should preemptively guarantee connections are above the low watermark
94
+ * How long to wait between attempting to keep our number of concurrent connections
95
+ * above minConnections
96
+ */
97
+ autoDialInterval: number
98
+
99
+ /**
100
+ * Sort the known addresses of a peer before trying to dial
101
+ */
102
+ addressSorter?: AddressSorter
103
+
104
+ /**
105
+ * Number of max concurrent dials
106
+ */
107
+ maxParallelDials?: number
108
+
109
+ /**
110
+ * Number of max addresses to dial for a given peer
111
+ */
112
+ maxAddrsToDial?: number
113
+
114
+ /**
115
+ * How long a dial attempt is allowed to take
95
116
  */
96
- autoDialInterval?: number
117
+ dialTimeout?: number
118
+
119
+ /**
120
+ * Number of max concurrent dials per peer
121
+ */
122
+ maxDialsPerPeer?: number
123
+
124
+ /**
125
+ * Multiaddr resolvers to use when dialing
126
+ */
127
+ resolvers?: Record<string, Resolver>
128
+ }
129
+
130
+ export interface ConnectionManagerEvents {
131
+ 'peer:connect': CustomEvent<PeerId>
132
+ 'peer:disconnect': CustomEvent<PeerId>
97
133
  }
98
134
 
99
135
  /**
100
136
  * Responsible for managing known connections.
101
137
  */
102
- export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEvents> implements ConnectionManager, Startable {
103
- private readonly components: Components
104
- private readonly init: Required<ConnectionManagerInit>
138
+ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEvents> implements ConnectionManager, Startable, Initializable {
139
+ public readonly dialer: Dialer
140
+ private components = new Components()
141
+ private readonly opts: Required<ConnectionManagerInit>
105
142
  private readonly peerValues: Map<string, number>
106
143
  private readonly connections: Map<string, Connection[]>
107
144
  private started: boolean
108
145
  private timer?: ReturnType<retimer>
109
146
  private readonly latencyMonitor: LatencyMonitor
110
147
 
111
- constructor (components: Components, init: ConnectionManagerInit = {}) {
148
+ constructor (init: ConnectionManagerInit) {
112
149
  super()
113
150
 
114
- this.components = components
115
- this.init = mergeOptions.call({ ignoreUndefined: true }, defaultOptions, init)
151
+ this.opts = mergeOptions.call({ ignoreUndefined: true }, defaultOptions, init)
116
152
 
117
- if (this.init.maxConnections < this.init.minConnections) {
153
+ if (this.opts.maxConnections < this.opts.minConnections) {
118
154
  throw errCode(new Error('Connection Manager maxConnections must be greater than minConnections'), codes.ERR_INVALID_PARAMETERS)
119
155
  }
120
156
 
121
- log('options: %o', this.init)
157
+ log('options: %o', this.opts)
122
158
 
123
159
  /**
124
160
  * Map of peer identifiers to their peer value for pruning connections.
@@ -153,12 +189,16 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
153
189
  setMaxListeners?.(Infinity, this)
154
190
  } catch {}
155
191
 
156
- this.components.getUpgrader().addEventListener('connection', (evt) => {
157
- void this.onConnect(evt).catch(err => {
158
- log.error(err)
159
- })
160
- })
161
- this.components.getUpgrader().addEventListener('connectionEnd', this.onDisconnect.bind(this))
192
+ this.dialer = new Dialer(this.opts)
193
+
194
+ this.onConnect = this.onConnect.bind(this)
195
+ this.onDisconnect = this.onDisconnect.bind(this)
196
+ }
197
+
198
+ init (components: Components): void {
199
+ this.components = components
200
+
201
+ this.dialer.init(components)
162
202
  }
163
203
 
164
204
  isStarted () {
@@ -171,18 +211,29 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
171
211
  */
172
212
  async start () {
173
213
  if (this.components.getMetrics() != null) {
174
- this.timer = this.timer ?? retimer(this._checkMetrics, this.init.pollInterval)
214
+ this.timer = this.timer ?? retimer(this._checkMetrics, this.opts.pollInterval)
175
215
  }
176
216
 
177
217
  // latency monitor
178
218
  this.latencyMonitor.start()
179
219
  this._onLatencyMeasure = this._onLatencyMeasure.bind(this)
180
220
  this.latencyMonitor.addEventListener('data', this._onLatencyMeasure)
221
+ await this.dialer.start()
181
222
 
182
223
  this.started = true
183
224
  log('started')
184
225
  }
185
226
 
227
+ async afterStart () {
228
+ this.components.getUpgrader().addEventListener('connection', this.onConnect)
229
+ this.components.getUpgrader().addEventListener('connectionEnd', this.onDisconnect)
230
+ }
231
+
232
+ async beforeStop () {
233
+ this.components.getUpgrader().removeEventListener('connection', this.onConnect)
234
+ this.components.getUpgrader().removeEventListener('connectionEnd', this.onDisconnect)
235
+ }
236
+
186
237
  /**
187
238
  * Stops the Connection Manager
188
239
  */
@@ -191,6 +242,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
191
242
 
192
243
  this.latencyMonitor.removeEventListener('data', this._onLatencyMeasure)
193
244
  this.latencyMonitor.stop()
245
+ await this.dialer.stop()
194
246
 
195
247
  this.started = false
196
248
  await this._close()
@@ -238,23 +290,29 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
238
290
  if (metrics != null) {
239
291
  try {
240
292
  const movingAverages = metrics.getGlobal().getMovingAverages()
241
- const received = movingAverages.dataReceived[this.init.movingAverageInterval].movingAverage
293
+ const received = movingAverages.dataReceived[this.opts.movingAverageInterval].movingAverage
242
294
  await this._checkMaxLimit('maxReceivedData', received)
243
- const sent = movingAverages.dataSent[this.init.movingAverageInterval].movingAverage
295
+ const sent = movingAverages.dataSent[this.opts.movingAverageInterval].movingAverage
244
296
  await this._checkMaxLimit('maxSentData', sent)
245
297
  const total = received + sent
246
298
  await this._checkMaxLimit('maxData', total)
247
- log('metrics update', total)
299
+ log.trace('metrics update', total)
248
300
  } finally {
249
- this.timer = retimer(this._checkMetrics, this.init.pollInterval)
301
+ this.timer = retimer(this._checkMetrics, this.opts.pollInterval)
250
302
  }
251
303
  }
252
304
  }
253
305
 
306
+ onConnect (evt: CustomEvent<Connection>) {
307
+ void this._onConnect(evt).catch(err => {
308
+ log.error(err)
309
+ })
310
+ }
311
+
254
312
  /**
255
313
  * Tracks the incoming connection and check the connection limit
256
314
  */
257
- async onConnect (evt: CustomEvent<Connection>) {
315
+ async _onConnect (evt: CustomEvent<Connection>) {
258
316
  const { detail: connection } = evt
259
317
 
260
318
  if (!this.started) {
@@ -267,8 +325,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
267
325
  const peerIdStr = peerId.toString()
268
326
  const storedConns = this.connections.get(peerIdStr)
269
327
 
270
- this.dispatchEvent(new CustomEvent<Connection>('peer:connect', { detail: connection }))
271
-
272
328
  if (storedConns != null) {
273
329
  storedConns.push(connection)
274
330
  } else {
@@ -280,10 +336,11 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
280
336
  }
281
337
 
282
338
  if (!this.peerValues.has(peerIdStr)) {
283
- this.peerValues.set(peerIdStr, this.init.defaultPeerValue)
339
+ this.peerValues.set(peerIdStr, this.opts.defaultPeerValue)
284
340
  }
285
341
 
286
- await this._checkMaxLimit('maxConnections', this.getConnectionList().length)
342
+ await this._checkMaxLimit('maxConnections', this.getConnections().length)
343
+ this.dispatchEvent(new CustomEvent<Connection>('peer:connect', { detail: connection }))
287
344
  }
288
345
 
289
346
  /**
@@ -312,35 +369,64 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
312
369
  }
313
370
  }
314
371
 
315
- getConnectionMap (): Map<string, Connection[]> {
316
- return this.connections
317
- }
372
+ getConnections (peerId?: PeerId): Connection[] {
373
+ if (peerId != null) {
374
+ return this.connections.get(peerId.toString()) ?? []
375
+ }
318
376
 
319
- getConnectionList (): Connection[] {
320
- let output: Connection[] = []
377
+ let conns: Connection[] = []
321
378
 
322
- for (const connections of this.connections.values()) {
323
- output = output.concat(connections)
379
+ for (const c of this.connections.values()) {
380
+ conns = conns.concat(c)
324
381
  }
325
382
 
326
- return output
383
+ return conns
327
384
  }
328
385
 
329
- getConnections (peerId: PeerId): Connection[] {
330
- return this.connections.get(peerId.toString()) ?? []
331
- }
386
+ async openConnection (peerId: PeerId, options?: AbortOptions): Promise<Connection> {
387
+ log('dial to %p', peerId)
388
+ const existingConnections = this.getConnections(peerId)
332
389
 
333
- /**
334
- * Get a connection with a peer
335
- */
336
- getConnection (peerId: PeerId): Connection | undefined {
337
- const connections = this.getAll(peerId)
390
+ if (existingConnections.length > 0) {
391
+ log('had an existing connection to %p', peerId)
392
+
393
+ return existingConnections[0]
394
+ }
395
+
396
+ const connection = await this.dialer.dial(peerId, options)
397
+ let peerConnections = this.connections.get(peerId.toString())
398
+
399
+ if (peerConnections == null) {
400
+ peerConnections = []
401
+ this.connections.set(peerId.toString(), peerConnections)
402
+ }
338
403
 
339
- if (connections.length > 0) {
340
- return connections[0]
404
+ // we get notified of connections via the Upgrader emitting "connection"
405
+ // events, double check we aren't already tracking this connection before
406
+ // storing it
407
+ let trackedConnection = false
408
+
409
+ for (const conn of peerConnections) {
410
+ if (conn.id === connection.id) {
411
+ trackedConnection = true
412
+ }
413
+ }
414
+
415
+ if (!trackedConnection) {
416
+ peerConnections.push(connection)
341
417
  }
342
418
 
343
- return undefined
419
+ return connection
420
+ }
421
+
422
+ async closeConnections (peerId: PeerId): Promise<void> {
423
+ const connections = this.connections.get(peerId.toString()) ?? []
424
+
425
+ await Promise.all(
426
+ connections.map(async connection => {
427
+ return await connection.close()
428
+ })
429
+ )
344
430
  }
345
431
 
346
432
  /**
@@ -378,7 +464,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
378
464
  * If the `value` of `name` has exceeded its limit, maybe close a connection
379
465
  */
380
466
  async _checkMaxLimit (name: keyof ConnectionManagerInit, value: number) {
381
- const limit = this.init[name]
467
+ const limit = this.opts[name]
382
468
  log.trace('checking limit of %s. current value: %d of %d', name, value, limit)
383
469
  if (value > limit) {
384
470
  log('%s: limit exceeded: %p, %d', this.components.getPeerId(), name, value)
@@ -391,7 +477,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
391
477
  * to the lowest valued peer.
392
478
  */
393
479
  async _maybeDisconnectOne () {
394
- if (this.init.minConnections < this.connections.size) {
480
+ if (this.opts.minConnections < this.connections.size) {
395
481
  const peerValues = Array.from(new Map([...this.peerValues.entries()].sort((a, b) => a[1] - b[1])))
396
482
 
397
483
  log('%p: sorted peer values: %j', this.components.getPeerId(), peerValues)
@@ -2,7 +2,7 @@
2
2
  * This code is based on `latency-monitor` (https://github.com/mlucool/latency-monitor) by `mlucool` (https://github.com/mlucool), available under Apache License 2.0 (https://github.com/mlucool/latency-monitor/blob/master/LICENSE)
3
3
  */
4
4
 
5
- import { CustomEvent, EventEmitter } from '@libp2p/interfaces'
5
+ import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
6
6
  import { VisibilityChangeEmitter } from './visibility-change-emitter.js'
7
7
  import { logger } from '@libp2p/logger'
8
8
 
@@ -2,7 +2,7 @@
2
2
  * This code is based on `latency-monitor` (https://github.com/mlucool/latency-monitor) by `mlucool` (https://github.com/mlucool), available under Apache License 2.0 (https://github.com/mlucool/latency-monitor/blob/master/LICENSE)
3
3
  */
4
4
 
5
- import { CustomEvent, EventEmitter } from '@libp2p/interfaces'
5
+ import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
6
6
  import { logger } from '@libp2p/logger'
7
7
 
8
8
  const log = logger('libp2p:connection-manager:latency-monitor:visibility-change-emitter')
@@ -9,7 +9,8 @@ import drain from 'it-drain'
9
9
  import merge from 'it-merge'
10
10
  import { pipe } from 'it-pipe'
11
11
  import type { ContentRouting } from '@libp2p/interfaces/content-routing'
12
- import type { AbortOptions, Startable } from '@libp2p/interfaces'
12
+ import type { AbortOptions } from '@libp2p/interfaces'
13
+ import type { Startable } from '@libp2p/interfaces/startable'
13
14
  import type { CID } from 'multiformats/cid'
14
15
  import type { Components } from '@libp2p/interfaces/components'
15
16
 
@@ -2,9 +2,18 @@ import type { DualDHT, QueryEvent, SingleDHT } from '@libp2p/interfaces/dht'
2
2
  import type { PeerDiscoveryEvents } from '@libp2p/interfaces/peer-discovery'
3
3
  import errCode from 'err-code'
4
4
  import { messages, codes } from '../errors.js'
5
- import { EventEmitter } from '@libp2p/interfaces'
5
+ import { EventEmitter } from '@libp2p/interfaces/events'
6
+ import { symbol } from '@libp2p/interfaces/peer-discovery'
6
7
 
7
8
  export class DummyDHT extends EventEmitter<PeerDiscoveryEvents> implements DualDHT {
9
+ get [symbol] (): true {
10
+ return true
11
+ }
12
+
13
+ get [Symbol.toStringTag] () {
14
+ return '@libp2p/dummy-dht'
15
+ }
16
+
8
17
  get wan (): SingleDHT {
9
18
  throw errCode(new Error(messages.DHT_DISABLED), codes.DHT_DISABLED)
10
19
  }
@@ -6,7 +6,7 @@ import { FetchRequest, FetchResponse } from './pb/proto.js'
6
6
  import { handshake } from 'it-handshake'
7
7
  import { PROTOCOL } from './constants.js'
8
8
  import type { PeerId } from '@libp2p/interfaces/peer-id'
9
- import type { Startable } from '@libp2p/interfaces'
9
+ import type { Startable } from '@libp2p/interfaces/startable'
10
10
  import type { Stream } from '@libp2p/interfaces/connection'
11
11
  import type { IncomingStreamData } from '@libp2p/interfaces/registrar'
12
12
  import type { Components } from '@libp2p/interfaces/components'
@@ -70,7 +70,7 @@ export class FetchService implements Startable {
70
70
  async fetch (peer: PeerId, key: string): Promise<Uint8Array | null> {
71
71
  log('dialing %s to %p', this.protocol, peer)
72
72
 
73
- const connection = await this.components.getDialer().dial(peer)
73
+ const connection = await this.components.getConnectionManager().openConnection(peer)
74
74
  const { stream } = await connection.newStream([this.protocol])
75
75
  const shake = handshake(stream)
76
76
 
@@ -2,13 +2,14 @@
2
2
  /* eslint-disable @typescript-eslint/no-namespace */
3
3
 
4
4
  import { encodeMessage, decodeMessage, message, string, enumeration, bytes } from 'protons-runtime'
5
+ import type { Codec } from 'protons-runtime'
5
6
 
6
7
  export interface FetchRequest {
7
8
  identifier: string
8
9
  }
9
10
 
10
11
  export namespace FetchRequest {
11
- export const codec = () => {
12
+ export const codec = (): Codec<FetchRequest> => {
12
13
  return message<FetchRequest>({
13
14
  1: { name: 'identifier', codec: string }
14
15
  })
@@ -35,13 +36,19 @@ export namespace FetchResponse {
35
36
  ERROR = 'ERROR'
36
37
  }
37
38
 
39
+ enum __StatusCodeValues {
40
+ OK = 0,
41
+ NOT_FOUND = 1,
42
+ ERROR = 2
43
+ }
44
+
38
45
  export namespace StatusCode {
39
46
  export const codec = () => {
40
- return enumeration<typeof StatusCode>(StatusCode)
47
+ return enumeration<typeof StatusCode>(__StatusCodeValues)
41
48
  }
42
49
  }
43
50
 
44
- export const codec = () => {
51
+ export const codec = (): Codec<FetchResponse> => {
45
52
  return message<FetchResponse>({
46
53
  1: { name: 'status', codec: FetchResponse.StatusCode.codec() },
47
54
  2: { name: 'data', codec: bytes }
@@ -22,8 +22,8 @@ import {
22
22
  import { codes } from '../errors.js'
23
23
  import type { IncomingStreamData } from '@libp2p/interfaces/registrar'
24
24
  import type { Connection } from '@libp2p/interfaces/connection'
25
- import type { Startable } from '@libp2p/interfaces'
26
- import { peerIdFromKeys, peerIdFromString } from '@libp2p/peer-id'
25
+ import type { Startable } from '@libp2p/interfaces/startable'
26
+ import { peerIdFromKeys } from '@libp2p/peer-id'
27
27
  import type { Components } from '@libp2p/interfaces/components'
28
28
 
29
29
  const log = logger('libp2p:identify')
@@ -161,15 +161,15 @@ export class IdentifyService implements Startable {
161
161
 
162
162
  const connections: Connection[] = []
163
163
 
164
- for (const [peerIdStr, conns] of this.components.getConnectionManager().getConnectionMap().entries()) {
165
- const peerId = peerIdFromString(peerIdStr)
164
+ for (const conn of this.components.getConnectionManager().getConnections()) {
165
+ const peerId = conn.remotePeer
166
166
  const peer = await this.components.getPeerStore().get(peerId)
167
167
 
168
168
  if (!peer.protocols.includes(this.identifyPushProtocolStr)) {
169
169
  continue
170
170
  }
171
171
 
172
- connections.push(...conns)
172
+ connections.push(conn)
173
173
  }
174
174
 
175
175
  await this.push(connections)
@@ -2,6 +2,7 @@
2
2
  /* eslint-disable @typescript-eslint/no-namespace */
3
3
 
4
4
  import { encodeMessage, decodeMessage, message, string, bytes } from 'protons-runtime'
5
+ import type { Codec } from 'protons-runtime'
5
6
 
6
7
  export interface Identify {
7
8
  protocolVersion?: string
@@ -14,7 +15,7 @@ export interface Identify {
14
15
  }
15
16
 
16
17
  export namespace Identify {
17
- export const codec = () => {
18
+ export const codec = (): Codec<Identify> => {
18
19
  return message<Identify>({
19
20
  5: { name: 'protocolVersion', codec: string, optional: true },
20
21
  6: { name: 'agentVersion', codec: string, optional: true },
package/src/index.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { createLibp2pNode } from './libp2p.js'
2
- import type { AbortOptions, EventEmitter, RecursivePartial, Startable } from '@libp2p/interfaces'
2
+ import type { AbortOptions, RecursivePartial } from '@libp2p/interfaces'
3
+ import type { EventEmitter } from '@libp2p/interfaces/events'
4
+ import type { Startable } from '@libp2p/interfaces/startable'
3
5
  import type { Multiaddr } from '@multiformats/multiaddr'
4
6
  import type { FaultTolerance } from './transport-manager.js'
5
7
  import type { HostProperties } from './identify/index.js'
@@ -16,11 +18,12 @@ import type { ConnectionEncrypter } from '@libp2p/interfaces/connection-encrypte
16
18
  import type { PeerRouting } from '@libp2p/interfaces/peer-routing'
17
19
  import type { ContentRouting } from '@libp2p/interfaces/content-routing'
18
20
  import type { PubSub } from '@libp2p/interfaces/pubsub'
19
- import type { ConnectionManager, Registrar, StreamHandler } from '@libp2p/interfaces/registrar'
21
+ import type { Registrar, StreamHandler } from '@libp2p/interfaces/registrar'
22
+ import type { ConnectionManager } from '@libp2p/interfaces/connection-manager'
20
23
  import type { Metrics, MetricsInit } from '@libp2p/interfaces/metrics'
21
24
  import type { PeerInfo } from '@libp2p/interfaces/peer-info'
22
- import type { DialerInit } from '@libp2p/interfaces/dialer'
23
25
  import type { KeyChain } from './keychain/index.js'
26
+ import type { ConnectionManagerInit } from './connection-manager/index.js'
24
27
 
25
28
  export interface PersistentPeerStoreOptions {
26
29
  threshold?: number
@@ -71,29 +74,6 @@ export interface AddressesConfig {
71
74
  announceFilter: (multiaddrs: Multiaddr[]) => Multiaddr[]
72
75
  }
73
76
 
74
- export interface ConnectionManagerConfig {
75
- /**
76
- * If true, try to connect to all discovered peers up to the connection manager limit
77
- */
78
- autoDial?: boolean
79
-
80
- /**
81
- * The maximum number of connections to keep open
82
- */
83
- maxConnections: number
84
-
85
- /**
86
- * The minimum number of connections to keep open
87
- */
88
- minConnections: number
89
-
90
- /**
91
- * How long to wait between attempting to keep our number of concurrent connections
92
- * above minConnections
93
- */
94
- autoDialInterval: number
95
- }
96
-
97
77
  export interface TransportManagerConfig {
98
78
  faultTolerance?: FaultTolerance
99
79
  }
@@ -117,11 +97,10 @@ export interface Libp2pInit {
117
97
  peerId: PeerId
118
98
  host: HostProperties
119
99
  addresses: AddressesConfig
120
- connectionManager: ConnectionManagerConfig
100
+ connectionManager: ConnectionManagerInit
121
101
  connectionGater: Partial<ConnectionGater>
122
102
  transportManager: TransportManagerConfig
123
103
  datastore: Datastore
124
- dialer: DialerInit
125
104
  metrics: MetricsInit
126
105
  peerStore: PeerStoreInit
127
106
  peerRouting: PeerRoutingConfig
@@ -2,6 +2,7 @@
2
2
  /* eslint-disable @typescript-eslint/no-namespace */
3
3
 
4
4
  import { encodeMessage, decodeMessage, message, bytes, enumeration } from 'protons-runtime'
5
+ import type { Codec } from 'protons-runtime'
5
6
 
6
7
  export interface Exchange {
7
8
  id?: Uint8Array
@@ -9,7 +10,7 @@ export interface Exchange {
9
10
  }
10
11
 
11
12
  export namespace Exchange {
12
- export const codec = () => {
13
+ export const codec = (): Codec<Exchange> => {
13
14
  return message<Exchange>({
14
15
  1: { name: 'id', codec: bytes, optional: true },
15
16
  2: { name: 'pubkey', codec: PublicKey.codec(), optional: true }
@@ -32,19 +33,25 @@ export enum KeyType {
32
33
  ECDSA = 'ECDSA'
33
34
  }
34
35
 
36
+ enum __KeyTypeValues {
37
+ RSA = 0,
38
+ Ed25519 = 1,
39
+ Secp256k1 = 2,
40
+ ECDSA = 3
41
+ }
42
+
35
43
  export namespace KeyType {
36
44
  export const codec = () => {
37
- return enumeration<typeof KeyType>(KeyType)
45
+ return enumeration<typeof KeyType>(__KeyTypeValues)
38
46
  }
39
47
  }
40
-
41
48
  export interface PublicKey {
42
49
  Type: KeyType
43
50
  Data: Uint8Array
44
51
  }
45
52
 
46
53
  export namespace PublicKey {
47
- export const codec = () => {
54
+ export const codec = (): Codec<PublicKey> => {
48
55
  return message<PublicKey>({
49
56
  1: { name: 'Type', codec: KeyType.codec() },
50
57
  2: { name: 'Data', codec: bytes }
@@ -9,7 +9,6 @@ import errCode from 'err-code'
9
9
  import { codes } from '../errors.js'
10
10
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
11
11
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
12
- import 'node-forge/lib/sha512.js'
13
12
  import { generateKeyPair, importKey, unmarshalPrivateKey } from '@libp2p/crypto/keys'
14
13
  import type { PeerId } from '@libp2p/interfaces/peer-id'
15
14
  import type { Components } from '@libp2p/interfaces/components'