@libp2p/pubsub 8.0.13-738dd40f1 → 8.0.14

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@libp2p/pubsub",
3
- "version": "8.0.13-738dd40f1",
3
+ "version": "8.0.14",
4
4
  "description": "libp2p pubsub base class",
5
5
  "license": "Apache-2.0 OR MIT",
6
- "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/pubsub#readme",
6
+ "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/pubsub#readme",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/libp2p/js-libp2p.git"
@@ -11,10 +11,6 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/libp2p/js-libp2p/issues"
13
13
  },
14
- "publishConfig": {
15
- "access": "public",
16
- "provenance": true
17
- },
18
14
  "keywords": [
19
15
  "interface",
20
16
  "libp2p"
@@ -71,7 +67,7 @@
71
67
  "scripts": {
72
68
  "clean": "aegir clean",
73
69
  "lint": "aegir lint",
74
- "dep-check": "aegir dep-check",
70
+ "dep-check": "aegir dep-check -i protons",
75
71
  "build": "aegir build",
76
72
  "generate": "protons test/message/rpc.proto",
77
73
  "test": "aegir test",
@@ -83,30 +79,30 @@
83
79
  "test:electron-main": "aegir test -t electron-main"
84
80
  },
85
81
  "dependencies": {
86
- "@libp2p/crypto": "3.0.1-738dd40f1",
87
- "@libp2p/interface": "1.0.1-738dd40f1",
88
- "@libp2p/interface-internal": "1.0.0-738dd40f1",
89
- "@libp2p/peer-collections": "4.0.10-738dd40f1",
90
- "@libp2p/peer-id": "4.0.1-738dd40f1",
91
- "@libp2p/utils": "5.0.1-738dd40f1",
92
- "it-length-prefixed": "^9.0.3",
82
+ "@libp2p/crypto": "^2.0.8",
83
+ "@libp2p/interface": "^0.1.6",
84
+ "@libp2p/interface-internal": "^0.1.9",
85
+ "@libp2p/logger": "^3.1.0",
86
+ "@libp2p/peer-collections": "^4.0.8",
87
+ "@libp2p/peer-id": "^3.0.6",
88
+ "abortable-iterator": "^5.0.1",
89
+ "it-length-prefixed": "^9.0.1",
93
90
  "it-pipe": "^3.0.1",
94
- "it-pushable": "^3.2.1",
95
- "multiformats": "^12.1.3",
96
- "p-queue": "^7.4.1",
91
+ "it-pushable": "^3.2.0",
92
+ "multiformats": "^12.0.1",
93
+ "p-queue": "^7.3.4",
97
94
  "uint8arraylist": "^2.4.3",
98
95
  "uint8arrays": "^4.0.6"
99
96
  },
100
97
  "devDependencies": {
101
- "@libp2p/logger": "4.0.1-738dd40f1",
102
- "@libp2p/peer-id-factory": "3.0.10-738dd40f1",
98
+ "@libp2p/peer-id-factory": "^3.0.8",
103
99
  "@types/sinon": "^17.0.0",
104
100
  "aegir": "^41.0.2",
105
101
  "delay": "^6.0.0",
106
102
  "it-pair": "^2.0.6",
107
103
  "p-defer": "^4.0.0",
108
104
  "p-wait-for": "^5.0.2",
109
- "protons": "^7.3.0",
105
+ "protons": "^7.0.2",
110
106
  "protons-runtime": "^5.0.0",
111
107
  "sinon": "^17.0.0"
112
108
  }
package/src/index.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  * A set of components to be extended in order to create a pubsub implementation.
5
5
  *
6
6
  * @example
7
- *
8
7
  * ```javascript
9
8
  * import { PubSubBaseProtocol } from '@libp2p/pubsub'
10
9
  *
@@ -14,8 +13,10 @@
14
13
  * ```
15
14
  */
16
15
 
17
- import { CodeError, TypedEventEmitter, CustomEvent } from '@libp2p/interface'
18
- import { type PubSub, type Message, type StrictNoSign, type StrictSign, type PubSubInit, type PubSubEvents, type PeerStreams, type PubSubRPCMessage, type PubSubRPC, type PubSubRPCSubscription, type SubscriptionChangeData, type PublishResult, type TopicValidatorFn, TopicValidatorResult, type ComponentLogger, type Logger, type Connection, type PeerId } from '@libp2p/interface'
16
+ import { CodeError } from '@libp2p/interface/errors'
17
+ import { TypedEventEmitter, CustomEvent } from '@libp2p/interface/events'
18
+ import { type PubSub, type Message, type StrictNoSign, type StrictSign, type PubSubInit, type PubSubEvents, type PeerStreams, type PubSubRPCMessage, type PubSubRPC, type PubSubRPCSubscription, type SubscriptionChangeData, type PublishResult, type TopicValidatorFn, TopicValidatorResult } from '@libp2p/interface/pubsub'
19
+ import { logger } from '@libp2p/logger'
19
20
  import { PeerMap, PeerSet } from '@libp2p/peer-collections'
20
21
  import { pipe } from 'it-pipe'
21
22
  import Queue from 'p-queue'
@@ -26,13 +27,16 @@ import {
26
27
  verifySignature
27
28
  } from './sign.js'
28
29
  import { toMessage, ensureArray, noSignMsgId, msgId, toRpcMessage, randomSeqno } from './utils.js'
29
- import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal'
30
+ import type { Connection } from '@libp2p/interface/connection'
31
+ import type { PeerId } from '@libp2p/interface/peer-id'
32
+ import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
30
33
  import type { Uint8ArrayList } from 'uint8arraylist'
31
34
 
35
+ const log = logger('libp2p:pubsub')
36
+
32
37
  export interface PubSubComponents {
33
38
  peerId: PeerId
34
39
  registrar: Registrar
35
- logger: ComponentLogger
36
40
  }
37
41
 
38
42
  /**
@@ -40,8 +44,6 @@ export interface PubSubComponents {
40
44
  * and specifies the API that pubsub routers should have.
41
45
  */
42
46
  export abstract class PubSubBaseProtocol<Events extends Record<string, any> = PubSubEvents> extends TypedEventEmitter<Events> implements PubSub<Events> {
43
- protected log: Logger
44
-
45
47
  public started: boolean
46
48
  /**
47
49
  * Map of topics to which peers are subscribed to
@@ -96,7 +98,6 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
96
98
  maxOutboundStreams = 1
97
99
  } = props
98
100
 
99
- this.log = components.logger.forComponent('libp2p:pubsub')
100
101
  this.components = components
101
102
  this.multicodecs = ensureArray(multicodecs)
102
103
  this.enabled = props.enabled !== false
@@ -127,7 +128,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
127
128
  return
128
129
  }
129
130
 
130
- this.log('starting')
131
+ log('starting')
131
132
 
132
133
  const registrar = this.components.registrar
133
134
  // Incoming streams
@@ -147,7 +148,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
147
148
  }
148
149
  this._registrarTopologyIds = await Promise.all(this.multicodecs.map(async multicodec => registrar.register(multicodec, topology)))
149
150
 
150
- this.log('started')
151
+ log('started')
151
152
  this.started = true
152
153
  }
153
154
 
@@ -172,7 +173,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
172
173
  await registrar.unhandle(multicodec)
173
174
  }))
174
175
 
175
- this.log('stopping')
176
+ log('stopping')
176
177
  for (const peerStreams of this.peers.values()) {
177
178
  peerStreams.close()
178
179
  }
@@ -180,7 +181,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
180
181
  this.peers.clear()
181
182
  this.subscriptions = new Set()
182
183
  this.started = false
183
- this.log('stopped')
184
+ log('stopped')
184
185
  }
185
186
 
186
187
  isStarted (): boolean {
@@ -203,18 +204,18 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
203
204
  const inboundStream = peer.attachInboundStream(stream)
204
205
 
205
206
  this.processMessages(peerId, inboundStream, peer)
206
- .catch(err => { this.log(err) })
207
+ .catch(err => { log(err) })
207
208
  }
208
209
 
209
210
  /**
210
211
  * Registrar notifies an established connection with pubsub protocol
211
212
  */
212
213
  protected _onPeerConnected (peerId: PeerId, conn: Connection): void {
213
- this.log('connected %p', peerId)
214
+ log('connected %p', peerId)
214
215
 
215
216
  // if this connection is already in use for pubsub, ignore it
216
217
  if (conn.streams.find(stream => stream.direction === 'outbound' && stream.protocol != null && this.multicodecs.includes(stream.protocol)) != null) {
217
- this.log('outbound pubsub streams already present on connection from %p', peerId)
218
+ log('outbound pubsub streams already present on connection from %p', peerId)
218
219
  return
219
220
  }
220
221
 
@@ -230,14 +231,14 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
230
231
  const peer = this.addPeer(peerId, stream.protocol)
231
232
  await peer.attachOutboundStream(stream)
232
233
  } catch (err: any) {
233
- this.log.error(err)
234
+ log.error(err)
234
235
  }
235
236
 
236
237
  // Immediately send my own subscriptions to the newly established conn
237
238
  this.send(peerId, { subscriptions: Array.from(this.subscriptions).map(sub => sub.toString()), subscribe: true })
238
239
  })
