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
@@ -1,70 +1,43 @@
1
- import { logger } from '@libp2p/logger'
2
- import { CodeError } from '@libp2p/interfaces/errors'
3
- import * as lp from 'it-length-prefixed'
4
- import { pipe } from 'it-pipe'
5
- import first from 'it-first'
6
- import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
7
- import { Multiaddr, multiaddr, protocols } from '@multiformats/multiaddr'
8
1
  import { Identify } from './pb/message.js'
9
- import { RecordEnvelope, PeerRecord } from '@libp2p/peer-record'
10
2
  import {
11
3
  MULTICODEC_IDENTIFY,
12
- MULTICODEC_IDENTIFY_PUSH,
13
- IDENTIFY_PROTOCOL_VERSION,
14
- MULTICODEC_IDENTIFY_PROTOCOL_NAME,
15
- MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME,
16
- MULTICODEC_IDENTIFY_PROTOCOL_VERSION,
17
- MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION
4
+ MULTICODEC_IDENTIFY_PUSH
18
5
  } from './consts.js'
19
- import { codes } from '../errors.js'
20
- import type { IncomingStreamData, Registrar } from '@libp2p/interface-registrar'
21
- import type { Connection, Stream } from '@libp2p/interface-connection'
22
- import type { Startable } from '@libp2p/interfaces/startable'
23
- import { peerIdFromKeys } from '@libp2p/peer-id'
24
- import { TimeoutController } from 'timeout-abort-controller'
25
- import type { AbortOptions } from '@libp2p/interfaces'
26
- import { abortableDuplex } from 'abortable-iterator'
27
- import { setMaxListeners } from 'events'
6
+ import type { Registrar } from '@libp2p/interface-registrar'
28
7
  import type { ConnectionManager } from '@libp2p/interface-connection-manager'
29
8
  import type { PeerId } from '@libp2p/interface-peer-id'
30
9
  import type { PeerStore } from '@libp2p/interface-peer-store'
31
10
  import type { AddressManager } from '@libp2p/interface-address-manager'
32
-
33
- const log = logger('libp2p:identify')
34
-
35
- // https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L52
36
- const MAX_IDENTIFY_MESSAGE_SIZE = 1024 * 8
37
-
38
- export interface HostProperties {
39
- agentVersion: string
40
- }
11
+ import type { EventEmitter } from '@libp2p/interfaces/events'
12
+ import type { Libp2pEvents } from '@libp2p/interface-libp2p'
13
+ import { DefaultIdentifyService } from './identify.js'
41
14
 
42
15
  export interface IdentifyServiceInit {
43
16
  /**
44
17
  * The prefix to use for the protocol (default: 'ipfs')
45
18
  */
46
- protocolPrefix: string
19
+ protocolPrefix?: string
47
20
 
48
21
  /**
49
22
  * What details we should send as part of an identify message
50
23
  */
51
- host: HostProperties
24
+ agentVersion?: string
52
25
 
53
26
  /**
54
27
  * How long we should wait for a remote peer to send their identify response
55
28
  */
56
- timeout: number
29
+ timeout?: number
57
30
 
58
31
  /**
59
32
  * Identify responses larger than this in bytes will be rejected (default: 8192)
60
33
  */
61
34
  maxIdentifyMessageSize?: number
62
35
 
63
- maxInboundStreams: number
64
- maxOutboundStreams: number
36
+ maxInboundStreams?: number
37
+ maxOutboundStreams?: number
65
38
 
66
- maxPushIncomingStreams: number
67
- maxPushOutgoingStreams: number
39
+ maxPushIncomingStreams?: number
40
+ maxPushOutgoingStreams?: number
68
41
  maxObservedAddresses?: number
69
42
  }
70
43
 
