libp2p 0.37.2 → 0.37.3-3c0fb13

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 (165) hide show
  1. package/README.md +1 -2
  2. package/dist/src/address-manager/index.d.ts +2 -2
  3. package/dist/src/address-manager/index.d.ts.map +1 -1
  4. package/dist/src/circuit/auto-relay.d.ts +4 -4
  5. package/dist/src/circuit/auto-relay.d.ts.map +1 -1
  6. package/dist/src/circuit/circuit/hop.d.ts +5 -4
  7. package/dist/src/circuit/circuit/hop.d.ts.map +1 -1
  8. package/dist/src/circuit/circuit/hop.js +8 -4
  9. package/dist/src/circuit/circuit/hop.js.map +1 -1
  10. package/dist/src/circuit/circuit/stop.d.ts +3 -2
  11. package/dist/src/circuit/circuit/stop.d.ts.map +1 -1
  12. package/dist/src/circuit/circuit/stop.js +4 -2
  13. package/dist/src/circuit/circuit/stop.js.map +1 -1
  14. package/dist/src/circuit/circuit/stream-handler.d.ts +1 -1
  15. package/dist/src/circuit/circuit/stream-handler.d.ts.map +1 -1
  16. package/dist/src/circuit/index.d.ts +4 -12
  17. package/dist/src/circuit/index.d.ts.map +1 -1
  18. package/dist/src/circuit/index.js.map +1 -1
  19. package/dist/src/circuit/listener.d.ts +3 -3
  20. package/dist/src/circuit/listener.d.ts.map +1 -1
  21. package/dist/src/circuit/transport.d.ts +8 -5
  22. package/dist/src/circuit/transport.d.ts.map +1 -1
  23. package/dist/src/circuit/transport.js +81 -59
  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 +27 -4
  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/dialer/auto-dialer.d.ts +2 -2
  31. package/dist/src/connection-manager/dialer/auto-dialer.d.ts.map +1 -1
  32. package/dist/src/connection-manager/dialer/auto-dialer.js +6 -0
  33. package/dist/src/connection-manager/dialer/auto-dialer.js.map +1 -1
  34. package/dist/src/connection-manager/dialer/dial-request.d.ts +1 -1
  35. package/dist/src/connection-manager/dialer/dial-request.d.ts.map +1 -1
  36. package/dist/src/connection-manager/dialer/index.d.ts +9 -9
  37. package/dist/src/connection-manager/dialer/index.d.ts.map +1 -1
  38. package/dist/src/connection-manager/dialer/index.js +11 -11
  39. package/dist/src/connection-manager/dialer/index.js.map +1 -1
  40. package/dist/src/connection-manager/index.d.ts +24 -20
  41. package/dist/src/connection-manager/index.d.ts.map +1 -1
  42. package/dist/src/connection-manager/index.js +209 -82
  43. package/dist/src/connection-manager/index.js.map +1 -1
  44. package/dist/src/constants.d.ts +4 -0
  45. package/dist/src/constants.d.ts.map +1 -1
  46. package/dist/src/constants.js +4 -0
  47. package/dist/src/constants.js.map +1 -1
  48. package/dist/src/content-routing/index.d.ts +4 -4
  49. package/dist/src/content-routing/index.d.ts.map +1 -1
  50. package/dist/src/content-routing/utils.d.ts +2 -2
  51. package/dist/src/content-routing/utils.d.ts.map +1 -1
  52. package/dist/src/dht/dht-content-routing.d.ts +3 -3
  53. package/dist/src/dht/dht-content-routing.d.ts.map +1 -1
  54. package/dist/src/dht/dht-peer-routing.d.ts +5 -5
  55. package/dist/src/dht/dht-peer-routing.d.ts.map +1 -1
  56. package/dist/src/dht/dummy-dht.d.ts +3 -3
  57. package/dist/src/dht/dummy-dht.d.ts.map +1 -1
  58. package/dist/src/dht/dummy-dht.js +1 -1
  59. package/dist/src/dht/dummy-dht.js.map +1 -1
  60. package/dist/src/errors.d.ts +4 -1
  61. package/dist/src/errors.d.ts.map +1 -1
  62. package/dist/src/errors.js +3 -0
  63. package/dist/src/errors.js.map +1 -1
  64. package/dist/src/fetch/index.d.ts +11 -4
  65. package/dist/src/fetch/index.d.ts.map +1 -1
  66. package/dist/src/fetch/index.js +82 -41
  67. package/dist/src/fetch/index.js.map +1 -1
  68. package/dist/src/get-peer.d.ts +2 -2
  69. package/dist/src/get-peer.d.ts.map +1 -1
  70. package/dist/src/get-peer.js +1 -1
  71. package/dist/src/get-peer.js.map +1 -1
  72. package/dist/src/identify/index.d.ts +8 -8
  73. package/dist/src/identify/index.d.ts.map +1 -1
  74. package/dist/src/identify/index.js +48 -33
  75. package/dist/src/identify/index.js.map +1 -1
  76. package/dist/src/index.d.ts +18 -17
  77. package/dist/src/index.d.ts.map +1 -1
  78. package/dist/src/index.js.map +1 -1
  79. package/dist/src/insecure/index.d.ts +2 -2
  80. package/dist/src/insecure/index.d.ts.map +1 -1
  81. package/dist/src/insecure/index.js +1 -1
  82. package/dist/src/insecure/index.js.map +1 -1
  83. package/dist/src/keychain/index.d.ts +2 -2
  84. package/dist/src/keychain/index.d.ts.map +1 -1
  85. package/dist/src/libp2p.d.ts +14 -14
  86. package/dist/src/libp2p.d.ts.map +1 -1
  87. package/dist/src/libp2p.js +17 -17
  88. package/dist/src/libp2p.js.map +1 -1
  89. package/dist/src/metrics/index.d.ts +3 -3
  90. package/dist/src/metrics/index.d.ts.map +1 -1
  91. package/dist/src/metrics/index.js +6 -2
  92. package/dist/src/metrics/index.js.map +1 -1
  93. package/dist/src/metrics/moving-average.d.ts +1 -1
  94. package/dist/src/metrics/moving-average.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/nat-manager.d.ts +1 -1
  98. package/dist/src/nat-manager.d.ts.map +1 -1
  99. package/dist/src/peer-record-updater.d.ts +1 -1
  100. package/dist/src/peer-record-updater.d.ts.map +1 -1
  101. package/dist/src/peer-routing.d.ts +4 -4
  102. package/dist/src/peer-routing.d.ts.map +1 -1
  103. package/dist/src/ping/index.d.ts +10 -3
  104. package/dist/src/ping/index.d.ts.map +1 -1
  105. package/dist/src/ping/index.js +31 -8
  106. package/dist/src/ping/index.js.map +1 -1
  107. package/dist/src/pnet/index.d.ts +1 -2
  108. package/dist/src/pnet/index.d.ts.map +1 -1
  109. package/dist/src/pnet/index.js.map +1 -1
  110. package/dist/src/pubsub/dummy-pubsub.d.ts +2 -2
  111. package/dist/src/pubsub/dummy-pubsub.d.ts.map +1 -1
  112. package/dist/src/registrar.d.ts +10 -8
  113. package/dist/src/registrar.d.ts.map +1 -1
  114. package/dist/src/registrar.js +63 -44
  115. package/dist/src/registrar.js.map +1 -1
  116. package/dist/src/transport-manager.d.ts +3 -3
  117. package/dist/src/transport-manager.d.ts.map +1 -1
  118. package/dist/src/upgrader.d.ts +12 -6
  119. package/dist/src/upgrader.d.ts.map +1 -1
  120. package/dist/src/upgrader.js +164 -65
  121. package/dist/src/upgrader.js.map +1 -1
  122. package/dist/src/version.d.ts.map +1 -1
  123. package/dist/src/version.js.map +1 -1
  124. package/package.json +56 -32
  125. package/src/address-manager/index.ts +2 -2
  126. package/src/circuit/auto-relay.ts +4 -4
  127. package/src/circuit/circuit/hop.ts +15 -8
  128. package/src/circuit/circuit/stop.ts +8 -4
  129. package/src/circuit/circuit/stream-handler.ts +1 -1
  130. package/src/circuit/index.ts +4 -13
  131. package/src/circuit/listener.ts +3 -3
  132. package/src/circuit/transport.ts +90 -63
  133. package/src/config.ts +27 -4
  134. package/src/connection-manager/auto-dialler.ts +1 -1
  135. package/src/connection-manager/dialer/auto-dialer.ts +8 -2
  136. package/src/connection-manager/dialer/dial-request.ts +1 -1
  137. package/src/connection-manager/dialer/index.ts +15 -15
  138. package/src/connection-manager/index.ts +267 -97
  139. package/src/constants.ts +5 -0
  140. package/src/content-routing/index.ts +2 -2
  141. package/src/content-routing/utils.ts +2 -2
  142. package/src/dht/dht-content-routing.ts +2 -2
  143. package/src/dht/dht-peer-routing.ts +3 -3
  144. package/src/dht/dummy-dht.ts +3 -3
  145. package/src/errors.ts +4 -1
  146. package/src/fetch/index.ts +120 -53
  147. package/src/get-peer.ts +3 -3
  148. package/src/identify/index.ts +60 -42
  149. package/src/index.ts +18 -17
  150. package/src/insecure/index.ts +3 -3
  151. package/src/keychain/index.ts +2 -2
  152. package/src/libp2p.ts +34 -29
  153. package/src/metrics/index.ts +9 -5
  154. package/src/metrics/moving-average.ts +1 -1
  155. package/src/metrics/stats.ts +1 -1
  156. package/src/nat-manager.ts +1 -1
  157. package/src/peer-record-updater.ts +1 -1
  158. package/src/peer-routing.ts +4 -4
  159. package/src/ping/index.ts +47 -14
  160. package/src/pnet/index.ts +1 -2
  161. package/src/pubsub/dummy-pubsub.ts +2 -2
  162. package/src/registrar.ts +79 -55
  163. package/src/transport-manager.ts +3 -3
  164. package/src/upgrader.ts +204 -76
  165. package/src/version.ts +1 -2
