@libp2p/pubsub 1.2.7 → 1.2.10
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/README.md +2 -2
- package/dist/src/index.d.ts +34 -25
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +86 -93
- package/dist/src/index.js.map +1 -1
- package/dist/src/peer-streams.d.ts +2 -2
- package/dist/src/peer-streams.d.ts.map +1 -1
- package/dist/src/peer-streams.js +3 -3
- package/dist/src/peer-streams.js.map +1 -1
- package/dist/src/{message/sign.d.ts → sign.d.ts} +3 -3
- package/dist/src/sign.d.ts.map +1 -0
- package/dist/src/{message/sign.js → sign.js} +6 -7
- package/dist/src/sign.js.map +1 -0
- package/dist/src/utils.d.ts +3 -4
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +2 -2
- package/dist/src/utils.js.map +1 -1
- package/package.json +21 -28
- package/src/index.ts +120 -109
- package/src/peer-streams.ts +4 -4
- package/src/{message/sign.ts → sign.ts} +7 -8
- package/src/utils.ts +5 -6
- package/dist/src/message/rpc.d.ts +0 -669
- package/dist/src/message/rpc.js +0 -1870
- package/dist/src/message/sign.d.ts.map +0 -1
- package/dist/src/message/sign.js.map +0 -1
- package/dist/src/message/topic-descriptor.d.ts +0 -254
- package/dist/src/message/topic-descriptor.js +0 -647
- package/src/message/rpc.d.ts +0 -669
- package/src/message/rpc.js +0 -1870
- package/src/message/rpc.proto +0 -54
- package/src/message/topic-descriptor.d.ts +0 -254
- package/src/message/topic-descriptor.js +0 -647
- package/src/message/topic-descriptor.proto +0 -30
package/README.md
CHANGED
@@ -15,9 +15,9 @@ npm i libp2p-pubsub
|
|
15
15
|
```
|
16
16
|
|
17
17
|
```javascript
|
18
|
-
import {
|
18
|
+
import { PubSubBaseProtocol } from '@libp2p/pubsub'
|
19
19
|
|
20
|
-
class MyPubsubImplementation extends
|
20
|
+
class MyPubsubImplementation extends PubSubBaseProtocol {
|
21
21
|
// .. extra methods here
|
22
22
|
}
|
23
23
|
```
|
package/dist/src/index.d.ts
CHANGED
@@ -1,27 +1,24 @@
|
|
1
1
|
import { EventEmitter, EventHandler } from '@libp2p/interfaces';
|
2
2
|
import Queue from 'p-queue';
|
3
3
|
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
4
|
-
import type {
|
4
|
+
import type { IncomingStreamData } from '@libp2p/interfaces/registrar';
|
5
5
|
import type { Connection } from '@libp2p/interfaces/connection';
|
6
|
-
import type { PubSub, Message, StrictNoSign, StrictSign,
|
7
|
-
import
|
8
|
-
import
|
9
|
-
import type { IRPC } from './message/rpc.js';
|
10
|
-
import { RPC as RPCProto } from './message/rpc.js';
|
6
|
+
import type { PubSub, Message, StrictNoSign, StrictSign, PubSubInit, PubSubEvents, PeerStreams, PubSubRPCMessage, PubSubRPC, PubSubRPCSubscription } from '@libp2p/interfaces/pubsub';
|
7
|
+
import { PeerMap, PeerSet } from '@libp2p/peer-collections';
|
8
|
+
import { Components, Initializable } from '@libp2p/interfaces/components';
|
11
9
|
export interface TopicValidator {
|
12
10
|
(topic: string, message: Message): Promise<void>;
|
13
11
|
}
|
14
12
|
/**
|
15
|
-
*
|
13
|
+
* PubSubBaseProtocol handles the peers and connections logic for pubsub routers
|
16
14
|
* and specifies the API that pubsub routers should have.
|
17
15
|
*/
|
18
|
-
export declare abstract class
|
19
|
-
peerId: PeerId;
|
16
|
+
export declare abstract class PubSubBaseProtocol<EventMap extends PubSubEvents = PubSubEvents> extends EventEmitter<EventMap & PubSubEvents> implements PubSub<EventMap & PubSubEvents>, Initializable {
|
20
17
|
started: boolean;
|
21
18
|
/**
|
22
19
|
* Map of topics to which peers are subscribed to
|
23
20
|
*/
|
24
|
-
topics: Map<string,
|
21
|
+
topics: Map<string, PeerSet>;
|
25
22
|
/**
|
26
23
|
* List of our subscriptions
|
27
24
|
*/
|
@@ -50,13 +47,12 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
|
|
50
47
|
*/
|
51
48
|
topicValidators: Map<string, TopicValidator>;
|
52
49
|
queue: Queue;
|
53
|
-
registrar: Registrar;
|
54
50
|
multicodecs: string[];
|
55
|
-
|
56
|
-
protected _libp2p: any;
|
57
|
-
private _registrarHandlerId;
|
51
|
+
components: Components;
|
58
52
|
private _registrarTopologyId;
|
59
|
-
|
53
|
+
protected enabled: boolean;
|
54
|
+
constructor(props: PubSubInit);
|
55
|
+
init(components: Components): void;
|
60
56
|
/**
|
61
57
|
* Register the pubsub protocol onto the libp2p node.
|
62
58
|
*
|
@@ -71,7 +67,7 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
|
|
71
67
|
/**
|
72
68
|
* On an inbound stream opened
|
73
69
|
*/
|
74
|
-
protected _onIncomingStream(
|
70
|
+
protected _onIncomingStream(data: IncomingStreamData): void;
|
75
71
|
/**
|
76
72
|
* Registrar notifies an established connection with pubsub protocol
|
77
73
|
*/
|
@@ -95,13 +91,13 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
|
|
95
91
|
/**
|
96
92
|
* Handles an rpc request from a peer
|
97
93
|
*/
|
98
|
-
processRpc(from: PeerId, peerStreams: PeerStreams, rpc:
|
94
|
+
processRpc(from: PeerId, peerStreams: PeerStreams, rpc: PubSubRPC): Promise<boolean>;
|
99
95
|
/**
|
100
96
|
* Handles a subscription change from a peer
|
101
97
|
*/
|
102
|
-
processRpcSubOpt(id: PeerId, subOpt:
|
98
|
+
processRpcSubOpt(id: PeerId, subOpt: PubSubRPCSubscription): void;
|
103
99
|
/**
|
104
|
-
* Handles
|
100
|
+
* Handles a message from a peer
|
105
101
|
*/
|
106
102
|
processMessage(from: PeerId, msg: Message): Promise<void>;
|
107
103
|
/**
|
@@ -118,12 +114,22 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
|
|
118
114
|
* Decode Uint8Array into an RPC object.
|
119
115
|
* This can be override to use a custom router protobuf.
|
120
116
|
*/
|
121
|
-
decodeRpc(bytes: Uint8Array):
|
117
|
+
abstract decodeRpc(bytes: Uint8Array): PubSubRPC;
|
122
118
|
/**
|
123
119
|
* Encode RPC object into a Uint8Array.
|
124
120
|
* This can be override to use a custom router protobuf.
|
125
121
|
*/
|
126
|
-
encodeRpc(rpc:
|
122
|
+
abstract encodeRpc(rpc: PubSubRPC): Uint8Array;
|
123
|
+
/**
|
124
|
+
* Decode Uint8Array into an RPC object.
|
125
|
+
* This can be override to use a custom router protobuf.
|
126
|
+
*/
|
127
|
+
abstract decodeMessage(bytes: Uint8Array): PubSubRPCMessage;
|
128
|
+
/**
|
129
|
+
* Encode RPC object into a Uint8Array.
|
130
|
+
* This can be override to use a custom router protobuf.
|
131
|
+
*/
|
132
|
+
abstract encodeMessage(rpc: PubSubRPCMessage): Uint8Array;
|
127
133
|
/**
|
128
134
|
* Send an rpc object to a peer
|
129
135
|
*/
|
@@ -135,7 +141,7 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
|
|
135
141
|
/**
|
136
142
|
* Send an rpc object to a peer
|
137
143
|
*/
|
138
|
-
sendRpc(peer: PeerId, rpc:
|
144
|
+
sendRpc(peer: PeerId, rpc: PubSubRPC): void;
|
139
145
|
/**
|
140
146
|
* Validates the given message. The signature will be checked for authenticity.
|
141
147
|
* Throws an error on invalid messages
|
@@ -153,12 +159,15 @@ export declare abstract class PubsubBaseProtocol<EventMap extends PubSubEvents =
|
|
153
159
|
/**
|
154
160
|
* Publishes messages to all subscribed peers
|
155
161
|
*/
|
156
|
-
dispatchEvent(event: CustomEvent): boolean;
|
162
|
+
dispatchEvent(event: CustomEvent<Uint8Array | Message>): boolean;
|
157
163
|
/**
|
158
164
|
* Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
|
159
|
-
* For example, a Floodsub implementation might simply publish each message to each topic for every peer
|
165
|
+
* For example, a Floodsub implementation might simply publish each message to each topic for every peer.
|
166
|
+
*
|
167
|
+
* `sender` might be this peer, or we might be forwarding a message on behalf of another peer, in which case sender
|
168
|
+
* is the peer we received the message from, which may not be the peer the message was created by.
|
160
169
|
*/
|
161
|
-
abstract publishMessage(
|
170
|
+
abstract publishMessage(sender: PeerId, message: Message): Promise<void>;
|
162
171
|
/**
|
163
172
|
* Subscribes to a given topic.
|
164
173
|
*/
|
package/dist/src/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAe,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAG5E,OAAO,KAAK,MAAM,SAAS,CAAA;AAS3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
@@ -3,31 +3,29 @@ import { EventEmitter, CustomEvent } from '@libp2p/interfaces';
|
|
3
3
|
import errcode from 'err-code';
|
4
4
|
import { pipe } from 'it-pipe';
|
5
5
|
import Queue from 'p-queue';
|
6
|
-
import {
|
6
|
+
import { createTopology } from '@libp2p/topology';
|
7
7
|
import { codes } from './errors.js';
|
8
8
|
import { PeerStreams as PeerStreamsImpl } from './peer-streams.js';
|
9
9
|
import { toMessage, ensureArray, randomSeqno, noSignMsgId, msgId, toRpcMessage } from './utils.js';
|
10
|
-
import { signMessage, verifySignature } from './
|
11
|
-
import {
|
12
|
-
import {
|
13
|
-
|
14
|
-
import { RPC as RPCProto } from './message/rpc.js';
|
10
|
+
import { signMessage, verifySignature } from './sign.js';
|
11
|
+
import { PeerMap, PeerSet } from '@libp2p/peer-collections';
|
12
|
+
import { Components } from '@libp2p/interfaces/components';
|
13
|
+
const log = logger('libp2p:pubsub');
|
15
14
|
/**
|
16
|
-
*
|
15
|
+
* PubSubBaseProtocol handles the peers and connections logic for pubsub routers
|
17
16
|
* and specifies the API that pubsub routers should have.
|
18
17
|
*/
|
19
|
-
export class
|
18
|
+
export class PubSubBaseProtocol extends EventEmitter {
|
20
19
|
constructor(props) {
|
21
20
|
super();
|
22
|
-
|
23
|
-
|
21
|
+
this.components = new Components();
|
22
|
+
const { multicodecs = [], globalSignaturePolicy = 'StrictSign', canRelayMessage = false, emitSelf = false, messageProcessingConcurrency = 10 } = props;
|
24
23
|
this.multicodecs = ensureArray(multicodecs);
|
25
|
-
this.
|
26
|
-
this.peerId = peerId;
|
24
|
+
this.enabled = props.enabled !== false;
|
27
25
|
this.started = false;
|
28
26
|
this.topics = new Map();
|
29
27
|
this.subscriptions = new Set();
|
30
|
-
this.peers =
|
28
|
+
this.peers = new PeerMap();
|
31
29
|
this.globalSignaturePolicy = globalSignaturePolicy === 'StrictNoSign' ? 'StrictNoSign' : 'StrictSign';
|
32
30
|
this.canRelayMessage = canRelayMessage;
|
33
31
|
this.emitSelf = emitSelf;
|
@@ -37,6 +35,9 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
37
35
|
this._onPeerConnected = this._onPeerConnected.bind(this);
|
38
36
|
this._onPeerDisconnected = this._onPeerDisconnected.bind(this);
|
39
37
|
}
|
38
|
+
init(components) {
|
39
|
+
this.components = components;
|
40
|
+
}
|
40
41
|
// LIFECYCLE METHODS
|
41
42
|
/**
|
42
43
|
* Register the pubsub protocol onto the libp2p node.
|
@@ -44,45 +45,43 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
44
45
|
* @returns {void}
|
45
46
|
*/
|
46
47
|
async start() {
|
47
|
-
if (this.started) {
|
48
|
+
if (this.started || !this.enabled) {
|
48
49
|
return;
|
49
50
|
}
|
50
|
-
|
51
|
+
log('starting');
|
51
52
|
// Incoming streams
|
52
53
|
// Called after a peer dials us
|
53
|
-
|
54
|
+
await this.components.getRegistrar().handle(this.multicodecs, this._onIncomingStream);
|
54
55
|
// register protocol with topology
|
55
56
|
// Topology callbacks called on connection manager changes
|
56
|
-
const topology =
|
57
|
+
const topology = createTopology({
|
57
58
|
onConnect: this._onPeerConnected,
|
58
59
|
onDisconnect: this._onPeerDisconnected
|
59
60
|
});
|
60
|
-
this._registrarTopologyId = this.
|
61
|
-
|
61
|
+
this._registrarTopologyId = await this.components.getRegistrar().register(this.multicodecs, topology);
|
62
|
+
log('started');
|
62
63
|
this.started = true;
|
63
64
|
}
|
64
65
|
/**
|
65
66
|
* Unregister the pubsub protocol and the streams with other peers will be closed.
|
66
67
|
*/
|
67
68
|
async stop() {
|
68
|
-
if (!this.started) {
|
69
|
+
if (!this.started || !this.enabled) {
|
69
70
|
return;
|
70
71
|
}
|
71
72
|
// unregister protocol and handlers
|
72
73
|
if (this._registrarTopologyId != null) {
|
73
|
-
this.
|
74
|
+
this.components.getRegistrar().unregister(this._registrarTopologyId);
|
74
75
|
}
|
75
|
-
|
76
|
-
|
77
|
-
}
|
78
|
-
this.log('stopping');
|
76
|
+
await this.components.getRegistrar().unhandle(this.multicodecs);
|
77
|
+
log('stopping');
|
79
78
|
for (const peerStreams of this.peers.values()) {
|
80
79
|
peerStreams.close();
|
81
80
|
}
|
82
81
|
this.peers.clear();
|
83
82
|
this.subscriptions = new Set();
|
84
83
|
this.started = false;
|
85
|
-
|
84
|
+
log('stopped');
|
86
85
|
}
|
87
86
|
isStarted() {
|
88
87
|
return this.started;
|
@@ -90,26 +89,26 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
90
89
|
/**
|
91
90
|
* On an inbound stream opened
|
92
91
|
*/
|
93
|
-
_onIncomingStream(
|
94
|
-
const { protocol, stream, connection } =
|
92
|
+
_onIncomingStream(data) {
|
93
|
+
const { protocol, stream, connection } = data;
|
95
94
|
const peerId = connection.remotePeer;
|
96
95
|
const peer = this.addPeer(peerId, protocol);
|
97
96
|
const inboundStream = peer.attachInboundStream(stream);
|
98
97
|
this.processMessages(peerId, inboundStream, peer)
|
99
|
-
.catch(err =>
|
98
|
+
.catch(err => log(err));
|
100
99
|
}
|
101
100
|
/**
|
102
101
|
* Registrar notifies an established connection with pubsub protocol
|
103
102
|
*/
|
104
103
|
async _onPeerConnected(peerId, conn) {
|
105
|
-
|
104
|
+
log('connected %p', peerId);
|
106
105
|
try {
|
107
106
|
const { stream, protocol } = await conn.newStream(this.multicodecs);
|
108
107
|
const peer = this.addPeer(peerId, protocol);
|
109
108
|
await peer.attachOutboundStream(stream);
|
110
109
|
}
|
111
110
|
catch (err) {
|
112
|
-
|
111
|
+
log.error(err);
|
113
112
|
}
|
114
113
|
// Immediately send my own subscriptions to the newly established conn
|
115
114
|
this.send(peerId, { subscriptions: Array.from(this.subscriptions).map(sub => sub.toString()), subscribe: true });
|
@@ -119,7 +118,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
119
118
|
*/
|
120
119
|
_onPeerDisconnected(peerId, conn) {
|
121
120
|
const idB58Str = peerId.toString();
|
122
|
-
|
121
|
+
log('connection ended', idB58Str);
|
123
122
|
this._removePeer(peerId);
|
124
123
|
}
|
125
124
|
/**
|
@@ -132,7 +131,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
132
131
|
return existing;
|
133
132
|
}
|
134
133
|
// else create a new peer streams
|
135
|
-
|
134
|
+
log('new peer %p', peerId);
|
136
135
|
const peerStreams = new PeerStreamsImpl({
|
137
136
|
id: peerId,
|
138
137
|
protocol
|
@@ -147,7 +146,6 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
147
146
|
* Notifies the router that a peer has been disconnected
|
148
147
|
*/
|
149
148
|
_removePeer(peerId) {
|
150
|
-
const id = peerId.toString();
|
151
149
|
const peerStreams = this.peers.get(peerId);
|
152
150
|
if (peerStreams == null) {
|
153
151
|
return;
|
@@ -155,11 +153,11 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
155
153
|
// close peer streams
|
156
154
|
peerStreams.close();
|
157
155
|
// delete peer streams
|
158
|
-
|
156
|
+
log('delete peer %p', peerId);
|
159
157
|
this.peers.delete(peerId);
|
160
158
|
// remove peer from topics map
|
161
159
|
for (const peers of this.topics.values()) {
|
162
|
-
peers.delete(
|
160
|
+
peers.delete(peerId);
|
163
161
|
}
|
164
162
|
return peerStreams;
|
165
163
|
}
|
@@ -175,14 +173,14 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
175
173
|
const messages = [];
|
176
174
|
for (const msg of (rpcMsg.messages ?? [])) {
|
177
175
|
if (msg.from == null || msg.data == null || msg.topic == null) {
|
178
|
-
|
176
|
+
log('message from %p was missing from, data or topic fields, dropping', peerId);
|
179
177
|
continue;
|
180
178
|
}
|
181
179
|
messages.push({
|
182
180
|
from: msg.from,
|
183
181
|
data: msg.data,
|
184
182
|
topic: msg.topic,
|
185
|
-
|
183
|
+
sequenceNumber: msg.sequenceNumber ?? undefined,
|
186
184
|
signature: msg.signature ?? undefined,
|
187
185
|
key: msg.key ?? undefined
|
188
186
|
});
|
@@ -192,13 +190,13 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
192
190
|
// to prevent a top-level unhandled exception
|
193
191
|
// This processing of rpc messages should happen without awaiting full validation/execution of prior messages
|
194
192
|
this.processRpc(peerId, peerStreams, {
|
195
|
-
subscriptions: (rpcMsg.subscriptions).map(sub => ({
|
193
|
+
subscriptions: (rpcMsg.subscriptions ?? []).map(sub => ({
|
196
194
|
subscribe: Boolean(sub.subscribe),
|
197
195
|
topic: sub.topic ?? ''
|
198
196
|
})),
|
199
197
|
messages
|
200
198
|
})
|
201
|
-
.catch(err =>
|
199
|
+
.catch(err => log(err));
|
202
200
|
}
|
203
201
|
});
|
204
202
|
}
|
@@ -211,38 +209,45 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
211
209
|
*/
|
212
210
|
async processRpc(from, peerStreams, rpc) {
|
213
211
|
if (!this.acceptFrom(from)) {
|
214
|
-
|
215
|
-
return;
|
212
|
+
log('received message from unacceptable peer %p', from);
|
213
|
+
return false;
|
216
214
|
}
|
217
|
-
|
215
|
+
log('rpc from %p', from);
|
218
216
|
const { subscriptions, messages } = rpc;
|
219
|
-
if (subscriptions.length > 0) {
|
220
|
-
|
217
|
+
if (subscriptions != null && subscriptions.length > 0) {
|
218
|
+
log('subscription update from %p', from);
|
221
219
|
// update peer subscriptions
|
222
220
|
subscriptions.forEach((subOpt) => {
|
223
221
|
this.processRpcSubOpt(from, subOpt);
|
224
222
|
});
|
225
223
|
super.dispatchEvent(new CustomEvent('pubsub:subscription-change', {
|
226
|
-
detail: {
|
224
|
+
detail: {
|
225
|
+
peerId: peerStreams.id,
|
226
|
+
subscriptions: subscriptions.map(({ topic, subscribe }) => ({
|
227
|
+
topic: `${topic ?? ''}`,
|
228
|
+
subscribe: Boolean(subscribe)
|
229
|
+
}))
|
230
|
+
}
|
227
231
|
}));
|
228
232
|
}
|
229
|
-
if (messages.length > 0) {
|
230
|
-
|
233
|
+
if (messages != null && messages.length > 0) {
|
234
|
+
log('messages from %p', from);
|
231
235
|
this.queue.addAll(messages.map(message => async () => {
|
232
|
-
if (!this.subscriptions.has(message.topic) && !this.canRelayMessage) {
|
233
|
-
|
234
|
-
return;
|
236
|
+
if (message.topic == null || (!this.subscriptions.has(message.topic) && !this.canRelayMessage)) {
|
237
|
+
log('received message we didn\'t subscribe to. Dropping.');
|
238
|
+
return false;
|
235
239
|
}
|
236
240
|
try {
|
237
241
|
const msg = await toMessage(message);
|
238
242
|
await this.processMessage(from, msg);
|
239
243
|
}
|
240
244
|
catch (err) {
|
241
|
-
|
245
|
+
log.error(err);
|
242
246
|
}
|
243
247
|
}))
|
244
|
-
.catch(err =>
|
248
|
+
.catch(err => log(err));
|
245
249
|
}
|
250
|
+
return true;
|
246
251
|
}
|
247
252
|
/**
|
248
253
|
* Handles a subscription change from a peer
|
@@ -254,23 +259,23 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
254
259
|
}
|
255
260
|
let topicSet = this.topics.get(t);
|
256
261
|
if (topicSet == null) {
|
257
|
-
topicSet = new
|
262
|
+
topicSet = new PeerSet();
|
258
263
|
this.topics.set(t, topicSet);
|
259
264
|
}
|
260
|
-
if (subOpt.subscribe) {
|
265
|
+
if (subOpt.subscribe === true) {
|
261
266
|
// subscribe peer to new topic
|
262
|
-
topicSet.add(id
|
267
|
+
topicSet.add(id);
|
263
268
|
}
|
264
269
|
else {
|
265
270
|
// unsubscribe from existing topic
|
266
|
-
topicSet.delete(id
|
271
|
+
topicSet.delete(id);
|
267
272
|
}
|
268
273
|
}
|
269
274
|
/**
|
270
|
-
* Handles
|
275
|
+
* Handles a message from a peer
|
271
276
|
*/
|
272
277
|
async processMessage(from, msg) {
|
273
|
-
if (this.
|
278
|
+
if (this.components.getPeerId().equals(from) && !this.emitSelf) {
|
274
279
|
return;
|
275
280
|
}
|
276
281
|
// Ensure the message is valid before processing it
|
@@ -278,11 +283,11 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
278
283
|
await this.validate(msg);
|
279
284
|
}
|
280
285
|
catch (err) {
|
281
|
-
|
286
|
+
log('Message is invalid, dropping it. %O', err);
|
282
287
|
return;
|
283
288
|
}
|
284
289
|
if (this.subscriptions.has(msg.topic)) {
|
285
|
-
const isFromSelf = this.
|
290
|
+
const isFromSelf = this.components.getPeerId().equals(from);
|
286
291
|
if (!isFromSelf || this.emitSelf) {
|
287
292
|
super.dispatchEvent(new CustomEvent(msg.topic, {
|
288
293
|
detail: msg
|
@@ -299,13 +304,13 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
299
304
|
const signaturePolicy = this.globalSignaturePolicy;
|
300
305
|
switch (signaturePolicy) {
|
301
306
|
case 'StrictSign':
|
302
|
-
if (msg.
|
307
|
+
if (msg.sequenceNumber == null) {
|
303
308
|
throw errcode(new Error('Need seqno when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_SEQNO);
|
304
309
|
}
|
305
310
|
if (msg.key == null) {
|
306
311
|
throw errcode(new Error('Need key when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_KEY);
|
307
312
|
}
|
308
|
-
return msgId(msg.key, msg.
|
313
|
+
return msgId(msg.key, msg.sequenceNumber);
|
309
314
|
case 'StrictNoSign':
|
310
315
|
return noSignMsgId(msg.data);
|
311
316
|
default:
|
@@ -319,20 +324,6 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
319
324
|
acceptFrom(id) {
|
320
325
|
return true;
|
321
326
|
}
|
322
|
-
/**
|
323
|
-
* Decode Uint8Array into an RPC object.
|
324
|
-
* This can be override to use a custom router protobuf.
|
325
|
-
*/
|
326
|
-
decodeRpc(bytes) {
|
327
|
-
return RPCProto.decode(bytes);
|
328
|
-
}
|
329
|
-
/**
|
330
|
-
* Encode RPC object into a Uint8Array.
|
331
|
-
* This can be override to use a custom router protobuf.
|
332
|
-
*/
|
333
|
-
encodeRpc(rpc) {
|
334
|
-
return RPCProto.encode(rpc).finish();
|
335
|
-
}
|
336
327
|
/**
|
337
328
|
* Send an rpc object to a peer
|
338
329
|
*/
|
@@ -349,8 +340,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
349
340
|
sendRpc(peer, rpc) {
|
350
341
|
const peerStreams = this.peers.get(peer);
|
351
342
|
if (peerStreams == null || !peerStreams.isWritable) {
|
352
|
-
|
353
|
-
this.log.error(msg);
|
343
|
+
log.error('Cannot send RPC to %p as there is no open stream to it available', peer);
|
354
344
|
return;
|
355
345
|
}
|
356
346
|
peerStreams.write(this.encodeRpc(rpc));
|
@@ -369,7 +359,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
369
359
|
if (message.key != null) {
|
370
360
|
throw errcode(new Error('StrictNoSigning: key should not be present'), codes.ERR_UNEXPECTED_KEY);
|
371
361
|
}
|
372
|
-
if (message.
|
362
|
+
if (message.sequenceNumber != null) {
|
373
363
|
throw errcode(new Error('StrictNoSigning: seqno should not be present'), codes.ERR_UNEXPECTED_SEQNO);
|
374
364
|
}
|
375
365
|
break;
|
@@ -377,10 +367,10 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
377
367
|
if (message.signature == null) {
|
378
368
|
throw errcode(new Error('StrictSigning: Signing required and no signature was present'), codes.ERR_MISSING_SIGNATURE);
|
379
369
|
}
|
380
|
-
if (message.
|
370
|
+
if (message.sequenceNumber == null) {
|
381
371
|
throw errcode(new Error('StrictSigning: Signing required and no seqno was present'), codes.ERR_MISSING_SEQNO);
|
382
372
|
}
|
383
|
-
if (!(await verifySignature(message))) {
|
373
|
+
if (!(await verifySignature(message, this.encodeMessage.bind(this)))) {
|
384
374
|
throw errcode(new Error('StrictSigning: Invalid message signature'), codes.ERR_INVALID_SIGNATURE);
|
385
375
|
}
|
386
376
|
break;
|
@@ -400,8 +390,8 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
400
390
|
const signaturePolicy = this.globalSignaturePolicy;
|
401
391
|
switch (signaturePolicy) {
|
402
392
|
case 'StrictSign':
|
403
|
-
message.
|
404
|
-
return await signMessage(this.
|
393
|
+
message.sequenceNumber = randomSeqno();
|
394
|
+
return await signMessage(this.components.getPeerId(), message, this.encodeMessage.bind(this));
|
405
395
|
case 'StrictNoSign':
|
406
396
|
return await Promise.resolve(message);
|
407
397
|
default:
|
@@ -423,7 +413,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
423
413
|
if (peersInTopic == null) {
|
424
414
|
return [];
|
425
415
|
}
|
426
|
-
return Array.from(peersInTopic
|
416
|
+
return Array.from(peersInTopic.values());
|
427
417
|
}
|
428
418
|
/**
|
429
419
|
* Publishes messages to all subscribed peers
|
@@ -433,15 +423,18 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
433
423
|
throw new Error('Pubsub has not started');
|
434
424
|
}
|
435
425
|
const topic = event.type;
|
436
|
-
let message
|
437
|
-
if (
|
426
|
+
let message;
|
427
|
+
if (event.detail instanceof Uint8Array) {
|
438
428
|
message = {
|
439
|
-
from: this.
|
429
|
+
from: this.components.getPeerId(),
|
440
430
|
topic,
|
441
|
-
data:
|
431
|
+
data: event.detail
|
442
432
|
};
|
443
433
|
}
|
444
|
-
|
434
|
+
else {
|
435
|
+
message = event.detail;
|
436
|
+
}
|
437
|
+
log('publish topic: %s from: %p data: %m', topic, message.from, message.data);
|
445
438
|
Promise.resolve().then(async () => {
|
446
439
|
message = await this.buildMessage(message);
|
447
440
|
// dispatch the event if we are interested
|
@@ -456,10 +449,10 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
456
449
|
}
|
457
450
|
}
|
458
451
|
// send to all the other peers
|
459
|
-
await this.publishMessage(this.
|
452
|
+
await this.publishMessage(this.components.getPeerId(), message);
|
460
453
|
})
|
461
454
|
.catch(err => {
|
462
|
-
|
455
|
+
log.error(err);
|
463
456
|
});
|
464
457
|
return true;
|
465
458
|
}
|
@@ -496,7 +489,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
496
489
|
}
|
497
490
|
const wasSubscribed = this.subscriptions.has(topicStr);
|
498
491
|
const listeners = this.listenerCount(topicStr);
|
499
|
-
|
492
|
+
log('unsubscribe from %s - am subscribed %s, listeners %d', topic, wasSubscribed, listeners);
|
500
493
|
if (wasSubscribed && listeners === 0) {
|
501
494
|
this.subscriptions.delete(topicStr);
|
502
495
|
for (const peerId of this.peers.keys()) {
|