libp2p 0.44.0 → 0.45.0

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 (188) hide show
  1. package/dist/index.min.js +30 -30
  2. package/dist/src/address-manager/index.d.ts +8 -4
  3. package/dist/src/address-manager/index.d.ts.map +1 -1
  4. package/dist/src/address-manager/index.js +37 -6
  5. package/dist/src/address-manager/index.js.map +1 -1
  6. package/dist/src/address-manager/utils.d.ts +2 -0
  7. package/dist/src/address-manager/utils.d.ts.map +1 -0
  8. package/dist/src/address-manager/utils.js +12 -0
  9. package/dist/src/address-manager/utils.js.map +1 -0
  10. package/dist/src/autonat/constants.d.ts +16 -2
  11. package/dist/src/autonat/constants.d.ts.map +1 -1
  12. package/dist/src/autonat/constants.js +16 -2
  13. package/dist/src/autonat/constants.js.map +1 -1
  14. package/dist/src/autonat/index.d.ts +12 -33
  15. package/dist/src/autonat/index.d.ts.map +1 -1
  16. package/dist/src/autonat/index.js +36 -30
  17. package/dist/src/autonat/index.js.map +1 -1
  18. package/dist/src/circuit-relay/server/advert-service.d.ts.map +1 -1
  19. package/dist/src/circuit-relay/server/advert-service.js +2 -2
  20. package/dist/src/circuit-relay/server/advert-service.js.map +1 -1
  21. package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
  22. package/dist/src/circuit-relay/server/index.js +10 -3
  23. package/dist/src/circuit-relay/server/index.js.map +1 -1
  24. package/dist/src/circuit-relay/transport/discovery.d.ts.map +1 -1
  25. package/dist/src/circuit-relay/transport/discovery.js +4 -2
  26. package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
  27. package/dist/src/circuit-relay/transport/index.d.ts +3 -0
  28. package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
  29. package/dist/src/circuit-relay/transport/index.js +6 -4
  30. package/dist/src/circuit-relay/transport/index.js.map +1 -1
  31. package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
  32. package/dist/src/circuit-relay/transport/listener.js +30 -26
  33. package/dist/src/circuit-relay/transport/listener.js.map +1 -1
  34. package/dist/src/circuit-relay/transport/reservation-store.d.ts +5 -4
  35. package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
  36. package/dist/src/circuit-relay/transport/reservation-store.js +37 -30
  37. package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
  38. package/dist/src/components.d.ts +6 -63
  39. package/dist/src/components.d.ts.map +1 -1
  40. package/dist/src/components.js +60 -164
  41. package/dist/src/components.js.map +1 -1
  42. package/dist/src/config/connection-gater.browser.d.ts +8 -0
  43. package/dist/src/config/connection-gater.browser.d.ts.map +1 -0
  44. package/dist/src/config/connection-gater.browser.js +27 -0
  45. package/dist/src/config/connection-gater.browser.js.map +1 -0
  46. package/dist/src/config/connection-gater.d.ts +6 -0
  47. package/dist/src/config/connection-gater.d.ts.map +1 -0
  48. package/dist/src/config/connection-gater.js +18 -0
  49. package/dist/src/config/connection-gater.js.map +1 -0
  50. package/dist/src/config.d.ts +2 -1
  51. package/dist/src/config.d.ts.map +1 -1
  52. package/dist/src/config.js +0 -62
  53. package/dist/src/config.js.map +1 -1
  54. package/dist/src/connection-manager/auto-dial.d.ts +3 -0
  55. package/dist/src/connection-manager/auto-dial.d.ts.map +1 -1
  56. package/dist/src/connection-manager/auto-dial.js +36 -13
  57. package/dist/src/connection-manager/auto-dial.js.map +1 -1
  58. package/dist/src/connection-manager/connection-pruner.d.ts +4 -0
  59. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  60. package/dist/src/connection-manager/connection-pruner.js +23 -8
  61. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  62. package/dist/src/connection-manager/dial-queue.d.ts +2 -1
  63. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  64. package/dist/src/connection-manager/dial-queue.js +36 -14
  65. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  66. package/dist/src/connection-manager/index.d.ts +8 -7
  67. package/dist/src/connection-manager/index.d.ts.map +1 -1
  68. package/dist/src/connection-manager/index.js +23 -34
  69. package/dist/src/connection-manager/index.js.map +1 -1
  70. package/dist/src/content-routing/index.d.ts +0 -10
  71. package/dist/src/content-routing/index.d.ts.map +1 -1
  72. package/dist/src/content-routing/index.js +7 -42
  73. package/dist/src/content-routing/index.js.map +1 -1
  74. package/dist/src/content-routing/utils.d.ts.map +1 -1
  75. package/dist/src/content-routing/utils.js +3 -1
  76. package/dist/src/content-routing/utils.js.map +1 -1
  77. package/dist/src/fetch/index.d.ts +13 -35
  78. package/dist/src/fetch/index.d.ts.map +1 -1
  79. package/dist/src/fetch/index.js +7 -9
  80. package/dist/src/fetch/index.js.map +1 -1
  81. package/dist/src/identify/identify.d.ts +53 -0
  82. package/dist/src/identify/identify.d.ts.map +1 -0
  83. package/dist/src/identify/identify.js +405 -0
  84. package/dist/src/identify/identify.js.map +1 -0
  85. package/dist/src/identify/index.d.ts +12 -58
  86. package/dist/src/identify/index.d.ts.map +1 -1
  87. package/dist/src/identify/index.js +5 -388
  88. package/dist/src/identify/index.js.map +1 -1
  89. package/dist/src/index.d.ts +13 -68
  90. package/dist/src/index.d.ts.map +1 -1
  91. package/dist/src/index.js +2 -1
  92. package/dist/src/index.js.map +1 -1
  93. package/dist/src/insecure/index.js.map +1 -1
  94. package/dist/src/libp2p.d.ts +11 -42
  95. package/dist/src/libp2p.d.ts.map +1 -1
  96. package/dist/src/libp2p.js +137 -196
  97. package/dist/src/libp2p.js.map +1 -1
  98. package/dist/src/peer-routing.d.ts +1 -38
  99. package/dist/src/peer-routing.d.ts.map +1 -1
  100. package/dist/src/peer-routing.js +0 -59
  101. package/dist/src/peer-routing.js.map +1 -1
  102. package/dist/src/ping/constants.d.ts +4 -0
  103. package/dist/src/ping/constants.d.ts.map +1 -1
  104. package/dist/src/ping/constants.js +10 -0
  105. package/dist/src/ping/constants.js.map +1 -1
  106. package/dist/src/ping/index.d.ts +10 -27
  107. package/dist/src/ping/index.d.ts.map +1 -1
  108. package/dist/src/ping/index.js +18 -21
  109. package/dist/src/ping/index.js.map +1 -1
  110. package/dist/src/registrar.d.ts +5 -2
  111. package/dist/src/registrar.d.ts.map +1 -1
  112. package/dist/src/registrar.js +27 -25
  113. package/dist/src/registrar.js.map +1 -1
  114. package/dist/src/transport-manager.d.ts +11 -4
  115. package/dist/src/transport-manager.d.ts.map +1 -1
  116. package/dist/src/transport-manager.js +19 -10
  117. package/dist/src/transport-manager.js.map +1 -1
  118. package/dist/src/upgrader.d.ts +15 -10
  119. package/dist/src/upgrader.d.ts.map +1 -1
  120. package/dist/src/upgrader.js +39 -48
  121. package/dist/src/upgrader.js.map +1 -1
  122. package/dist/src/upnp-nat/index.d.ts +42 -0
  123. package/dist/src/upnp-nat/index.d.ts.map +1 -0
  124. package/dist/src/{nat-manager.js → upnp-nat/index.js} +11 -7
  125. package/dist/src/upnp-nat/index.js.map +1 -0
  126. package/dist/src/version.d.ts +1 -1
  127. package/dist/src/version.d.ts.map +1 -1
  128. package/dist/src/version.js +1 -1
  129. package/dist/src/version.js.map +1 -1
  130. package/dist/typedoc-urls.json +25 -10
  131. package/package.json +61 -45
  132. package/src/address-manager/index.ts +50 -8
  133. package/src/address-manager/utils.ts +14 -0
  134. package/src/autonat/constants.ts +17 -2
  135. package/src/autonat/index.ts +53 -45
  136. package/src/circuit-relay/server/advert-service.ts +2 -2
  137. package/src/circuit-relay/server/index.ts +11 -3
  138. package/src/circuit-relay/transport/discovery.ts +5 -3
  139. package/src/circuit-relay/transport/index.ts +9 -4
  140. package/src/circuit-relay/transport/listener.ts +38 -28
  141. package/src/circuit-relay/transport/reservation-store.ts +34 -20
  142. package/src/components.ts +71 -234
  143. package/src/config/connection-gater.browser.ts +31 -0
  144. package/src/config/connection-gater.ts +19 -0
  145. package/src/config.ts +3 -64
  146. package/src/connection-manager/auto-dial.ts +44 -15
  147. package/src/connection-manager/connection-pruner.ts +28 -8
  148. package/src/connection-manager/dial-queue.ts +41 -21
  149. package/src/connection-manager/index.ts +31 -43
  150. package/src/content-routing/index.ts +7 -55
  151. package/src/content-routing/utils.ts +3 -1
  152. package/src/fetch/index.ts +51 -14
  153. package/src/identify/identify.ts +518 -0
  154. package/src/identify/index.ts +17 -507
  155. package/src/index.ts +14 -77
  156. package/src/insecure/index.ts +4 -4
  157. package/src/libp2p.ts +139 -260
  158. package/src/peer-routing.ts +1 -101
  159. package/src/ping/constants.ts +11 -0
  160. package/src/ping/index.ts +32 -28
  161. package/src/registrar.ts +31 -27
  162. package/src/transport-manager.ts +27 -13
  163. package/src/upgrader.ts +62 -58
  164. package/src/{nat-manager.ts → upnp-nat/index.ts} +16 -17
  165. package/src/version.ts +1 -1
  166. package/dist/src/dht/dht-content-routing.d.ts +0 -17
  167. package/dist/src/dht/dht-content-routing.d.ts.map +0 -1
  168. package/dist/src/dht/dht-content-routing.js +0 -32
  169. package/dist/src/dht/dht-content-routing.js.map +0 -1
  170. package/dist/src/dht/dht-peer-routing.d.ts +0 -15
  171. package/dist/src/dht/dht-peer-routing.d.ts.map +0 -1
  172. package/dist/src/dht/dht-peer-routing.js +0 -26
  173. package/dist/src/dht/dht-peer-routing.js.map +0 -1
  174. package/dist/src/dht/dummy-dht.d.ts +0 -20
  175. package/dist/src/dht/dummy-dht.d.ts.map +0 -1
  176. package/dist/src/dht/dummy-dht.js +0 -46
  177. package/dist/src/dht/dummy-dht.js.map +0 -1
  178. package/dist/src/nat-manager.d.ts +0 -74
  179. package/dist/src/nat-manager.d.ts.map +0 -1
  180. package/dist/src/nat-manager.js.map +0 -1
  181. package/dist/src/peer-record-updater.d.ts +0 -24
  182. package/dist/src/peer-record-updater.d.ts.map +0 -1
  183. package/dist/src/peer-record-updater.js +0 -44
  184. package/dist/src/peer-record-updater.js.map +0 -1
  185. package/src/dht/dht-content-routing.ts +0 -44
  186. package/src/dht/dht-peer-routing.ts +0 -36
  187. package/src/dht/dummy-dht.ts +0 -60
  188. package/src/peer-record-updater.ts +0 -65