239
240
  .catch(err => {
240
- this.log.error(err)
241
+ log.error(err)
241
242
  })
242
243
  }
243
244
 
@@ -247,7 +248,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
247
248
  protected _onPeerDisconnected (peerId: PeerId, conn?: Connection): void {
248
249
  const idB58Str = peerId.toString()
249
250
 
250
- this.log('connection ended', idB58Str)
251
+ log('connection ended', idB58Str)
251
252
  this._removePeer(peerId)
252
253
  }
253
254
 
@@ -263,9 +264,9 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
263
264
  }
264
265
 
265
266
  // else create a new peer streams
266
- this.log('new peer %p', peerId)
267
+ log('new peer %p', peerId)
267
268
 
268
- const peerStreams: PeerStreams = new PeerStreamsImpl(this.components, {
269
+ const peerStreams: PeerStreams = new PeerStreamsImpl({
269
270
  id: peerId,
270
271
  protocol
271
272
  })
@@ -291,7 +292,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
291
292
  peerStreams.close()
292
293
 
293
294
  // delete peer streams
294
- this.log('delete peer %p', peerId)
295
+ log('delete peer %p', peerId)
295
296
  this.peers.delete(peerId)
296
297
 
297
298
  // remove peer from topics map
@@ -318,7 +319,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
318
319
 
319
320
  for (const msg of (rpcMsg.messages ?? [])) {
320
321
  if (msg.from == null || msg.data == null || msg.topic == null) {
321
- this.log('message from %p was missing from, data or topic fields, dropping', peerId)
322
+ log('message from %p was missing from, data or topic fields, dropping', peerId)
322
323
  continue
323
324
  }
324
325
 
@@ -343,7 +344,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
343
344
  })),
