libp2p 0.44.0 → 0.45.0-08d4c261

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 (238) hide show
  1. package/dist/index.min.js +32 -32
  2. package/dist/src/address-manager/index.d.ts +9 -5
  3. package/dist/src/address-manager/index.d.ts.map +1 -1
  4. package/dist/src/address-manager/index.js +44 -7
  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 +48 -33
  17. package/dist/src/autonat/index.js.map +1 -1
  18. package/dist/src/circuit-relay/index.d.ts +1 -1
  19. package/dist/src/circuit-relay/index.d.ts.map +1 -1
  20. package/dist/src/circuit-relay/server/advert-service.d.ts +2 -2
  21. package/dist/src/circuit-relay/server/advert-service.d.ts.map +1 -1
  22. package/dist/src/circuit-relay/server/advert-service.js +8 -4
  23. package/dist/src/circuit-relay/server/advert-service.js.map +1 -1
  24. package/dist/src/circuit-relay/server/index.d.ts +8 -8
  25. package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
  26. package/dist/src/circuit-relay/server/index.js +32 -12
  27. package/dist/src/circuit-relay/server/index.js.map +1 -1
  28. package/dist/src/circuit-relay/server/reservation-store.d.ts +5 -5
  29. package/dist/src/circuit-relay/server/reservation-store.d.ts.map +1 -1
  30. package/dist/src/circuit-relay/server/reservation-store.js +10 -3
  31. package/dist/src/circuit-relay/server/reservation-store.js.map +1 -1
  32. package/dist/src/circuit-relay/server/reservation-voucher.d.ts.map +1 -1
  33. package/dist/src/circuit-relay/server/reservation-voucher.js +5 -2
  34. package/dist/src/circuit-relay/server/reservation-voucher.js.map +1 -1
  35. package/dist/src/circuit-relay/transport/discovery.d.ts +4 -4
  36. package/dist/src/circuit-relay/transport/discovery.d.ts.map +1 -1
  37. package/dist/src/circuit-relay/transport/discovery.js +13 -5
  38. package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
  39. package/dist/src/circuit-relay/transport/index.d.ts +10 -8
  40. package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
  41. package/dist/src/circuit-relay/transport/index.js +26 -18
  42. package/dist/src/circuit-relay/transport/index.js.map +1 -1
  43. package/dist/src/circuit-relay/transport/listener.d.ts +1 -1
  44. package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
  45. package/dist/src/circuit-relay/transport/listener.js +43 -43
  46. package/dist/src/circuit-relay/transport/listener.js.map +1 -1
  47. package/dist/src/circuit-relay/transport/reservation-store.d.ts +8 -7
  48. package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
  49. package/dist/src/circuit-relay/transport/reservation-store.js +65 -52
  50. package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
  51. package/dist/src/circuit-relay/utils.d.ts.map +1 -1
  52. package/dist/src/circuit-relay/utils.js +3 -3
  53. package/dist/src/circuit-relay/utils.js.map +1 -1
  54. package/dist/src/components.d.ts +10 -67
  55. package/dist/src/components.d.ts.map +1 -1
  56. package/dist/src/components.js +61 -165
  57. package/dist/src/components.js.map +1 -1
  58. package/dist/src/config/connection-gater.browser.d.ts +8 -0
  59. package/dist/src/config/connection-gater.browser.d.ts.map +1 -0
  60. package/dist/src/config/connection-gater.browser.js +27 -0
  61. package/dist/src/config/connection-gater.browser.js.map +1 -0
  62. package/dist/src/config/connection-gater.d.ts +6 -0
  63. package/dist/src/config/connection-gater.d.ts.map +1 -0
  64. package/dist/src/config/connection-gater.js +18 -0
  65. package/dist/src/config/connection-gater.js.map +1 -0
  66. package/dist/src/config.d.ts +2 -1
  67. package/dist/src/config.d.ts.map +1 -1
  68. package/dist/src/config.js +4 -66
  69. package/dist/src/config.js.map +1 -1
  70. package/dist/src/connection/index.d.ts +3 -3
  71. package/dist/src/connection/index.d.ts.map +1 -1
  72. package/dist/src/connection/index.js +38 -8
  73. package/dist/src/connection/index.js.map +1 -1
  74. package/dist/src/connection-manager/auto-dial.d.ts +4 -1
  75. package/dist/src/connection-manager/auto-dial.d.ts.map +1 -1
  76. package/dist/src/connection-manager/auto-dial.js +44 -13
  77. package/dist/src/connection-manager/auto-dial.js.map +1 -1
  78. package/dist/src/connection-manager/connection-pruner.d.ts +4 -0
  79. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  80. package/dist/src/connection-manager/connection-pruner.js +28 -8
  81. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  82. package/dist/src/connection-manager/dial-queue.d.ts +7 -6
  83. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  84. package/dist/src/connection-manager/dial-queue.js +59 -23
  85. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  86. package/dist/src/connection-manager/index.d.ts +16 -15
  87. package/dist/src/connection-manager/index.d.ts.map +1 -1
  88. package/dist/src/connection-manager/index.js +44 -41
  89. package/dist/src/connection-manager/index.js.map +1 -1
  90. package/dist/src/connection-manager/utils.d.ts +2 -3
  91. package/dist/src/connection-manager/utils.d.ts.map +1 -1
  92. package/dist/src/connection-manager/utils.js +3 -3
  93. package/dist/src/connection-manager/utils.js.map +1 -1
  94. package/dist/src/content-routing/index.d.ts +2 -12
  95. package/dist/src/content-routing/index.d.ts.map +1 -1
  96. package/dist/src/content-routing/index.js +12 -44
  97. package/dist/src/content-routing/index.js.map +1 -1
  98. package/dist/src/content-routing/utils.d.ts +1 -1
  99. package/dist/src/content-routing/utils.d.ts.map +1 -1
  100. package/dist/src/content-routing/utils.js +3 -1
  101. package/dist/src/content-routing/utils.js.map +1 -1
  102. package/dist/src/fetch/index.d.ts +15 -37
  103. package/dist/src/fetch/index.d.ts.map +1 -1
  104. package/dist/src/fetch/index.js +19 -16
  105. package/dist/src/fetch/index.js.map +1 -1
  106. package/dist/src/get-peer.d.ts +1 -1
  107. package/dist/src/get-peer.d.ts.map +1 -1
  108. package/dist/src/get-peer.js +3 -3
  109. package/dist/src/get-peer.js.map +1 -1
  110. package/dist/src/identify/identify.d.ts +53 -0
  111. package/dist/src/identify/identify.d.ts.map +1 -0
  112. package/dist/src/identify/identify.js +417 -0
  113. package/dist/src/identify/identify.js.map +1 -0
  114. package/dist/src/identify/index.d.ts +14 -59
  115. package/dist/src/identify/index.d.ts.map +1 -1
  116. package/dist/src/identify/index.js +5 -388
  117. package/dist/src/identify/index.js.map +1 -1
  118. package/dist/src/index.d.ts +28 -79
  119. package/dist/src/index.d.ts.map +1 -1
  120. package/dist/src/index.js +2 -1
  121. package/dist/src/index.js.map +1 -1
  122. package/dist/src/insecure/index.js +6 -8
  123. package/dist/src/insecure/index.js.map +1 -1
  124. package/dist/src/libp2p.d.ts +16 -47
  125. package/dist/src/libp2p.d.ts.map +1 -1
  126. package/dist/src/libp2p.js +141 -201
  127. package/dist/src/libp2p.js.map +1 -1
  128. package/dist/src/peer-routing.d.ts +3 -40
  129. package/dist/src/peer-routing.d.ts.map +1 -1
  130. package/dist/src/peer-routing.js +8 -65
  131. package/dist/src/peer-routing.js.map +1 -1
  132. package/dist/src/ping/constants.d.ts +4 -0
  133. package/dist/src/ping/constants.d.ts.map +1 -1
  134. package/dist/src/ping/constants.js +10 -0
  135. package/dist/src/ping/constants.js.map +1 -1
  136. package/dist/src/ping/index.d.ts +11 -28
  137. package/dist/src/ping/index.d.ts.map +1 -1
  138. package/dist/src/ping/index.js +31 -28
  139. package/dist/src/ping/index.js.map +1 -1
  140. package/dist/src/pnet/crypto.js +3 -3
  141. package/dist/src/pnet/crypto.js.map +1 -1
  142. package/dist/src/pnet/index.d.ts.map +1 -1
  143. package/dist/src/pnet/index.js +9 -6
  144. package/dist/src/pnet/index.js.map +1 -1
  145. package/dist/src/pnet/key-generator.js +1 -1
  146. package/dist/src/pnet/key-generator.js.map +1 -1
  147. package/dist/src/pubsub/dummy-pubsub.d.ts.map +1 -1
  148. package/dist/src/pubsub/dummy-pubsub.js +2 -5
  149. package/dist/src/pubsub/dummy-pubsub.js.map +1 -1
  150. package/dist/src/registrar.d.ts +6 -4
  151. package/dist/src/registrar.d.ts.map +1 -1
  152. package/dist/src/registrar.js +33 -28
  153. package/dist/src/registrar.js.map +1 -1
  154. package/dist/src/transport-manager.d.ts +14 -7
  155. package/dist/src/transport-manager.d.ts.map +1 -1
  156. package/dist/src/transport-manager.js +27 -13
  157. package/dist/src/transport-manager.js.map +1 -1
  158. package/dist/src/upgrader.d.ts +20 -15
  159. package/dist/src/upgrader.d.ts.map +1 -1
  160. package/dist/src/upgrader.js +49 -53
  161. package/dist/src/upgrader.js.map +1 -1
  162. package/dist/src/{nat-manager.d.ts → upnp-nat/index.d.ts} +12 -15
  163. package/dist/src/upnp-nat/index.d.ts.map +1 -0
  164. package/dist/src/{nat-manager.js → upnp-nat/index.js} +23 -10
  165. package/dist/src/upnp-nat/index.js.map +1 -0
  166. package/dist/src/version.d.ts +1 -1
  167. package/dist/src/version.d.ts.map +1 -1
  168. package/dist/src/version.js +1 -1
  169. package/dist/src/version.js.map +1 -1
  170. package/package.json +62 -47
  171. package/src/address-manager/index.ts +52 -10
  172. package/src/address-manager/utils.ts +14 -0
  173. package/src/autonat/constants.ts +17 -2
  174. package/src/autonat/index.ts +65 -57
  175. package/src/circuit-relay/index.ts +1 -1
  176. package/src/circuit-relay/server/advert-service.ts +5 -5
  177. package/src/circuit-relay/server/index.ts +28 -20
  178. package/src/circuit-relay/server/reservation-store.ts +5 -5
  179. package/src/circuit-relay/server/reservation-voucher.ts +1 -1
  180. package/src/circuit-relay/transport/discovery.ts +12 -10
  181. package/src/circuit-relay/transport/index.ts +26 -26
  182. package/src/circuit-relay/transport/listener.ts +43 -33
  183. package/src/circuit-relay/transport/reservation-store.ts +42 -28
  184. package/src/circuit-relay/utils.ts +6 -6
  185. package/src/components.ts +75 -238
  186. package/src/config/connection-gater.browser.ts +31 -0
  187. package/src/config/connection-gater.ts +19 -0
  188. package/src/config.ts +9 -70
  189. package/src/connection/index.ts +6 -10
  190. package/src/connection-manager/auto-dial.ts +46 -17
  191. package/src/connection-manager/connection-pruner.ts +30 -10
  192. package/src/connection-manager/dial-queue.ts +56 -35
  193. package/src/connection-manager/index.ts +45 -57
  194. package/src/connection-manager/utils.ts +4 -5
  195. package/src/content-routing/index.ts +11 -59
  196. package/src/content-routing/utils.ts +4 -2
  197. package/src/fetch/index.ts +63 -26
  198. package/src/get-peer.ts +4 -4
  199. package/src/identify/identify.ts +519 -0
  200. package/src/identify/index.ts +19 -509
  201. package/src/index.ts +25 -88
  202. package/src/insecure/index.ts +10 -10
  203. package/src/libp2p.ts +158 -279
  204. package/src/peer-routing.ts +10 -110
  205. package/src/ping/constants.ts +11 -0
  206. package/src/ping/index.ts +43 -39
  207. package/src/pnet/crypto.ts +3 -3
  208. package/src/pnet/index.ts +6 -6
  209. package/src/pnet/key-generator.ts +1 -1
  210. package/src/pubsub/dummy-pubsub.ts +2 -2
  211. package/src/registrar.ts +34 -31
  212. package/src/transport-manager.ts +33 -19
  213. package/src/upgrader.ts +75 -71
  214. package/src/{nat-manager.ts → upnp-nat/index.ts} +23 -24
  215. package/src/version.ts +1 -1
  216. package/dist/src/dht/dht-content-routing.d.ts +0 -17
  217. package/dist/src/dht/dht-content-routing.d.ts.map +0 -1
  218. package/dist/src/dht/dht-content-routing.js +0 -32
  219. package/dist/src/dht/dht-content-routing.js.map +0 -1
  220. package/dist/src/dht/dht-peer-routing.d.ts +0 -15
  221. package/dist/src/dht/dht-peer-routing.d.ts.map +0 -1
  222. package/dist/src/dht/dht-peer-routing.js +0 -26
  223. package/dist/src/dht/dht-peer-routing.js.map +0 -1
  224. package/dist/src/dht/dummy-dht.d.ts +0 -20
  225. package/dist/src/dht/dummy-dht.d.ts.map +0 -1
  226. package/dist/src/dht/dummy-dht.js +0 -46
  227. package/dist/src/dht/dummy-dht.js.map +0 -1
  228. package/dist/src/nat-manager.d.ts.map +0 -1
  229. package/dist/src/nat-manager.js.map +0 -1
  230. package/dist/src/peer-record-updater.d.ts +0 -24
  231. package/dist/src/peer-record-updater.d.ts.map +0 -1
  232. package/dist/src/peer-record-updater.js +0 -44
  233. package/dist/src/peer-record-updater.js.map +0 -1
  234. package/dist/typedoc-urls.json +0 -41
  235. package/src/dht/dht-content-routing.ts +0 -44
  236. package/src/dht/dht-peer-routing.ts +0 -36
  237. package/src/dht/dummy-dht.ts +0 -60
  238. package/src/peer-record-updater.ts +0 -65
