libp2p 1.5.1 → 1.5.2-3c73707ff

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libp2p",
3
- "version": "1.5.1",
3
+ "version": "1.5.2-3c73707ff",
4
4
  "description": "JavaScript implementation of libp2p, a modular peer to peer network stack",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/libp2p#readme",
@@ -85,16 +85,16 @@
85
85
  "test:webkit": "aegir test -t browser -f \"./dist/test/**/*.spec.js\" -- --browser webkit"
86
86
  },
87
87
  "dependencies": {
88
- "@libp2p/crypto": "^4.1.1",
89
- "@libp2p/interface": "^1.3.1",
90
- "@libp2p/interface-internal": "^1.2.0",
91
- "@libp2p/logger": "^4.0.12",
92
- "@libp2p/multistream-select": "^5.1.9",
93
- "@libp2p/peer-collections": "^5.2.0",
94
- "@libp2p/peer-id": "^4.1.1",
95
- "@libp2p/peer-id-factory": "^4.1.1",
96
- "@libp2p/peer-store": "^10.0.17",
97
- "@libp2p/utils": "^5.4.0",
88
+ "@libp2p/crypto": "4.1.1-3c73707ff",
89
+ "@libp2p/interface": "1.3.1-3c73707ff",
90
+ "@libp2p/interface-internal": "1.2.1-3c73707ff",
91
+ "@libp2p/logger": "4.0.12-3c73707ff",
92
+ "@libp2p/multistream-select": "5.1.9-3c73707ff",
93
+ "@libp2p/peer-collections": "5.2.1-3c73707ff",
94
+ "@libp2p/peer-id": "4.1.1-3c73707ff",
95
+ "@libp2p/peer-id-factory": "4.1.1-3c73707ff",
96
+ "@libp2p/peer-store": "10.0.18-3c73707ff",
97
+ "@libp2p/utils": "5.4.1-3c73707ff",
98
98
  "@multiformats/dns": "^1.0.5",
99
99
  "@multiformats/multiaddr": "^12.2.1",
100
100
  "@multiformats/multiaddr-matcher": "^1.2.0",
@@ -112,13 +112,13 @@
112
112
  },
113
113
  "devDependencies": {
114
114
  "@chainsafe/libp2p-yamux": "^6.0.2",
115
- "@libp2p/circuit-relay-v2": "^1.0.22",
116
- "@libp2p/identify": "^2.0.0",
117
- "@libp2p/interface-compliance-tests": "^5.4.3",
118
- "@libp2p/mplex": "^10.0.22",
119
- "@libp2p/plaintext": "^1.0.22",
120
- "@libp2p/tcp": "^9.0.24",
121
- "@libp2p/websockets": "^8.0.22",
115
+ "@libp2p/circuit-relay-v2": "1.0.23-3c73707ff",
116
+ "@libp2p/identify": "2.0.1-3c73707ff",
117
+ "@libp2p/interface-compliance-tests": "5.4.4-3c73707ff",
118
+ "@libp2p/mplex": "10.0.23-3c73707ff",
119
+ "@libp2p/plaintext": "1.0.23-3c73707ff",
120
+ "@libp2p/tcp": "9.0.25-3c73707ff",
121
+ "@libp2p/websockets": "8.0.23-3c73707ff",
122
122
  "@multiformats/mafmt": "^12.1.6",
123
123
  "aegir": "^42.2.5",
124
124
  "delay": "^6.0.0",
package/src/components.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CodeError } from '@libp2p/interface'
2
2
  import { isStartable, type Startable, type Libp2pEvents, type ComponentLogger, type NodeInfo, type ConnectionProtector, type ConnectionGater, type ContentRouting, type TypedEventTarget, type Metrics, type PeerId, type PeerRouting, type PeerStore, type PrivateKey, type Upgrader } from '@libp2p/interface'
3
3
  import { defaultLogger } from '@libp2p/logger'
