libp2p 1.4.3 → 1.5.0-9d13a2f6a

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.
@@ -0,0 +1,138 @@
1
+ import { randomBytes } from '@libp2p/crypto'
2
+ import { TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
3
+ import { anySignal } from 'any-signal'
4
+ import pDefer, { type DeferredPromise } from 'p-defer'
5
+ import { raceEvent } from 'race-event'
6
+ import { raceSignal } from 'race-signal'
7
+ import type { AbortOptions, ComponentLogger, Logger, PeerInfo, PeerRouting, Startable } from '@libp2p/interface'
8
+ import type { RandomWalk as RandomWalkInterface } from '@libp2p/interface-internal'
9
+
10
+ export interface RandomWalkComponents {
11
+ peerRouting: PeerRouting
12
+ logger: ComponentLogger
13
+ }
14
+
15
+ interface RandomWalkEvents {
16
+ 'walk:peer': CustomEvent<PeerInfo>
17
+ 'walk:error': CustomEvent<Error>
18
+ }
19
+
20
+ export class RandomWalk extends TypedEventEmitter<RandomWalkEvents> implements RandomWalkInterface, Startable {
21
+ private readonly peerRouting: PeerRouting
22
+ private readonly log: Logger
23
+ private walking: boolean
24
+ private walkers: number
25
+ private shutdownController: AbortController
26
+ private walkController?: AbortController
27
+ private needNext?: DeferredPromise<void>
28
+
29
+ constructor (components: RandomWalkComponents) {
30
+ super()
31
+
32
+ this.log = components.logger.forComponent('libp2p:random-walk')
33
+ this.peerRouting = components.peerRouting
34
+ this.walkers = 0
35
+ this.walking = false
36
+
37
+ // stops any in-progress walks when the node is shut down
38
+ this.shutdownController = new AbortController()
39
+ setMaxListeners(Infinity, this.shutdownController.signal)
40
+ }
41
+
42
+ start (): void {
43
+ this.shutdownController = new AbortController()
44
+ setMaxListeners(Infinity, this.shutdownController.signal)
45
+ }
46
+
47
+ stop (): void {
48
+ this.shutdownController.abort()
49
+ }
50
+
51
+ async * walk (options?: AbortOptions): AsyncGenerator<PeerInfo> {
52
+ if (!this.walking) {
53
+ // start the query that causes walk:peer events to be emitted
54
+ this.startWalk()
55
+ }
56
+
57
+ this.walkers++
58
+ const signal = anySignal([this.shutdownController.signal, options?.signal])
59
+ setMaxListeners(Infinity, signal)
60
+
61
+ try {
62
+ while (true) {
63
+ // if another consumer has paused the query, start it again
64
+ this.needNext?.resolve()
65
+ this.needNext = pDefer()
66
+
67
+ // wait for a walk:peer or walk:error event
68
+ const event = await raceEvent<CustomEvent<PeerInfo>>(this, 'walk:peer', signal, {
69
+ errorEvent: 'walk:error'
70
+ })
71
+
72
+ yield event.detail
73
+ }
74
+ } finally {
75
+ signal.clear()
76
+ this.walkers--
77
+
78
+ // stop the walk if no more consumers are interested
79
+ if (this.walkers === 0) {
80
+ this.walkController?.abort()
81
+ this.walkController = undefined
82
+ }
83
+ }
84
+ }
85
+
86
+ private startWalk (): void {
87
+ this.walking = true
88
+
89
+ // the signal for this controller will be aborted if no more random peers
90
+ // are required
91
+ this.walkController = new AbortController()
92
+ setMaxListeners(Infinity, this.walkController.signal)
93
+
94
+ const signal = anySignal([this.walkController.signal, this.shutdownController.signal])
95
+ setMaxListeners(Infinity, signal)
96
+
97
+ const start = Date.now()
98
+ let found = 0
99
+
100
+ Promise.resolve().then(async () => {
101
+ this.log('start walk')
102
+
103
+ // find peers until no more consumers are interested
104
+ while (this.walkers > 0) {
105
+ try {
106
+ for await (const peer of this.peerRouting.getClosestPeers(randomBytes(32), { signal })) {
107
+ signal.throwIfAborted()
108
+
109
+ this.log('found peer %p', peer.id)
110
+ found++
111
+ this.safeDispatchEvent('walk:peer', {
112
+ detail: peer
113
+ })
114
+
115
+ // if we only have one consumer, pause the query until they request
116
+ // another random peer or they signal they are no longer interested
117
+ if (this.walkers === 1 && this.needNext != null) {
118
+ await raceSignal(this.needNext.promise, signal)
119
+ }
120
+ }
121
+ } catch (err) {
122
+ this.log.error('randomwalk errored', err)
123
+
124
+ this.safeDispatchEvent('walk:error', {
125
+ detail: err
126
+ })
127
+ }
128
+ }
129
+ })
130
+ .catch(err => {
131
+ this.log.error('randomwalk errored', err)
132
+ })
133
+ .finally(() => {
134
+ this.log('finished walk, found %d peers after %dms', found, Date.now() - start)
135
+ this.walking = false
136
+ })
137
+ }
138
+ }
@@ -106,7 +106,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
106
106
  * Dials the given Multiaddr over it's supported transport
107
107
  */
108
108
  async dial (ma: Multiaddr, options?: AbortOptions): Promise<Connection> {
109
- const transport = this.transportForMultiaddr(ma)
109
+ const transport = this.dialTransportForMultiaddr(ma)
110
110
 
111
111
  if (transport == null) {
112
112
  throw new CodeError(`No transport available for address ${String(ma)}`, codes.ERR_TRANSPORT_UNAVAILABLE)
@@ -156,9 +156,22 @@ export class DefaultTransportManager implements TransportManager, Startable {
156
156
  /**
157
157
  * Finds a transport that matches the given Multiaddr
158
158
  */
159
- transportForMultiaddr (ma: Multiaddr): Transport | undefined {
159
+ dialTransportForMultiaddr (ma: Multiaddr): Transport | undefined {
160
160
  for (const transport of this.transports.values()) {
161
- const addrs = transport.filter([ma])
161
+ const addrs = transport.dialFilter([ma])
162
+
163
+ if (addrs.length > 0) {
164
+ return transport
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Finds a transport that matches the given Multiaddr
171
+ */
172
+ listenTransportForMultiaddr (ma: Multiaddr): Transport | undefined {
173
+ for (const transport of this.transports.values()) {
174
+ const addrs = transport.listenFilter([ma])
162
175
 
163
176
  if (addrs.length > 0) {
164
177
  return transport
@@ -182,7 +195,7 @@ export class DefaultTransportManager implements TransportManager, Startable {
182
195
  const couldNotListen = []
183
196
 
184
197
  for (const [key, transport] of this.transports.entries()) {
185
- const supportedAddrs = transport.filter(addrs)
198
+ const supportedAddrs = transport.listenFilter(addrs)
186
199
  const tasks = []
187
200
 
188
201
  // For each supported multiaddr, create a listener
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '1.4.3'
1
+ export const version = '1.5.0-9d13a2f6a'
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
- }