344
345
  messages
345
346
  })
346
- .catch(err => { this.log(err) })
347
+ .catch(err => { log(err) })
347
348
  }
348
349
  }
349
350
  )
@@ -357,16 +358,16 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
357
358
  */
358
359
  async processRpc (from: PeerId, peerStreams: PeerStreams, rpc: PubSubRPC): Promise<boolean> {
359
360
  if (!this.acceptFrom(from)) {
360
- this.log('received message from unacceptable peer %p', from)
361
+ log('received message from unacceptable peer %p', from)
361
362
  return false
362
363
  }
363
364
 
364
- this.log('rpc from %p', from)
365
+ log('rpc from %p', from)
365
366
 
366
367
  const { subscriptions, messages } = rpc
367
368
 
368
369
  if (subscriptions != null && subscriptions.length > 0) {
369
- this.log('subscription update from %p', from)
370
+ log('subscription update from %p', from)
370
371
 
371
372
  // update peer subscriptions
372
373
  subscriptions.forEach((subOpt) => {
@@ -385,11 +386,11 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
385
386
  }
386
387
 
387
388
  if (messages != null && messages.length > 0) {
388
- this.log('messages from %p', from)
389
+ log('messages from %p', from)
389
390
 
390
391
  this.queue.addAll(messages.map(message => async () => {
391
392
  if (message.topic == null || (!this.subscriptions.has(message.topic) && !this.canRelayMessage)) {
392
- this.log('received message we didn\'t subscribe to. Dropping.')
393
+ log('received message we didn\'t subscribe to. Dropping.')
393
394
  return false
394
395
  }
395
396
 
@@ -398,10 +399,10 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
398
399
 
399
400
  await this.processMessage(from, msg)
400
401
  } catch (err: any) {
401
- this.log.error(err)
402
+ log.error(err)
402
403
  }
403
404
  }))
404
- .catch(err => { this.log(err) })
405
+ .catch(err => { log(err) })
405
406
  }
406
407
 
407
408
  return true
@@ -444,7 +445,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
444
445
  try {
445
446
  await this.validate(from, msg)
446
447
  } catch (err: any) {
447
- this.log('Message is invalid, dropping it. %O', err)
448
+ log('Message is invalid, dropping it. %O', err)
448
449
  return
449
450
  }
450
451
 
@@ -534,13 +535,13 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
534
535
  const peerStreams = this.peers.get(peer)
535
536
 
536
537
  if (peerStreams == null) {
537
- this.log.error('Cannot send RPC to %p as there are no streams to it available', peer)
538
+ log.error('Cannot send RPC to %p as there are no streams to it available', peer)
538
539
 
539
540
  return
540
541
  }
541
542
 
542
543
  if (!peerStreams.isWritable) {
543
- this.log.error('Cannot send RPC to %p as there is no outbound stream to it available', peer)
544
+ log.error('Cannot send RPC to %p as there is no outbound stream to it available', peer)
544
545
 
545
546
  return
546
547
  }
@@ -663,7 +664,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
663
664
  sequenceNumber: randomSeqno()
664
665
  }
665
666
 
666
- this.log('publish topic: %s from: %p data: %m', topic, message.from, message.data)
667
+ log('publish topic: %s from: %p data: %m', topic, message.from, message.data)
667
668
 
668
669
  const rpcMessage = await this.buildMessage(message)
669
670
  let emittedToSelf = false
@@ -705,7 +706,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
705
706
  throw new Error('Pubsub has not started')
706
707
  }