4
- import type { AddressManager, ConnectionManager, Registrar, TransportManager } from '@libp2p/interface-internal'
4
+ import type { AddressManager, ConnectionManager, RandomWalk, Registrar, TransportManager } from '@libp2p/interface-internal'
5
5
  import type { DNS } from '@multiformats/dns'
6
6
  import type { Datastore } from 'interface-datastore'
7
7
 
@@ -14,6 +14,7 @@ export interface Components extends Record<string, any>, Startable {
14
14
  addressManager: AddressManager
15
15
  peerStore: PeerStore
16
16
  upgrader: Upgrader
17
+ randomWalk: RandomWalk
17
18
  registrar: Registrar
18
19
  connectionManager: ConnectionManager
19
20
  transportManager: TransportManager
@@ -35,6 +36,7 @@ export interface ComponentsInit {
35
36
  addressManager?: AddressManager
36
37
  peerStore?: PeerStore
37
38
  upgrader?: Upgrader
39
+ randomWalk?: RandomWalk
38
40
  metrics?: Metrics
39
41
  registrar?: Registrar
40
42
  connectionManager?: ConnectionManager
@@ -1,6 +1,7 @@
1
1
  import { PeerMap } from '@libp2p/peer-collections'
2
+ import { safelyCloseConnectionIfUnused } from '@libp2p/utils/close'
2
3
  import { MAX_CONNECTIONS } from './constants.js'
3
- import type { Libp2pEvents, Logger, ComponentLogger, TypedEventTarget, PeerStore } from '@libp2p/interface'
4
+ import type { Libp2pEvents, Logger, ComponentLogger, TypedEventTarget, PeerStore, Connection } from '@libp2p/interface'
4
5
  import type { ConnectionManager } from '@libp2p/interface-internal'
5
6
  import type { Multiaddr } from '@multiformats/multiaddr'
6
7
 
@@ -56,14 +57,13 @@ export class ConnectionPruner {
56
57
  async maybePruneConnections (): Promise<void> {
57
58
  const connections = this.connectionManager.getConnections()
58
59
  const numConnections = connections.length
59
- const toPrune = Math.max(numConnections - this.maxConnections, 0)
60
60
 
61
61
  this.log('checking max connections limit %d/%d', numConnections, this.maxConnections)
62
+
62
63
  if (numConnections <= this.maxConnections) {
63
64
  return
64
65
  }
65
66
 
66
- this.log('max connections limit exceeded %d/%d, pruning %d connection(s)', numConnections, this.maxConnections, toPrune)
67
67
  const peerValues = new PeerMap<number>()
68
68
 
69
69
  // work out peer values
@@ -90,35 +90,10 @@ export class ConnectionPruner {
90
90
  }
91
91
  }
92
92
 
93
- // sort by value, lowest to highest
94
- const sortedConnections = connections.sort((a, b) => {
95
- const peerAValue = peerValues.get(a.remotePeer) ?? 0
96
- const peerBValue = peerValues.get(b.remotePeer) ?? 0
97
-
98
- if (peerAValue > peerBValue) {
99
- return 1
100
- }
101
-
102
- if (peerAValue < peerBValue) {
103
- return -1
104
- }
105
-
106
- // if the peers have an equal tag value then we want to close short-lived connections first
107
- const connectionALifespan = a.timeline.open
108
- const connectionBLifespan = b.timeline.open
109
-
110
- if (connectionALifespan < connectionBLifespan) {
111
- return 1
112
- }
113
-
114
- if (connectionALifespan > connectionBLifespan) {
115
- return -1
116
- }
117
-
118
- return 0
119
- })
93
+ const sortedConnections = this.sortConnections(connections, peerValues)
120
94
 
121
95
  // close some connections
96
+ const toPrune = Math.max(numConnections - this.maxConnections, 0)
122
97
  const toClose = []
123
98
 
124
99
  for (const connection of sortedConnections) {
@@ -141,15 +116,71 @@ export class ConnectionPruner {
141
116
  // close connections
142
117
  await Promise.all(
143
118
  toClose.map(async connection => {
144
- try {
145
- await connection.close()
146
- } catch (err) {
147
- this.log.error(err)
148
- }
119
+ await safelyCloseConnectionIfUnused(connection, {
120
+ signal: AbortSignal.timeout(1000)
121
+ })
149
122
  })
150
123
  )
151
124
 
152
125
  // despatch prune event
153
126
  this.events.safeDispatchEvent('connection:prune', { detail: toClose })
154
127
  }
128
+
129
+ sortConnections (connections: Connection[], peerValues: PeerMap<number>): Connection[] {
130
+ return connections
131
+ // sort by connection age, newest to oldest
132
+ .sort((a, b) => {
133
+ const connectionALifespan = a.timeline.open
134
+ const connectionBLifespan = b.timeline.open
135
+
136
+ if (connectionALifespan < connectionBLifespan) {
137
+ return 1
138
+ }
139
+
140
+ if (connectionALifespan > connectionBLifespan) {
141
+ return -1
142
+ }
143
+
144
+ return 0
145
+ })
146
+ // sort by direction, incoming first then outgoing
147
+ .sort((a, b) => {
148
+ if (a.direction === 'outbound' && b.direction === 'inbound') {
149
+ return 1
150
+ }
151
+
152
+ if (a.direction === 'inbound' && b.direction === 'outbound') {
153
+ return -1
154
+ }
155
+
156
+ return 0
157
+ })
158
+ // sort by number of streams, lowest to highest
159
+ .sort((a, b) => {
160
+ if (a.streams.length > b.streams.length) {
161
+ return 1
162
+ }
163
+
164
+ if (a.streams.length < b.streams.length) {
165
+ return -1
166
+ }
167
+
168
+ return 0
169
+ })
170
+ // sort by tag value, lowest to highest
171
+ .sort((a, b) => {
172
+ const peerAValue = peerValues.get(a.remotePeer) ?? 0
173
+ const peerBValue = peerValues.get(b.remotePeer) ?? 0
174
+
175
+ if (peerAValue > peerBValue) {
176
+ return 1
177
+ }
178
+
179
+ if (peerAValue < peerBValue) {
180
+ return -1
181
+ }
182
+
183
+ return 0
184
+ })
185
+ }
155
186
  }
@@ -2,7 +2,7 @@
2
2
  import { CodeError, AggregateCodeError, ERR_TIMEOUT, setMaxListeners } from '@libp2p/interface'
3
3
  import { PeerMap } from '@libp2p/peer-collections'
4
4
  import { defaultAddressSort } from '@libp2p/utils/address-sort'
5
- import { Queue, type QueueAddOptions } from '@libp2p/utils/queue'
5
+ import { PriorityQueue, type PriorityQueueJobOptions } from '@libp2p/utils/priority-queue'
6
6
  import { type Multiaddr, type Resolver, resolvers, multiaddr } from '@multiformats/multiaddr'
7
7
  import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
8
8
  import { Circuit } from '@multiformats/multiaddr-matcher'
@@ -18,6 +18,7 @@ import {
18
18
  MAX_DIAL_QUEUE_LENGTH
19
19
  } from './constants.js'
20
20
  import { resolveMultiaddrs } from './utils.js'
21
+ import { DEFAULT_DIAL_PRIORITY } from './index.js'
21
22
  import type { AddressSorter, AbortOptions, ComponentLogger, Logger, Connection, ConnectionGater, Metrics, PeerId, Address, PeerStore, PeerRouting, IsDialableOptions } from '@libp2p/interface'
22
23
  import type { TransportManager } from '@libp2p/interface-internal'
23
24
  import type { DNS } from '@multiformats/dns'
@@ -32,7 +33,7 @@ export interface DialOptions extends AbortOptions {
32
33
  force?: boolean
33
34
  }
34
35
 
35
- interface DialQueueJobOptions extends QueueAddOptions {
36
+ interface DialQueueJobOptions extends PriorityQueueJobOptions {
36
37
  peerId?: PeerId
37
38
  multiaddrs: Set<string>
38
39
  }
@@ -70,7 +71,7 @@ interface DialQueueComponents {
70
71
  }
71
72
 
72
73
  export class DialQueue {
73
- public queue: Queue<Connection, DialQueueJobOptions>
74
+ public queue: PriorityQueue<Connection, DialQueueJobOptions>
74
75
  private readonly components: DialQueueComponents
75
76
  private readonly addressSorter: AddressSorter
76
77
  private readonly maxPeerAddrsToDial: number
@@ -97,7 +98,7 @@ export class DialQueue {
97
98
  }
98
99
 
99
100
  // controls dial concurrency
100
- this.queue = new Queue({
101
+ this.queue = new PriorityQueue({
101
102
  concurrency: init.maxParallelDials ?? defaultOptions.maxParallelDials,
102
103
  metricName: 'libp2p_dial_queue',
103
104
  metrics: components.metrics
@@ -277,7 +278,7 @@ export class DialQueue {
277
278
  }
278
279
  }, {
279
280
  peerId,
280
- priority: options.priority,
281
+ priority: options.priority ?? DEFAULT_DIAL_PRIORITY,
281
282
  multiaddrs: new Set(multiaddrs.map(ma => ma.toString())),
282
283
  signal: options.signal
283
284
  })
@@ -8,13 +8,13 @@ import { codes } from '../errors.js'
8
8
  import { getPeerAddress } from '../get-peer.js'
9
9
  import { AutoDial } from './auto-dial.js'
10
10
  import { ConnectionPruner } from './connection-pruner.js'
11
- import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PRIORITY, DIAL_TIMEOUT, INBOUND_CONNECTION_THRESHOLD, MAX_CONNECTIONS, MAX_DIAL_QUEUE_LENGTH, MAX_INCOMING_PENDING_CONNECTIONS, MAX_PARALLEL_DIALS, MAX_PEER_ADDRS_TO_DIAL, MIN_CONNECTIONS } from './constants.js'
11
+ import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PEER_RETRY_THRESHOLD, AUTO_DIAL_PRIORITY, DIAL_TIMEOUT, INBOUND_CONNECTION_THRESHOLD, MAX_CONNECTIONS, MAX_DIAL_QUEUE_LENGTH, MAX_INCOMING_PENDING_CONNECTIONS, MAX_PARALLEL_DIALS, MAX_PEER_ADDRS_TO_DIAL, MIN_CONNECTIONS } from './constants.js'
12
12
  import { DialQueue } from './dial-queue.js'
13
13
  import type { PendingDial, AddressSorter, Libp2pEvents, AbortOptions, ComponentLogger, Logger, Connection, MultiaddrConnection, ConnectionGater, TypedEventTarget, Metrics, PeerId, Peer, PeerStore, Startable, PendingDialStatus, PeerRouting, IsDialableOptions } from '@libp2p/interface'
14
14
  import type { ConnectionManager, OpenConnectionOptions, TransportManager } from '@libp2p/interface-internal'
15
15
  import type { JobStatus } from '@libp2p/utils/queue'
16
16
 
17
- const DEFAULT_DIAL_PRIORITY = 50
17
+ export const DEFAULT_DIAL_PRIORITY = 50
18
18
 
19
19
  export interface ConnectionManagerInit {
20
20
  /**
@@ -147,7 +147,9 @@ const defaultOptions = {
147
147
  maxIncomingPendingConnections: MAX_INCOMING_PENDING_CONNECTIONS,
148
148
  autoDialConcurrency: AUTO_DIAL_CONCURRENCY,
149
149
  autoDialPriority: AUTO_DIAL_PRIORITY,
150
- autoDialMaxQueueLength: AUTO_DIAL_MAX_QUEUE_LENGTH
150
+ autoDialMaxQueueLength: AUTO_DIAL_MAX_QUEUE_LENGTH,
151
+ autoDialPeerRetryThreshold: AUTO_DIAL_PEER_RETRY_THRESHOLD,
152
+ autoDialDiscoveredPeersDebounce: AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE
151
153
  }
152
154
 
153
155
  export interface DefaultConnectionManagerComponents {
@@ -229,6 +231,8 @@ export class DefaultConnectionManager implements ConnectionManager, Startable {
229
231
  minConnections,
230
232
  autoDialConcurrency: init.autoDialConcurrency ?? defaultOptions.autoDialConcurrency,
231
233
  autoDialPriority: init.autoDialPriority ?? defaultOptions.autoDialPriority,
234
+ autoDialPeerRetryThreshold: init.autoDialPeerRetryThreshold ?? defaultOptions.autoDialPeerRetryThreshold,
235
+ autoDialDiscoveredPeersDebounce: init.autoDialDiscoveredPeersDebounce ?? defaultOptions.autoDialDiscoveredPeersDebounce,
232
236
  maxQueueLength: init.autoDialMaxQueueLength ?? defaultOptions.autoDialMaxQueueLength
233
237
  })
234
238
 
package/src/registrar.ts CHANGED
@@ -164,6 +164,11 @@ export class DefaultRegistrar implements Registrar {
164
164
  }
165
165
 
166
166
  for (const topology of topologies.values()) {
167
+ if (topology.filter?.has(remotePeer) === false) {
168
+ continue
169
+ }
170
+
171
+ topology.filter?.remove(remotePeer)
167
172
  topology.onDisconnect?.(remotePeer)
168
173
  }
169
174
  }
@@ -195,6 +200,11 @@ export class DefaultRegistrar implements Registrar {
195
200
  }
196
201
 
197
202
  for (const topology of topologies.values()) {
203
+ if (topology.filter?.has(peer.id) === false) {
204
+ continue
205
+ }
206
+
207
+ topology.filter?.remove(peer.id)
198
208
  topology.onDisconnect?.(peer.id)
199
209
  }
200
210
  }
@@ -222,6 +232,11 @@ export class DefaultRegistrar implements Registrar {
222
232
  continue
223
233
  }
224
234
 
235
+ if (topology.filter?.has(peerId) === true) {
236
+ continue
237
+ }
238
+
239
+ topology.filter?.add(peerId)
225
240
  topology.onConnect?.(peerId, connection)
226
241
  }
227
242
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '1.5.1'
1
+ export const version = '1.5.2-3c73707ff'
2
2
  export const name = 'libp2p'
@@ -1,14 +0,0 @@
1
- {
2
- "Libp2pInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.Libp2pInit.html",
3
- ".:Libp2pInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.Libp2pInit.html",
4
- "Libp2pOptions": "https://libp2p.github.io/js-libp2p/types/libp2p.index.Libp2pOptions.html",
5
- ".:Libp2pOptions": "https://libp2p.github.io/js-libp2p/types/libp2p.index.Libp2pOptions.html",
6
- "ServiceFactoryMap": "https://libp2p.github.io/js-libp2p/types/libp2p.index.ServiceFactoryMap.html",
7
- ".:ServiceFactoryMap": "https://libp2p.github.io/js-libp2p/types/libp2p.index.ServiceFactoryMap.html",
8
- "createLibp2p": "https://libp2p.github.io/js-libp2p/functions/libp2p.index.createLibp2p.html",
9
- ".:createLibp2p": "https://libp2p.github.io/js-libp2p/functions/libp2p.index.createLibp2p.html",
10
- "name": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.name.html",
11
- "./version:name": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.name.html",
12
- "version": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.version.html",
13
- "./version:version": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.version.html"
14
- }