@libp2p/pubsub 8.0.10-c960eb659 → 8.0.10-d729d66a5

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/src/index.ts CHANGED
@@ -16,7 +16,6 @@
16
16
  import { CodeError } from '@libp2p/interface/errors'
17
17
  import { TypedEventEmitter, CustomEvent } from '@libp2p/interface/events'
18
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'
20
19
  import { PeerMap, PeerSet } from '@libp2p/peer-collections'
21
20
  import { pipe } from 'it-pipe'
22
21
  import Queue from 'p-queue'
@@ -27,16 +26,16 @@ import {
27
26
  verifySignature
28
27
  } from './sign.js'
29
28
  import { toMessage, ensureArray, noSignMsgId, msgId, toRpcMessage, randomSeqno } from './utils.js'
29
+ import type { ComponentLogger, Logger } from '@libp2p/interface'
30
30
  import type { Connection } from '@libp2p/interface/connection'
31
31
  import type { PeerId } from '@libp2p/interface/peer-id'
32
32
  import type { IncomingStreamData, Registrar } from '@libp2p/interface-internal/registrar'
33
33
  import type { Uint8ArrayList } from 'uint8arraylist'
34
34
 
35
- const log = logger('libp2p:pubsub')
36
-
37
35
  export interface PubSubComponents {
38
36
  peerId: PeerId
39
37
  registrar: Registrar
38
+ logger: ComponentLogger
40
39
  }
41
40
 
42
41
  /**
@@ -44,6 +43,8 @@ export interface PubSubComponents {
44
43
  * and specifies the API that pubsub routers should have.
45
44
  */
46
45
  export abstract class PubSubBaseProtocol<Events extends Record<string, any> = PubSubEvents> extends TypedEventEmitter<Events> implements PubSub<Events> {
46
+ protected log: Logger
47
+
47
48
  public started: boolean
48
49
  /**
49
50
  * Map of topics to which peers are subscribed to
@@ -98,6 +99,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
98
99
  maxOutboundStreams = 1
99
100
  } = props
100
101
 
102
+ this.log = components.logger.forComponent('libp2p:pubsub')
101
103
  this.components = components
102
104
  this.multicodecs = ensureArray(multicodecs)
103
105
  this.enabled = props.enabled !== false
@@ -128,7 +130,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
128
130
  return
129
131
  }
130
132
 
131
- log('starting')
133
+ this.log('starting')
132
134
 
133
135
  const registrar = this.components.registrar
134
136
  // Incoming streams
@@ -148,7 +150,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
148
150
  }
149
151
  this._registrarTopologyIds = await Promise.all(this.multicodecs.map(async multicodec => registrar.register(multicodec, topology)))
150
152
 
151
- log('started')
153
+ this.log('started')
152
154
  this.started = true
153
155
  }
154
156
 
@@ -173,7 +175,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
173
175
  await registrar.unhandle(multicodec)
174
176
  }))
175
177
 
176
- log('stopping')
178
+ this.log('stopping')
177
179
  for (const peerStreams of this.peers.values()) {
178
180
  peerStreams.close()
179
181
  }
@@ -181,7 +183,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
181
183
  this.peers.clear()
182
184
  this.subscriptions = new Set()
183
185
  this.started = false
184
- log('stopped')
186
+ this.log('stopped')
185
187
  }
186
188
 
187
189
  isStarted (): boolean {
@@ -204,18 +206,18 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
204
206
  const inboundStream = peer.attachInboundStream(stream)
205
207
 
206
208
  this.processMessages(peerId, inboundStream, peer)
207
- .catch(err => { log(err) })
209
+ .catch(err => { this.log(err) })
208
210
  }
209
211
 
210
212
  /**
211
213
  * Registrar notifies an established connection with pubsub protocol
212
214
  */
213
215
  protected _onPeerConnected (peerId: PeerId, conn: Connection): void {
214
- log('connected %p', peerId)
216
+ this.log('connected %p', peerId)
215
217
 
216
218
  // if this connection is already in use for pubsub, ignore it
217
219
  if (conn.streams.find(stream => stream.direction === 'outbound' && stream.protocol != null && this.multicodecs.includes(stream.protocol)) != null) {
218
- log('outbound pubsub streams already present on connection from %p', peerId)
220
+ this.log('outbound pubsub streams already present on connection from %p', peerId)
219
221
  return
220
222
  }
221
223
 
@@ -231,14 +233,14 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
231
233
  const peer = this.addPeer(peerId, stream.protocol)
232
234
  await peer.attachOutboundStream(stream)
233
235
  } catch (err: any) {
234
- log.error(err)
236
+ this.log.error(err)
235
237
  }
236
238
 
237
239
  // Immediately send my own subscriptions to the newly established conn
238
240
  this.send(peerId, { subscriptions: Array.from(this.subscriptions).map(sub => sub.toString()), subscribe: true })
239
241
  })
240
242
  .catch(err => {
241
- log.error(err)
243
+ this.log.error(err)
242
244
  })