@@ -3,21 +3,30 @@ import errCode from 'err-code'
3
3
  import { codes } from '../errors.js'
4
4
  import * as lp from 'it-length-prefixed'
5
5
  import { FetchRequest, FetchResponse } from './pb/proto.js'
6
- import { handshake } from 'it-handshake'
7
6
  import { PROTOCOL_NAME, PROTOCOL_VERSION } from './constants.js'
8
- import type { PeerId } from '@libp2p/interfaces/peer-id'
7
+ import type { PeerId } from '@libp2p/interface-peer-id'
9
8
  import type { Startable } from '@libp2p/interfaces/startable'
10
- import type { Stream } from '@libp2p/interfaces/connection'
11
- import type { IncomingStreamData } from '@libp2p/interfaces/registrar'
12
- import type { Components } from '@libp2p/interfaces/components'
9
+ import type { Stream } from '@libp2p/interface-connection'
10
+ import type { IncomingStreamData } from '@libp2p/interface-registrar'
11
+ import type { Components } from '@libp2p/components'
13
12
  import type { AbortOptions } from '@libp2p/interfaces'
14
- import type { Duplex } from 'it-stream-types'
15
13
  import { abortableDuplex } from 'abortable-iterator'
14
+ import { pipe } from 'it-pipe'
15
+ import first from 'it-first'
16
+ import { TimeoutController } from 'timeout-abort-controller'
17
+ import { setMaxListeners } from 'events'
16
18
 