@@ -6,52 +6,20 @@ import {
6
6
  uniquePeers,
7
7
  requirePeers
8
8
  } from './content-routing/utils.js'
9
- import { TimeoutController } from 'timeout-abort-controller'
10
9
  import merge from 'it-merge'
11
10
  import { pipe } from 'it-pipe'
12
11
  import first from 'it-first'
13
- import drain from 'it-drain'
14
12
  import filter from 'it-filter'
15
- import {
16
- setDelayedInterval,
17
- clearDelayedInterval
18
- // @ts-expect-error module with no types
19
- } from 'set-delayed-interval'
20
- import { setMaxListeners } from 'events'
21
13
  import type { PeerId } from '@libp2p/interface-peer-id'
22
14
  import type { PeerRouting } from '@libp2p/interface-peer-routing'
23
15
  import type { AbortOptions } from '@libp2p/interfaces'
24
- import type { Startable } from '@libp2p/interfaces/startable'
25
16
  import type { PeerInfo } from '@libp2p/interface-peer-info'
26
17
  import type { PeerStore } from '@libp2p/interface-peer-store'
27
18
 
28
19
  const log = logger('libp2p:peer-routing')
29
20
 
30
- export interface RefreshManagerInit {
31
- /**
32
- * Whether to enable the Refresh manager
33
- */
34
- enabled?: boolean
35
-
36
- /**
37
- * Boot delay to start the Refresh Manager (in ms)
38
- */
39
- bootDelay?: number
40
-
41
- /**
42
- * Interval between each Refresh Manager run (in ms)
43
- */
44
- interval?: number
45
-
46
- /**
47
- * How long to let each refresh run (in ms)
48
- */
49
- timeout?: number
50
- }
51
-
52
21
  export interface PeerRoutingInit {
53
22
  routers?: PeerRouting[]
54
- refreshManager?: RefreshManagerInit
55
23
  }
