libp2p 0.45.9 → 0.46.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.
- package/README.md +96 -77
- package/dist/index.min.js +27 -27
- package/dist/src/address-manager/index.d.ts +5 -5
- package/dist/src/address-manager/index.d.ts.map +1 -1
- package/dist/src/address-manager/utils.d.ts.map +1 -1
- package/dist/src/address-manager/utils.js.map +1 -1
- package/dist/src/autonat/index.d.ts +26 -6
- package/dist/src/autonat/index.d.ts.map +1 -1
- package/dist/src/autonat/index.js +23 -3
- package/dist/src/autonat/index.js.map +1 -1
- package/dist/src/circuit-relay/index.d.ts +36 -1
- package/dist/src/circuit-relay/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/index.js +35 -0
- package/dist/src/circuit-relay/index.js.map +1 -1
- package/dist/src/circuit-relay/server/advert-service.d.ts +3 -3
- package/dist/src/circuit-relay/server/advert-service.d.ts.map +1 -1
- package/dist/src/circuit-relay/server/advert-service.js +1 -1
- package/dist/src/circuit-relay/server/advert-service.js.map +1 -1
- package/dist/src/circuit-relay/server/index.d.ts +8 -8
- package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/server/index.js +30 -28
- package/dist/src/circuit-relay/server/index.js.map +1 -1
- package/dist/src/circuit-relay/server/reservation-store.d.ts +3 -3
- package/dist/src/circuit-relay/server/reservation-store.d.ts.map +1 -1
- package/dist/src/circuit-relay/server/reservation-voucher.d.ts +2 -2
- package/dist/src/circuit-relay/transport/discovery.d.ts +8 -8
- package/dist/src/circuit-relay/transport/discovery.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/discovery.js +3 -4
- package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
- package/dist/src/circuit-relay/transport/index.d.ts +21 -10
- package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/index.js +52 -25
- package/dist/src/circuit-relay/transport/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/listener.d.ts +2 -2
- package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/listener.js +4 -3
- package/dist/src/circuit-relay/transport/listener.js.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.d.ts +13 -7
- package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.js +24 -10
- package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
- package/dist/src/circuit-relay/utils.d.ts +1 -1
- package/dist/src/components.d.ts +15 -14
- package/dist/src/components.d.ts.map +1 -1
- package/dist/src/components.js +2 -2
- package/dist/src/components.js.map +1 -1
- package/dist/src/config/connection-gater.browser.d.ts +1 -1
- package/dist/src/config/connection-gater.d.ts +1 -1
- package/dist/src/config.d.ts +1 -2
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +2 -2
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection/index.d.ts +22 -13
- package/dist/src/connection/index.d.ts.map +1 -1
- package/dist/src/connection/index.js +54 -30
- package/dist/src/connection/index.js.map +1 -1
- package/dist/src/connection-manager/auto-dial.d.ts +5 -5
- package/dist/src/connection-manager/auto-dial.d.ts.map +1 -1
- package/dist/src/connection-manager/auto-dial.js +3 -1
- package/dist/src/connection-manager/auto-dial.js.map +1 -1
- package/dist/src/connection-manager/connection-pruner.d.ts +4 -4
- package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
- package/dist/src/connection-manager/connection-pruner.js +2 -2
- package/dist/src/connection-manager/connection-pruner.js.map +1 -1
- package/dist/src/connection-manager/constants.d.ts.map +1 -1
- package/dist/src/connection-manager/constants.js.map +1 -1
- package/dist/src/connection-manager/dial-queue.d.ts +11 -17
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
- package/dist/src/connection-manager/dial-queue.js +6 -6
- package/dist/src/connection-manager/dial-queue.js.map +1 -1
- package/dist/src/connection-manager/index.d.ts +11 -12
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/connection-manager/index.js +17 -11
- package/dist/src/connection-manager/index.js.map +1 -1
- package/dist/src/content-routing/index.d.ts +5 -5
- package/dist/src/content-routing/index.d.ts.map +1 -1
- package/dist/src/content-routing/index.js +1 -1
- package/dist/src/content-routing/index.js.map +1 -1
- package/dist/src/content-routing/utils.d.ts +2 -2
- package/dist/src/content-routing/utils.js +1 -1
- package/dist/src/content-routing/utils.js.map +1 -1
- package/dist/src/fetch/constants.d.ts.map +1 -1
- package/dist/src/fetch/constants.js.map +1 -1
- package/dist/src/fetch/index.d.ts +5 -5
- package/dist/src/fetch/index.d.ts.map +1 -1
- package/dist/src/fetch/index.js +5 -5
- package/dist/src/fetch/index.js.map +1 -1
- package/dist/src/get-peer.d.ts +1 -1
- package/dist/src/get-peer.js +2 -2
- package/dist/src/get-peer.js.map +1 -1
- package/dist/src/identify/consts.d.ts.map +1 -1
- package/dist/src/identify/consts.js.map +1 -1
- package/dist/src/identify/identify.d.ts +8 -7
- package/dist/src/identify/identify.d.ts.map +1 -1
- package/dist/src/identify/identify.js +66 -72
- package/dist/src/identify/identify.js.map +1 -1
- package/dist/src/identify/index.d.ts +28 -9
- package/dist/src/identify/index.d.ts.map +1 -1
- package/dist/src/identify/index.js.map +1 -1
- package/dist/src/index.d.ts +11 -12
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/insecure/index.d.ts +1 -1
- package/dist/src/insecure/index.js +1 -1
- package/dist/src/insecure/index.js.map +1 -1
- package/dist/src/libp2p.d.ts +13 -13
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +13 -8
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/peer-routing.d.ts +5 -5
- package/dist/src/peer-routing.d.ts.map +1 -1
- package/dist/src/peer-routing.js +1 -1
- package/dist/src/peer-routing.js.map +1 -1
- package/dist/src/ping/constants.d.ts.map +1 -1
- package/dist/src/ping/constants.js.map +1 -1
- package/dist/src/ping/index.d.ts +5 -4
- package/dist/src/ping/index.d.ts.map +1 -1
- package/dist/src/ping/index.js +32 -21
- package/dist/src/ping/index.js.map +1 -1
- package/dist/src/pnet/index.d.ts +1 -1
- package/dist/src/pnet/index.js +1 -1
- package/dist/src/pnet/index.js.map +1 -1
- package/dist/src/registrar.d.ts +7 -6
- package/dist/src/registrar.d.ts.map +1 -1
- package/dist/src/registrar.js +7 -11
- package/dist/src/registrar.js.map +1 -1
- package/dist/src/transport-manager.d.ts +9 -9
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/transport-manager.js +7 -4
- package/dist/src/transport-manager.js.map +1 -1
- package/dist/src/upgrader.d.ts +13 -12
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +37 -26
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/upnp-nat/index.d.ts +4 -4
- package/dist/src/upnp-nat/index.d.ts.map +1 -1
- package/dist/src/upnp-nat/index.js +1 -1
- package/dist/src/upnp-nat/index.js.map +1 -1
- package/dist/src/utils/peer-job-queue.d.ts +1 -1
- package/dist/src/utils/peer-job-queue.js +1 -1
- package/dist/src/utils/peer-job-queue.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +52 -85
- package/src/address-manager/README.md +1 -1
- package/src/address-manager/index.ts +5 -5
- package/src/address-manager/utils.ts +0 -1
- package/src/autonat/index.ts +33 -12
- package/src/circuit-relay/index.ts +37 -1
- package/src/circuit-relay/server/advert-service.ts +3 -3
- package/src/circuit-relay/server/index.ts +41 -38
- package/src/circuit-relay/server/reservation-store.ts +3 -3
- package/src/circuit-relay/server/reservation-voucher.ts +2 -2
- package/src/circuit-relay/transport/discovery.ts +10 -11
- package/src/circuit-relay/transport/index.ts +76 -38
- package/src/circuit-relay/transport/listener.ts +9 -7
- package/src/circuit-relay/transport/reservation-store.ts +41 -18
- package/src/circuit-relay/utils.ts +1 -1
- package/src/components.ts +16 -15
- package/src/config/connection-gater.browser.ts +1 -1
- package/src/config/connection-gater.ts +1 -1
- package/src/config.ts +3 -4
- package/src/connection/index.ts +82 -40
- package/src/connection-manager/auto-dial.ts +8 -6
- package/src/connection-manager/connection-pruner.ts +6 -6
- package/src/connection-manager/constants.ts +0 -1
- package/src/connection-manager/dial-queue.ts +20 -27
- package/src/connection-manager/index.ts +27 -22
- package/src/content-routing/index.ts +6 -6
- package/src/content-routing/utils.ts +3 -3
- package/src/fetch/constants.ts +0 -1
- package/src/fetch/index.ts +11 -11
- package/src/get-peer.ts +3 -3
- package/src/identify/consts.ts +0 -1
- package/src/identify/identify.ts +85 -92
- package/src/identify/index.ts +32 -8
- package/src/index.ts +11 -12
- package/src/insecure/index.ts +3 -3
- package/src/libp2p.ts +24 -18
- package/src/peer-routing.ts +6 -6
- package/src/ping/constants.ts +0 -1
- package/src/ping/index.ts +45 -27
- package/src/pnet/index.ts +2 -2
- package/src/registrar.ts +14 -17
- package/src/transport-manager.ts +16 -12
- package/src/upgrader.ts +52 -39
- package/src/upnp-nat/index.ts +5 -5
- package/src/utils/peer-job-queue.ts +2 -2
- package/src/version.ts +1 -1
- package/dist/src/pubsub/dummy-pubsub.d.ts +0 -18
- package/dist/src/pubsub/dummy-pubsub.d.ts.map +0 -1
- package/dist/src/pubsub/dummy-pubsub.js +0 -38
- package/dist/src/pubsub/dummy-pubsub.js.map +0 -1
- package/src/pubsub/dummy-pubsub.ts +0 -53
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { CodeError } from '@libp2p/
|
|
2
|
-
import { EventEmitter } from '@libp2p/
|
|
1
|
+
import { CodeError } from '@libp2p/interface/errors'
|
|
2
|
+
import { EventEmitter } from '@libp2p/interface/events'
|
|
3
3
|
import { logger } from '@libp2p/logger'
|
|
4
4
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
5
5
|
import { peerIdFromString } from '@libp2p/peer-id'
|
|
6
6
|
import { multiaddr } from '@multiformats/multiaddr'
|
|
7
7
|
import type { ReservationStore } from './reservation-store.js'
|
|
8
|
-
import type { Connection } from '@libp2p/interface
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
11
|
-
import type {
|
|
8
|
+
import type { Connection } from '@libp2p/interface/connection'
|
|
9
|
+
import type { PeerId } from '@libp2p/interface/peer-id'
|
|
10
|
+
import type { Listener, ListenerEvents } from '@libp2p/interface/transport'
|
|
11
|
+
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
|
|
12
12
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
13
13
|
|
|
14
14
|
const log = logger('libp2p:circuit-relay:transport:listener')
|
|
@@ -37,7 +37,7 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
async listen (addr: Multiaddr): Promise<void> {
|
|
40
|
-
log('listen on %
|
|
40
|
+
log('listen on %a', addr)
|
|
41
41
|
|
|
42
42
|
const relayPeerStr = addr.getPeerId()
|
|
43
43
|
let relayConn: Connection | undefined
|
|
@@ -95,6 +95,8 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
|
|
|
95
95
|
#removeRelayPeer (peerId: PeerId): void {
|
|
96
96
|
const had = this.listeningAddrs.has(peerId)
|
|
97
97
|
|
|
98
|
+
log('relay peer removed %p - had reservation', peerId, had)
|
|
99
|
+
|
|
98
100
|
this.listeningAddrs.delete(peerId)
|
|
99
101
|
|
|
100
102
|
if (had) {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { EventEmitter } from '@libp2p/
|
|
1
|
+
import { EventEmitter } from '@libp2p/interface/events'
|
|
2
2
|
import { logger } from '@libp2p/logger'
|
|
3
3
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
4
4
|
import { multiaddr } from '@multiformats/multiaddr'
|
|
5
|
-
import { pbStream } from 'it-
|
|
5
|
+
import { pbStream } from 'it-protobuf-stream'
|
|
6
6
|
import { PeerJobQueue } from '../../utils/peer-job-queue.js'
|
|
7
7
|
import { DEFAULT_RESERVATION_CONCURRENCY, RELAY_TAG, RELAY_V2_HOP_CODEC } from '../constants.js'
|
|
8
8
|
import { HopMessage, Status } from '../pb/index.js'
|
|
9
9
|
import { getExpirationMilliseconds } from '../utils.js'
|
|
10
10
|
import type { Reservation } from '../pb/index.js'
|
|
11
|
-
import type {
|
|
12
|
-
import type {
|
|
13
|
-
import type {
|
|
14
|
-
import type {
|
|
15
|
-
import type {
|
|
16
|
-
import type {
|
|
17
|
-
import type {
|
|
11
|
+
import type { Libp2pEvents, AbortOptions } from '@libp2p/interface'
|
|
12
|
+
import type { Connection } from '@libp2p/interface/connection'
|
|
13
|
+
import type { PeerId } from '@libp2p/interface/peer-id'
|
|
14
|
+
import type { PeerStore } from '@libp2p/interface/peer-store'
|
|
15
|
+
import type { Startable } from '@libp2p/interface/startable'
|
|
16
|
+
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
|
|
17
|
+
import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
|
|
18
18
|
|
|
19
19
|
const log = logger('libp2p:circuit-relay:transport:reservation-store')
|
|
20
20
|
|
|
@@ -55,6 +55,12 @@ export interface RelayStoreInit {
|
|
|
55
55
|
* Limit the number of potential relays we will dial (default: 100)
|
|
56
56
|
*/
|
|
57
57
|
maxReservationQueueLength?: number
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* When creating a reservation it must complete within this number of ms
|
|
61
|
+
* (default: 5000)
|
|
62
|
+
*/
|
|
63
|
+
reservationCompletionTimeout?: number
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
export type RelayType = 'discovered' | 'configured'
|
|
@@ -80,6 +86,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
80
86
|
private readonly reservations: PeerMap<RelayEntry>
|
|
81
87
|
private readonly maxDiscoveredRelays: number
|
|
82
88
|
private readonly maxReservationQueueLength: number
|
|
89
|
+
private readonly reservationCompletionTimeout: number
|
|
83
90
|
private started: boolean
|
|
84
91
|
|
|
85
92
|
constructor (components: RelayStoreComponents, init?: RelayStoreInit) {
|
|
@@ -93,6 +100,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
93
100
|
this.reservations = new PeerMap()
|
|
94
101
|
this.maxDiscoveredRelays = init?.discoverRelays ?? 0
|
|
95
102
|
this.maxReservationQueueLength = init?.maxReservationQueueLength ?? 100
|
|
103
|
+
this.reservationCompletionTimeout = init?.reservationCompletionTimeout ?? 10000
|
|
96
104
|
this.started = false
|
|
97
105
|
|
|
98
106
|
// ensure we don't listen on multiple relays simultaneously
|
|
@@ -117,12 +125,12 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
async stop (): Promise<void> {
|
|
128
|
+
this.reserveQueue.clear()
|
|
120
129
|
this.reservations.forEach(({ timeout }) => {
|
|
121
130
|
clearTimeout(timeout)
|
|
122
131
|
})
|
|
123
132
|
this.reservations.clear()
|
|
124
|
-
|
|
125
|
-
this.started = true
|
|
133
|
+
this.started = false
|
|
126
134
|
}
|
|
127
135
|
|
|
128
136
|
/**
|
|
@@ -175,14 +183,20 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
175
183
|
return
|
|
176
184
|
}
|
|
177
185
|
|
|
178
|
-
const
|
|
186
|
+
const signal = AbortSignal.timeout(this.reservationCompletionTimeout)
|
|
187
|
+
|
|
188
|
+
const connection = await this.connectionManager.openConnection(peerId, {
|
|
189
|
+
signal
|
|
190
|
+
})
|
|
179
191
|
|
|
180
192
|
if (connection.remoteAddr.protoNames().includes('p2p-circuit')) {
|
|
181
193
|
log('not creating reservation over relayed connection')
|
|
182
194
|
return
|
|
183
195
|
}
|
|
184
196
|
|
|
185
|
-
const reservation = await this.#createReservation(connection
|
|
197
|
+
const reservation = await this.#createReservation(connection, {
|
|
198
|
+
signal
|
|
199
|
+
})
|
|
186
200
|
|
|
187
201
|
log('created reservation on relay peer %p', peerId)
|
|
188
202
|
|
|
@@ -220,6 +234,13 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
220
234
|
} catch (err) {
|
|
221
235
|
log.error('could not reserve slot on %p', peerId, err)
|
|
222
236
|
|
|
237
|
+
// cancel the renewal timeout if it's been set
|
|
238
|
+
const reservation = this.reservations.get(peerId)
|
|
239
|
+
|
|
240
|
+
if (reservation != null) {
|
|
241
|
+
clearTimeout(reservation.timeout)
|
|
242
|
+
}
|
|
243
|
+
|
|
223
244
|
// if listening failed, remove the reservation
|
|
224
245
|
this.reservations.delete(peerId)
|
|
225
246
|
}
|
|
@@ -236,22 +257,24 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
236
257
|
return this.reservations.get(peerId)?.reservation
|
|
237
258
|
}
|
|
238
259
|
|
|
239
|
-
async #createReservation (connection: Connection): Promise<Reservation> {
|
|
240
|
-
|
|
260
|
+
async #createReservation (connection: Connection, options: AbortOptions): Promise<Reservation> {
|
|
261
|
+
options.signal?.throwIfAborted()
|
|
262
|
+
|
|
263
|
+
log('requesting reservation from %p', connection.remotePeer)
|
|
241
264
|
const stream = await connection.newStream(RELAY_V2_HOP_CODEC)
|
|
242
265
|
const pbstr = pbStream(stream)
|
|
243
266
|
const hopstr = pbstr.pb(HopMessage)
|
|
244
|
-
hopstr.write({ type: HopMessage.Type.RESERVE })
|
|
267
|
+
await hopstr.write({ type: HopMessage.Type.RESERVE }, options)
|
|
245
268
|
|
|
246
269
|
let response: HopMessage
|
|
247
270
|
|
|
248
271
|
try {
|
|
249
|
-
response = await hopstr.read()
|
|
272
|
+
response = await hopstr.read(options)
|
|
250
273
|
} catch (err: any) {
|
|
251
274
|
log.error('error parsing reserve message response from %p because', connection.remotePeer, err)
|
|
252
275
|
throw err
|
|
253
276
|
} finally {
|
|
254
|
-
stream.close()
|
|
277
|
+
await stream.close()
|
|
255
278
|
}
|
|
256
279
|
|
|
257
280
|
if (response.status === Status.OK && (response.reservation != null)) {
|
|
@@ -5,7 +5,7 @@ import { CID } from 'multiformats/cid'
|
|
|
5
5
|
import { sha256 } from 'multiformats/hashes/sha2'
|
|
6
6
|
import { DEFAULT_DATA_LIMIT, DEFAULT_DURATION_LIMIT } from './constants.js'
|
|
7
7
|
import type { Limit } from './pb/index.js'
|
|
8
|
-
import type { Stream } from '@libp2p/interface
|
|
8
|
+
import type { Stream } from '@libp2p/interface/connection'
|
|
9
9
|
import type { Source } from 'it-stream-types'
|
|
10
10
|
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
11
11
|
|
package/src/components.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { CodeError } from '@libp2p/
|
|
2
|
-
import { isStartable, type Startable } from '@libp2p/
|
|
3
|
-
import type {
|
|
4
|
-
import type { ConnectionProtector } from '@libp2p/interface
|
|
5
|
-
import type { ConnectionGater } from '@libp2p/interface
|
|
6
|
-
import type {
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
11
|
-
import type {
|
|
12
|
-
import type {
|
|
13
|
-
import type {
|
|
14
|
-
import type {
|
|
15
|
-
import type {
|
|
1
|
+
import { CodeError } from '@libp2p/interface/errors'
|
|
2
|
+
import { isStartable, type Startable } from '@libp2p/interface/startable'
|
|
3
|
+
import type { Libp2pEvents } from '@libp2p/interface'
|
|
4
|
+
import type { ConnectionProtector } from '@libp2p/interface/connection'
|
|
5
|
+
import type { ConnectionGater } from '@libp2p/interface/connection-gater'
|
|
6
|
+
import type { ContentRouting } from '@libp2p/interface/content-routing'
|
|
7
|
+
import type { EventEmitter } from '@libp2p/interface/events'
|
|
8
|
+
import type { Metrics } from '@libp2p/interface/metrics'
|
|
9
|
+
import type { PeerId } from '@libp2p/interface/peer-id'
|
|
10
|
+
import type { PeerRouting } from '@libp2p/interface/peer-routing'
|
|
11
|
+
import type { PeerStore } from '@libp2p/interface/peer-store'
|
|
12
|
+
import type { Upgrader } from '@libp2p/interface/transport'
|
|
13
|
+
import type { AddressManager } from '@libp2p/interface-internal/address-manager'
|
|
14
|
+
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
|
|
15
|
+
import type { Registrar } from '@libp2p/interface-internal/registrar'
|
|
16
|
+
import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
|
|
16
17
|
import type { Datastore } from 'interface-datastore'
|
|
17
18
|
|
|
18
19
|
export interface Components extends Record<string, any>, Startable {
|
package/src/config.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { CodeError } from '@libp2p/interface/errors'
|
|
2
|
+
import { FaultTolerance } from '@libp2p/interface/transport'
|
|
3
3
|
import { publicAddressesFirst } from '@libp2p/utils/address-sort'
|
|
4
4
|
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
|
5
5
|
import mergeOptions from 'merge-options'
|
|
6
6
|
import { codes, messages } from './errors.js'
|
|
7
7
|
import type { Libp2pInit } from './index.js'
|
|
8
|
-
import type { ServiceMap } from '@libp2p/interface
|
|
9
|
-
import type { RecursivePartial } from '@libp2p/interfaces'
|
|
8
|
+
import type { ServiceMap, RecursivePartial } from '@libp2p/interface'
|
|
10
9
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
11
10
|
|
|
12
11
|
const DefaultConfig: Partial<Libp2pInit> = {
|
package/src/connection/index.ts
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { CodeError } from '@libp2p/
|
|
1
|
+
import { setMaxListeners } from 'events'
|
|
2
|
+
import { symbol } from '@libp2p/interface/connection'
|
|
3
|
+
import { CodeError } from '@libp2p/interface/errors'
|
|
4
4
|
import { logger } from '@libp2p/logger'
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
7
|
-
import type {
|
|
5
|
+
import type { AbortOptions } from '@libp2p/interface'
|
|
6
|
+
import type { Direction, Connection, Stream, ConnectionTimeline, ConnectionStatus, NewStreamOptions } from '@libp2p/interface/connection'
|
|
7
|
+
import type { PeerId } from '@libp2p/interface/peer-id'
|
|
8
8
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
9
9
|
|
|
10
10
|
const log = logger('libp2p:connection')
|
|
11
11
|
|
|
12
|
+
const CLOSE_TIMEOUT = 500
|
|
13
|
+
|
|
12
14
|
interface ConnectionInit {
|
|
13
15
|
remoteAddr: Multiaddr
|
|
14
16
|
remotePeer: PeerId
|
|
15
17
|
newStream: (protocols: string[], options?: AbortOptions) => Promise<Stream>
|
|
16
|
-
close: () => Promise<void>
|
|
18
|
+
close: (options?: AbortOptions) => Promise<void>
|
|
19
|
+
abort: (err: Error) => void
|
|
17
20
|
getStreams: () => Stream[]
|
|
18
|
-
|
|
21
|
+
status: ConnectionStatus
|
|
22
|
+
direction: Direction
|
|
23
|
+
timeline: ConnectionTimeline
|
|
24
|
+
multiplexer?: string
|
|
25
|
+
encryption?: string
|
|
26
|
+
transient?: boolean
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
/**
|
|
@@ -38,10 +46,12 @@ export class ConnectionImpl implements Connection {
|
|
|
38
46
|
*/
|
|
39
47
|
public readonly remotePeer: PeerId
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
public
|
|
49
|
+
public direction: Direction
|
|
50
|
+
public timeline: ConnectionTimeline
|
|
51
|
+
public multiplexer?: string
|
|
52
|
+
public encryption?: string
|
|
53
|
+
public status: ConnectionStatus
|
|
54
|
+
public transient: boolean
|
|
45
55
|
|
|
46
56
|
/**
|
|
47
57
|
* User provided tags
|
|
@@ -52,39 +62,42 @@ export class ConnectionImpl implements Connection {
|
|
|
52
62
|
/**
|
|
53
63
|
* Reference to the new stream function of the multiplexer
|
|
54
64
|
*/
|
|
55
|
-
private readonly _newStream: (protocols: string[], options?:
|
|
65
|
+
private readonly _newStream: (protocols: string[], options?: NewStreamOptions) => Promise<Stream>
|
|
56
66
|
|
|
57
67
|
/**
|
|
58
68
|
* Reference to the close function of the raw connection
|
|
59
69
|
*/
|
|
60
|
-
private readonly _close: () => Promise<void>
|
|
70
|
+
private readonly _close: (options?: AbortOptions) => Promise<void>
|
|
71
|
+
|
|
72
|
+
private readonly _abort: (err: Error) => void
|
|
61
73
|
|
|
62
74
|
/**
|
|
63
75
|
* Reference to the getStreams function of the muxer
|
|
64
76
|
*/
|
|
65
77
|
private readonly _getStreams: () => Stream[]
|
|
66
78
|
|
|
67
|
-
private _closing: boolean
|
|
68
|
-
|
|
69
79
|
/**
|
|
70
80
|
* An implementation of the js-libp2p connection.
|
|
71
81
|
* Any libp2p transport should use an upgrader to return this connection.
|
|
72
82
|
*/
|
|
73
83
|
constructor (init: ConnectionInit) {
|
|
74
|
-
const { remoteAddr, remotePeer, newStream, close,
|
|
84
|
+
const { remoteAddr, remotePeer, newStream, close, abort, getStreams } = init
|
|
75
85
|
|
|
76
86
|
this.id = `${(parseInt(String(Math.random() * 1e9))).toString(36)}${Date.now()}`
|
|
77
87
|
this.remoteAddr = remoteAddr
|
|
78
88
|
this.remotePeer = remotePeer
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
this.direction = init.direction
|
|
90
|
+
this.status = 'open'
|
|
91
|
+
this.timeline = init.timeline
|
|
92
|
+
this.multiplexer = init.multiplexer
|
|
93
|
+
this.encryption = init.encryption
|
|
94
|
+
this.transient = init.transient ?? false
|
|
95
|
+
|
|
83
96
|
this._newStream = newStream
|
|
84
97
|
this._close = close
|
|
98
|
+
this._abort = abort
|
|
85
99
|
this._getStreams = getStreams
|
|
86
100
|
this.tags = []
|
|
87
|
-
this._closing = false
|
|
88
101
|
}
|
|
89
102
|
|
|
90
103
|
readonly [Symbol.toStringTag] = 'Connection'
|
|
@@ -101,12 +114,12 @@ export class ConnectionImpl implements Connection {
|
|
|
101
114
|
/**
|
|
102
115
|
* Create a new stream from this connection
|
|
103
116
|
*/
|
|
104
|
-
async newStream (protocols: string | string[], options?:
|
|
105
|
-
if (this.
|
|
117
|
+
async newStream (protocols: string | string[], options?: NewStreamOptions): Promise<Stream> {
|
|
118
|
+
if (this.status === 'closing') {
|
|
106
119
|
throw new CodeError('the connection is being closed', 'ERR_CONNECTION_BEING_CLOSED')
|
|
107
120
|
}
|
|
108
121
|
|
|
109
|
-
if (this.
|
|
122
|
+
if (this.status === 'closed') {
|
|
110
123
|
throw new CodeError('the connection is closed', 'ERR_CONNECTION_CLOSED')
|
|
111
124
|
}
|
|
112
125
|
|
|
@@ -114,9 +127,13 @@ export class ConnectionImpl implements Connection {
|
|
|
114
127
|
protocols = [protocols]
|
|
115
128
|
}
|
|
116
129
|
|
|
130
|
+
if (this.transient && options?.runOnTransientConnection !== true) {
|
|
131
|
+
throw new CodeError('Cannot open protocol stream on transient connection', 'ERR_TRANSIENT_CONNECTION')
|
|
132
|
+
}
|
|
133
|
+
|
|
117
134
|
const stream = await this._newStream(protocols, options)
|
|
118
135
|
|
|
119
|
-
stream.
|
|
136
|
+
stream.direction = 'outbound'
|
|
120
137
|
|
|
121
138
|
return stream
|
|
122
139
|
}
|
|
@@ -125,7 +142,7 @@ export class ConnectionImpl implements Connection {
|
|
|
125
142
|
* Add a stream when it is opened to the registry
|
|
126
143
|
*/
|
|
127
144
|
addStream (stream: Stream): void {
|
|
128
|
-
stream.
|
|
145
|
+
stream.direction = 'inbound'
|
|
129
146
|
}
|
|
130
147
|
|
|
131
148
|
/**
|
|
@@ -138,27 +155,52 @@ export class ConnectionImpl implements Connection {
|
|
|
138
155
|
/**
|
|
139
156
|
* Close the connection
|
|
140
157
|
*/
|
|
141
|
-
async close (): Promise<void> {
|
|
142
|
-
if (this.
|
|
158
|
+
async close (options: AbortOptions = {}): Promise<void> {
|
|
159
|
+
if (this.status === 'closed' || this.status === 'closing') {
|
|
143
160
|
return
|
|
144
161
|
}
|
|
145
162
|
|
|
146
|
-
this.
|
|
163
|
+
log('closing connection to %a', this.remoteAddr)
|
|
164
|
+
|
|
165
|
+
this.status = 'closing'
|
|
166
|
+
|
|
167
|
+
options.signal = options?.signal ?? AbortSignal.timeout(CLOSE_TIMEOUT)
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// fails on node < 15.4
|
|
171
|
+
setMaxListeners?.(Infinity, options.signal)
|
|
172
|
+
} catch { }
|
|
147
173
|
|
|
148
|
-
// close all streams - this can throw if we're not multiplexed
|
|
149
174
|
try {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
175
|
+
// close all streams gracefully - this can throw if we're not multiplexed
|
|
176
|
+
await Promise.all(
|
|
177
|
+
this.streams.map(async s => s.close(options))
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
// Close raw connection
|
|
181
|
+
await this._close(options)
|
|
182
|
+
|
|
183
|
+
this.timeline.close = Date.now()
|
|
184
|
+
this.status = 'closed'
|
|
185
|
+
} catch (err: any) {
|
|
186
|
+
log.error('error encountered during graceful close of connection to %a', this.remoteAddr, err)
|
|
187
|
+
this.abort(err)
|
|
153
188
|
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
abort (err: Error): void {
|
|
192
|
+
log.error('aborting connection to %a due to error', this.remoteAddr, err)
|
|
193
|
+
|
|
194
|
+
this.status = 'closing'
|
|
195
|
+
this.streams.forEach(s => { s.abort(err) })
|
|
196
|
+
|
|
197
|
+
log.error('all streams aborted', this.streams.length)
|
|
154
198
|
|
|
155
|
-
//
|
|
156
|
-
this.
|
|
157
|
-
await this._close()
|
|
158
|
-
this._closing = false
|
|
199
|
+
// Abort raw connection
|
|
200
|
+
this._abort(err)
|
|
159
201
|
|
|
160
|
-
this.
|
|
161
|
-
this.
|
|
202
|
+
this.timeline.close = Date.now()
|
|
203
|
+
this.status = 'closed'
|
|
162
204
|
}
|
|
163
205
|
}
|
|
164
206
|
|
|
@@ -2,11 +2,11 @@ import { logger } from '@libp2p/logger'
|
|
|
2
2
|
import { PeerMap, PeerSet } from '@libp2p/peer-collections'
|
|
3
3
|
import { PeerJobQueue } from '../utils/peer-job-queue.js'
|
|
4
4
|
import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_INTERVAL, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PRIORITY, MIN_CONNECTIONS } from './constants.js'
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
7
|
-
import type { PeerStore } from '@libp2p/interface
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
5
|
+
import type { Libp2pEvents } from '@libp2p/interface'
|
|
6
|
+
import type { EventEmitter } from '@libp2p/interface/events'
|
|
7
|
+
import type { PeerStore } from '@libp2p/interface/peer-store'
|
|
8
|
+
import type { Startable } from '@libp2p/interface/startable'
|
|
9
|
+
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
|
|
10
10
|
|
|
11
11
|
const log = logger('libp2p:connection-manager:auto-dial')
|
|
12
12
|
|
|
@@ -113,7 +113,9 @@ export class AutoDial implements Startable {
|
|
|
113
113
|
|
|
114
114
|
// Already has enough connections
|
|
115
115
|
if (numConnections >= this.minConnections) {
|
|
116
|
-
|
|
116
|
+
if (this.minConnections > 0) {
|
|
117
|
+
log.trace('have enough connections %d/%d', numConnections, this.minConnections)
|
|
118
|
+
}
|
|
117
119
|
return
|
|
118
120
|
}
|
|
119
121
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { logger } from '@libp2p/logger'
|
|
2
2
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
3
3
|
import { MAX_CONNECTIONS } from './constants.js'
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
6
|
-
import type { PeerStore } from '@libp2p/interface
|
|
7
|
-
import type {
|
|
4
|
+
import type { Libp2pEvents } from '@libp2p/interface'
|
|
5
|
+
import type { EventEmitter } from '@libp2p/interface/events'
|
|
6
|
+
import type { PeerStore } from '@libp2p/interface/peer-store'
|
|
7
|
+
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
|
|
8
8
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
9
9
|
|
|
10
10
|
const log = logger('libp2p:connection-manager:connection-pruner')
|
|
@@ -106,8 +106,8 @@ export class ConnectionPruner {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// if the peers have an equal tag value then we want to close short-lived connections first
|
|
109
|
-
const connectionALifespan = a.
|
|
110
|
-
const connectionBLifespan = b.
|
|
109
|
+
const connectionALifespan = a.timeline.open
|
|
110
|
+
const connectionBLifespan = b.timeline.open
|
|
111
111
|
|
|
112
112
|
if (connectionALifespan < connectionBLifespan) {
|
|
113
113
|
return 1
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { setMaxListeners } from 'events'
|
|
2
|
-
import { AbortError, CodeError } from '@libp2p/
|
|
2
|
+
import { AbortError, CodeError } from '@libp2p/interface/errors'
|
|
3
3
|
import { logger } from '@libp2p/logger'
|
|
4
4
|
import { publicAddressesFirst } from '@libp2p/utils/address-sort'
|
|
5
5
|
import { type Multiaddr, type Resolver, resolvers } from '@multiformats/multiaddr'
|
|
@@ -16,27 +16,16 @@ import {
|
|
|
16
16
|
MAX_PEER_ADDRS_TO_DIAL
|
|
17
17
|
} from './constants.js'
|
|
18
18
|
import { combineSignals, resolveMultiaddrs } from './utils.js'
|
|
19
|
-
import type {
|
|
20
|
-
import type {
|
|
21
|
-
import type {
|
|
22
|
-
import type { Metric, Metrics } from '@libp2p/interface
|
|
23
|
-
import type { PeerId } from '@libp2p/interface
|
|
24
|
-
import type { Address, PeerStore } from '@libp2p/interface
|
|
25
|
-
import type { TransportManager } from '@libp2p/interface-transport'
|
|
26
|
-
import type { AbortOptions } from '@libp2p/interfaces'
|
|
19
|
+
import type { AddressSorter, AbortOptions, PendingDial } from '@libp2p/interface'
|
|
20
|
+
import type { Connection } from '@libp2p/interface/connection'
|
|
21
|
+
import type { ConnectionGater } from '@libp2p/interface/connection-gater'
|
|
22
|
+
import type { Metric, Metrics } from '@libp2p/interface/metrics'
|
|
23
|
+
import type { PeerId } from '@libp2p/interface/peer-id'
|
|
24
|
+
import type { Address, PeerStore } from '@libp2p/interface/peer-store'
|
|
25
|
+
import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
|
|
27
26
|
|
|
28
27
|
const log = logger('libp2p:connection-manager:dial-queue')
|
|
29
28
|
|
|
30
|
-
export type PendingDialStatus = 'queued' | 'active' | 'error' | 'success'
|
|
31
|
-
|
|
32
|
-
export interface PendingDial {
|
|
33
|
-
id: string
|
|
34
|
-
status: PendingDialStatus
|
|
35
|
-
peerId?: PeerId
|
|
36
|
-
multiaddrs: Multiaddr[]
|
|
37
|
-
promise: Promise<Connection>
|
|
38
|
-
}
|
|
39
|
-
|
|
40
29
|
export interface PendingDialTarget {
|
|
41
30
|
resolve: (value: any) => void
|
|
42
31
|
reject: (err: Error) => void
|
|
@@ -46,6 +35,10 @@ export interface DialOptions extends AbortOptions {
|
|
|
46
35
|
priority?: number
|
|
47
36
|
}
|
|
48
37
|
|
|
38
|
+
interface PendingDialInternal extends PendingDial {
|
|
39
|
+
promise: Promise<Connection>
|
|
40
|
+
}
|
|
41
|
+
|
|
49
42
|
interface DialerInit {
|
|
50
43
|
addressSorter?: AddressSorter
|
|
51
44
|
maxParallelDials?: number
|
|
@@ -75,7 +68,7 @@ interface DialQueueComponents {
|
|
|
75
68
|
}
|
|
76
69
|
|
|
77
70
|
export class DialQueue {
|
|
78
|
-
public pendingDials:
|
|
71
|
+
public pendingDials: PendingDialInternal[]
|
|
79
72
|
public queue: PQueue
|
|
80
73
|
private readonly peerId: PeerId
|
|
81
74
|
private readonly peerStore: PeerStore
|
|
@@ -219,7 +212,7 @@ export class DialQueue {
|
|
|
219
212
|
|
|
220
213
|
log('creating dial target for', addrsToDial.map(({ multiaddr }) => multiaddr.toString()))
|
|
221
214
|
// @ts-expect-error .promise property is set below
|
|
222
|
-
const pendingDial:
|
|
215
|
+
const pendingDial: PendingDialInternal = {
|
|
223
216
|
id: randomId(),
|
|
224
217
|
status: 'queued',
|
|
225
218
|
peerId,
|
|
@@ -395,7 +388,7 @@ export class DialQueue {
|
|
|
395
388
|
return sortedGatedAddrs
|
|
396
389
|
}
|
|
397
390
|
|
|
398
|
-
private async performDial (pendingDial:
|
|
391
|
+
private async performDial (pendingDial: PendingDialInternal, options: DialOptions = {}): Promise<Connection> {
|
|
399
392
|
const dialAbortControllers: Array<(AbortController | undefined)> = pendingDial.multiaddrs.map(() => new AbortController())
|
|
400
393
|
|
|
401
394
|
try {
|
|
@@ -419,13 +412,13 @@ export class DialQueue {
|
|
|
419
412
|
// let any signal abort the dial
|
|
420
413
|
const signal = combineSignals(controller.signal, options.signal)
|
|
421
414
|
signal.addEventListener('abort', () => {
|
|
422
|
-
log('dial to %
|
|
415
|
+
log('dial to %a aborted', addr)
|
|
423
416
|
})
|
|
424
417
|
const deferred = pDefer<Connection>()
|
|
425
418
|
|
|
426
419
|
await peerDialQueue.add(async () => {
|
|
427
420
|
if (signal.aborted) {
|
|
428
|
-
log('dial to %
|
|
421
|
+
log('dial to %a was aborted before reaching the head of the peer dial queue', addr)
|
|
429
422
|
deferred.reject(new AbortError())
|
|
430
423
|
return
|
|
431
424
|
}
|
|
@@ -434,7 +427,7 @@ export class DialQueue {
|
|
|
434
427
|
await this.queue.add(async () => {
|
|
435
428
|
try {
|
|
436
429
|
if (signal.aborted) {
|
|
437
|
-
log('dial to %
|
|
430
|
+
log('dial to %a was aborted before reaching the head of the dial queue', addr)
|
|
438
431
|
deferred.reject(new AbortError())
|
|
439
432
|
return
|
|
440
433
|
}
|
|
@@ -469,13 +462,13 @@ export class DialQueue {
|
|
|
469
462
|
}
|
|
470
463
|
})
|
|
471
464
|
|
|
472
|
-
log('dial to %
|
|
465
|
+
log('dial to %a succeeded', addr)
|
|
473
466
|
|
|
474
467
|
// resolve the connection promise
|
|
475
468
|
deferred.resolve(conn)
|
|
476
469
|
} catch (err: any) {
|
|
477
470
|
// something only went wrong if our signal was not aborted
|
|
478
|
-
log.error('error during dial of %
|
|
471
|
+
log.error('error during dial of %a', addr, err)
|
|
479
472
|
deferred.reject(err)
|
|
480
473
|
}
|
|
481
474
|
}, {
|