@libp2p/pubsub 1.2.4 → 1.2.5

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
@@ -5,9 +5,8 @@ import { pipe } from 'it-pipe'
5
5
  import Queue from 'p-queue'
6
6
  import { Topology } from '@libp2p/topology'
7
7
  import { codes } from './errors.js'
8
- import { RPC, IRPC } from './message/rpc.js'
9
- import { PeerStreams } from './peer-streams.js'
10
- import * as utils from './utils.js'
8
+ import { PeerStreams as PeerStreamsImpl } from './peer-streams.js'
9
+ import { toRpcMessage, toMessage, ensureArray, randomSeqno, noSignMsgId, msgId } from './utils.js'
11
10
  import {
12
11
  signMessage,
13
12
  verifySignature
@@ -15,9 +14,14 @@ import {
15
14
  import type { PeerId } from '@libp2p/interfaces/peer-id'
16
15
  import type { Registrar, IncomingStreamData } from '@libp2p/interfaces/registrar'
17
16
  import type { Connection } from '@libp2p/interfaces/connection'
18
- import type BufferList from 'bl'
19
- import type { PubSub, Message, StrictNoSign, StrictSign, PubsubOptions, PubsubEvents } from '@libp2p/interfaces/pubsub'
17
+ import type { PubSub, Message, StrictNoSign, StrictSign, PubSubOptions, PubSubEvents, RPCMessage, RPC, PeerStreams, RPCSubscription } from '@libp2p/interfaces/pubsub'
20
18
  import type { Logger } from '@libp2p/logger'
19
+ import { base58btc } from 'multiformats/bases/base58'
20
+ import { peerMap } from '@libp2p/peer-map'
21
+ import type { PeerMap } from '@libp2p/peer-map'
22
+ import { peerIdFromString } from '@libp2p/peer-id'
23
+ import type { IRPC } from './message/rpc.js'
24
+ import { RPC as RPCProto } from './message/rpc.js'
21
25
 
22
26
  export interface TopicValidator { (topic: string, message: Message): Promise<void> }
23
27
 
@@ -25,7 +29,7 @@ export interface TopicValidator { (topic: string, message: Message): Promise<voi
25
29
  * PubsubBaseProtocol handles the peers and connections logic for pubsub routers
26
30
  * and specifies the API that pubsub routers should have.
27
31
  */
28
- export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap & PubsubEvents> implements PubSub<EventMap & PubsubEvents> {
32
+ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap & PubSubEvents> implements PubSub<EventMap & PubSubEvents> {
29
33
  public peerId: PeerId
30
34
  public started: boolean
31
35
  /**
@@ -39,11 +43,11 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
39
43
  /**
40
44
  * Map of peer streams
41
45
  */
42
- public peers: Map<string, PeerStreams>
46
+ public peers: PeerMap<PeerStreams>
43
47
  /**
44
48
  * The signature policy to follow by default
45
49
  */
46
- public globalSignaturePolicy: StrictNoSign | StrictSign
50
+ public globalSignaturePolicy: typeof StrictNoSign | typeof StrictSign
47
51
  /**
48
52
  * If router can relay received messages, even if not subscribed
49
53
  */
@@ -61,20 +65,21 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
61
65
  public topicValidators: Map<string, TopicValidator>
62
66
  public queue: Queue
63
67
  public registrar: Registrar
68
+ public multicodecs: string[]
64
69
 
65
70
  protected log: Logger
66
- protected multicodecs: string[]
67
71
  protected _libp2p: any
68
72
  private _registrarHandlerId: string | undefined
69
73
  private _registrarTopologyId: string | undefined
70
74
 
71
- constructor (props: PubsubOptions) {
75
+ constructor (props: PubSubOptions) {
72
76
  super()
73
77
 
74
78
  const {
75
79
  debugName = 'libp2p:pubsub',
76
80
  multicodecs = [],
77
- libp2p = null,
81
+ peerId,
82
+ registrar,
78
83
  globalSignaturePolicy = 'StrictSign',
79
84
  canRelayMessage = false,
80
85
  emitSelf = false,
@@ -82,14 +87,13 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
82
87
  } = props
83
88
 
84
89
  this.log = logger(debugName)
85
- this.multicodecs = utils.ensureArray(multicodecs)
86
- this._libp2p = libp2p
87
- this.registrar = libp2p.registrar
88
- this.peerId = libp2p.peerId
90
+ this.multicodecs = ensureArray(multicodecs)
91
+ this.registrar = registrar
92
+ this.peerId = peerId
89
93
  this.started = false
90
94
  this.topics = new Map()
91
95
  this.subscriptions = new Set()
92
- this.peers = new Map()
96
+ this.peers = peerMap<PeerStreams>()
93
97
  this.globalSignaturePolicy = globalSignaturePolicy === 'StrictNoSign' ? 'StrictNoSign' : 'StrictSign'
94
98
  this.canRelayMessage = canRelayMessage
95
99
  this.emitSelf = emitSelf
@@ -148,9 +152,11 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
148
152
  }
149
153
 
150
154
  this.log('stopping')
151
- this.peers.forEach((peerStreams) => peerStreams.close())
155
+ for (const peerStreams of this.peers.values()) {
156
+ peerStreams.close()
157
+ }
152
158
 
153
- this.peers = new Map()
159
+ this.peers.clear()
154
160
  this.subscriptions = new Set()
155
161
  this.started = false
156
162
  this.log('stopped')
@@ -166,11 +172,10 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
166
172
  protected _onIncomingStream (evt: CustomEvent<IncomingStreamData>) {
167
173
  const { protocol, stream, connection } = evt.detail
168
174
  const peerId = connection.remotePeer
169
- const idB58Str = peerId.toString()
170
175
  const peer = this._addPeer(peerId, protocol)
171
176
  const inboundStream = peer.attachInboundStream(stream)
172
177
 
173
- this._processMessages(idB58Str, inboundStream, peer)
178
+ this._processMessages(peerId, inboundStream, peer)
174
179
  .catch(err => this.log(err))
175
180
  }
176
181
 
@@ -178,8 +183,7 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
178
183
  * Registrar notifies an established connection with pubsub protocol
179
184
  */
180
185
  protected async _onPeerConnected (peerId: PeerId, conn: Connection) {
181
- const idB58Str = peerId.toString()
182
- this.log('connected', idB58Str)
186
+ this.log('connected %p', peerId)
183
187
 
184
188
  try {
185
189
  const { stream, protocol } = await conn.newStream(this.multicodecs)
@@ -190,7 +194,7 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
190
194
  }
191
195
 
192
196
  // Immediately send my own subscriptions to the newly established conn
193
- this._sendSubscriptions(idB58Str, Array.from(this.subscriptions), true)
197
+ this._sendSubscriptions(peerId, Array.from(this.subscriptions), true)
194
198
  }
195
199
 
196
200
  /**
@@ -206,9 +210,8 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
206
210
  /**
207
211
  * Notifies the router that a peer has been connected
208
212
  */
209
- protected _addPeer (peerId: PeerId, protocol: string) {
210
- const id = peerId.toString()
211
- const existing = this.peers.get(id)
213
+ protected _addPeer (peerId: PeerId, protocol: string): PeerStreams {
214
+ const existing = this.peers.get(peerId)
212
215
 
213
216
  // If peer streams already exists, do nothing
214
217
  if (existing != null) {
@@ -216,14 +219,14 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
216
219
  }
217
220
 
218
221
  // else create a new peer streams
219
- this.log('new peer', id)
222
+ this.log('new peer %p', peerId)
220
223
 
221
- const peerStreams = new PeerStreams({
224
+ const peerStreams: PeerStreams = new PeerStreamsImpl({
222
225
  id: peerId,
223
226
  protocol
224
227
  })
225
228
 
226
- this.peers.set(id, peerStreams)
229
+ this.peers.set(peerId, peerStreams)
227
230
  peerStreams.addEventListener('close', () => this._removePeer(peerId), {
228
231
  once: true
229
232
  })
@@ -236,7 +239,7 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
236
239
  */
237
240
  protected _removePeer (peerId: PeerId) {
238
241
  const id = peerId.toString()
239
- const peerStreams = this.peers.get(id)
242
+ const peerStreams = this.peers.get(peerId)
240
243
  if (peerStreams == null) {
241
244
  return
242
245
  }
@@ -245,8 +248,8 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
245
248
  peerStreams.close()
246
249
 
247
250
  // delete peer streams
248
- this.log('delete peer', id)
249
- this.peers.delete(id)
251
+ this.log('delete peer %p', peerId)
252
+ this.peers.delete(peerId)
250
253
 
251
254
  // remove peer from topics map
252
255
  for (const peers of this.topics.values()) {
@@ -261,20 +264,32 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
261
264
  /**
262
265
  * Responsible for processing each RPC message received by other peers.
263
266
  */
264
- async _processMessages (idB58Str: string, stream: AsyncIterable<Uint8Array|BufferList>, peerStreams: PeerStreams) {
267
+ async _processMessages (peerId: PeerId, stream: AsyncIterable<Uint8Array>, peerStreams: PeerStreams) {
265
268
  try {
266
269
  await pipe(
267
270
  stream,
268
271
  async (source) => {
269
272
  for await (const data of source) {
270
- const rpcBytes = data instanceof Uint8Array ? data : data.slice()
271
- const rpcMsg = this._decodeRpc(rpcBytes)
273
+ const rpcMsg = this._decodeRpc(data)
272
274
 
273
275
  // Since _processRpc may be overridden entirely in unsafe ways,
274
276
  // the simplest/safest option here is to wrap in a function and capture all errors
275
277
  // to prevent a top-level unhandled exception
276
278
  // This processing of rpc messages should happen without awaiting full validation/execution of prior messages
277
- this._processRpc(idB58Str, peerStreams, rpcMsg)
279
+ this.processRpc(peerId, peerStreams, {
280
+ subscriptions: (rpcMsg.subscriptions).map(sub => ({
281
+ subscribe: Boolean(sub.subscribe),
282
+ topicID: sub.topicID ?? ''
283
+ })),
284
+ msgs: (rpcMsg.msgs ?? []).map(msg => ({
285
+ from: msg.from ?? peerId.multihash.bytes,
286
+ data: msg.data ?? new Uint8Array(0),
287
+ topicIDs: msg.topicIDs ?? [],
288
+ seqno: msg.seqno ?? undefined,
289
+ signature: msg.signature ?? undefined,
290
+ key: msg.key ?? undefined
291
+ }))
292
+ })
278
293
  .catch(err => this.log(err))
279
294
  }
280
295
  }
@@ -287,23 +302,23 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
287
302
  /**
288
303
  * Handles an rpc request from a peer
289
304
  */
290
- async _processRpc (idB58Str: string, peerStreams: PeerStreams, rpc: RPC) {
291
- this.log('rpc from', idB58Str)
305
+ async processRpc (from: PeerId, peerStreams: PeerStreams, rpc: RPC) {
306
+ this.log('rpc from %p', from)
292
307
  const subs = rpc.subscriptions
293
308
  const msgs = rpc.msgs
294
309
 
295
310
  if (subs.length > 0) {
296
311
  // update peer subscriptions
297
312
  subs.forEach((subOpt) => {
298
- this._processRpcSubOpt(idB58Str, subOpt)
313
+ this._processRpcSubOpt(from, subOpt)
299
314
  })
300
315
  this.dispatchEvent(new CustomEvent('pubsub:subscription-change', {
301
316
  detail: { peerId: peerStreams.id, subscriptions: subs }
302
317
  }))
303
318
  }
304
319
 
305
- if (!this._acceptFrom(idB58Str)) {
306
- this.log('received message from unacceptable peer %s', idB58Str)
320
+ if (!this._acceptFrom(from)) {
321
+ this.log('received message from unacceptable peer %p', from)
307
322
  return false
308
323
  }
309
324
 
@@ -318,9 +333,12 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
318
333
  }
319
334
 
320
335
  try {
321
- const msg = utils.normalizeInRpcMessage(message, idB58Str)
336
+ const msg = toMessage({
337
+ ...message,
338
+ from: from.multihash.bytes
339
+ })
322
340
 
323
- await this._processRpcMessage(msg)
341
+ await this._processMessage(msg)
324
342
  } catch (err: any) {
325
343
  this.log.error(err)
326
344
  }
@@ -333,7 +351,7 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
333
351
  /**
334
352
  * Handles a subscription change from a peer
335
353
  */
336
- _processRpcSubOpt (id: string, subOpt: RPC.ISubOpts) {
354
+ _processRpcSubOpt (id: PeerId, subOpt: RPCSubscription) {
337
355
  const t = subOpt.topicID
338
356
 
339
357
  if (t == null) {
@@ -346,20 +364,20 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
346
364
  this.topics.set(t, topicSet)
347
365
  }
348
366
 
349
- if (subOpt.subscribe === true) {
367
+ if (subOpt.subscribe) {
350
368
  // subscribe peer to new topic
351
- topicSet.add(id)
369
+ topicSet.add(id.toString())
352
370
  } else {
353
371
  // unsubscribe from existing topic
354
- topicSet.delete(id)
372
+ topicSet.delete(id.toString())
355
373
  }
356
374
  }
357
375
 
358
376
  /**
359
377
  * Handles an message from a peer
360
378
  */
361
- async _processRpcMessage (msg: Message) {
362
- if ((msg.from != null) && this.peerId.equals(msg.from) && !this.emitSelf) {
379
+ async _processMessage (msg: Message) {
380
+ if (this.peerId.equals(msg.from) && !this.emitSelf) {
363
381
  return
364
382
  }
365
383
 
@@ -372,15 +390,15 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
372
390
  }
373
391
 
374
392
  // Emit to self
375
- this._emitMessage(msg)
393
+ this.emitMessage(msg)
376
394
 
377
- return await this._publish(utils.normalizeOutRpcMessage(msg))
395
+ return await this._publish(toRpcMessage(msg))
378
396
  }
379
397
 
380
398
  /**
381
399
  * Emit a message from a peer
382
400
  */
383
- _emitMessage (message: Message) {
401
+ emitMessage (message: Message) {
384
402
  message.topicIDs.forEach((topic) => {
385
403
  if (this.subscriptions.has(topic)) {
386
404
  this.dispatchEvent(new CustomEvent(topic, {
@@ -398,10 +416,13 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
398
416
  const signaturePolicy = this.globalSignaturePolicy
399
417
  switch (signaturePolicy) {
400
418
  case 'StrictSign':
401
- // @ts-expect-error seqno is optional in protobuf definition but it will exist
402
- return utils.msgId(msg.from, msg.seqno)
419
+ if (msg.seqno == null) {
420
+ throw errcode(new Error('Need seqno when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_SEQNO)
421
+ }
422
+
423
+ return msgId(msg.from, msg.seqno)
403
424
  case 'StrictNoSign':
404
- return utils.noSignMsgId(msg.data)
425
+ return noSignMsgId(msg.data)
405
426
  default:
406
427
  throw errcode(new Error('Cannot get message id: unhandled signature policy'), codes.ERR_UNHANDLED_SIGNATURE_POLICY)
407
428
  }
@@ -411,7 +432,7 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
411
432
  * Whether to accept a message from a peer
412
433
  * Override to create a graylist
413
434
  */
414
- _acceptFrom (id: string) {
435
+ _acceptFrom (id: PeerId) {
415
436
  return true
416
437
  }
417
438
 
@@ -420,7 +441,7 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
420
441
  * This can be override to use a custom router protobuf.
421
442
  */
422
443
  _decodeRpc (bytes: Uint8Array) {
423
- return RPC.decode(bytes)
444
+ return RPCProto.decode(bytes)
424
445
  }
425
446
 
426
447
  /**
@@ -428,27 +449,29 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
428
449
  * This can be override to use a custom router protobuf.
429
450
  */
430
451
  _encodeRpc (rpc: IRPC) {
431
- return RPC.encode(rpc).finish()
452
+ return RPCProto.encode(rpc).finish()
432
453
  }
433
454
 
434
455
  /**
435
456
  * Send an rpc object to a peer
436
457
  */
437
- _sendRpc (id: string, rpc: IRPC) {
438
- const peerStreams = this.peers.get(id)
439
- if ((peerStreams == null) || !peerStreams.isWritable) {
440
- const msg = `Cannot send RPC to ${id} as there is no open stream to it available`
458
+ _sendRpc (peer: PeerId, rpc: IRPC) {
459
+ const peerStreams = this.peers.get(peer)
460
+
461
+ if (peerStreams == null || !peerStreams.isWritable) {
462
+ const msg = `Cannot send RPC to ${peer.toString(base58btc)} as there is no open stream to it available`
441
463
 
442
464
  this.log.error(msg)
443
465
  return
444
466
  }
467
+
445
468
  peerStreams.write(this._encodeRpc(rpc))
446
469
  }
447
470
 
448
471
  /**
449
472
  * Send subscriptions to a peer
450
473
  */
451
- _sendSubscriptions (id: string, topics: string[], subscribe: boolean) {
474
+ _sendSubscriptions (id: PeerId, topics: string[], subscribe: boolean) {
452
475
  return this._sendRpc(id, {
453
476
  subscriptions: topics.map(t => ({ topicID: t, subscribe: subscribe }))
454
477
  })
@@ -462,9 +485,6 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
462
485
  const signaturePolicy = this.globalSignaturePolicy
463
486
  switch (signaturePolicy) {
464
487
  case 'StrictNoSign':
465
- if (message.from != null) {
466
- throw errcode(new Error('StrictNoSigning: from should not be present'), codes.ERR_UNEXPECTED_FROM)
467
- }
468
488
  if (message.signature != null) {
469
489
  throw errcode(new Error('StrictNoSigning: signature should not be present'), codes.ERR_UNEXPECTED_SIGNATURE)
470
490
  }
@@ -502,12 +522,11 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
502
522
  * Normalizes the message and signs it, if signing is enabled.
503
523
  * Should be used by the routers to create the message to send.
504
524
  */
505
- protected async _buildMessage (message: Message) {
525
+ protected async _maybeSignMessage (message: Message) {
506
526
  const signaturePolicy = this.globalSignaturePolicy
507
527
  switch (signaturePolicy) {
508
528
  case 'StrictSign':
509
- message.from = this.peerId.multihash.bytes
510
- message.seqno = utils.randomSeqno()
529
+ message.seqno = randomSeqno()
511
530
  return await signMessage(this.peerId, message)
512
531
  case 'StrictNoSign':
513
532
  return await Promise.resolve(message)
@@ -536,7 +555,7 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
536
555
  return []
537
556
  }
538
557
 
539
- return Array.from(peersInTopic)
558
+ return Array.from(peersInTopic).map(str => peerIdFromString(str))
540
559
  }
541
560
 
542
561
  /**
@@ -549,29 +568,27 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
549
568
 
550
569
  this.log('publish', topic, message)
551
570
 
552
- const from = this.peerId.toString()
553
571
  const msgObject = {
554
- receivedFrom: from,
572
+ from: this.peerId,
555
573
  data: message,
556
574
  topicIDs: [topic]
557
575
  }
558
576
 
559
577
  // ensure that the message follows the signature policy
560
- const outMsg = await this._buildMessage(msgObject)
561
- const msg = utils.normalizeInRpcMessage(outMsg)
578
+ const msg = await this._maybeSignMessage(msgObject)
562
579
 
563
580
  // Emit to self if I'm interested and emitSelf enabled
564
- this.emitSelf && this._emitMessage(msg)
581
+ this.emitSelf && this.emitMessage(msg)
565
582
 
566
583
  // send to all the other peers
567
- await this._publish(msg)
584
+ await this._publish(toRpcMessage(msg))
568
585
  }
569
586
 
570
587
  /**
571
588
  * Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
572
589
  * For example, a Floodsub implementation might simply publish each message to each topic for every peer
573
590
  */
574
- abstract _publish (message: Message): Promise<void>
591
+ abstract _publish (message: RPCMessage): Promise<void>
575
592
 
576
593
  /**
577
594
  * Subscribes to a given topic.
@@ -583,7 +600,10 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
583
600
 
584
601
  if (!this.subscriptions.has(topic)) {
585
602
  this.subscriptions.add(topic)
586
- this.peers.forEach((_, id) => this._sendSubscriptions(id, [topic], true))
603
+
604
+ for (const peerId of this.peers.keys()) {
605
+ this._sendSubscriptions(peerId, [topic], true)
606
+ }
587
607
  }
588
608
  }
589
609
 
@@ -597,7 +617,10 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
597
617
 
598
618
  if (this.subscriptions.has(topic) && this.listenerCount(topic) === 0) {
599
619
  this.subscriptions.delete(topic)
600
- this.peers.forEach((_, id) => this._sendSubscriptions(id, [topic], false))
620
+
621
+ for (const peerId of this.peers.keys()) {
622
+ this._sendSubscriptions(peerId, [topic], false)
623
+ }
601
624
  }
602
625
  }
603
626
 
@@ -611,4 +634,12 @@ export abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap
611
634
 
612
635
  return Array.from(this.subscriptions)
613
636
  }
637
+
638
+ getPeers () {
639
+ if (!this.started) {
640
+ throw new Error('Pubsub is not started')
641
+ }
642
+
643
+ return Array.from(this.peers.keys())
644
+ }
614
645
  }
@@ -2,10 +2,9 @@ import * as PeerIdFactory from '@libp2p/peer-id-factory'
2
2
  import { RPC } from './rpc.js'
3
3
  import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
4
4
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
5
- import { normalizeOutRpcMessage } from '../utils.js'
5
+ import { toRpcMessage } from '../utils.js'
6
6
  import type { PeerId } from '@libp2p/interfaces/peer-id'
7
7
  import { keys } from '@libp2p/crypto'
8
- import { peerIdFromBytes } from '@libp2p/peer-id'
9
8
  import type { Message } from '@libp2p/interfaces/pubsub'
10
9
 
11
10
  export const SignPrefix = uint8ArrayFromString('libp2p-pubsub:')
@@ -17,7 +16,7 @@ export async function signMessage (peerId: PeerId, message: Message) {
17
16
  // Get the message in bytes, and prepend with the pubsub prefix
18
17
  const bytes = uint8ArrayConcat([
19
18
  SignPrefix,
20
- RPC.Message.encode(normalizeOutRpcMessage(message)).finish()
19
+ RPC.Message.encode(toRpcMessage(message)).finish()
21
20
  ])
22
21
 
23
22
  if (peerId.privateKey == null) {
@@ -56,7 +55,7 @@ export async function verifySignature (message: Message) {
56
55
  const bytes = uint8ArrayConcat([
57
56
  SignPrefix,
58
57
  RPC.Message.encode({
59
- ...message,
58
+ ...toRpcMessage(message),
60
59
  signature: undefined,
61
60
  key: undefined
62
61
  }).finish()
@@ -80,21 +79,19 @@ export async function messagePublicKey (message: Message) {
80
79
  throw new Error('Could not get the public key from the originator id')
81
80
  }
82
81
 
83
- const from = peerIdFromBytes(message.from)
84
-
85
82
  if (message.key != null) {
86
83
  const keyPeerId = await PeerIdFactory.createFromPubKey(keys.unmarshalPublicKey(message.key))
87
84
 
88
85
  // the key belongs to the sender, return the key
89
- if (!keyPeerId.equals(from)) {
86
+ if (!keyPeerId.equals(message.from)) {
90
87
  throw new Error('Public Key does not match the originator')
91
88
  }
92
89
 
93
90
  if (keyPeerId.publicKey != null) {
94
91
  return keyPeerId.publicKey
95
92
  }
96
- } else if (from.publicKey != null) {
97
- return from.publicKey
93
+ } else if (message.from.publicKey != null) {
94
+ return message.from.publicKey
98
95
  }
99
96
 
100
97
  // We couldn't validate pubkey is from the originator, error
@@ -25,19 +25,19 @@ export class PeerStreams extends EventEmitter<PeerStreamEvents> {
25
25
  /**
26
26
  * Write stream - it's preferable to use the write method
27
27
  */
28
- public outboundStream: Pushable<Uint8Array> | undefined
28
+ public outboundStream?: Pushable<Uint8Array>
29
29
  /**
30
30
  * Read stream
31
31
  */
32
- public inboundStream: AsyncIterable<Uint8Array> | undefined
32
+ public inboundStream?: AsyncIterable<Uint8Array>
33
33
  /**
34
34
  * The raw outbound stream, as retrieved from conn.newStream
35
35
  */
36
- private _rawOutboundStream: Stream | undefined
36
+ private _rawOutboundStream?: Stream
37
37
  /**
38
38
  * The raw inbound stream, as retrieved from the callback from libp2p.handle
39
39
  */
40
- private _rawInboundStream: Stream | undefined
40
+ private _rawInboundStream?: Stream
41
41
  /**
42
42
  * An AbortController for controlled shutdown of the inbound stream
43
43
  */
@@ -142,6 +142,8 @@ export class PeerStreams extends EventEmitter<PeerStreamEvents> {
142
142
  if (_prevStream == null) {
143
143
  this.dispatchEvent(new CustomEvent('stream:outbound'))
144
144
  }
145
+
146
+ return this.outboundStream
145
147
  }
146
148
 
147
149
  /**