243
245
  }
244
246
 
@@ -248,7 +250,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
248
250
  protected _onPeerDisconnected (peerId: PeerId, conn?: Connection): void {
249
251
  const idB58Str = peerId.toString()
250
252
 
251
- log('connection ended', idB58Str)
253
+ this.log('connection ended', idB58Str)
252
254
  this._removePeer(peerId)
253
255
  }
254
256
 
@@ -264,9 +266,9 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
264
266
  }
265
267
 
266
268
  // else create a new peer streams
267
- log('new peer %p', peerId)
269
+ this.log('new peer %p', peerId)
268
270
 
269
- const peerStreams: PeerStreams = new PeerStreamsImpl({
271
+ const peerStreams: PeerStreams = new PeerStreamsImpl(this.components, {
270
272
  id: peerId,
271
273
  protocol
272
274
  })
@@ -292,7 +294,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
292
294
  peerStreams.close()
293
295
 
294
296
  // delete peer streams
295
- log('delete peer %p', peerId)
297
+ this.log('delete peer %p', peerId)
296
298
  this.peers.delete(peerId)
297
299
 
298
300
  // remove peer from topics map
@@ -319,7 +321,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
319
321
 
320
322
  for (const msg of (rpcMsg.messages ?? [])) {
321
323
  if (msg.from == null || msg.data == null || msg.topic == null) {
322
- log('message from %p was missing from, data or topic fields, dropping', peerId)
324
+ this.log('message from %p was missing from, data or topic fields, dropping', peerId)
323
325
  continue
324
326
  }
325
327
 
@@ -344,7 +346,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
344
346
  })),
345
347
  messages
346
348
  })
347
- .catch(err => { log(err) })
349
+ .catch(err => { this.log(err) })
348
350
  }
349
351
  }
350
352
  )
@@ -358,16 +360,16 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
358
360
  */
359
361
  async processRpc (from: PeerId, peerStreams: PeerStreams, rpc: PubSubRPC): Promise<boolean> {
360
362
  if (!this.acceptFrom(from)) {
361
- log('received message from unacceptable peer %p', from)
363
+ this.log('received message from unacceptable peer %p', from)
362
364
  return false
363
365
  }
364
366
 
365
- log('rpc from %p', from)
367
+ this.log('rpc from %p', from)
366
368
 
367
369
  const { subscriptions, messages } = rpc
368
370
 
369
371
  if (subscriptions != null && subscriptions.length > 0) {
370
- log('subscription update from %p', from)
372
+ this.log('subscription update from %p', from)
371
373
 
372
374
  // update peer subscriptions
373
375
  subscriptions.forEach((subOpt) => {
@@ -386,11 +388,11 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
386
388
  }
387
389
 
388
390
  if (messages != null && messages.length > 0) {
389
- log('messages from %p', from)
391
+ this.log('messages from %p', from)
390
392
 
391
393
  this.queue.addAll(messages.map(message => async () => {
392
394
  if (message.topic == null || (!this.subscriptions.has(message.topic) && !this.canRelayMessage)) {
393
- log('received message we didn\'t subscribe to. Dropping.')
395
+ this.log('received message we didn\'t subscribe to. Dropping.')
394
396
  return false
395
397
  }
396
398
 
@@ -399,10 +401,10 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
399
401
 
400
402
  await this.processMessage(from, msg)
401
403
  } catch (err: any) {
402
- log.error(err)
404
+ this.log.error(err)
403
405
  }
404
406
  }))
405
- .catch(err => { log(err) })
407
+ .catch(err => { this.log(err) })
406
408
  }
407
409
 
408
410
  return true
@@ -445,7 +447,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
445
447
  try {
446
448
  await this.validate(from, msg)
447
449
  } catch (err: any) {
448
- log('Message is invalid, dropping it. %O', err)
450
+ this.log('Message is invalid, dropping it. %O', err)
449
451
  return
450
452
  }
451
453
 
@@ -535,13 +537,13 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
535
537
  const peerStreams = this.peers.get(peer)
536
538
 
537
539
  if (peerStreams == null) {
538
- log.error('Cannot send RPC to %p as there are no streams to it available', peer)
540
+ this.log.error('Cannot send RPC to %p as there are no streams to it available', peer)
539
541
 
540
542
  return
541
543
  }
542
544
 
543
545
  if (!peerStreams.isWritable) {
544
- log.error('Cannot send RPC to %p as there is no outbound stream to it available', peer)
546
+ this.log.error('Cannot send RPC to %p as there is no outbound stream to it available', peer)
545
547
 
546
548
  return
547
549
  }
@@ -664,7 +666,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
664
666
  sequenceNumber: randomSeqno()
665
667
  }
666
668
 
667
- log('publish topic: %s from: %p data: %m', topic, message.from, message.data)
669
+ this.log('publish topic: %s from: %p data: %m', topic, message.from, message.data)
668
670
 
669
671
  const rpcMessage = await this.buildMessage(message)
670
672
  let emittedToSelf = false
@@ -706,7 +708,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
706
708
  throw new Error('Pubsub has not started')
707
709
  }