17
19
  const log = logger('libp2p:fetch')
18
20
 
19
21
  export interface FetchServiceInit {
20
22
  protocolPrefix: string
23
+ maxInboundStreams: number
24
+ maxOutboundStreams: number
25
+
26
+ /**
27
+ * How long we should wait for a remote peer to send any data
28
+ */
29
+ timeout: number
21
30
  }
22
31
 
23
32
  export interface HandleMessageOptions {
@@ -40,6 +49,7 @@ export class FetchService implements Startable {
40
49
  private readonly components: Components
41
50
  private readonly lookupFunctions: Map<string, LookupFunction>
42
51
  private started: boolean
52
+ private readonly init: FetchServiceInit
43
53
 
44
54
  constructor (components: Components, init: FetchServiceInit) {
45
55
  this.started = false
@@ -47,13 +57,21 @@ export class FetchService implements Startable {
47
57
  this.protocol = `/${init.protocolPrefix ?? 'libp2p'}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
48
58
  this.lookupFunctions = new Map() // Maps key prefix to value lookup function
49
59
  this.handleMessage = this.handleMessage.bind(this)
60
+ this.init = init
50
61
  }
51
62
 
52
63
  async start () {
53
64
  await this.components.getRegistrar().handle(this.protocol, (data) => {
54
- void this.handleMessage(data).catch(err => {
55
- log.error(err)
56
- })
65
+ void this.handleMessage(data)
66
+ .catch(err => {
67
+ log.error(err)
68
+ })
69
+ .finally(() => {
70
+ data.stream.close()
71
+ })
72
+ }, {
73
+ maxInboundStreams: this.init.maxInboundStreams,
74
+ maxOutboundStreams: this.init.maxOutboundStreams
57
75
  })
58
76
  this.started = true
59
77
  }
@@ -74,35 +92,69 @@ export class FetchService implements Startable {
74
92
  log('dialing %s to %p', this.protocol, peer)
75
93
 
76
94
  const connection = await this.components.getConnectionManager().openConnection(peer, options)
77
- const { stream } = await connection.newStream([this.protocol], options)
78
- let source: Duplex<Uint8Array> = stream
79
-
80
- // make stream abortable if AbortSignal passed
81
- if (options.signal != null) {
82
- source = abortableDuplex(stream, options.signal)
95
+ let timeoutController
96
+ let signal = options.signal
97
+ let stream: Stream | undefined
98
+
99
+ // create a timeout if no abort signal passed
100
+ if (signal == null) {
101
+ timeoutController = new TimeoutController(this.init.timeout)
102
+ signal = timeoutController.signal
103
+
104
+ try {
105
+ // fails on node < 15.4
106
+ setMaxListeners?.(Infinity, timeoutController.signal)
107
+ } catch {}
83
108
  }
84
109
 
85
- const shake = handshake(source)
86
-
87
- // send message
88
- shake.write(lp.encode.single(FetchRequest.encode({ identifier: key })).slice())
110
+ try {
111
+ stream = await connection.newStream([this.protocol], {
112
+ signal
113
+ })
89
114
 
90
- // read response
91
- // @ts-expect-error fromReader returns a Source which has no .next method
92
- const response = FetchResponse.decode((await lp.decode.fromReader(shake.reader).next()).value.slice())
93
- switch (response.status) {
94
- case (FetchResponse.StatusCode.OK): {
95
- return response.data
96
- }
97
- case (FetchResponse.StatusCode.NOT_FOUND): {
98
- return null
115
+ // make stream abortable
116
+ const source = abortableDuplex(stream, signal)
117
+
118
+ const result = await pipe(
119
+ [FetchRequest.encode({ identifier: key })],
120
+ lp.encode(),
121
+ source,
122
+ lp.decode(),
123
+ async function (source) {
124
+ const buf = await first(source)
125
+
126
+ if (buf == null) {
127
+ throw errCode(new Error('No data received'), codes.ERR_INVALID_MESSAGE)
128
+ }
129
+
130
+ const response = FetchResponse.decode(buf)
131
+
132
+ switch (response.status) {
133
+ case (FetchResponse.StatusCode.OK): {
134
+ return response.data
135
+ }
136
+ case (FetchResponse.StatusCode.NOT_FOUND): {
137
+ return null
138
+ }
139
+ case (FetchResponse.StatusCode.ERROR): {
140
+ const errmsg = (new TextDecoder()).decode(response.data)
141
+ throw errCode(new Error('Error in fetch protocol response: ' + errmsg), codes.ERR_INVALID_PARAMETERS)
142
+ }
143
+ default: {
144
+ throw errCode(new Error('Unknown response status'), codes.ERR_INVALID_MESSAGE)
145
+ }
146
+ }
147
+ }
148
+ )
149
+
150
+ return result ?? null
151
+ } finally {
152
+ if (timeoutController != null) {
153
+ timeoutController.clear()
99
154
  }
100
- case (FetchResponse.StatusCode.ERROR): {
101
- const errmsg = (new TextDecoder()).decode(response.data)
102
- throw errCode(new Error('Error in fetch protocol response: ' + errmsg), codes.ERR_INVALID_PARAMETERS)
103
- }
104
- default: {
105
- throw errCode(new Error('Unknown response status'), codes.ERR_INVALID_MESSAGE)
155
+
156
+ if (stream != null) {
157
+ stream.close()
106
158
  }
107
159
  }
108
160
  }
@@ -114,25 +166,40 @@ export class FetchService implements Startable {
114
166
  */
115
167
  async handleMessage (data: IncomingStreamData) {
116
168
  const { stream } = data
117
- const shake = handshake(stream)
118
- // @ts-expect-error fromReader returns a Source which has no .next method
119
- const request = FetchRequest.decode((await lp.decode.fromReader(shake.reader).next()).value.slice())
120
-
121
- let response: FetchResponse
122
- const lookup = this._getLookupFunction(request.identifier)
123
- if (lookup != null) {
124
- const data = await lookup(request.identifier)
125
- if (data != null) {
126
- response = { status: FetchResponse.StatusCode.OK, data }
127
- } else {
128
- response = { status: FetchResponse.StatusCode.NOT_FOUND, data: new Uint8Array(0) }
129
- }
130
- } else {
131
- const errmsg = (new TextEncoder()).encode('No lookup function registered for key: ' + request.identifier)
132
- response = { status: FetchResponse.StatusCode.ERROR, data: errmsg }
133
- }
134
-
135
- shake.write(lp.encode.single(FetchResponse.encode(response)).slice())
169
+ const self = this
170
+
171
+ await pipe(
172
+ stream,
173
+ lp.decode(),
174
+ async function * (source) {
175
+ const buf = await first(source)
176
+
177
+ if (buf == null) {
178
+ throw errCode(new Error('No data received'), codes.ERR_INVALID_MESSAGE)
179
+ }
180
+
181
+ // for await (const buf of source) {
182
+ const request = FetchRequest.decode(buf)
183
+
184
+ let response: FetchResponse
185
+ const lookup = self._getLookupFunction(request.identifier)
186
+ if (lookup != null) {
187
+ const data = await lookup(request.identifier)
188
+ if (data != null) {
189
+ response = { status: FetchResponse.StatusCode.OK, data }
190
+ } else {
191
+ response = { status: FetchResponse.StatusCode.NOT_FOUND, data: new Uint8Array(0) }
192
+ }
193
+ } else {
194
+ const errmsg = (new TextEncoder()).encode('No lookup function registered for key: ' + request.identifier)
195
+ response = { status: FetchResponse.StatusCode.ERROR, data: errmsg }
196
+ }
197
+
198
+ yield FetchResponse.encode(response)
199
+ },
200
+ lp.encode(),
201
+ stream
202
+ )
136
203
  }
137
204
 
138
205
  /**
package/src/get-peer.ts CHANGED
@@ -2,9 +2,9 @@ import { peerIdFromString } from '@libp2p/peer-id'
2
2
  import { Multiaddr } from '@multiformats/multiaddr'
3
3
  import errCode from 'err-code'
4
4
  import { codes } from './errors.js'
5
- import { isPeerId } from '@libp2p/interfaces/peer-id'
6
- import type { PeerId } from '@libp2p/interfaces/peer-id'
7
- import type { PeerInfo } from '@libp2p/interfaces/peer-info'
5
+ import { isPeerId } from '@libp2p/interface-peer-id'
6
+ import type { PeerId } from '@libp2p/interface-peer-id'
7
+ import type { PeerInfo } from '@libp2p/interface-peer-info'
8
8
 
9
9
  function peerIdFromMultiaddr (ma: Multiaddr) {
10
10
  const idStr = ma.getPeerId()
@@ -18,21 +18,19 @@ import {
18
18
  MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION
19
19
  } from './consts.js'
20
20
  import { codes } from '../errors.js'
21
- import type { IncomingStreamData } from '@libp2p/interfaces/registrar'
22
- import type { Connection, Stream } from '@libp2p/interfaces/connection'
21
+ import type { IncomingStreamData } from '@libp2p/interface-registrar'
22
+ import type { Connection, Stream } from '@libp2p/interface-connection'
23
23
  import type { Startable } from '@libp2p/interfaces/startable'
24
24
  import { peerIdFromKeys } from '@libp2p/peer-id'
25
- import type { Components } from '@libp2p/interfaces/components'
25
+ import type { Components } from '@libp2p/components'
26
26
  import { TimeoutController } from 'timeout-abort-controller'
27
27
  import type { AbortOptions } from '@libp2p/interfaces'
28
28
  import { abortableDuplex } from 'abortable-iterator'
29
29
  import type { Duplex } from 'it-stream-types'
30
+ import { setMaxListeners } from 'events'
30
31
 
31
32
  const log = logger('libp2p:identify')
32
33
 
33
- // https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L48
34
- const IDENTIFY_TIMEOUT = 60000
35
-
36
34
  // https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L52
37
35
  const MAX_IDENTIFY_MESSAGE_SIZE = 1024 * 8
38
36
 
@@ -54,12 +52,18 @@ export interface IdentifyServiceInit {
54
52
  /**
55
53
  * How long we should wait for a remote peer to send their identify response
56
54
  */
57
- timeout?: number
55
+ timeout: number
58
56
 
59
57
  /**
60
58
  * Identify responses larger than this in bytes will be rejected (default: 8192)
61
59
  */
62
60
  maxIdentifyMessageSize?: number
61
+
62
+ maxInboundStreams: number
63
+ maxOutboundStreams: number
64
+
65
+ maxPushIncomingStreams: number
66
+ maxPushOutgoingStreams: number
63
67
  }
64
68
 
65
69
  export class IdentifyService implements Startable {
@@ -79,8 +83,6 @@ export class IdentifyService implements Startable {
79
83
  this.started = false
80
84
  this.init = init
81
85
 
82
- this.handleMessage = this.handleMessage.bind(this)
83
-
84
86
  this.identifyProtocolStr = `/${init.protocolPrefix}/${MULTICODEC_IDENTIFY_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PROTOCOL_VERSION}`
85
87
  this.identifyPushProtocolStr = `/${init.protocolPrefix}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION}`
86
88
 
@@ -127,13 +129,21 @@ export class IdentifyService implements Startable {
127
129
  await this.components.getPeerStore().metadataBook.setValue(this.components.getPeerId(), 'AgentVersion', uint8ArrayFromString(this.host.agentVersion))
128
130
  await this.components.getPeerStore().metadataBook.setValue(this.components.getPeerId(), 'ProtocolVersion', uint8ArrayFromString(this.host.protocolVersion))
129
131
 
130
- await this.components.getRegistrar().handle([
131
- this.identifyProtocolStr,
132
- this.identifyPushProtocolStr
133
- ], (data) => {
134
- void this.handleMessage(data)?.catch(err => {
132
+ await this.components.getRegistrar().handle(this.identifyProtocolStr, (data) => {
133
+ void this._handleIdentify(data).catch(err => {
134
+ log.error(err)
135
+ })
136
+ }, {
137
+ maxInboundStreams: this.init.maxInboundStreams,
138
+ maxOutboundStreams: this.init.maxOutboundStreams
139
+ })
140
+ await this.components.getRegistrar().handle(this.identifyPushProtocolStr, (data) => {
141
+ void this._handlePush(data).catch(err => {
135
142
  log.error(err)
136
143
  })
144
+ }, {
145
+ maxInboundStreams: this.init.maxPushIncomingStreams,
146
+ maxOutboundStreams: this.init.maxPushOutgoingStreams
137
147
  })
138
148
 
139
149
  this.started = true
@@ -155,14 +165,18 @@ export class IdentifyService implements Startable {
155
165
  const protocols = await this.components.getPeerStore().protoBook.get(this.components.getPeerId())
156
166
 
157
167
  const pushes = connections.map(async connection => {
158
- const timeoutController = new TimeoutController(this.init.timeout ?? IDENTIFY_TIMEOUT)
159
168
  let stream: Stream | undefined
169
+ const timeoutController = new TimeoutController(this.init.timeout)
160
170
 
161
171
  try {
162
- const data = await connection.newStream([this.identifyPushProtocolStr], {
172
+ // fails on node < 15.4
173
+ setMaxListeners?.(Infinity, timeoutController.signal)
174
+ } catch {}
175
+
176
+ try {
177
+ stream = await connection.newStream([this.identifyPushProtocolStr], {
163
178
  signal: timeoutController.signal
164
179
  })
165
- stream = data.stream
166
180
 
167
181
  // make stream abortable
168
182
  const source: Duplex<Uint8Array> = abortableDuplex(stream, timeoutController.signal)
@@ -218,21 +232,29 @@ export class IdentifyService implements Startable {
218
232
  }
219
233
 
220
234
  async _identify (connection: Connection, options: AbortOptions = {}): Promise<Identify> {
221
- const { stream } = await connection.newStream([this.identifyProtocolStr], options)
222
- let source: Duplex<Uint8Array> = stream
223
235
  let timeoutController
224
236
  let signal = options.signal
237
+ let stream: Stream | undefined
225
238
 
226
239
  // create a timeout if no abort signal passed
227
240
  if (signal == null) {
228
- timeoutController = new TimeoutController(this.init.timeout ?? IDENTIFY_TIMEOUT)
241
+ timeoutController = new TimeoutController(this.init.timeout)
229
242
  signal = timeoutController.signal
230
- }
231
243
 
232
- // make stream abortable if AbortSignal passed
233
- source = abortableDuplex(stream, signal)
244
+ try {
245
+ // fails on node < 15.4
246
+ setMaxListeners?.(Infinity, timeoutController.signal)
247
+ } catch {}
248
+ }
234
249
 
235
250
  try {
251
+ stream = await connection.newStream([this.identifyProtocolStr], {
252
+ signal
253
+ })
254
+
255
+ // make stream abortable
256
+ const source = abortableDuplex(stream, signal)
257
+
236
258
  const data = await pipe(
237
259
  [],
238
260
  source,
@@ -256,7 +278,9 @@ export class IdentifyService implements Startable {
256
278
  timeoutController.clear()
257
279
  }
258
280
 
259
- stream.close()
281
+ if (stream != null) {
282
+ stream.close()
283
+ }
260
284
  }
261
285
  }
262
286
 
@@ -353,29 +377,18 @@ export class IdentifyService implements Startable {
353
377
  // this.components.getAddressManager().addObservedAddr(observedAddr)
354
378
  }
355
379
 
356
- /**
357
- * A handler to register with Libp2p to process identify messages
358
- */
359
- handleMessage (data: IncomingStreamData) {
360
- const { protocol } = data
361
-
362
- switch (protocol) {
363
- case this.identifyProtocolStr:
364
- return this._handleIdentify(data)
365
- case this.identifyPushProtocolStr:
366
- return this._handlePush(data)
367
- default:
368
- log.error('cannot handle unknown protocol %s', protocol)
369
- }
370
- }
371
-
372
380
  /**
373
381
  * Sends the `Identify` response with the Signed Peer Record
374
382
  * to the requesting peer over the given `connection`
375
383
  */
376
384
  async _handleIdentify (data: IncomingStreamData) {
377
385
  const { connection, stream } = data
378
- const timeoutController = new TimeoutController(this.init.timeout ?? IDENTIFY_TIMEOUT)
386
+ const timeoutController = new TimeoutController(this.init.timeout)
387
+
388
+ try {
389
+ // fails on node < 15.4
390
+ setMaxListeners?.(Infinity, timeoutController.signal)
391
+ } catch {}
379
392
 
380
393
  try {
381
394
  const publicKey = this.components.getPeerId().publicKey ?? new Uint8Array(0)
@@ -426,7 +439,12 @@ export class IdentifyService implements Startable {
426
439
  */
427
440
  async _handlePush (data: IncomingStreamData) {
428
441
  const { connection, stream } = data
429
- const timeoutController = new TimeoutController(this.init.timeout ?? IDENTIFY_TIMEOUT)
442
+ const timeoutController = new TimeoutController(this.init.timeout)
443
+
444
+ try {
445
+ // fails on node < 15.4
446
+ setMaxListeners?.(Infinity, timeoutController.signal)
447
+ } catch {}
430
448
 
431
449
  let message: Identify | undefined
432
450
  try {
package/src/index.ts CHANGED
@@ -5,23 +5,23 @@ import type { Startable } from '@libp2p/interfaces/startable'
5
5
  import type { Multiaddr } from '@multiformats/multiaddr'
6
6
  import type { FaultTolerance } from './transport-manager.js'
7
7
  import type { IdentifyServiceInit } from './identify/index.js'
8
- import type { DualDHT } from '@libp2p/interfaces/dht'
8
+ import type { DualDHT } from '@libp2p/interface-dht'
9
9
  import type { Datastore } from 'interface-datastore'
10
- import type { PeerStore, PeerStoreInit } from '@libp2p/interfaces/peer-store'
11
- import type { PeerId } from '@libp2p/interfaces/peer-id'
10
+ import type { PeerStore, PeerStoreInit } from '@libp2p/interface-peer-store'
11
+ import type { PeerId } from '@libp2p/interface-peer-id'
12
12
  import type { AutoRelayConfig, RelayAdvertiseConfig } from './circuit/index.js'
13
- import type { PeerDiscovery } from '@libp2p/interfaces/peer-discovery'
14
- import type { Connection, ConnectionGater, ConnectionProtector, ProtocolStream } from '@libp2p/interfaces/connection'
15
- import type { Transport } from '@libp2p/interfaces/transport'
16
- import type { StreamMuxerFactory } from '@libp2p/interfaces/stream-muxer'
17
- import type { ConnectionEncrypter } from '@libp2p/interfaces/connection-encrypter'
18
- import type { PeerRouting } from '@libp2p/interfaces/peer-routing'
19
- import type { ContentRouting } from '@libp2p/interfaces/content-routing'
20
- import type { PubSub } from '@libp2p/interfaces/pubsub'
21
- import type { Registrar, StreamHandler } from '@libp2p/interfaces/registrar'
22
- import type { ConnectionManager } from '@libp2p/interfaces/connection-manager'
23
- import type { Metrics, MetricsInit } from '@libp2p/interfaces/metrics'
24
- import type { PeerInfo } from '@libp2p/interfaces/peer-info'
13
+ import type { PeerDiscovery } from '@libp2p/interface-peer-discovery'
14
+ import type { Connection, ConnectionGater, ConnectionProtector, Stream } from '@libp2p/interface-connection'
15
+ import type { Transport } from '@libp2p/interface-transport'
16
+ import type { StreamMuxerFactory } from '@libp2p/interface-stream-muxer'
17
+ import type { ConnectionEncrypter } from '@libp2p/interface-connection-encrypter'
18
+ import type { PeerRouting } from '@libp2p/interface-peer-routing'
19
+ import type { ContentRouting } from '@libp2p/interface-content-routing'
20
+ import type { PubSub } from '@libp2p/interface-pubsub'
21
+ import type { Registrar, StreamHandler, StreamHandlerOptions } from '@libp2p/interface-registrar'
22
+ import type { ConnectionManager } from '@libp2p/interface-connection-manager'
23
+ import type { Metrics, MetricsInit } from '@libp2p/interface-metrics'
24
+ import type { PeerInfo } from '@libp2p/interface-peer-info'
25
25
  import type { KeyChain } from './keychain/index.js'
26
26
  import type { ConnectionManagerInit } from './connection-manager/index.js'
27
27
  import type { PingServiceInit } from './ping/index.js'
@@ -50,6 +50,7 @@ export interface MetricsConfig {
50
50
  export interface HopConfig {
51
51
  enabled?: boolean
52
52
  active?: boolean
53
+ timeout: number
53
54
  }
54
55
 
55
56
  export interface RelayConfig {
@@ -177,7 +178,7 @@ export interface Libp2p extends Startable, EventEmitter<Libp2pEvents> {
177
178
  * If successful, the known metadata of the peer will be added to the nodes `peerStore`,
178
179
  * and the `MuxedStream` will be returned together with the successful negotiated protocol.
179
180
  */
180
- dialProtocol: (peer: PeerId | Multiaddr, protocols: string | string[], options?: AbortOptions) => Promise<ProtocolStream>
181
+ dialProtocol: (peer: PeerId | Multiaddr, protocols: string | string[], options?: AbortOptions) => Promise<Stream>
181
182
 
182
183
  /**
183
184
  * Disconnects all connections to the given `peer`
@@ -187,7 +188,7 @@ export interface Libp2p extends Startable, EventEmitter<Libp2pEvents> {
187
188
  /**
188
189
  * Registers the `handler` for each protocol
189
190
  */
190
- handle: (protocol: string | string[], handler: StreamHandler) => Promise<void>
191
+ handle: (protocol: string | string[], handler: StreamHandler, options?: StreamHandlerOptions) => Promise<void>
191
192
 
192
193
  /**
193
194
  * Removes the handler for each protocol. The protocol
@@ -1,11 +1,11 @@
1
1
  import { logger } from '@libp2p/logger'
2
2
  import { handshake } from 'it-handshake'
3
3
  import * as lp from 'it-length-prefixed'
4
- import { UnexpectedPeerError, InvalidCryptoExchangeError } from '@libp2p/interfaces/connection-encrypter/errors'
4
+ import { UnexpectedPeerError, InvalidCryptoExchangeError } from '@libp2p/interface-connection-encrypter/errors'
5
5
  import { Exchange, KeyType } from './pb/proto.js'
6
- import type { PeerId } from '@libp2p/interfaces/peer-id'
6
+ import type { PeerId } from '@libp2p/interface-peer-id'
7
7
  import { peerIdFromBytes, peerIdFromKeys } from '@libp2p/peer-id'
8
- import type { ConnectionEncrypter, SecuredConnection } from '@libp2p/interfaces/connection-encrypter'
8
+ import type { ConnectionEncrypter, SecuredConnection } from '@libp2p/interface-connection-encrypter'
9
9
  import type { Duplex } from 'it-stream-types'
10
10
 
11
11
  const log = logger('libp2p:plaintext')
@@ -10,8 +10,8 @@ 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
12
  import { generateKeyPair, importKey, unmarshalPrivateKey } from '@libp2p/crypto/keys'
13
- import type { PeerId } from '@libp2p/interfaces/peer-id'
14
- import type { Components } from '@libp2p/interfaces/components'
13
+ import type { PeerId } from '@libp2p/interface-peer-id'
14
+ import type { Components } from '@libp2p/components'
15
15
  import { pbkdf2, randomBytes } from '@libp2p/crypto'
16
16
 
17
17
  const log = logger('libp2p:keychain')
package/src/libp2p.ts CHANGED
@@ -27,25 +27,25 @@ import { DHTPeerRouting } from './dht/dht-peer-routing.js'
27
27
  import { PersistentPeerStore } from '@libp2p/peer-store'
28
28
  import { DHTContentRouting } from './dht/dht-content-routing.js'
29
29
  import { AutoDialer } from './connection-manager/dialer/auto-dialer.js'
30
- import { Initializable, Components, isInitializable } from '@libp2p/interfaces/components'
31
- import type { PeerId } from '@libp2p/interfaces/peer-id'
32
- import type { Connection } from '@libp2p/interfaces/connection'
33
- import type { PeerRouting } from '@libp2p/interfaces/peer-routing'
34
- import type { ContentRouting } from '@libp2p/interfaces/content-routing'
35
- import type { PubSub } from '@libp2p/interfaces/pubsub'
36
- import type { Registrar, StreamHandler } from '@libp2p/interfaces/registrar'
37
- import type { ConnectionManager } from '@libp2p/interfaces/connection-manager'
38
- import type { PeerInfo } from '@libp2p/interfaces/peer-info'
30
+ import { Initializable, Components, isInitializable } from '@libp2p/components'
31
+ import type { PeerId } from '@libp2p/interface-peer-id'
32
+ import type { Connection } from '@libp2p/interface-connection'
33
+ import type { PeerRouting } from '@libp2p/interface-peer-routing'
34
+ import type { ContentRouting } from '@libp2p/interface-content-routing'
35
+ import type { PubSub } from '@libp2p/interface-pubsub'
36
+ import type { Registrar, StreamHandler, StreamHandlerOptions } from '@libp2p/interface-registrar'
37
+ import type { ConnectionManager } from '@libp2p/interface-connection-manager'
38
+ import type { PeerInfo } from '@libp2p/interface-peer-info'
39
39
  import type { Libp2p, Libp2pEvents, Libp2pInit, Libp2pOptions } from './index.js'
40
40
  import { validateConfig } from './config.js'
41
41
  import { createEd25519PeerId } from '@libp2p/peer-id-factory'
42
- import type { PeerStore } from '@libp2p/interfaces/peer-store'
43
- import type { DualDHT } from '@libp2p/interfaces/dht'
42
+ import type { PeerStore } from '@libp2p/interface-peer-store'
43
+ import type { DualDHT } from '@libp2p/interface-dht'
44
44
  import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
45
45
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
46
46
  import errCode from 'err-code'
47
47
  import { unmarshalPublicKey } from '@libp2p/crypto/keys'
48
- import type { Metrics } from '@libp2p/interfaces/metrics'
48
+ import type { Metrics } from '@libp2p/interface-metrics'
49
49
  import { DummyDHT } from './dht/dummy-dht.js'
50
50
  import { DummyPubSub } from './pubsub/dummy-pubsub.js'
51
51
  import { PeerSet } from '@libp2p/peer-collections'
@@ -124,7 +124,8 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
124
124
  // Set up the Upgrader
125
125
  this.components.setUpgrader(new DefaultUpgrader(this.components, {
126
126
  connectionEncryption: (init.connectionEncryption ?? []).map(component => this.configureComponent(component)),
127
- muxers: (init.streamMuxers ?? []).map(component => this.configureComponent(component))
127
+ muxers: (init.streamMuxers ?? []).map(component => this.configureComponent(component)),
128
+ inboundUpgradeTimeout: init.connectionManager.inboundUpgradeTimeout
128
129
  }))
129
130
 
130
131
  // Create the Connection Manager
@@ -217,7 +218,7 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
217
218
  })))
218
219
 
219
220
  if (init.relay.enabled) {
220
- this.components.getTransportManager().add(this.configureComponent(new Circuit()))
221
+ this.components.getTransportManager().add(this.configureComponent(new Circuit(init.relay)))
221
222
 
222
223
  this.configureComponent(new Relay(this.components, {
223
224
  addressSorter: init.connectionManager.addressSorter,
@@ -309,18 +310,6 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
309
310
  )
310
311
 
311
312
  log('libp2p has started')
312
-
313
- // Once we start, emit any peers we may have already discovered
314
- // TODO: this should be removed, as we already discovered these peers in the past
315
- await this.components.getPeerStore().forEach(peer => {
316
- this.dispatchEvent(new CustomEvent<PeerInfo>('peer:discovery', {
317
- detail: {
318
- id: peer.id,
319
- multiaddrs: peer.addresses.map(addr => addr.multiaddr),
320
- protocols: peer.protocols
321
- }
322
- }))
323
- })
324
313
  } catch (err: any) {
325
314
  log.error('An error occurred starting libp2p', err)
326
315
  await this.stop()
@@ -490,12 +479,28 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
490
479
  return await this.pingService.ping(id, options)
491
480
  }
492
481
 
493
- async handle (protocols: string | string[], handler: StreamHandler): Promise<void> {
494
- return await this.components.getRegistrar().handle(protocols, handler)
482
+ async handle (protocols: string | string[], handler: StreamHandler, options?: StreamHandlerOptions): Promise<void> {
483
+ if (!Array.isArray(protocols)) {
484
+ protocols = [protocols]
485
+ }
486
+
487
+ await Promise.all(
488
+ protocols.map(async protocol => {
489
+ await this.components.getRegistrar().handle(protocol, handler, options)
490
+ })
491
+ )
495
492
  }
496
493
 
497
494
  async unhandle (protocols: string[] | string): Promise<void> {
498
- return await this.components.getRegistrar().unhandle(protocols)
495
+ if (!Array.isArray(protocols)) {
496
+ protocols = [protocols]
497
+ }
498
+
499
+ await Promise.all(
500
+ protocols.map(async protocol => {
501
+ await this.components.getRegistrar().unhandle(protocol)
502
+ })
503
+ )
499
504
  }
500
505
 
501
506
  /**