@@ -74,474 +47,7 @@ export interface IdentifyServiceComponents {
74
47
  connectionManager: ConnectionManager
75
48
  registrar: Registrar
76
49
  addressManager: AddressManager
77
- }
78
-
79
- export class IdentifyService implements Startable {
80
- private readonly components: IdentifyServiceComponents
81
- private readonly identifyProtocolStr: string
82
- private readonly identifyPushProtocolStr: string
83
- public readonly host: {
84
- protocolVersion: string
85
- agentVersion: string
86
- }
87
-
88
- private readonly init: IdentifyServiceInit
89
- private started: boolean
90
-
91
- constructor (components: IdentifyServiceComponents, init: IdentifyServiceInit) {
92
- this.components = components
93
- this.started = false
94
- this.init = init
95
-
96
- this.identifyProtocolStr = `/${init.protocolPrefix}/${MULTICODEC_IDENTIFY_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PROTOCOL_VERSION}`
97
- this.identifyPushProtocolStr = `/${init.protocolPrefix}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION}`
98
-
99
- // Store self host metadata
100
- this.host = {
101
- protocolVersion: `${init.protocolPrefix}/${IDENTIFY_PROTOCOL_VERSION}`,
102
- ...init.host
103
- }
104
-
105
- // When a new connection happens, trigger identify
106
- this.components.connectionManager.addEventListener('peer:connect', (evt) => {
107
- const connection = evt.detail
108
- this.identify(connection).catch(log.error)
109
- })
110
-
111
- // When self multiaddrs change, trigger identify-push
112
- this.components.peerStore.addEventListener('change:multiaddrs', (evt) => {
113
- const { peerId } = evt.detail
114
-
115
- if (this.components.peerId.equals(peerId)) {
116
- void this.pushToPeerStore().catch(err => { log.error(err) })
117
- }
118
- })
119
-
120
- // When self protocols change, trigger identify-push
121
- this.components.peerStore.addEventListener('change:protocols', (evt) => {
122
- const { peerId } = evt.detail
123
-
124
- if (this.components.peerId.equals(peerId)) {
125
- void this.pushToPeerStore().catch(err => { log.error(err) })
126
- }
127
- })
128
- }
129
-
130
- isStarted (): boolean {
131
- return this.started
132
- }
133
-
134
- async start (): Promise<void> {
135
- if (this.started) {
136
- return
137
- }
138
-
139
- await this.components.peerStore.metadataBook.setValue(this.components.peerId, 'AgentVersion', uint8ArrayFromString(this.host.agentVersion))
140
- await this.components.peerStore.metadataBook.setValue(this.components.peerId, 'ProtocolVersion', uint8ArrayFromString(this.host.protocolVersion))
141
-
142
- await this.components.registrar.handle(this.identifyProtocolStr, (data) => {
143
- void this._handleIdentify(data).catch(err => {
144
- log.error(err)
145
- })
146
- }, {
147
- maxInboundStreams: this.init.maxInboundStreams,
148
- maxOutboundStreams: this.init.maxOutboundStreams
149
- })
150
- await this.components.registrar.handle(this.identifyPushProtocolStr, (data) => {
151
- void this._handlePush(data).catch(err => {
152
- log.error(err)
153
- })
154
- }, {
155
- maxInboundStreams: this.init.maxPushIncomingStreams,
156
- maxOutboundStreams: this.init.maxPushOutgoingStreams
157
- })
158
-
159
- this.started = true
160
- }
161
-
162
- async stop (): Promise<void> {
163
- await this.components.registrar.unhandle(this.identifyProtocolStr)
164
- await this.components.registrar.unhandle(this.identifyPushProtocolStr)
165
-
166
- this.started = false
167
- }
168
-
169
- /**
170
- * Send an Identify Push update to the list of connections
171
- */
172
- async push (connections: Connection[]): Promise<void> {
173
- const signedPeerRecord = await this.components.peerStore.addressBook.getRawEnvelope(this.components.peerId)
174
- const listenAddrs = this.components.addressManager.getAddresses().map((ma) => ma.bytes)
175
- const protocols = await this.components.peerStore.protoBook.get(this.components.peerId)
176
-
177
- const pushes = connections.map(async connection => {
178
- let stream: Stream | undefined
179
- const timeoutController = new TimeoutController(this.init.timeout)
180
-
181
- try {
182
- // fails on node < 15.4
183
- setMaxListeners?.(Infinity, timeoutController.signal)
184
- } catch {}
185
-
186
- try {
187
- stream = await connection.newStream([this.identifyPushProtocolStr], {
188
- signal: timeoutController.signal
189
- })
190
-
191
- // make stream abortable
192
- const source = abortableDuplex(stream, timeoutController.signal)
193
-
194
- await source.sink(pipe(
195
- [Identify.encode({
196
- listenAddrs,
197
- signedPeerRecord,
198
- protocols
199
- })],
200
- (source) => lp.encode(source)
201
- ))
202
- } catch (err: any) {
203
- // Just log errors
204
- log.error('could not push identify update to peer', err)
205
- } finally {
206
- if (stream != null) {
207
- stream.close()
208
- }
209
-
210
- timeoutController.clear()
211
- }
212
- })
213
-
214
- await Promise.all(pushes)
215
- }
216
-
217
- /**
218
- * Calls `push` on all peer connections
219
- */
220
- async pushToPeerStore (): Promise<void> {
221
- // Do not try to push if we are not running
222
- if (!this.isStarted()) {
223
- return
224
- }
225
-
226
- const connections: Connection[] = []
227
-
228
- for (const conn of this.components.connectionManager.getConnections()) {
229
- const peerId = conn.remotePeer
230
- const peer = await this.components.peerStore.get(peerId)
231
-
232
- if (!peer.protocols.includes(this.identifyPushProtocolStr)) {
233
- continue
234
- }
235
-
236
- connections.push(conn)
237
- }
238
-
239
- await this.push(connections)
240
- }
241
-
242
- async _identify (connection: Connection, options: AbortOptions = {}): Promise<Identify> {
243
- let timeoutController
244
- let signal = options.signal
245
- let stream: Stream | undefined
246
-
247
- // create a timeout if no abort signal passed
248
- if (signal == null) {
249
- timeoutController = new TimeoutController(this.init.timeout)
250
- signal = timeoutController.signal
251
-
252
- try {
253
- // fails on node < 15.4
254
- setMaxListeners?.(Infinity, timeoutController.signal)
255
- } catch {}
256
- }
257
-
258
- try {
259
- stream = await connection.newStream([this.identifyProtocolStr], {
260
- signal
261
- })
262
-
263
- // make stream abortable
264
- const source = abortableDuplex(stream, signal)
265
-
266
- const data = await pipe(
267
- [],
268
- source,
269
- (source) => lp.decode(source, {
270
- maxDataLength: this.init.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
271
- }),
272
- async (source) => await first(source)
273
- )
274
-
275
- if (data == null) {
276
- throw new CodeError('No data could be retrieved', codes.ERR_CONNECTION_ENDED)
277
- }
278
-
279
- try {
280
- return Identify.decode(data)
281
- } catch (err: any) {
282
- throw new CodeError(String(err), codes.ERR_INVALID_MESSAGE)
283
- }
284
- } finally {
285
- if (timeoutController != null) {
286
- timeoutController.clear()
287
- }
288
-
289
- if (stream != null) {
290
- stream.close()
291
- }
292
- }
293
- }
294
-
295
- /**
296
- * Requests the `Identify` message from peer associated with the given `connection`.
297
- * If the identified peer does not match the `PeerId` associated with the connection,
298
- * an error will be thrown.
299
- */
300
- async identify (connection: Connection, options: AbortOptions = {}): Promise<void> {
301
- const message = await this._identify(connection, options)
302
-
303
- const {
304
- publicKey,
305
- listenAddrs,
306
- protocols,
307
- observedAddr,
308
- signedPeerRecord,
309
- agentVersion,
310
- protocolVersion
311
- } = message
312
-
313
- if (publicKey == null) {
314
- throw new CodeError('public key was missing from identify message', codes.ERR_MISSING_PUBLIC_KEY)
315
- }
316
-
317
- const id = await peerIdFromKeys(publicKey)
318
-
319
- if (!connection.remotePeer.equals(id)) {
320
- throw new CodeError('identified peer does not match the expected peer', codes.ERR_INVALID_PEER)
321
- }
322
-
323
- if (this.components.peerId.equals(id)) {
324
- throw new CodeError('identified peer is our own peer id?', codes.ERR_INVALID_PEER)
325
- }
326
-
327
- // Get the observedAddr if there is one
328
- const cleanObservedAddr = IdentifyService.getCleanMultiaddr(observedAddr)
329
-
330
- if (signedPeerRecord != null) {
331
- log('received signed peer record from %p', id)
332
-
333
- try {
334
- const envelope = await RecordEnvelope.openAndCertify(signedPeerRecord, PeerRecord.DOMAIN)
335
-
336
- if (!envelope.peerId.equals(id)) {
337
- throw new CodeError('identified peer does not match the expected peer', codes.ERR_INVALID_PEER)
338
- }
339
-
340
- if (await this.components.peerStore.addressBook.consumePeerRecord(envelope)) {
341
- await this.components.peerStore.protoBook.set(id, protocols)
342
-
343
- if (agentVersion != null) {
344
- await this.components.peerStore.metadataBook.setValue(id, 'AgentVersion', uint8ArrayFromString(agentVersion))
345
- }
346
-
347
- if (protocolVersion != null) {
348
- await this.components.peerStore.metadataBook.setValue(id, 'ProtocolVersion', uint8ArrayFromString(protocolVersion))
349
- }
350
-
351
- log('identify completed for peer %p with protocols %o', id, protocols)
352
-
353
- return
354
- }
355
- } catch (err: any) {
356
- log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
357
- }
358
- } else {
359
- log('no signed peer record received from %p', id)
360
- }
361
-
362
- log('falling back to legacy addresses from %p', id)
363
-
364
- // LEGACY: Update peers data in PeerStore
365
- try {
366
- await this.components.peerStore.addressBook.set(id, listenAddrs.map((addr) => multiaddr(addr)))
367
- } catch (err: any) {
368
- log.error('received invalid addrs', err)
369
- }
370
-
371
- await this.components.peerStore.protoBook.set(id, protocols)
372
-
373
- if (agentVersion != null) {
374
- await this.components.peerStore.metadataBook.setValue(id, 'AgentVersion', uint8ArrayFromString(agentVersion))
375
- }
376
-
377
- if (protocolVersion != null) {
378
- await this.components.peerStore.metadataBook.setValue(id, 'ProtocolVersion', uint8ArrayFromString(protocolVersion))
379
- }
380
-
381
- log('identify completed for peer %p and protocols %o', id, protocols)
382
- log('our observed address is %s', cleanObservedAddr)
383
-
384
- if (cleanObservedAddr != null &&
385
- this.components.addressManager.getObservedAddrs().length < (this.init.maxObservedAddresses ?? Infinity)) {
386
- log('storing our observed address %s', cleanObservedAddr?.toString())
387
- this.components.addressManager.addObservedAddr(cleanObservedAddr)
388
- }
389
- }
390
-
391
- /**
392
- * Sends the `Identify` response with the Signed Peer Record
393
- * to the requesting peer over the given `connection`
394
- */
395
- async _handleIdentify (data: IncomingStreamData): Promise<void> {
396
- const { connection, stream } = data
397
- const timeoutController = new TimeoutController(this.init.timeout)
398
-
399
- try {
400
- // fails on node < 15.4
401
- setMaxListeners?.(Infinity, timeoutController.signal)
402
- } catch {}
403
-
404
- try {
405
- const publicKey = this.components.peerId.publicKey ?? new Uint8Array(0)
406
- const peerData = await this.components.peerStore.get(this.components.peerId)
407
- const multiaddrs = this.components.addressManager.getAddresses().map(ma => ma.decapsulateCode(protocols('p2p').code))
408
- let signedPeerRecord = peerData.peerRecordEnvelope
409
-
410
- if (multiaddrs.length > 0 && signedPeerRecord == null) {
411
- const peerRecord = new PeerRecord({
412
- peerId: this.components.peerId,
413
- multiaddrs
414
- })
415
-
416
- const envelope = await RecordEnvelope.seal(peerRecord, this.components.peerId)
417
- await this.components.peerStore.addressBook.consumePeerRecord(envelope)
418
- signedPeerRecord = envelope.marshal().subarray()
419
- }
420
-
421
- const message = Identify.encode({
422
- protocolVersion: this.host.protocolVersion,
423
- agentVersion: this.host.agentVersion,
424
- publicKey,
425
- listenAddrs: multiaddrs.map(addr => addr.bytes),
426
- signedPeerRecord,
427
- observedAddr: connection.remoteAddr.bytes,
428
- protocols: peerData.protocols
429
- })
430
-
431
- // make stream abortable
432
- const source = abortableDuplex(stream, timeoutController.signal)
433
-
434
- const msgWithLenPrefix = pipe([message], (source) => lp.encode(source))
435
- await source.sink(msgWithLenPrefix)
436
- } catch (err: any) {
437
- log.error('could not respond to identify request', err)
438
- } finally {
439
- stream.close()
440
- timeoutController.clear()
441
- }
442
- }
443
-
444
- /**
445
- * Reads the Identify Push message from the given `connection`
446
- */
447
- async _handlePush (data: IncomingStreamData): Promise<void> {
448
- const { connection, stream } = data
449
- const timeoutController = new TimeoutController(this.init.timeout)
450
-
451
- try {
452
- // fails on node < 15.4
453
- setMaxListeners?.(Infinity, timeoutController.signal)
454
- } catch {}
455
-
456
- let message: Identify | undefined
457
- try {
458
- // make stream abortable
459
- const source = abortableDuplex(stream, timeoutController.signal)
460
-
461
- const data = await pipe(
462
- [],
463
- source,
464
- (source) => lp.decode(source, {
465
- maxDataLength: this.init.maxIdentifyMessageSize ?? MAX_IDENTIFY_MESSAGE_SIZE
466
- }),
467
- async (source) => await first(source)
468
- )
469
-
470
- if (data != null) {
471
- message = Identify.decode(data)
472
- }
473
- } catch (err: any) {
474
- log.error('received invalid message', err)
475
- return
476
- } finally {
477
- stream.close()
478
- timeoutController.clear()
479
- }
480
-
481
- if (message == null) {
482
- log.error('received invalid message')
483
- return
484
- }
485
-
486
- const id = connection.remotePeer
487
-
488
- if (this.components.peerId.equals(id)) {
489
- log('received push from ourselves?')
490
- return
491
- }
492
-
493
- log('received push from %p', id)
494
-
495
- if (message.signedPeerRecord != null) {
496
- log('received signedPeerRecord in push')
497
-
498
- try {
499
- const envelope = await RecordEnvelope.openAndCertify(message.signedPeerRecord, PeerRecord.DOMAIN)
500
-
501
- if (await this.components.peerStore.addressBook.consumePeerRecord(envelope)) {
502
- log('consumed signedPeerRecord sent in push')
503
-
504
- await this.components.peerStore.protoBook.set(id, message.protocols)
505
- return
506
- } else {
507
- log('failed to consume signedPeerRecord sent in push')
508
- }
509
- } catch (err: any) {
510
- log('received invalid envelope, discard it and fallback to listenAddrs is available', err)
511
- }
512
- } else {
513
- log('did not receive signedPeerRecord in push')
514
- }
515
-
516
- // LEGACY: Update peers data in PeerStore
517
- try {
518
- await this.components.peerStore.addressBook.set(id, message.listenAddrs.map((addr) => multiaddr(addr)))
519
- } catch (err: any) {
520
- log.error('received invalid addrs', err)
521
- }
522
-
523
- // Update the protocols
524
- try {
525
- await this.components.peerStore.protoBook.set(id, message.protocols)
526
- } catch (err: any) {
527
- log.error('received invalid protocols', err)
528
- }
529
-
530
- log('handled push from %p', id)
531
- }
532
-
533
- /**
534
- * Takes the `addr` and converts it to a Multiaddr if possible
535
- */
536
- static getCleanMultiaddr (addr: Uint8Array | string | null | undefined): Multiaddr | undefined {
537
- if (addr != null && addr.length > 0) {
538
- try {
539
- return multiaddr(addr)
540
- } catch {
541
-
542
- }
543
- }
544
- }
50
+ events: EventEmitter<Libp2pEvents>
545
51
  }
546
52
 
547
53
  /**
@@ -553,3 +59,7 @@ export const multicodecs = {
553
59
  }
554
60
 
555
61
  export const Message = { Identify }
62
+
63
+ export function identifyService (init: IdentifyServiceInit = {}): (components: IdentifyServiceComponents) => {} {
64
+ return (components) => new DefaultIdentifyService(components, init)
65
+ }