libp2p 0.44.0-e3deaa40 → 0.44.0-ed2fa794
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/dist/index.min.js +17 -17
- package/dist/src/autonat/constants.d.ts +16 -2
- package/dist/src/autonat/constants.d.ts.map +1 -1
- package/dist/src/autonat/constants.js +16 -2
- package/dist/src/autonat/constants.js.map +1 -1
- package/dist/src/autonat/index.d.ts +9 -30
- package/dist/src/autonat/index.d.ts.map +1 -1
- package/dist/src/autonat/index.js +22 -18
- package/dist/src/autonat/index.js.map +1 -1
- package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/server/index.js +3 -0
- package/dist/src/circuit-relay/server/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/discovery.js +2 -2
- package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
- package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/index.js +4 -6
- package/dist/src/circuit-relay/transport/index.js.map +1 -1
- package/dist/src/circuit-relay/transport/listener.d.ts +0 -3
- package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/listener.js +27 -24
- package/dist/src/circuit-relay/transport/listener.js.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.d.ts +2 -4
- package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
- package/dist/src/circuit-relay/transport/reservation-store.js +28 -26
- package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +0 -55
- package/dist/src/config.js.map +1 -1
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
- package/dist/src/connection-manager/dial-queue.js +11 -0
- package/dist/src/connection-manager/dial-queue.js.map +1 -1
- package/dist/src/index.d.ts +2 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p.d.ts.map +1 -1
- package/dist/src/libp2p.js +0 -1
- package/dist/src/libp2p.js.map +1 -1
- package/dist/src/peer-routing.d.ts +1 -38
- package/dist/src/peer-routing.d.ts.map +1 -1
- package/dist/src/peer-routing.js +0 -60
- package/dist/src/peer-routing.js.map +1 -1
- package/dist/src/transport-manager.d.ts +5 -1
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/transport-manager.js +10 -1
- package/dist/src/transport-manager.js.map +1 -1
- package/dist/src/upgrader.d.ts.map +1 -1
- package/dist/src/upgrader.js +3 -2
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/upnp-nat/index.d.ts +2 -2
- 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/package.json +2 -2
- package/src/autonat/constants.ts +17 -2
- package/src/autonat/index.ts +37 -30
- package/src/circuit-relay/server/index.ts +4 -0
- package/src/circuit-relay/transport/discovery.ts +2 -2
- package/src/circuit-relay/transport/index.ts +4 -7
- package/src/circuit-relay/transport/listener.ts +35 -29
- package/src/circuit-relay/transport/reservation-store.ts +21 -15
- package/src/config.ts +0 -55
- package/src/connection-manager/dial-queue.ts +11 -0
- package/src/index.ts +2 -7
- package/src/libp2p.ts +0 -1
- package/src/peer-routing.ts +1 -103
- package/src/transport-manager.ts +13 -1
- package/src/upgrader.ts +3 -3
- package/src/upnp-nat/index.ts +2 -2
- package/src/version.ts +1 -1
|
@@ -91,7 +91,7 @@ export class RelayDiscovery extends EventEmitter<RelayDiscoveryEvents> implement
|
|
|
91
91
|
log('searching peer store for relays')
|
|
92
92
|
const peers = (await this.peerStore.all())
|
|
93
93
|
// filter by a list of peers supporting RELAY_V2_HOP and ones we are not listening on
|
|
94
|
-
.filter(({
|
|
94
|
+
.filter(({ protocols }) => protocols.includes(RELAY_V2_HOP_CODEC))
|
|
95
95
|
.sort(() => Math.random() - 0.5)
|
|
96
96
|
|
|
97
97
|
for (const peer of peers) {
|
|
@@ -112,11 +112,11 @@ export class RelayDiscovery extends EventEmitter<RelayDiscoveryEvents> implement
|
|
|
112
112
|
const peerId = provider.id
|
|
113
113
|
|
|
114
114
|
found++
|
|
115
|
-
log('found relay peer %p in content routing', peerId)
|
|
116
115
|
await this.peerStore.merge(peerId, {
|
|
117
116
|
multiaddrs: provider.multiaddrs
|
|
118
117
|
})
|
|
119
118
|
|
|
119
|
+
log('found relay peer %p in content routing', peerId)
|
|
120
120
|
this.safeDispatchEvent('relay:discover', { detail: peerId })
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -84,7 +84,6 @@ class CircuitRelayTransport implements Transport {
|
|
|
84
84
|
private readonly upgrader: Upgrader
|
|
85
85
|
private readonly addressManager: AddressManager
|
|
86
86
|
private readonly connectionGater: ConnectionGater
|
|
87
|
-
private readonly events: EventEmitter<Libp2pEvents>
|
|
88
87
|
private readonly reservationStore: ReservationStore
|
|
89
88
|
private started: boolean
|
|
90
89
|
|
|
@@ -96,7 +95,6 @@ class CircuitRelayTransport implements Transport {
|
|
|
96
95
|
this.upgrader = components.upgrader
|
|
97
96
|
this.addressManager = components.addressManager
|
|
98
97
|
this.connectionGater = components.connectionGater
|
|
99
|
-
this.events = components.events
|
|
100
98
|
|
|
101
99
|
if (init.discoverRelays != null && init.discoverRelays > 0) {
|
|
102
100
|
this.discovery = new RelayDiscovery(components)
|
|
@@ -170,7 +168,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
170
168
|
const destinationId = destinationAddr.getPeerId()
|
|
171
169
|
|
|
172
170
|
if (relayId == null || destinationId == null) {
|
|
173
|
-
const errMsg =
|
|
171
|
+
const errMsg = `Circuit relay dial to ${ma.toString()} failed as address did not have peer ids`
|
|
174
172
|
log.error(errMsg)
|
|
175
173
|
throw new CodeError(errMsg, codes.ERR_RELAYED_DIAL)
|
|
176
174
|
}
|
|
@@ -203,7 +201,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
203
201
|
disconnectOnFailure
|
|
204
202
|
})
|
|
205
203
|
} catch (err: any) {
|
|
206
|
-
log.error(
|
|
204
|
+
log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${relayPeer.toString()} failed`, err)
|
|
207
205
|
disconnectOnFailure && await relayConnection.close()
|
|
208
206
|
throw err
|
|
209
207
|
}
|
|
@@ -244,7 +242,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
244
242
|
log('new outbound connection %s', maConn.remoteAddr)
|
|
245
243
|
return await this.upgrader.upgradeOutbound(maConn)
|
|
246
244
|
} catch (err) {
|
|
247
|
-
log.error(
|
|
245
|
+
log.error(`Circuit relay dial to destination ${destinationPeer.toString()} via relay ${connection.remotePeer.toString()} failed`, err)
|
|
248
246
|
disconnectOnFailure && await connection.close()
|
|
249
247
|
throw err
|
|
250
248
|
}
|
|
@@ -256,8 +254,7 @@ class CircuitRelayTransport implements Transport {
|
|
|
256
254
|
createListener (options: CreateListenerOptions): Listener {
|
|
257
255
|
return createListener({
|
|
258
256
|
connectionManager: this.connectionManager,
|
|
259
|
-
relayStore: this.reservationStore
|
|
260
|
-
events: this.events
|
|
257
|
+
relayStore: this.reservationStore
|
|
261
258
|
})
|
|
262
259
|
}
|
|
263
260
|
|
|
@@ -7,47 +7,57 @@ import type { ReservationStore } from './reservation-store.js'
|
|
|
7
7
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
8
8
|
import { PeerMap } from '@libp2p/peer-collections'
|
|
9
9
|
import { logger } from '@libp2p/logger'
|
|
10
|
-
import
|
|
10
|
+
import { peerIdFromString } from '@libp2p/peer-id'
|
|
11
|
+
import type { Connection } from '@libp2p/interface-connection'
|
|
12
|
+
import { CodeError } from '@libp2p/interfaces/errors'
|
|
11
13
|
|
|
12
14
|
const log = logger('libp2p:circuit-relay:transport:listener')
|
|
13
15
|
|
|
14
16
|
export interface CircuitRelayTransportListenerComponents {
|
|
15
17
|
connectionManager: ConnectionManager
|
|
16
18
|
relayStore: ReservationStore
|
|
17
|
-
events: EventEmitter<Libp2pEvents>
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> implements Listener {
|
|
21
22
|
private readonly connectionManager: ConnectionManager
|
|
22
23
|
private readonly relayStore: ReservationStore
|
|
23
|
-
private readonly listeningAddrs: PeerMap<Multiaddr>
|
|
24
|
-
private readonly events: EventEmitter<Libp2pEvents>
|
|
24
|
+
private readonly listeningAddrs: PeerMap<Multiaddr[]>
|
|
25
25
|
|
|
26
26
|
constructor (components: CircuitRelayTransportListenerComponents) {
|
|
27
27
|
super()
|
|
28
28
|
|
|
29
29
|
this.connectionManager = components.connectionManager
|
|
30
30
|
this.relayStore = components.relayStore
|
|
31
|
-
this.events = components.events
|
|
32
31
|
this.listeningAddrs = new PeerMap()
|
|
33
32
|
|
|
34
33
|
// remove listening addrs when a relay is removed
|
|
35
34
|
this.relayStore.addEventListener('relay:removed', (evt) => {
|
|
36
35
|
this.#removeRelayPeer(evt.detail)
|
|
37
36
|
})
|
|
38
|
-
|
|
39
|
-
// remove listening addrs when a peer disconnects
|
|
40
|
-
this.events.addEventListener('connection:close', (evt) => {
|
|
41
|
-
this.#removeRelayPeer(evt.detail.remotePeer)
|
|
42
|
-
})
|
|
43
37
|
}
|
|
44
38
|
|
|
45
39
|
async listen (addr: Multiaddr): Promise<void> {
|
|
46
40
|
log('listen on %s', addr)
|
|
47
41
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
const relayPeerStr = addr.getPeerId()
|
|
43
|
+
let relayConn: Connection | undefined
|
|
44
|
+
|
|
45
|
+
// check if we already have a connection to the relay
|
|
46
|
+
if (relayPeerStr != null) {
|
|
47
|
+
const relayPeer = peerIdFromString(relayPeerStr)
|
|
48
|
+
const connections = this.connectionManager.getConnectionsMap().get(relayPeer) ?? []
|
|
49
|
+
|
|
50
|
+
if (connections.length > 0) {
|
|
51
|
+
relayConn = connections[0]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// open a new connection as we don't already have one
|
|
56
|
+
if (relayConn == null) {
|
|
57
|
+
const addrString = addr.toString().split('/p2p-circuit').find(a => a !== '')
|
|
58
|
+
const ma = multiaddr(addrString)
|
|
59
|
+
relayConn = await this.connectionManager.openConnection(ma)
|
|
60
|
+
}
|
|
51
61
|
|
|
52
62
|
if (!this.relayStore.hasReservation(relayConn.remotePeer)) {
|
|
53
63
|
// addRelay calls transportManager.listen which calls this listen method
|
|
@@ -55,31 +65,27 @@ class CircuitRelayTransportListener extends EventEmitter<ListenerEvents> impleme
|
|
|
55
65
|
return
|
|
56
66
|
}
|
|
57
67
|
|
|
68
|
+
const reservation = this.relayStore.getReservation(relayConn.remotePeer)
|
|
69
|
+
|
|
70
|
+
if (reservation == null) {
|
|
71
|
+
throw new CodeError('Did not have reservation after making reservation', 'ERR_NO_RESERVATION')
|
|
72
|
+
}
|
|
73
|
+
|
|
58
74
|
if (this.listeningAddrs.has(relayConn.remotePeer)) {
|
|
59
75
|
log('already listening on relay %p', relayConn.remotePeer)
|
|
60
76
|
return
|
|
61
77
|
}
|
|
62
78
|
|
|
63
|
-
|
|
79
|
+
// add all addresses from the relay reservation
|
|
80
|
+
this.listeningAddrs.set(relayConn.remotePeer, reservation.addrs.map(buf => {
|
|
81
|
+
return multiaddr(buf).encapsulate('/p2p-circuit')
|
|
82
|
+
}))
|
|
83
|
+
|
|
64
84
|
this.safeDispatchEvent('listening', {})
|
|
65
85
|
}
|
|
66
86
|
|
|
67
|
-
/**
|
|
68
|
-
* Get fixed up multiaddrs
|
|
69
|
-
*
|
|
70
|
-
* NOTE: This method will grab the peers multiaddrs and expand them such that:
|
|
71
|
-
*
|
|
72
|
-
* a) If it's an existing /p2p-circuit address for a specific relay i.e.
|
|
73
|
-
* `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit` this method will expand the
|
|
74
|
-
* address to `/ip4/0.0.0.0/tcp/0/ipfs/QmRelay/p2p-circuit/ipfs/QmPeer` where
|
|
75
|
-
* `QmPeer` is this peers id
|
|
76
|
-
* b) If it's not a /p2p-circuit address, it will encapsulate the address as a /p2p-circuit
|
|
77
|
-
* addr, such when dialing over a relay with this address, it will create the circuit using
|
|
78
|
-
* the encapsulated transport address. This is useful when for example, a peer should only
|
|
79
|
-
* be dialed over TCP rather than any other transport
|
|
80
|
-
*/
|
|
81
87
|
getAddrs (): Multiaddr[] {
|
|
82
|
-
return [...this.listeningAddrs.values()]
|
|
88
|
+
return [...this.listeningAddrs.values()].flat()
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
async close (): Promise<void> {
|
|
@@ -96,8 +96,8 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
96
96
|
// When a peer disconnects, if we had a reservation on that peer
|
|
97
97
|
// remove the reservation and multiaddr and maybe trigger search
|
|
98
98
|
// for new relays
|
|
99
|
-
this.events.addEventListener('
|
|
100
|
-
this
|
|
99
|
+
this.events.addEventListener('peer:disconnect', (evt) => {
|
|
100
|
+
this.#removeRelay(evt.detail)
|
|
101
101
|
})
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -125,15 +125,15 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
125
125
|
* on the remote peer
|
|
126
126
|
*/
|
|
127
127
|
async addRelay (peerId: PeerId, type: RelayType): Promise<void> {
|
|
128
|
-
|
|
128
|
+
if (this.peerId.equals(peerId)) {
|
|
129
|
+
log('not trying to use self as relay')
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
log('add relay %p', peerId)
|
|
129
134
|
|
|
130
135
|
await this.reserveQueue.add(async () => {
|
|
131
136
|
try {
|
|
132
|
-
if (this.peerId.equals(peerId)) {
|
|
133
|
-
log('not trying to use self as relay')
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
|
|
137
137
|
// allow refresh of an existing reservation if it is about to expire
|
|
138
138
|
const existingReservation = this.reservations.get(peerId)
|
|
139
139
|
|
|
@@ -181,6 +181,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
181
181
|
})
|
|
182
182
|
}, timeoutDuration)
|
|
183
183
|
|
|
184
|
+
// we've managed to create a reservation successfully
|
|
184
185
|
this.reservations.set(peerId, {
|
|
185
186
|
timeout,
|
|
186
187
|
reservation,
|
|
@@ -197,13 +198,13 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
197
198
|
}
|
|
198
199
|
})
|
|
199
200
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return multiaddr(ma).encapsulate('/p2p-circuit')
|
|
203
|
-
})
|
|
204
|
-
)
|
|
201
|
+
// listen on multiaddr that only the circuit transport is listening for
|
|
202
|
+
await this.transportManager.listen([multiaddr(`/p2p/${peerId.toString()}/p2p-circuit`)])
|
|
205
203
|
} catch (err) {
|
|
206
204
|
log.error('could not reserve slot on %p', peerId, err)
|
|
205
|
+
|
|
206
|
+
// if listening failed, remove the reservation
|
|
207
|
+
this.reservations.delete(peerId)
|
|
207
208
|
}
|
|
208
209
|
})
|
|
209
210
|
}
|
|
@@ -212,6 +213,10 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
212
213
|
return this.reservations.has(peerId)
|
|
213
214
|
}
|
|
214
215
|
|
|
216
|
+
getReservation (peerId: PeerId): Reservation | undefined {
|
|
217
|
+
return this.reservations.get(peerId)?.reservation
|
|
218
|
+
}
|
|
219
|
+
|
|
215
220
|
async #createReservation (connection: Connection): Promise<Reservation> {
|
|
216
221
|
log('requesting reservation from %s', connection.remotePeer)
|
|
217
222
|
const stream = await connection.newStream(RELAY_V2_HOP_CODEC)
|
|
@@ -243,14 +248,14 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
243
248
|
/**
|
|
244
249
|
* Remove listen relay
|
|
245
250
|
*/
|
|
246
|
-
removeRelay (peerId: PeerId): void {
|
|
251
|
+
#removeRelay (peerId: PeerId): void {
|
|
247
252
|
const existingReservation = this.reservations.get(peerId)
|
|
248
253
|
|
|
249
254
|
if (existingReservation == null) {
|
|
250
255
|
return
|
|
251
256
|
}
|
|
252
257
|
|
|
253
|
-
log('
|
|
258
|
+
log('connection to relay %p closed, removing reservation from local store', peerId)
|
|
254
259
|
|
|
255
260
|
clearTimeout(existingReservation.timeout)
|
|
256
261
|
this.reservations.delete(peerId)
|
|
@@ -258,6 +263,7 @@ export class ReservationStore extends EventEmitter<ReservationStoreEvents> imple
|
|
|
258
263
|
this.safeDispatchEvent('relay:removed', { detail: peerId })
|
|
259
264
|
|
|
260
265
|
if (this.reservations.size < this.maxDiscoveredRelays) {
|
|
266
|
+
log('not enough relays %d/%d', this.reservations.size, this.maxDiscoveredRelays)
|
|
261
267
|
this.safeDispatchEvent('relay:not-enough-relays', {})
|
|
262
268
|
}
|
|
263
269
|
}
|
package/src/config.ts
CHANGED
|
@@ -24,62 +24,7 @@ const DefaultConfig: Partial<Libp2pInit> = {
|
|
|
24
24
|
},
|
|
25
25
|
transportManager: {
|
|
26
26
|
faultTolerance: FaultTolerance.FATAL_ALL
|
|
27
|
-
},
|
|
28
|
-
peerRouting: {
|
|
29
|
-
refreshManager: {
|
|
30
|
-
enabled: true,
|
|
31
|
-
interval: 6e5,
|
|
32
|
-
bootDelay: 10e3
|
|
33
|
-
}
|
|
34
27
|
}
|
|
35
|
-
/*
|
|
36
|
-
|
|
37
|
-
nat: {
|
|
38
|
-
enabled: true,
|
|
39
|
-
ttl: 7200,
|
|
40
|
-
keepAlive: true
|
|
41
|
-
},
|
|
42
|
-
identify: {
|
|
43
|
-
protocolPrefix: 'ipfs',
|
|
44
|
-
host: {
|
|
45
|
-
agentVersion: AGENT_VERSION
|
|
46
|
-
},
|
|
47
|
-
// https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/identify/id.go#L48
|
|
48
|
-
timeout: 60000,
|
|
49
|
-
maxInboundStreams: 1,
|
|
50
|
-
maxOutboundStreams: 1,
|
|
51
|
-
maxPushIncomingStreams: 1,
|
|
52
|
-
maxPushOutgoingStreams: 1,
|
|
53
|
-
maxObservedAddresses: 10
|
|
54
|
-
},
|
|
55
|
-
ping: {
|
|
56
|
-
protocolPrefix: 'ipfs',
|
|
57
|
-
// See https://github.com/libp2p/specs/blob/d4b5fb0152a6bb86cfd9ea/ping/ping.md?plain=1#L38-L43
|
|
58
|
-
// The dialing peer MUST NOT keep more than one outbound stream for the ping protocol per peer.
|
|
59
|
-
// The listening peer SHOULD accept at most two streams per peer since cross-stream behavior is
|
|
60
|
-
// non-linear and stream writes occur asynchronously. The listening peer may perceive the
|
|
61
|
-
// dialing peer closing and opening the wrong streams (for instance, closing stream B and
|
|
62
|
-
// opening stream A even though the dialing peer is opening stream B and closing stream A).
|
|
63
|
-
maxInboundStreams: 2,
|
|
64
|
-
maxOutboundStreams: 1,
|
|
65
|
-
timeout: 10000
|
|
66
|
-
},
|
|
67
|
-
fetch: {
|
|
68
|
-
protocolPrefix: 'libp2p',
|
|
69
|
-
maxInboundStreams: 1,
|
|
70
|
-
maxOutboundStreams: 1,
|
|
71
|
-
timeout: 10000
|
|
72
|
-
},
|
|
73
|
-
autonat: {
|
|
74
|
-
protocolPrefix: 'libp2p',
|
|
75
|
-
maxInboundStreams: 1,
|
|
76
|
-
maxOutboundStreams: 1,
|
|
77
|
-
timeout: 30000,
|
|
78
|
-
startupDelay: 5000,
|
|
79
|
-
refreshInterval: 60000
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
*/
|
|
83
28
|
}
|
|
84
29
|
|
|
85
30
|
export function validateConfig <T extends ServiceMap = {}> (opts: RecursivePartial<Libp2pInit<T>>): Libp2pInit<T> {
|
|
@@ -23,6 +23,7 @@ import { combineSignals, resolveMultiaddrs } from './utils.js'
|
|
|
23
23
|
import pDefer from 'p-defer'
|
|
24
24
|
import { ClearableSignal, anySignal } from 'any-signal'
|
|
25
25
|
import type { AddressSorter } from '@libp2p/interface-libp2p'
|
|
26
|
+
import { setMaxListeners } from 'events'
|
|
26
27
|
|
|
27
28
|
const log = logger('libp2p:connection-manager:dial-queue')
|
|
28
29
|
|
|
@@ -100,6 +101,11 @@ export class DialQueue {
|
|
|
100
101
|
this.transportManager = components.transportManager
|
|
101
102
|
this.shutDownController = new AbortController()
|
|
102
103
|
|
|
104
|
+
try {
|
|
105
|
+
// This emitter gets listened to a lot
|
|
106
|
+
setMaxListeners?.(Infinity, this.shutDownController.signal)
|
|
107
|
+
} catch {}
|
|
108
|
+
|
|
103
109
|
this.pendingDialCount = components.metrics?.registerMetric('libp2p_dialler_pending_dials')
|
|
104
110
|
this.inProgressDialCount = components.metrics?.registerMetric('libp2p_dialler_in_progress_dials')
|
|
105
111
|
this.pendingDials = []
|
|
@@ -258,6 +264,11 @@ export class DialQueue {
|
|
|
258
264
|
]
|
|
259
265
|
)
|
|
260
266
|
|
|
267
|
+
try {
|
|
268
|
+
// This emitter gets listened to a lot
|
|
269
|
+
setMaxListeners?.(Infinity, signal)
|
|
270
|
+
} catch {}
|
|
271
|
+
|
|
261
272
|
return signal
|
|
262
273
|
}
|
|
263
274
|
|
package/src/index.ts
CHANGED
|
@@ -32,7 +32,6 @@ import type { Components } from './components.js'
|
|
|
32
32
|
import type { Libp2p, ServiceMap } from '@libp2p/interface-libp2p'
|
|
33
33
|
import type { KeyChainInit } from '@libp2p/keychain'
|
|
34
34
|
import type { AddressManagerInit } from './address-manager/index.js'
|
|
35
|
-
import type { PeerRoutingInit } from './peer-routing.js'
|
|
36
35
|
import type { ConnectionManagerInit } from './connection-manager/index.js'
|
|
37
36
|
import type { PersistentPeerStoreInit } from '@libp2p/peer-store'
|
|
38
37
|
|
|
@@ -81,11 +80,6 @@ export interface Libp2pInit<T extends ServiceMap = {}> {
|
|
|
81
80
|
*/
|
|
82
81
|
peerStore: PersistentPeerStoreInit
|
|
83
82
|
|
|
84
|
-
/**
|
|
85
|
-
* libp2p Peer routing service configuration
|
|
86
|
-
*/
|
|
87
|
-
peerRouting: PeerRoutingInit
|
|
88
|
-
|
|
89
83
|
/**
|
|
90
84
|
* keychain configuration
|
|
91
85
|
*/
|
|
@@ -134,11 +128,12 @@ export type Libp2pOptions<T extends ServiceMap = {}> = RecursivePartial<Libp2pIn
|
|
|
134
128
|
* import { tcp } from '@libp2p/tcp'
|
|
135
129
|
* import { mplex } from '@libp2p/mplex'
|
|
136
130
|
* import { noise } from '@chainsafe/libp2p-noise'
|
|
131
|
+
* import { yamux } from '@chainsafe/libp2p-yamux'
|
|
137
132
|
*
|
|
138
133
|
* // specify options
|
|
139
134
|
* const options = {
|
|
140
135
|
* transports: [tcp()],
|
|
141
|
-
* streamMuxers: [mplex()],
|
|
136
|
+
* streamMuxers: [yamux(), mplex()],
|
|
142
137
|
* connectionEncryption: [noise()]
|
|
143
138
|
* }
|
|
144
139
|
*
|
package/src/libp2p.ts
CHANGED
|
@@ -137,7 +137,6 @@ export class Libp2pNode<T extends ServiceMap = {}> extends EventEmitter<Libp2pEv
|
|
|
137
137
|
// Peer routers
|
|
138
138
|
const peerRouters: PeerRouting[] = (init.peerRouters ?? []).map((fn, index) => this.configureComponent(`peer-router-${index}`, fn(this.components)))
|
|
139
139
|
this.peerRouting = this.components.peerRouting = this.configureComponent('peerRouting', new DefaultPeerRouting(this.components, {
|
|
140
|
-
...init.peerRouting,
|
|
141
140
|
routers: peerRouters
|
|
142
141
|
}))
|
|
143
142
|
|
package/src/peer-routing.ts
CHANGED
|
@@ -9,49 +9,17 @@ import {
|
|
|
9
9
|
import merge from 'it-merge'
|
|
10
10
|
import { pipe } from 'it-pipe'
|
|
11
11
|
import first from 'it-first'
|
|
12
|
-
import drain from 'it-drain'
|
|
13
12
|
import filter from 'it-filter'
|
|
14
|
-
import {
|
|
15
|
-
setDelayedInterval,
|
|
16
|
-
clearDelayedInterval
|
|
17
|
-
// @ts-expect-error module with no types
|
|
18
|
-
} from 'set-delayed-interval'
|
|
19
|
-
import { setMaxListeners } from 'events'
|
|
20
13
|
import type { PeerId } from '@libp2p/interface-peer-id'
|
|
21
14
|
import type { PeerRouting } from '@libp2p/interface-peer-routing'
|
|
22
15
|
import type { AbortOptions } from '@libp2p/interfaces'
|
|
23
|
-
import type { Startable } from '@libp2p/interfaces/startable'
|
|
24
16
|
import type { PeerInfo } from '@libp2p/interface-peer-info'
|
|
25
17
|
import type { PeerStore } from '@libp2p/interface-peer-store'
|
|
26
|
-
import { anySignal } from 'any-signal'
|
|
27
18
|
|
|
28
19
|
const log = logger('libp2p:peer-routing')
|
|
29
20
|
|
|
30
|
-
export interface RefreshManagerInit {
|
|
31
|
-
/**
|
|
32
|
-
* Whether to enable the Refresh manager
|
|
33
|
-
*/
|
|
34
|
-
enabled?: boolean
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Boot delay to start the Refresh Manager (in ms)
|
|
38
|
-
*/
|
|
39
|
-
bootDelay?: number
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Interval between each Refresh Manager run (in ms)
|
|
43
|
-
*/
|
|
44
|
-
interval?: number
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* How long to let each refresh run (in ms)
|
|
48
|
-
*/
|
|
49
|
-
timeout?: number
|
|
50
|
-
}
|
|
51
|
-
|
|
52
21
|
export interface PeerRoutingInit {
|
|
53
22
|
routers?: PeerRouting[]
|
|
54
|
-
refreshManager?: RefreshManagerInit
|
|
55
23
|
}
|
|
56
24
|
|
|
57
25
|
export interface DefaultPeerRoutingComponents {
|
|
@@ -59,83 +27,13 @@ export interface DefaultPeerRoutingComponents {
|
|
|
59
27
|
peerStore: PeerStore
|
|
60
28
|
}
|
|
61
29
|
|
|
62
|
-
export class DefaultPeerRouting implements PeerRouting
|
|
30
|
+
export class DefaultPeerRouting implements PeerRouting {
|
|
63
31
|
private readonly components: DefaultPeerRoutingComponents
|
|
64
32
|
private readonly routers: PeerRouting[]
|
|
65
|
-
private readonly refreshManagerInit: RefreshManagerInit
|
|
66
|
-
private timeoutId?: ReturnType<typeof setTimeout>
|
|
67
|
-
private started: boolean
|
|
68
|
-
private abortController?: AbortController
|
|
69
33
|
|
|
70
34
|
constructor (components: DefaultPeerRoutingComponents, init: PeerRoutingInit) {
|
|
71
35
|
this.components = components
|
|
72
36
|
this.routers = init.routers ?? []
|
|
73
|
-
this.refreshManagerInit = init.refreshManager ?? {}
|
|
74
|
-
this.started = false
|
|
75
|
-
|
|
76
|
-
this._findClosestPeersTask = this._findClosestPeersTask.bind(this)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
isStarted (): boolean {
|
|
80
|
-
return this.started
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Start peer routing service.
|
|
85
|
-
*/
|
|
86
|
-
async start (): Promise<void> {
|
|
87
|
-
if (this.started || this.routers.length === 0 || this.timeoutId != null || this.refreshManagerInit.enabled === false) {
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
this.timeoutId = setDelayedInterval(
|
|
92
|
-
this._findClosestPeersTask, this.refreshManagerInit.interval, this.refreshManagerInit.bootDelay
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
this.started = true
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Recurrent task to find closest peers and add their addresses to the Address Book.
|
|
100
|
-
*/
|
|
101
|
-
async _findClosestPeersTask (): Promise<void> {
|
|
102
|
-
if (this.abortController != null) {
|
|
103
|
-
// we are already running the query
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
this.abortController = new AbortController()
|
|
108
|
-
|
|
109
|
-
const signal = anySignal([this.abortController.signal, AbortSignal.timeout(this.refreshManagerInit.timeout ?? 10e3)])
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
// this controller may be used while dialing lots of peers so prevent MaxListenersExceededWarning
|
|
113
|
-
// appearing in the console
|
|
114
|
-
try {
|
|
115
|
-
setMaxListeners?.(Infinity, signal)
|
|
116
|
-
} catch {}
|
|
117
|
-
|
|
118
|
-
// nb getClosestPeers adds the addresses to the address book
|
|
119
|
-
await drain(this.getClosestPeers(this.components.peerId.toBytes(), { signal }))
|
|
120
|
-
} catch (err: any) {
|
|
121
|
-
log.error(err)
|
|
122
|
-
} finally {
|
|
123
|
-
this.abortController?.abort()
|
|
124
|
-
this.abortController = undefined
|
|
125
|
-
signal.clear()
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Stop peer routing service.
|
|
131
|
-
*/
|
|
132
|
-
async stop (): Promise<void> {
|
|
133
|
-
clearDelayedInterval(this.timeoutId)
|
|
134
|
-
|
|
135
|
-
// abort query if it is in-flight
|
|
136
|
-
this.abortController?.abort()
|
|
137
|
-
|
|
138
|
-
this.started = false
|
|
139
37
|
}
|
|
140
38
|
|
|
141
39
|
/**
|
package/src/transport-manager.ts
CHANGED
|
@@ -157,6 +157,13 @@ export class DefaultTransportManager implements TransportManager, Startable {
|
|
|
157
157
|
return Array.of(...this.transports.values())
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Returns all the listener instances
|
|
162
|
+
*/
|
|
163
|
+
getListeners (): Listener[] {
|
|
164
|
+
return Array.of(...this.listeners.values()).flat()
|
|
165
|
+
}
|
|
166
|
+
|
|
160
167
|
/**
|
|
161
168
|
* Finds a transport that matches the given Multiaddr
|
|
162
169
|
*/
|
|
@@ -192,7 +199,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
|
|
|
192
199
|
upgrader: this.components.upgrader
|
|
193
200
|
})
|
|
194
201
|
|
|
195
|
-
let listeners = this.listeners.get(key)
|
|
202
|
+
let listeners: Listener[] = this.listeners.get(key) ?? []
|
|
196
203
|
|
|
197
204
|
if (listeners == null) {
|
|
198
205
|
listeners = []
|
|
@@ -216,6 +223,11 @@ export class DefaultTransportManager implements TransportManager, Startable {
|
|
|
216
223
|
})
|
|
217
224
|
})
|
|
218
225
|
listener.addEventListener('close', () => {
|
|
226
|
+
const index = listeners.findIndex(l => l === listener)
|
|
227
|
+
|
|
228
|
+
// remove the listener
|
|
229
|
+
listeners.splice(index, 1)
|
|
230
|
+
|
|
219
231
|
this.components.peerStore.patch(this.components.peerId, {
|
|
220
232
|
multiaddrs: this.getAddrs()
|
|
221
233
|
})
|
package/src/upgrader.ts
CHANGED
|
@@ -73,7 +73,6 @@ function findIncomingStreamLimit (protocol: string, registrar: Registrar): numbe
|
|
|
73
73
|
function findOutgoingStreamLimit (protocol: string, registrar: Registrar): number | undefined {
|
|
74
74
|
try {
|
|
75
75
|
const { options } = registrar.getHandler(protocol)
|
|
76
|
-
|
|
77
76
|
return options.maxOutboundStreams
|
|
78
77
|
} catch (err: any) {
|
|
79
78
|
if (err.code !== codes.ERR_NO_HANDLER_FOR_PROTOCOL) {
|
|
@@ -392,9 +391,10 @@ export class DefaultUpgrader implements Upgrader {
|
|
|
392
391
|
const streamCount = countStreams(protocol, 'inbound', connection)
|
|
393
392
|
|
|
394
393
|
if (streamCount === incomingLimit) {
|
|
395
|
-
|
|
394
|
+
const err = new CodeError(`Too many inbound protocol streams for protocol "${protocol}" - limit ${incomingLimit}`, codes.ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS)
|
|
395
|
+
muxedStream.abort(err)
|
|
396
396
|
|
|
397
|
-
|
|
397
|
+
throw err
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
// after the handshake the returned stream can have early data so override
|
package/src/upnp-nat/index.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface UPnPNATInit {
|
|
|
50
50
|
/**
|
|
51
51
|
* Whether to automatically refresh UPnP port mappings when their TTL is reached
|
|
52
52
|
*/
|
|
53
|
-
keepAlive
|
|
53
|
+
keepAlive?: boolean
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Pass a value to use instead of auto-detection
|
|
@@ -205,7 +205,7 @@ class UPnPNAT implements Startable {
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
export function
|
|
208
|
+
export function uPnPNATService (init: UPnPNATInit = {}): (components: UPnPNATComponents) => {} {
|
|
209
209
|
return (components: UPnPNATComponents) => {
|
|
210
210
|
return new UPnPNAT(components, init)
|
|
211
211
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '0.44.0-
|
|
1
|
+
export const version = '0.44.0-ed2fa794'
|
|
2
2
|
export const name = 'libp2p'
|