56
24
 
57
25
  export interface DefaultPeerRoutingComponents {
@@ -59,81 +27,13 @@ export interface DefaultPeerRoutingComponents {
59
27
  peerStore: PeerStore
60
28
  }
61
29
 
62
- export class DefaultPeerRouting implements PeerRouting, Startable {
30
+ export class DefaultPeerRouting implements PeerRouting {
63
31
  private readonly components: DefaultPeerRoutingComponents
64
32
  private readonly routers: PeerRouting[]
65
- private readonly refreshManagerInit: RefreshManagerInit
66
- private timeoutId?: ReturnType<typeof setTimeout>
67
- private started: boolean
68
- private abortController?: TimeoutController
69
33
 
70
34
  constructor (components: DefaultPeerRoutingComponents, init: PeerRoutingInit) {
71
35
  this.components = components
72
36
  this.routers = init.routers ?? []
73
- this.refreshManagerInit = init.refreshManager ?? {}
74
- this.started = false
75
-
76
- this._findClosestPeersTask = this._findClosestPeersTask.bind(this)
77
- }
78
-
79
- isStarted (): boolean {
80
- return this.started
81
- }
82
-
83
- /**
84
- * Start peer routing service.
85
- */
86
- async start (): Promise<void> {
87
- if (this.started || this.routers.length === 0 || this.timeoutId != null || this.refreshManagerInit.enabled === false) {
88
- return
89
- }
90
-
91
- this.timeoutId = setDelayedInterval(
92
- this._findClosestPeersTask, this.refreshManagerInit.interval, this.refreshManagerInit.bootDelay
93
- )
94
-
95
- this.started = true
96
- }
97
-
98
- /**
99
- * Recurrent task to find closest peers and add their addresses to the Address Book.
100
- */
101
- async _findClosestPeersTask (): Promise<void> {
102
- if (this.abortController != null) {
103
- // we are already running the query
104
- return
105
- }
106
-
107
- try {
108
- this.abortController = new TimeoutController(this.refreshManagerInit.timeout ?? 10e3)
109
-
110
- // this controller may be used while dialing lots of peers so prevent MaxListenersExceededWarning
111
- // appearing in the console
112
- try {
113
- // fails on node < 15.4
114
- setMaxListeners?.(Infinity, this.abortController.signal)
115
- } catch {}
116
-
117
- // nb getClosestPeers adds the addresses to the address book
118
- await drain(this.getClosestPeers(this.components.peerId.toBytes(), { signal: this.abortController.signal }))
119
- } catch (err: any) {
120
- log.error(err)
121
- } finally {
122
- this.abortController?.clear()
123
- this.abortController = undefined
124
- }
125
- }
126
-
127
- /**
128
- * Stop peer routing service.
129
- */
130
- async stop (): Promise<void> {
131
- clearDelayedInterval(this.timeoutId)
132
-
133
- // abort query if it is in-flight
134
- this.abortController?.abort()
135
-
136
- this.started = false
137
37
  }
138
38
 
139
39
  /**
@@ -3,3 +3,14 @@ export const PROTOCOL = '/ipfs/ping/1.0.0'
3
3
  export const PING_LENGTH = 32
4
4
  export const PROTOCOL_VERSION = '1.0.0'
5
5
  export const PROTOCOL_NAME = 'ping'
6
+ export const PROTOCOL_PREFIX = 'ipfs'
7
+ export const TIMEOUT = 10000
8
+
9
+ // See https://github.com/libp2p/specs/blob/d4b5fb0152a6bb86cfd9ea/ping/ping.md?plain=1#L38-L43
10
+ // The dialing peer MUST NOT keep more than one outbound stream for the ping protocol per peer.
11
+ // The listening peer SHOULD accept at most two streams per peer since cross-stream behavior is
12
+ // non-linear and stream writes occur asynchronously. The listening peer may perceive the
13
+ // dialing peer closing and opening the wrong streams (for instance, closing stream B and
14
+ // opening stream A even though the dialing peer is opening stream B and closing stream A).
15
+ export const MAX_INBOUND_STREAMS = 2
16
+ export const MAX_OUTBOUND_STREAMS = 1
package/src/ping/index.ts CHANGED
@@ -5,28 +5,33 @@ import { randomBytes } from '@libp2p/crypto'
5
5
  import { pipe } from 'it-pipe'
6
6
  import first from 'it-first'
7
7
  import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
8
- import { PROTOCOL_NAME, PING_LENGTH, PROTOCOL_VERSION } from './constants.js'
8
+ import { PROTOCOL_PREFIX, PROTOCOL_NAME, PING_LENGTH, PROTOCOL_VERSION, TIMEOUT, MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS } from './constants.js'
9
9
  import type { IncomingStreamData, Registrar } from '@libp2p/interface-registrar'
10
10
  import type { PeerId } from '@libp2p/interface-peer-id'
11
11
  import type { Startable } from '@libp2p/interfaces/startable'
12
12
  import type { AbortOptions } from '@libp2p/interfaces'
13
13
  import { abortableDuplex } from 'abortable-iterator'
14
- import { TimeoutController } from 'timeout-abort-controller'
15
14
  import type { Stream } from '@libp2p/interface-connection'
16
15
  import { setMaxListeners } from 'events'
17
16
  import type { ConnectionManager } from '@libp2p/interface-connection-manager'
17
+ import { anySignal } from 'any-signal'
18
+ import type { Multiaddr } from '@multiformats/multiaddr'
18
19
 
19
20
  const log = logger('libp2p:ping')
20
21
 
22
+ export interface PingService {
23
+ ping: (peer: PeerId | Multiaddr | Multiaddr[], options?: AbortOptions) => Promise<number>
24
+ }
25
+
21
26
  export interface PingServiceInit {
22
- protocolPrefix: string
23
- maxInboundStreams: number
24
- maxOutboundStreams: number
27
+ protocolPrefix?: string
28
+ maxInboundStreams?: number
29
+ maxOutboundStreams?: number
25
30
 
26
31
  /**
27
32
  * How long we should wait for a ping response
28
33
  */
29
- timeout: number
34
+ timeout?: number
30
35
  }
31
36
 
32
37
  export interface PingServiceComponents {
@@ -34,23 +39,27 @@ export interface PingServiceComponents {
34
39
  connectionManager: ConnectionManager
35
40
  }
36
41
 
37
- export class PingService implements Startable {
42
+ class DefaultPingService implements Startable, PingService {
38
43
  public readonly protocol: string
39
44
  private readonly components: PingServiceComponents
40
45
  private started: boolean
41
- private readonly init: PingServiceInit
46
+ private readonly timeout: number
47
+ private readonly maxInboundStreams: number
48
+ private readonly maxOutboundStreams: number
42
49
 
43
50
  constructor (components: PingServiceComponents, init: PingServiceInit) {
44
51
  this.components = components
45
52
  this.started = false
46
- this.protocol = `/${init.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
47
- this.init = init
53
+ this.protocol = `/${init.protocolPrefix ?? PROTOCOL_PREFIX}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
54
+ this.timeout = init.timeout ?? TIMEOUT
55
+ this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS
56
+ this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS
48
57
  }
49
58
 
50
59
  async start (): Promise<void> {
51
60
  await this.components.registrar.handle(this.protocol, this.handleMessage, {
52
- maxInboundStreams: this.init.maxInboundStreams,
53
- maxOutboundStreams: this.init.maxOutboundStreams
61
+ maxInboundStreams: this.maxInboundStreams,
62
+ maxOutboundStreams: this.maxOutboundStreams
54
63
  })
55
64
  this.started = true
56
65
  }
@@ -82,26 +91,20 @@ export class PingService implements Startable {
82
91
  * @param {PeerId|Multiaddr} peer
83
92
  * @returns {Promise<number>}
84
93
  */
85
- async ping (peer: PeerId, options: AbortOptions = {}): Promise<number> {
94
+ async ping (peer: PeerId | Multiaddr | Multiaddr[], options: AbortOptions = {}): Promise<number> {
86
95
  log('dialing %s to %p', this.protocol, peer)
87
96
 
88
97
  const start = Date.now()
89
98
  const data = randomBytes(PING_LENGTH)
90
99
  const connection = await this.components.connectionManager.openConnection(peer, options)
91
- let timeoutController
92
- let signal = options.signal
93
100
  let stream: Stream | undefined
94
101
 
95
- // create a timeout if no abort signal passed
96
- if (signal == null) {
97
- timeoutController = new TimeoutController(this.init.timeout)
98
- signal = timeoutController.signal
102
+ const signal = anySignal([AbortSignal.timeout(this.timeout), options?.signal])
99
103
 
100
- try {
101
- // fails on node < 15.4
102
- setMaxListeners?.(Infinity, timeoutController.signal)
103
- } catch {}
104
- }
104
+ try {
105
+ // fails on node < 15.4
106
+ setMaxListeners?.(Infinity, signal)
107
+ } catch {}
105
108
 
106
109
  try {
107
110
  stream = await connection.newStream([this.protocol], {
@@ -124,13 +127,14 @@ export class PingService implements Startable {
124
127
 
125
128
  return end - start
126
129
  } finally {
127
- if (timeoutController != null) {
128
- timeoutController.clear()
129
- }
130
-
131
130
  if (stream != null) {
132
131
  stream.close()
133
132
  }
133
+ signal.clear()
134
134
  }
135
135
  }
136
136
  }
137
+
138
+ export function pingService (init: PingServiceInit = {}): (components: PingServiceComponents) => PingService {
139
+ return (components) => new DefaultPingService(components, init)
140
+ }
package/src/registrar.ts CHANGED
@@ -4,10 +4,12 @@ import { codes } from './errors.js'
4
4
  import { isTopology, StreamHandlerOptions, StreamHandlerRecord } from '@libp2p/interface-registrar'
5
5
  import merge from 'merge-options'
6
6
  import type { Registrar, StreamHandler, Topology } from '@libp2p/interface-registrar'
7
- import type { PeerProtocolsChangeData, PeerStore } from '@libp2p/interface-peer-store'
7
+ import type { PeerStore } from '@libp2p/interface-peer-store'
8
8
  import type { Connection } from '@libp2p/interface-connection'
9
9
  import type { ConnectionManager } from '@libp2p/interface-connection-manager'
10
10
  import type { PeerId } from '@libp2p/interface-peer-id'
11
+ import type { EventEmitter } from '@libp2p/interfaces/events'
12
+ import type { Libp2pEvents, PeerUpdate } from '@libp2p/interface-libp2p'
11
13
 
12
14
  const log = logger('libp2p:registrar')
13
15
 
@@ -18,6 +20,7 @@ export interface RegistrarComponents {
18
20
  peerId: PeerId
19
21
  connectionManager: ConnectionManager
20
22
  peerStore: PeerStore
23
+ events: EventEmitter<Libp2pEvents>
21
24
  }
22
25
 
23
26
  /**
@@ -34,19 +37,16 @@ export class DefaultRegistrar implements Registrar {
34
37
  this.components = components
35
38
 
36
39
  this._onDisconnect = this._onDisconnect.bind(this)
37
- this._onProtocolChange = this._onProtocolChange.bind(this)
40
+ this._onPeerUpdate = this._onPeerUpdate.bind(this)
38
41
  this._onConnect = this._onConnect.bind(this)
39
42
 
40
- this.components.connectionManager.addEventListener('peer:disconnect', this._onDisconnect)
41
- this.components.connectionManager.addEventListener('peer:connect', this._onConnect)
42
-
43
- // happens after identify
44
- this.components.peerStore.addEventListener('change:protocols', this._onProtocolChange)
43
+ this.components.events.addEventListener('connection:close', this._onDisconnect)
44
+ this.components.events.addEventListener('connection:open', this._onConnect)
45
+ this.components.events.addEventListener('peer:update', this._onPeerUpdate)
45
46
  }
46
47
 
47
48
  getProtocols (): string[] {
48
49
  return Array.from(new Set<string>([
49
- ...this.topologies.keys(),
50
50
  ...this.handlers.keys()
51
51
  ])).sort()
52
52
  }
@@ -91,8 +91,10 @@ export class DefaultRegistrar implements Registrar {
91
91
  options
92
92
  })
93
93
 
94
- // Add new protocols to self protocols in the Protobook
95
- await this.components.peerStore.protoBook.add(this.components.peerId, [protocol])
94
+ // Add new protocol to self protocols in the peer store
95
+ await this.components.peerStore.merge(this.components.peerId, {
96
+ protocols: [protocol]
97
+ })
96
98
  }
97
99
 
98
100
  /**
@@ -106,8 +108,10 @@ export class DefaultRegistrar implements Registrar {
106
108
  this.handlers.delete(protocol)
107
109
  })
108
110
 
109
- // Remove protocols from self protocols in the Protobook
110
- await this.components.peerStore.protoBook.remove(this.components.peerId, protocolList)
111
+ // Update self protocols in the peer store
112
+ await this.components.peerStore.patch(this.components.peerId, {
113
+ protocols: protocolList
114
+ })
111
115
  }
112
116
 
113
117
  /**
@@ -158,9 +162,9 @@ export class DefaultRegistrar implements Registrar {
158
162
  _onDisconnect (evt: CustomEvent<Connection>): void {
159
163
  const connection = evt.detail
160
164
 
161
- void this.components.peerStore.protoBook.get(connection.remotePeer)
162
- .then(peerProtocols => {
163
- for (const protocol of peerProtocols) {
165
+ void this.components.peerStore.get(connection.remotePeer)
166
+ .then(peer => {
167
+ for (const protocol of peer.protocols) {
164
168
  const topologies = this.topologies.get(protocol)
165
169
 
166
170
  if (topologies == null) {
@@ -174,7 +178,7 @@ export class DefaultRegistrar implements Registrar {
174
178
  }
175
179
  })
176
180
  .catch(err => {
177
- log.error(err)
181
+ log.error('could not inform topologies of disconnecting peer %p', connection.remotePeer, err)
178
182
  })
179
183
  }
180
184
 
@@ -185,9 +189,9 @@ export class DefaultRegistrar implements Registrar {
185
189
  _onConnect (evt: CustomEvent<Connection>): void {
186
190
  const connection = evt.detail
187
191
 
188
- void this.components.peerStore.protoBook.get(connection.remotePeer)
189
- .then(peerProtocols => {
190
- for (const protocol of peerProtocols) {
192
+ void this.components.peerStore.get(connection.remotePeer)
193
+ .then(peer => {
194
+ for (const protocol of peer.protocols) {
191
195
  const topologies = this.topologies.get(protocol)
192
196
 
193
197
  if (topologies == null) {
@@ -201,17 +205,17 @@ export class DefaultRegistrar implements Registrar {
201
205
  }
202
206
  })
203
207
  .catch(err => {
204
- log.error(err)
208
+ log.error('could not inform topologies of connecting peer %p', connection.remotePeer, err)
205
209
  })
206
210
  }
207
211
 
208
212
  /**
209
213
  * Check if a new peer support the multicodecs for this topology
210
214
  */
211
- _onProtocolChange (evt: CustomEvent<PeerProtocolsChangeData>): void {
212
- const { peerId, protocols, oldProtocols } = evt.detail
213
- const removed = oldProtocols.filter(protocol => !protocols.includes(protocol))
214
- const added = protocols.filter(protocol => !oldProtocols.includes(protocol))
215
+ _onPeerUpdate (evt: CustomEvent<PeerUpdate>): void {
216
+ const { peer, previous } = evt.detail
217
+ const removed = (previous?.protocols ?? []).filter(protocol => !peer.protocols.includes(protocol))
218
+ const added = peer.protocols.filter(protocol => !(previous?.protocols ?? []).includes(protocol))
215
219
 
216
220
  for (const protocol of removed) {
217
221
  const topologies = this.topologies.get(protocol)
@@ -222,7 +226,7 @@ export class DefaultRegistrar implements Registrar {
222
226
  }
223
227
 
224
228
  for (const topology of topologies.values()) {
225
- topology.onDisconnect(peerId)
229
+ topology.onDisconnect(peer.id)
226
230
  }
227
231
  }
228
232
 
@@ -235,12 +239,12 @@ export class DefaultRegistrar implements Registrar {
235
239
  }
236
240
 
237
241
  for (const topology of topologies.values()) {
238
- const connection = this.components.connectionManager.getConnections(peerId)[0]
242
+ const connection = this.components.connectionManager.getConnections(peer.id)[0]
239
243
 
240
244
  if (connection == null) {
241
245
  continue
242
246
  }
243
- topology.onConnect(peerId, connection)
247
+ topology.onConnect(peer.id, connection)
244
248
  }
245
249
  }
246
250
  }
@@ -2,15 +2,16 @@ import { logger } from '@libp2p/logger'
2
2
  import { codes } from './errors.js'
3
3
  import { CodeError } from '@libp2p/interfaces/errors'
4
4
  import { FaultTolerance } from '@libp2p/interface-transport'
5
- import type { Listener, Transport, TransportManager, TransportManagerEvents, Upgrader } from '@libp2p/interface-transport'
5
+ import type { Listener, Transport, TransportManager, Upgrader } from '@libp2p/interface-transport'
6
6
  import type { Multiaddr } from '@multiformats/multiaddr'
7
7
  import type { Connection } from '@libp2p/interface-connection'
8
8
  import type { AbortOptions } from '@libp2p/interfaces'
9
- import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
9
+ import type { EventEmitter } from '@libp2p/interfaces/events'
10
10
  import type { Startable } from '@libp2p/interfaces/startable'
11
11
  import { trackedMap } from '@libp2p/tracked-map'
12
12
  import type { Metrics } from '@libp2p/interface-metrics'
13
13
  import type { AddressManager } from '@libp2p/interface-address-manager'
14
+ import type { Libp2pEvents } from '@libp2p/interface-libp2p'
14
15
 
15
16
  const log = logger('libp2p:transports')
16
17
 
@@ -22,9 +23,10 @@ export interface DefaultTransportManagerComponents {
22
23
  metrics?: Metrics
23
24
  addressManager: AddressManager
24
25
  upgrader: Upgrader
26
+ events: EventEmitter<Libp2pEvents>
25
27
  }
26
28
 
27
- export class DefaultTransportManager extends EventEmitter<TransportManagerEvents> implements TransportManager, Startable {
29
+ export class DefaultTransportManager implements TransportManager, Startable {
28
30
  private readonly components: DefaultTransportManagerComponents
29
31
  private readonly transports: Map<string, Transport>
30
32
  private readonly listeners: Map<string, Listener[]>
@@ -32,8 +34,6 @@ export class DefaultTransportManager extends EventEmitter<TransportManagerEvents
32
34
  private started: boolean
33
35
 
34
36
  constructor (components: DefaultTransportManagerComponents, init: TransportManagerInit = {}) {
35
- super()
36
-
37
37
  this.components = components
38
38
  this.started = false
39
39
  this.transports = new Map<string, Transport>()
@@ -71,13 +71,15 @@ export class DefaultTransportManager extends EventEmitter<TransportManagerEvents
71
71
  return this.started
72
72
  }
73
73
 
74
- async start (): Promise<void> {
74
+ start (): void {
75
+ this.started = true
76
+ }
77
+
78
+ async afterStart (): Promise<void> {
75
79
  // Listen on the provided transports for the provided addresses
76
80
  const addrs = this.components.addressManager.getListenAddrs()
77
81
 
78
82
  await this.listen(addrs)
79
-
80
- this.started = true
81
83
  }
82
84
 
83
85
  /**
@@ -151,6 +153,13 @@ export class DefaultTransportManager extends EventEmitter<TransportManagerEvents
151
153
  return Array.of(...this.transports.values())
152
154
  }
153
155
 
156
+ /**
157
+ * Returns all the listener instances
158
+ */
159
+ getListeners (): Listener[] {
160
+ return Array.of(...this.listeners.values()).flat()
161
+ }
162
+
154
163
  /**
155
164
  * Finds a transport that matches the given Multiaddr
156
165
  */
@@ -186,7 +195,7 @@ export class DefaultTransportManager extends EventEmitter<TransportManagerEvents
186
195
  upgrader: this.components.upgrader
187
196
  })
188
197
 
189
- let listeners = this.listeners.get(key)
198
+ let listeners: Listener[] = this.listeners.get(key) ?? []
190
199
 
191
200
  if (listeners == null) {
192
201
  listeners = []
@@ -197,14 +206,19 @@ export class DefaultTransportManager extends EventEmitter<TransportManagerEvents
197
206
 
198
207
  // Track listen/close events
199
208
  listener.addEventListener('listening', () => {
200
- this.dispatchEvent(new CustomEvent<Listener>('listener:listening', {
209
+ this.components.events.safeDispatchEvent('transport:listening', {
201
210
  detail: listener
202
- }))
211
+ })
203
212
  })
204
213
  listener.addEventListener('close', () => {
205
- this.dispatchEvent(new CustomEvent<Listener>('listener:close', {
214
+ const index = listeners.findIndex(l => l === listener)
215
+
216
+ // remove the listener
217
+ listeners.splice(index, 1)
218
+
219
+ this.components.events.safeDispatchEvent('transport:close', {
206
220
  detail: listener
207
- }))
221
+ })
208
222
  })
209
223
 
210
224
  // We need to attempt to listen on everything