708
710
 
709
- log('subscribe to topic: %s', topic)
711
+ this.log('subscribe to topic: %s', topic)
710
712
 
711
713
  if (!this.subscriptions.has(topic)) {
712
714
  this.subscriptions.add(topic)
@@ -729,7 +731,7 @@ export abstract class PubSubBaseProtocol<Events extends Record<string, any> = Pu
729
731
 
730
732
  const wasSubscribed = this.subscriptions.has(topic)
731
733
 
732
- log('unsubscribe from %s - am subscribed %s', topic, wasSubscribed)
734
+ this.log('unsubscribe from %s - am subscribed %s', topic, wasSubscribed)
733
735
 
734
736
  if (wasSubscribed) {
735
737
  this.subscriptions.delete(topic)
@@ -1,22 +1,24 @@
1
1
  import { TypedEventEmitter, CustomEvent } from '@libp2p/interface/events'
2
- import { logger } from '@libp2p/logger'
3
- import { abortableSource } from 'abortable-iterator'
2
+ import { closeSource } from '@libp2p/utils/close-source'
4
3
  import * as lp from 'it-length-prefixed'
5
4
  import { pipe } from 'it-pipe'
6
5
  import { pushable } from 'it-pushable'
7
6
  import { Uint8ArrayList } from 'uint8arraylist'
7
+ import type { ComponentLogger, Logger } from '@libp2p/interface'
8
8
  import type { Stream } from '@libp2p/interface/connection'
9
9
  import type { PeerId } from '@libp2p/interface/peer-id'
10
10
  import type { PeerStreamEvents } from '@libp2p/interface/pubsub'
11
11
  import type { Pushable } from 'it-pushable'
12
12
 
13
- const log = logger('libp2p-pubsub:peer-streams')
14
-
15
13
  export interface PeerStreamsInit {
16
14
  id: PeerId
17
15
  protocol: string
18
16
  }
19
17
 
18
+ export interface PeerStreamsComponents {
19
+ logger: ComponentLogger
20
+ }
21
+
20
22
  /**
21
23
  * Thin wrapper around a peer's inbound / outbound pubsub streams
22
24
  */
@@ -44,10 +46,12 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
44
46
  */
45
47
  private readonly _inboundAbortController: AbortController
46
48
  private closed: boolean
49
+ private readonly log: Logger
47
50
 
48
- constructor (init: PeerStreamsInit) {
51
+ constructor (components: PeerStreamsComponents, init: PeerStreamsInit) {
49
52
  super()
50
53
 
54
+ this.log = components.logger.forComponent('libp2p-pubsub:peer-streams')
51
55
  this.id = init.id
52
56
  this.protocol = init.protocol
53
57
 
@@ -86,18 +90,22 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
86
90
  * Attach a raw inbound stream and setup a read stream
87
91
  */
88
92
  attachInboundStream (stream: Stream): AsyncIterable<Uint8ArrayList> {
93
+ const abortListener = (): void => {
94
+ closeSource(stream.source, this.log)
95
+ }
96
+
97
+ this._inboundAbortController.signal.addEventListener('abort', abortListener, {
98
+ once: true
99
+ })
100
+
89
101
  // Create and attach a new inbound stream
90
102
  // The inbound stream is:
91
103
  // - abortable, set to only return on abort, rather than throw
92
104
  // - transformed with length-prefix transform
93
105
  this._rawInboundStream = stream
94
- this.inboundStream = abortableSource(
95
- pipe(
96
- this._rawInboundStream,
97
- (source) => lp.decode(source)
98
- ),
99
- this._inboundAbortController.signal,
100
- { returnOnAbort: true }
106
+ this.inboundStream = pipe(
107
+ this._rawInboundStream,
108
+ (source) => lp.decode(source)
101
109
  )
102
110
 
103
111
  this.dispatchEvent(new CustomEvent('stream:inbound'))
@@ -117,13 +125,12 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
117
125
 
118
126
  this._rawOutboundStream = stream
119
127
  this.outboundStream = pushable<Uint8ArrayList>({
120
- objectMode: true,
121
128
  onEnd: (shouldEmit) => {
122
129
  // close writable side of the stream
123
130
  if (this._rawOutboundStream != null) { // eslint-disable-line @typescript-eslint/prefer-optional-chain
124
131
  this._rawOutboundStream.closeWrite()
125
132
  .catch(err => {
126
- log('error closing outbound stream', err)
133
+ this.log('error closing outbound stream', err)
127
134
  })
128
135
  }
129
136
 
@@ -140,7 +147,7 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
140
147
  (source) => lp.encode(source),
141
148
  this._rawOutboundStream
142
149
  ).catch((err: Error) => {
143
- log.error(err)
150
+ this.log.error(err)
144
151
  })
145
152
 
146
153
  // Only emit if the connection is new