707
708
 
708
- this.log('subscribe to topic: %s', topic)
709
+ log('subscribe to topic: %s', topic)
709
710
 
710
711
  if (!this.subscriptions.has(topic)) {
711
712
  this.subscriptions.add(topic)
@@ -728,7 +729,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
728
729
 
729
730
  const wasSubscribed = this.subscriptions.has(topic)
730
731
 
731
- this.log('unsubscribe from %s - am subscribed %s', topic, wasSubscribed)
732
+ log('unsubscribe from %s - am subscribed %s', topic, wasSubscribed)
732
733
 
733
734
  if (wasSubscribed) {
734
735
  this.subscriptions.delete(topic)
@@ -1,21 +1,22 @@
1
- import { TypedEventEmitter, CustomEvent } from '@libp2p/interface'
2
- import { closeSource } from '@libp2p/utils/close-source'
1
+ import { TypedEventEmitter, CustomEvent } from '@libp2p/interface/events'
2
+ import { logger } from '@libp2p/logger'
3
+ import { abortableSource } from 'abortable-iterator'
3
4
  import * as lp from 'it-length-prefixed'
4
5
  import { pipe } from 'it-pipe'
5
6
  import { pushable } from 'it-pushable'
6
7
  import { Uint8ArrayList } from 'uint8arraylist'
7
- import type { ComponentLogger, Logger, Stream, PeerId, PeerStreamEvents } from '@libp2p/interface'
8
+ import type { Stream } from '@libp2p/interface/connection'
9
+ import type { PeerId } from '@libp2p/interface/peer-id'
10
+ import type { PeerStreamEvents } from '@libp2p/interface/pubsub'
8
11
  import type { Pushable } from 'it-pushable'
9
12
 
13
+ const log = logger('libp2p-pubsub:peer-streams')
14
+
10
15
  export interface PeerStreamsInit {
11
16
  id: PeerId
12
17
  protocol: string
13
18
  }
14
19
 
15
- export interface PeerStreamsComponents {
16
- logger: ComponentLogger
17
- }
18
-
19
20
  /**
20
21
  * Thin wrapper around a peer's inbound / outbound pubsub streams
21
22
  */
@@ -43,12 +44,10 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
43
44
  */
44
45
  private readonly _inboundAbortController: AbortController
45
46
  private closed: boolean
46
- private readonly log: Logger
47
47
 
48
- constructor (components: PeerStreamsComponents, init: PeerStreamsInit) {
48
+ constructor (init: PeerStreamsInit) {
49
49
  super()
50
50
 
51
- this.log = components.logger.forComponent('libp2p-pubsub:peer-streams')
52
51
  this.id = init.id
53
52
  this.protocol = init.protocol
54
53
 
@@ -87,22 +86,18 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
87
86
  * Attach a raw inbound stream and setup a read stream
88
87
  */
89
88
  attachInboundStream (stream: Stream): AsyncIterable<Uint8ArrayList> {
90
- const abortListener = (): void => {
91
- closeSource(stream.source, this.log)
92
- }
93
-
94
- this._inboundAbortController.signal.addEventListener('abort', abortListener, {
95
- once: true
96
- })
97
-
98
89
  // Create and attach a new inbound stream
99
90
  // The inbound stream is:
100
91
  // - abortable, set to only return on abort, rather than throw
101
92
  // - transformed with length-prefix transform
102
93
  this._rawInboundStream = stream
103
- this.inboundStream = pipe(
104
- this._rawInboundStream,
105
- (source) => lp.decode(source)
94
+ this.inboundStream = abortableSource(
95
+ pipe(
96
+ this._rawInboundStream,
97
+ (source) => lp.decode(source)
98
+ ),
99
+ this._inboundAbortController.signal,
100
+ { returnOnAbort: true }
106
101
  )
107
102
 
108
103
  this.dispatchEvent(new CustomEvent('stream:inbound'))
@@ -122,12 +117,13 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
122
117
 
123
118
  this._rawOutboundStream = stream
124
119
  this.outboundStream = pushable<Uint8ArrayList>({
120
+ objectMode: true,
125
121
  onEnd: (shouldEmit) => {
126
122
  // close writable side of the stream
127
123
  if (this._rawOutboundStream != null) { // eslint-disable-line @typescript-eslint/prefer-optional-chain
128
124
  this._rawOutboundStream.closeWrite()
129
125
  .catch(err => {
130
- this.log('error closing outbound stream', err)
126
+ log('error closing outbound stream', err)
131
127
  })
132
128
  }
133
129
 
@@ -144,7 +140,7 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
144
140
  (source) => lp.encode(source),
145
141
  this._rawOutboundStream
146
142
  ).catch((err: Error) => {
147
- this.log.error(err)
143
+ log.error(err)
148
144
  })
149
145
 
150
146
  // Only emit if the connection is new
package/src/sign.ts CHANGED
@@ -3,7 +3,8 @@ import { peerIdFromKeys } from '@libp2p/peer-id'
3
3
  import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
4
4
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
5
5
  import { toRpcMessage } from './utils.js'
6
- import type { PeerId, PubSubRPCMessage, SignedMessage } from '@libp2p/interface'
6
+ import type { PeerId } from '@libp2p/interface/peer-id'
7
+ import type { PubSubRPCMessage, SignedMessage } from '@libp2p/interface/pubsub'
7
8
 
8
9
  export const SignPrefix = uint8ArrayFromString('libp2p-pubsub:')
9
10
 
package/src/utils.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { randomBytes } from '@libp2p/crypto'
2
- import { CodeError } from '@libp2p/interface'
2
+ import { CodeError } from '@libp2p/interface/errors'
3
3
  import { peerIdFromBytes, peerIdFromKeys } from '@libp2p/peer-id'
4
4
  import { sha256 } from 'multiformats/hashes/sha2'
5
5
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
6
6
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
7
7
  import { codes } from './errors.js'
8
- import type { Message, PubSubRPCMessage } from '@libp2p/interface'
8
+ import type { Message, PubSubRPCMessage } from '@libp2p/interface/pubsub'
9
9
 
10
10
  /**
11
11
  * Generate a random sequence number