@@ -1,9 +1,11 @@
1
1
  import { logger } from '@libp2p/logger'
2
- import type { PeerStore } from '@libp2p/interface-peer-store'
3
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
4
- import { PeerMap } from '@libp2p/peer-collections'
2
+ import { PeerMap, PeerSet } from '@libp2p/peer-collections'
5
3
  import PQueue from 'p-queue'
6
4
  import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_INTERVAL, AUTO_DIAL_PRIORITY, MIN_CONNECTIONS } from './constants.js'
5
+ import type { ConnectionManager } from '@libp2p/interface-connection-manager'
6
+ import type { Libp2pEvents } from '@libp2p/interface-libp2p'
7
+ import type { PeerStore } from '@libp2p/interface-peer-store'
8
+ import type { EventEmitter } from '@libp2p/interfaces/events'
7
9
  import type { Startable } from '@libp2p/interfaces/startable'
8
10
 
9
11
  const log = logger('libp2p:connection-manager:auto-dial')
@@ -18,6 +20,7 @@ interface AutoDialInit {
18
20
  interface AutoDialComponents {
19
21
  connectionManager: ConnectionManager
20
22
  peerStore: PeerStore
23
+ events: EventEmitter<Libp2pEvents>
21
24
  }
22
25
 
23
26
  const defaultOptions = {
@@ -55,6 +58,14 @@ export class AutoDial implements Startable {
55
58
  this.queue.addListener('error', (err) => {
56
59
  log.error('error during auto-dial', err)
57
60
  })
61
+
62
+ // check the min connection limit whenever a peer disconnects
63
+ components.events.addEventListener('connection:close', () => {
64
+ this.autoDial()
65
+ .catch(err => {
66
+ log.error(err)
67
+ })
68
+ })
58
69
  }
59
70
 
60
71
  isStarted (): boolean {
@@ -86,7 +97,18 @@ export class AutoDial implements Startable {
86
97
  }
87
98
 
88
99
  async autoDial (): Promise<void> {
89
- const numConnections = this.connectionManager.getConnections().length
100
+ if (!this.started) {
101
+ return
102
+ }
103
+
104
+ const connections = this.connectionManager.getConnectionsMap()
105
+ const numConnections = connections.size
106
+ const dialQueue = new PeerSet(
107
+ // @ts-expect-error boolean filter removes falsy peer IDs
108
+ this.connectionManager.getDialQueue()
109
+ .map(queue => queue.peerId)
110
+ .filter(Boolean)
111
+ )
90
112
 
91
113
  // Already has enough connections
92
114
  if (numConnections >= this.minConnections) {
@@ -97,40 +119,47 @@ export class AutoDial implements Startable {
97
119
  log('not enough connections %d/%d - will dial peers to increase the number of connections', numConnections, this.minConnections)
98
120
 
99
121
  // Sort peers on whether we know protocols or public keys for them
100
- let peers = await this.peerStore.all()
101
-
102
- log('loaded %d peers from the peer store', peers.length)
122
+ const peers = await this.peerStore.all()
103
123
 
104
124
  // Remove some peers
105
- peers = peers.filter((peer) => {
125
+ const filteredPeers = peers.filter((peer) => {
106
126
  // Remove peers without addresses
107
127
  if (peer.addresses.length === 0) {
108
128
  return false
109
129
  }
110
130
 
131
+ // remove peers we are already connected to
132
+ if (connections.has(peer.id)) {
133
+ return false
134
+ }
135
+
136
+ // remove peers we are already dialling
137
+ if (dialQueue.has(peer.id)) {
138
+ return false
139
+ }
140
+
111
141
  return true
112
142
  })
113
143
 
114
- // shuffle the peers
115
- peers = peers.sort(() => Math.random() > 0.5 ? 1 : -1)
144
+ // shuffle the peers - this is so peers with the same tag values will be
145
+ // dialled in a different order each time
146
+ const shuffledPeers = filteredPeers.sort(() => Math.random() > 0.5 ? 1 : -1)
116
147
 
117
148
  // Sort shuffled peers by tag value
118
149
  const peerValues = new PeerMap<number>()
119
- for (const peer of peers) {
150
+ for (const peer of shuffledPeers) {
120
151
  if (peerValues.has(peer.id)) {
121
152
  continue
122
153
  }
123
154
 
124
- const tags = await this.peerStore.getTags(peer.id)
125
-
126
155
  // sum all tag values
127
- peerValues.set(peer.id, (tags ?? []).reduce((acc, curr) => {
156
+ peerValues.set(peer.id, [...peer.tags.values()].reduce((acc, curr) => {
128
157
  return acc + curr.value
129
158
  }, 0))
130
159
  }
131
160
 
132
161
  // sort by value, highest to lowest
133
- const sortedPeers = peers.sort((a, b) => {
162
+ const sortedPeers = shuffledPeers.sort((a, b) => {
134
163
  const peerAValue = peerValues.get(a.id) ?? 0
135
164
  const peerBValue = peerValues.get(b.id) ?? 0
136
165
 
@@ -145,11 +174,11 @@ export class AutoDial implements Startable {
145
174
  return 0
146
175
  })
147
176
 
148
- log('selected %d peers to dial', sortedPeers.length)
177
+ log('selected %d/%d peers to dial', sortedPeers.length, peers.length)
149
178
 
150
179
  for (const peer of sortedPeers) {
151
180
  this.queue.add(async () => {
152
- const numConnections = this.connectionManager.getConnections().length
181
+ const numConnections = this.connectionManager.getConnectionsMap().size
153
182
 
154
183
  // Check to see if we still need to auto dial
155
184
  if (numConnections >= this.minConnections) {
@@ -1,10 +1,11 @@
1
1
  import { logger } from '@libp2p/logger'
2
+ import { PeerMap } from '@libp2p/peer-collections'
3
+ import { MAX_CONNECTIONS } from './constants.js'
2
4
  import type { ConnectionManager } from '@libp2p/interface-connection-manager'
5
+ import type { Libp2pEvents } from '@libp2p/interface-libp2p'
3
6
  import type { PeerStore } from '@libp2p/interface-peer-store'
4
- import { PeerMap } from '@libp2p/peer-collections'
7
+ import type { EventEmitter } from '@libp2p/interfaces/events'
5
8
  import type { Multiaddr } from '@multiformats/multiaddr'
6
- import { MAX_CONNECTIONS } from './constants.js'
7
- import { CustomEvent } from '@libp2p/interfaces/events'
8
9
 
9
10
  const log = logger('libp2p:connection-manager:connection-pruner')
10
11
 
@@ -16,6 +17,7 @@ interface ConnectionPrunerInit {
16
17
  interface ConnectionPrunerComponents {
17
18
  connectionManager: ConnectionManager
18
19
  peerStore: PeerStore
20
+ events: EventEmitter<Libp2pEvents>
19
21
  }
20
22
 
21
23
  const defaultOptions = {
@@ -31,12 +33,22 @@ export class ConnectionPruner {
31
33
  private readonly connectionManager: ConnectionManager
32
34
  private readonly peerStore: PeerStore
33
35
  private readonly allow: Multiaddr[]
36
+ private readonly events: EventEmitter<Libp2pEvents>
34
37
 
35
38
  constructor (components: ConnectionPrunerComponents, init: ConnectionPrunerInit = {}) {
36
39
  this.maxConnections = init.maxConnections ?? defaultOptions.maxConnections
37
40
  this.allow = init.allow ?? defaultOptions.allow
38
41
  this.connectionManager = components.connectionManager
39
42
  this.peerStore = components.peerStore
43
+ this.events = components.events
44
+
45
+ // check the max connection limit whenever a peer connects
46
+ components.events.addEventListener('connection:open', () => {
47
+ this.maybePruneConnections()
48
+ .catch(err => {
49
+ log.error(err)
50
+ })
51
+ })
40
52
  }
41
53
 
42
54
  /**
@@ -48,7 +60,7 @@ export class ConnectionPruner {
48
60
  const numConnections = connections.length
49
61
  const toPrune = Math.max(numConnections - this.maxConnections, 0)
50
62
 
51
- log.trace('checking max connections limit %d/%d', numConnections, this.maxConnections)
63
+ log('checking max connections limit %d/%d', numConnections, this.maxConnections)
52
64
  if (numConnections <= this.maxConnections) {
53
65
  return
54
66
  }
@@ -64,12 +76,20 @@ export class ConnectionPruner {
64
76
  continue
65
77
  }
66
78
 
67
- const tags = await this.peerStore.getTags(remotePeer)
79
+ peerValues.set(remotePeer, 0)
80
+
81
+ try {
82
+ const peer = await this.peerStore.get(remotePeer)
68
83
 
69
- // sum all tag values
70
- peerValues.set(remotePeer, tags.reduce((acc, curr) => {
71
- return acc + curr.value
72
- }, 0))
84
+ // sum all tag values
85
+ peerValues.set(remotePeer, [...peer.tags.values()].reduce((acc, curr) => {
86
+ return acc + curr.value
87
+ }, 0))
88
+ } catch (err: any) {
89
+ if (err.code !== 'ERR_NOT_FOUND') {
90
+ log.error('error loading peer tags', err)
91
+ }
92
+ }
73
93
  }
74
94
 
75
95
  // sort by value, lowest to highest
@@ -132,6 +152,6 @@ export class ConnectionPruner {
132
152
  )
133
153
 
134
154
  // despatch prune event
135
- this.connectionManager.dispatchEvent(new CustomEvent('peer:prune', { detail: toClose.map(conn => conn.remotePeer) }))
155
+ this.events.safeDispatchEvent('connection:prune', { detail: toClose })
136
156
  }
137
157
  }
@@ -1,28 +1,29 @@
1
- import { logger } from '@libp2p/logger'
1
+ import { setMaxListeners } from 'events'
2
2
  import { AbortError, CodeError } from '@libp2p/interfaces/errors'
3
- import { Multiaddr, Resolver, resolvers } from '@multiformats/multiaddr'
4
- import { TimeoutController } from 'timeout-abort-controller'
3
+ import { logger } from '@libp2p/logger'
5
4
  import { publicAddressesFirst } from '@libp2p/utils/address-sort'
5
+ import { type Multiaddr, type Resolver, resolvers } from '@multiformats/multiaddr'
6
+ import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
7
+ import { type ClearableSignal, anySignal } from 'any-signal'
8
+ import pDefer from 'p-defer'
9
+ import PQueue from 'p-queue'
6
10
  import { codes } from '../errors.js'
11
+ import { getPeerAddress } from '../get-peer.js'
7
12
  import {
8
13
  DIAL_TIMEOUT,
9
14
  MAX_PARALLEL_DIALS_PER_PEER,
10
15
  MAX_PARALLEL_DIALS,
11
16
  MAX_PEER_ADDRS_TO_DIAL
12
17
  } from './constants.js'
18
+ import { combineSignals, resolveMultiaddrs } from './utils.js'
13
19
  import type { Connection } from '@libp2p/interface-connection'
14
- import type { AbortOptions } from '@libp2p/interfaces'
15
- import type { PeerId } from '@libp2p/interface-peer-id'
16
- import { getPeerAddress } from '../get-peer.js'
17
- import type { Address, AddressSorter, PeerStore } from '@libp2p/interface-peer-store'
20
+ import type { ConnectionGater } from '@libp2p/interface-connection-gater'
21
+ import type { AddressSorter } from '@libp2p/interface-libp2p'
18
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'
19
25
  import type { TransportManager } from '@libp2p/interface-transport'
20
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
21
- import PQueue from 'p-queue'
22
- import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
23
- import { combineSignals, resolveMultiaddrs } from './utils.js'
24
- import pDefer from 'p-defer'
25
- import type { ClearableSignal } from 'any-signal'
26
+ import type { AbortOptions } from '@libp2p/interfaces'
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 = []
@@ -175,7 +181,7 @@ export class DialQueue {
175
181
 
176
182
  // create abort conditions - need to do this before `calculateMultiaddrs` as we may be about to
177
183
  // resolve a dns addr which can time out
178
- const { timeoutController, signal } = this.createDialAbortControllers(options.signal)
184
+ const signal = this.createDialAbortControllers(options.signal)
179
185
  let addrsToDial: Address[]
180
186
 
181
187
  try {
@@ -186,7 +192,6 @@ export class DialQueue {
186
192
  })
187
193
  } catch (err) {
188
194
  signal.clear()
189
- timeoutController.clear()
190
195
  throw err
191
196
  }
192
197
 
@@ -209,8 +214,7 @@ export class DialQueue {
209
214
  if (existingDial != null) {
210
215
  log('joining existing dial target for %p', peerId)
211
216
  signal.clear()
212
- timeoutController.clear()
213
- return await existingDial.promise
217
+ return existingDial.promise
214
218
  }
215
219
 
216
220
  log('creating dial target for', addrsToDial.map(({ multiaddr }) => multiaddr.toString()))
@@ -232,13 +236,12 @@ export class DialQueue {
232
236
 
233
237
  // clean up abort signals/controllers
234
238
  signal.clear()
235
- timeoutController.clear()
236
239
  })
237
240
  .catch(err => {
238
- log.error('dial failed to %s', addrsToDial.map(({ multiaddr }) => multiaddr.toString()).join(', '), err)
241
+ log.error('dial failed to %s', pendingDial.multiaddrs.map(ma => ma.toString()).join(', '), err)
239
242
 
240
243
  // Error is a timeout
241
- if (timeoutController.signal.aborted) {
244
+ if (signal.aborted) {
242
245
  const error = new CodeError(err.message, codes.ERR_TIMEOUT)
243
246
  throw error
244
247
  }
@@ -249,23 +252,27 @@ export class DialQueue {
249
252
  // let other dials join this one
250
253
  this.pendingDials.push(pendingDial)
251
254
 
252
- return await pendingDial.promise
255
+ return pendingDial.promise
253
256
  }
254
257
 
255
- private createDialAbortControllers (userSignal?: AbortSignal): { timeoutController: TimeoutController, signal: ClearableSignal } {
256
- // ensure we throw if the dial takes longer than the dial timeout
257
- const timeoutController = new TimeoutController(this.dialTimeout)
258
-
258
+ private createDialAbortControllers (userSignal?: AbortSignal): ClearableSignal {
259
259
  // let any signal abort the dial
260
- const signal = combineSignals(
261
- timeoutController.signal,
262
- this.shutDownController.signal,
263
- userSignal
260
+ const signal = anySignal(
261
+ [AbortSignal.timeout(this.dialTimeout),
262
+ this.shutDownController.signal,
263
+ userSignal
264
+ ]
264
265
  )
265
266
 
266
- return { timeoutController, signal }
267
+ try {
268
+ // This emitter gets listened to a lot
269
+ setMaxListeners?.(Infinity, signal)
270
+ } catch {}
271
+
272
+ return signal
267
273
  }
268
274
 
275
+ // eslint-disable-next-line complexity
269
276
  private async calculateMultiaddrs (peerId?: PeerId, addrs: Address[] = [], options: DialOptions = {}): Promise<Address[]> {
270
277
  // if a peer id or multiaddr(s) with a peer id, make sure it isn't our peer id and that we are allowed to dial it
271
278
  if (peerId != null) {
@@ -280,8 +287,15 @@ export class DialQueue {
280
287
  // if just a peer id was passed, load available multiaddrs for this peer from the address book
281
288
  if (addrs.length === 0) {
282
289
  log('loading multiaddrs for %p', peerId)
283
- addrs.push(...(await this.peerStore.addressBook.get(peerId)))
284
- log('loaded multiaddrs for %p', peerId, addrs.map(({ multiaddr }) => multiaddr.toString()))
290
+ try {
291
+ const peer = await this.peerStore.get(peerId)
292
+ addrs.push(...peer.addresses)
293
+ log('loaded multiaddrs for %p', peerId, addrs.map(({ multiaddr }) => multiaddr.toString()))
294
+ } catch (err: any) {
295
+ if (err.code !== codes.ERR_NOT_FOUND) {
296
+ throw err
297
+ }
298
+ }
285
299
  }
286
300
  }
287
301
 
@@ -306,7 +320,7 @@ export class DialQueue {
306
320
  const filteredAddrs = resolvedAddresses.filter(addr => Boolean(this.transportManager.transportForMultiaddr(addr.multiaddr)))
307
321
 
308
322
  // deduplicate addresses
309
- const dedupedAddrs: Map<string, Address> = new Map()
323
+ const dedupedAddrs = new Map<string, Address>()
310
324
 
311
325
  for (const addr of filteredAddrs) {
312
326
  const maStr = addr.multiaddr.toString()
@@ -371,7 +385,14 @@ export class DialQueue {
371
385
  gatedAdrs.push(addr)
372
386
  }
373
387
 
374
- return gatedAdrs.sort(this.addressSorter)
388
+ const sortedGatedAddrs = gatedAdrs.sort(this.addressSorter)
389
+
390
+ // make sure we actually have some addresses to dial
391
+ if (sortedGatedAddrs.length === 0) {
392
+ throw new CodeError('The connection gater denied all addresses in the dial request', codes.ERR_NO_VALID_ADDRESSES)
393
+ }
394
+
395
+ return sortedGatedAddrs
375
396
  }
376
397
 
377
398
  private async performDial (pendingDial: PendingDial, options: DialOptions = {}): Promise<Connection> {
@@ -471,7 +492,7 @@ export class DialQueue {
471
492
  signal.clear()
472
493
  })
473
494
 
474
- return await deferred.promise
495
+ return deferred.promise
475
496
  }))
476
497
 
477
498
  // dial succeeded or failed
@@ -1,29 +1,28 @@
1
- import { logger } from '@libp2p/logger'
2
- import { CodeError } from '@libp2p/interfaces/errors'
3
- import type { AbortOptions } from '@libp2p/interfaces'
4
- import { CustomEvent, EventEmitter } from '@libp2p/interfaces/events'
5
- import type { Startable } from '@libp2p/interfaces/startable'
6
- import { codes } from '../errors.js'
7
- import type { PeerId } from '@libp2p/interface-peer-id'
8
- import { setMaxListeners } from 'events'
9
- import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection'
10
- import type { ConnectionManager, ConnectionManagerEvents } from '@libp2p/interface-connection-manager'
11
- import type { AddressSorter, PeerStore } from '@libp2p/interface-peer-store'
12
- import { Multiaddr, Resolver, multiaddr } from '@multiformats/multiaddr'
13
1
  import { KEEP_ALIVE } from '@libp2p/interface-peer-store/tags'
2
+ import { CodeError } from '@libp2p/interfaces/errors'
3
+ import { logger } from '@libp2p/logger'
4
+ import { PeerMap } from '@libp2p/peer-collections'
5
+ import { publicAddressesFirst } from '@libp2p/utils/address-sort'
6
+ import { type Multiaddr, type Resolver, multiaddr } from '@multiformats/multiaddr'
7
+ import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
14
8
  import { RateLimiterMemory } from 'rate-limiter-flexible'
15
- import type { Metrics } from '@libp2p/interface-metrics'
16
- import type { TransportManager, Upgrader } from '@libp2p/interface-transport'
9
+ import { codes } from '../errors.js'
17
10
  import { getPeerAddress } from '../get-peer.js'
18
11
  import { AutoDial } from './auto-dial.js'
19
- import { DialQueue } from './dial-queue.js'
20
12
  import { ConnectionPruner } from './connection-pruner.js'
21
- import type { ConnectionGater } from '@libp2p/interface-connection-gater'
22
- import { PeerMap } from '@libp2p/peer-collections'
23
- import { publicAddressesFirst } from '@libp2p/utils/address-sort'
24
13
  import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_PRIORITY, DIAL_TIMEOUT, INBOUND_CONNECTION_THRESHOLD, MAX_CONNECTIONS, MAX_INCOMING_PENDING_CONNECTIONS, MAX_PARALLEL_DIALS, MAX_PEER_ADDRS_TO_DIAL, MIN_CONNECTIONS } from './constants.js'
25
- import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
26
- import type { PendingDial } from '../libp2p.js'
14
+ import { DialQueue } from './dial-queue.js'
15
+ import type { Connection, MultiaddrConnection } from '@libp2p/interface-connection'
16
+ import type { ConnectionGater } from '@libp2p/interface-connection-gater'
17
+ import type { ConnectionManager } from '@libp2p/interface-connection-manager'
18
+ import type { PendingDial, AddressSorter, Libp2pEvents } from '@libp2p/interface-libp2p'
19
+ import type { Metrics } from '@libp2p/interface-metrics'
20
+ import type { PeerId } from '@libp2p/interface-peer-id'
21
+ import type { PeerStore } from '@libp2p/interface-peer-store'
22
+ import type { TransportManager } from '@libp2p/interface-transport'
23
+ import type { AbortOptions } from '@libp2p/interfaces'
24
+ import type { EventEmitter } from '@libp2p/interfaces/events'
25
+ import type { Startable } from '@libp2p/interfaces/startable'
27
26
 
28
27
  const log = logger('libp2p:connection-manager')
29
28
 
@@ -143,10 +142,10 @@ const defaultOptions = {
143
142
  export interface DefaultConnectionManagerComponents {
144
143
  peerId: PeerId
145
144
  metrics?: Metrics
146
- upgrader: Upgrader
147
145
  peerStore: PeerStore
148
146
  transportManager: TransportManager
149
147
  connectionGater: ConnectionGater
148
+ events: EventEmitter<Libp2pEvents>
150
149
  }
151
150
 
152
151
  export interface OpenConnectionOptions extends AbortOptions {
@@ -156,7 +155,7 @@ export interface OpenConnectionOptions extends AbortOptions {
156
155
  /**
157
156
  * Responsible for managing known connections.
158
157
  */
159
- export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEvents> implements ConnectionManager, Startable {
158
+ export class DefaultConnectionManager implements ConnectionManager, Startable {
160
159
  private started: boolean
161
160
  private readonly connections: PeerMap<Connection[]>
162
161
  private readonly allow: Multiaddr[]
@@ -172,10 +171,9 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
172
171
 
173
172
  private readonly peerStore: PeerStore
174
173
  private readonly metrics?: Metrics
174
+ private readonly events: EventEmitter<Libp2pEvents>
175
175
 
176
176
  constructor (components: DefaultConnectionManagerComponents, init: ConnectionManagerInit = {}) {
177
- super()
178
-
179
177
  this.maxConnections = init.maxConnections ?? defaultOptions.maxConnections
180
178
  const minConnections = init.minConnections ?? defaultOptions.minConnections
181
179
 
@@ -189,17 +187,14 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
189
187
  this.connections = new PeerMap()
190
188
 
191
189
  this.started = false
192
-
193
- try {
194
- // This emitter gets listened to a lot
195
- setMaxListeners?.(Infinity, this)
196
- } catch {}
197
-
198
190
  this.peerStore = components.peerStore
199
191
  this.metrics = components.metrics
192
+ this.events = components.events
200
193
 
201
194
  this.onConnect = this.onConnect.bind(this)
202
195
  this.onDisconnect = this.onDisconnect.bind(this)
196
+ this.events.addEventListener('connection:open', this.onConnect)
197
+ this.events.addEventListener('connection:close', this.onDisconnect)
203
198
 
204
199
  // allow/deny lists
205
200
  this.allow = (init.allow ?? []).map(ma => multiaddr(ma))
@@ -217,35 +212,23 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
217
212
  // controls what happens when we don't have enough connections
218
213
  this.autoDial = new AutoDial({
219
214
  connectionManager: this,
220
- peerStore: components.peerStore
215
+ peerStore: components.peerStore,
216
+ events: components.events
221
217
  }, {
222
218
  minConnections,
223
219
  autoDialConcurrency: init.autoDialConcurrency ?? defaultOptions.autoDialConcurrency,
224
220
  autoDialPriority: init.autoDialPriority ?? defaultOptions.autoDialPriority
225
221
  })
226
- // check the min connection limit whenever a peer disconnects
227
- this.addEventListener('peer:disconnect', () => {
228
- this.autoDial.autoDial()
229
- .catch(err => {
230
- log.error(err)
231
- })
232
- })
233
222
 
234
223
  // controls what happens when we have too many connections
235
224
  this.connectionPruner = new ConnectionPruner({
236
225
  connectionManager: this,
237
- peerStore: components.peerStore
226
+ peerStore: components.peerStore,
227
+ events: components.events
238
228
  }, {
239
229
  maxConnections: this.maxConnections,
240
230
  allow: this.allow
241
231
  })
242
- // check the max connection limit whenever a peer connects
243
- this.addEventListener('peer:connect', () => {
244
- this.connectionPruner.maybePruneConnections()
245
- .catch(err => {
246
- log.error(err)
247
- })
248
- })
249
232
 
250
233
  this.dialQueue = new DialQueue({
251
234
  peerId: components.peerId,
@@ -262,9 +245,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
262
245
  dnsaddr: dnsaddrResolver
263
246
  }
264
247
  })
265
-
266
- components.upgrader.addEventListener('connection', this.onConnect)
267
- components.upgrader.addEventListener('connectionEnd', this.onDisconnect)
268
248
  }
269
249
 
270
250
  isStarted (): boolean {
@@ -367,10 +347,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
367
347
  const keepAlivePeers: PeerId[] = []
368
348
 
369
349
  for (const peer of await this.peerStore.all()) {
370
- const tags = await this.peerStore.getTags(peer.id)
371
- const hasKeepAlive = tags.filter(tag => tag.name === KEEP_ALIVE).length > 0
372
-
373
- if (hasKeepAlive) {
350
+ if (peer.tags.has(KEEP_ALIVE)) {
374
351
  keepAlivePeers.push(peer.id)
375
352
  }
376
353
  }
@@ -439,18 +416,25 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
439
416
 
440
417
  const peerId = connection.remotePeer
441
418
  const storedConns = this.connections.get(peerId)
419
+ let isNewPeer = false
442
420
 
443
421
  if (storedConns != null) {
444
422
  storedConns.push(connection)
445
423
  } else {
424
+ isNewPeer = true
446
425
  this.connections.set(peerId, [connection])
447
426
  }
448
427
 
449
- if (peerId.publicKey != null) {
450
- await this.peerStore.keyBook.set(peerId, peerId.publicKey)
428
+ // only need to store RSA public keys, all other types are embedded in the peer id
429
+ if (peerId.publicKey != null && peerId.type === 'RSA') {
430
+ await this.peerStore.patch(peerId, {
431
+ publicKey: peerId.publicKey
432
+ })
451
433
  }
452
434
 
453
- this.dispatchEvent(new CustomEvent<Connection>('peer:connect', { detail: connection }))
435
+ if (isNewPeer) {
436
+ this.events.safeDispatchEvent('peer:connect', { detail: connection.remotePeer })
437
+ }
454
438
  }
455
439
 
456
440
  /**
@@ -472,7 +456,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
472
456
  this.connections.set(peerId, storedConn)
473
457
  } else if (storedConn != null) {
474
458
  this.connections.delete(peerId)
475
- this.dispatchEvent(new CustomEvent<Connection>('peer:disconnect', { detail: connection }))
459
+ this.events.safeDispatchEvent('peer:disconnect', { detail: connection.remotePeer })
476
460
  }
477
461
  }
478
462
 
@@ -495,6 +479,10 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
495
479
  }
496
480
 
497
481
  async openConnection (peerIdOrMultiaddr: PeerId | Multiaddr | Multiaddr[], options: OpenConnectionOptions = {}): Promise<Connection> {
482
+ if (!this.isStarted()) {
483
+ throw new CodeError('Not started', codes.ERR_NODE_NOT_STARTED)
484
+ }
485
+
498
486
  const { peerId } = getPeerAddress(peerIdOrMultiaddr)
499
487
 
500
488
  if (peerId != null) {
@@ -1,8 +1,7 @@
1
- import { AbortOptions, multiaddr } from '@multiformats/multiaddr'
2
- import type { Multiaddr } from '@multiformats/multiaddr'
3
- import { logger } from '@libp2p/logger'
4
- import { ClearableSignal, anySignal } from 'any-signal'
5
1
  import { setMaxListeners } from 'events'
2
+ import { logger } from '@libp2p/logger'
3
+ import { type AbortOptions, multiaddr, type Multiaddr } from '@multiformats/multiaddr'
4
+ import { type ClearableSignal, anySignal } from 'any-signal'
6
5
 
7
6
  const log = logger('libp2p:connection-manager:utils')
8
7
 
@@ -21,7 +20,7 @@ export async function resolveMultiaddrs (ma: Multiaddr, options: AbortOptions):
21
20
 
22
21
  const resolvedMultiaddrs = await resolveRecord(ma, options)
23
22
  const recursiveMultiaddrs = await Promise.all(resolvedMultiaddrs.map(async (nm) => {
24
- return await resolveMultiaddrs(nm, options)
23
+ return resolveMultiaddrs(nm, options)
25
24
  }))
26
25
 
27
26
  const addrs = recursiveMultiaddrs.flat()