@libp2p/pubsub 1.2.1 → 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/dist/src/errors.d.ts +4 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +4 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +28 -29
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +104 -85
- package/dist/src/index.js.map +1 -1
- package/dist/src/message/sign.d.ts +1 -1
- package/dist/src/message/sign.d.ts.map +1 -1
- package/dist/src/message/sign.js +6 -8
- package/dist/src/message/sign.js.map +1 -1
- package/dist/src/peer-streams.d.ts +5 -5
- package/dist/src/peer-streams.d.ts.map +1 -1
- package/dist/src/peer-streams.js +1 -0
- package/dist/src/peer-streams.js.map +1 -1
- package/dist/src/utils.d.ts +6 -5
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +36 -28
- package/dist/src/utils.js.map +1 -1
- package/package.json +4 -4
- package/src/errors.ts +4 -0
- package/src/index.ts +128 -100
- package/src/message/sign.ts +7 -9
- package/src/peer-streams.ts +6 -4
- package/src/utils.ts +39 -29
package/dist/src/errors.d.ts
CHANGED
@@ -19,6 +19,10 @@ export declare const codes: {
|
|
19
19
|
* Message `signature` is invalid
|
20
20
|
*/
|
21
21
|
ERR_INVALID_SIGNATURE: string;
|
22
|
+
/**
|
23
|
+
* Message expected to have a `from`, but doesn't
|
24
|
+
*/
|
25
|
+
ERR_MISSING_FROM: string;
|
22
26
|
/**
|
23
27
|
* Message expected to not have a `from`, but does
|
24
28
|
*/
|
package/dist/src/errors.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,KAAK;IAChB;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;CAEJ,CAAA"}
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,KAAK;IAChB;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAKH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;CAEJ,CAAA"}
|
package/dist/src/errors.js
CHANGED
@@ -20,6 +20,10 @@ export const codes = {
|
|
20
20
|
* Message `signature` is invalid
|
21
21
|
*/
|
22
22
|
ERR_INVALID_SIGNATURE: 'ERR_INVALID_SIGNATURE',
|
23
|
+
/**
|
24
|
+
* Message expected to have a `from`, but doesn't
|
25
|
+
*/
|
26
|
+
ERR_MISSING_FROM: 'ERR_MISSING_FROM',
|
23
27
|
// Strict no-signing codes
|
24
28
|
/**
|
25
29
|
* Message expected to not have a `from`, but does
|
package/dist/src/errors.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB;;OAEG;IACH,4BAA4B,EAAE,8BAA8B;IAC5D;;OAEG;IACH,8BAA8B,EAAE,gCAAgC;IAEhE,uBAAuB;IAEvB;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;IAC9C;;OAEG;IACH,iBAAiB,EAAE,mBAAmB;IACtC;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB;;OAEG;IACH,4BAA4B,EAAE,8BAA8B;IAC5D;;OAEG;IACH,8BAA8B,EAAE,gCAAgC;IAEhE,uBAAuB;IAEvB;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;IAC9C;;OAEG;IACH,iBAAiB,EAAE,mBAAmB;IACtC;;OAEG;IACH,qBAAqB,EAAE,uBAAuB;IAC9C;;OAEG;IACH,gBAAgB,EAAE,kBAAkB;IAEpC,0BAA0B;IAE1B;;OAEG;IACH,mBAAmB,EAAE,qBAAqB;IAC1C;;OAEG;IACH,wBAAwB,EAAE,0BAA0B;IACpD;;OAEG;IACH,kBAAkB,EAAE,oBAAoB;IACxC;;OAEG;IACH,oBAAoB,EAAE,sBAAsB;CAC7C,CAAA"}
|
package/dist/src/index.d.ts
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
import { EventEmitter } from '@libp2p/interfaces';
|
2
2
|
import Queue from 'p-queue';
|
3
|
-
import { RPC, IRPC } from './message/rpc.js';
|
4
|
-
import { PeerStreams } from './peer-streams.js';
|
5
3
|
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
6
|
-
import type { Registrar,
|
4
|
+
import type { Registrar, IncomingStreamData } from '@libp2p/interfaces/registrar';
|
7
5
|
import type { Connection } from '@libp2p/interfaces/connection';
|
8
|
-
import type
|
9
|
-
import type { PubSub, Message, StrictNoSign, StrictSign, PubsubOptions, PubsubEvents } from '@libp2p/interfaces/pubsub';
|
10
|
-
import type { Startable } from '@libp2p/interfaces';
|
6
|
+
import type { PubSub, Message, StrictNoSign, StrictSign, PubSubOptions, PubSubEvents, RPCMessage, RPC, PeerStreams, RPCSubscription } from '@libp2p/interfaces/pubsub';
|
11
7
|
import type { Logger } from '@libp2p/logger';
|
8
|
+
import type { PeerMap } from '@libp2p/peer-map';
|
9
|
+
import type { IRPC } from './message/rpc.js';
|
10
|
+
import { RPC as RPCProto } from './message/rpc.js';
|
12
11
|
export interface TopicValidator {
|
13
12
|
(topic: string, message: Message): Promise<void>;
|
14
13
|
}
|
@@ -16,7 +15,7 @@ export interface TopicValidator {
|
|
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 declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap &
|
18
|
+
export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<EventMap & PubSubEvents> implements PubSub<EventMap & PubSubEvents> {
|
20
19
|
peerId: PeerId;
|
21
20
|
started: boolean;
|
22
21
|
/**
|
@@ -30,11 +29,11 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
30
29
|
/**
|
31
30
|
* Map of peer streams
|
32
31
|
*/
|
33
|
-
peers:
|
32
|
+
peers: PeerMap<PeerStreams>;
|
34
33
|
/**
|
35
34
|
* The signature policy to follow by default
|
36
35
|
*/
|
37
|
-
globalSignaturePolicy: StrictNoSign | StrictSign;
|
36
|
+
globalSignaturePolicy: typeof StrictNoSign | typeof StrictSign;
|
38
37
|
/**
|
39
38
|
* If router can relay received messages, even if not subscribed
|
40
39
|
*/
|
@@ -52,28 +51,27 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
52
51
|
topicValidators: Map<string, TopicValidator>;
|
53
52
|
queue: Queue;
|
54
53
|
registrar: Registrar;
|
54
|
+
multicodecs: string[];
|
55
55
|
protected log: Logger;
|
56
|
-
protected multicodecs: string[];
|
57
56
|
protected _libp2p: any;
|
58
|
-
private
|
59
|
-
|
57
|
+
private _registrarHandlerId;
|
58
|
+
private _registrarTopologyId;
|
59
|
+
constructor(props: PubSubOptions);
|
60
60
|
/**
|
61
61
|
* Register the pubsub protocol onto the libp2p node.
|
62
62
|
*
|
63
63
|
* @returns {void}
|
64
64
|
*/
|
65
|
-
start(): void
|
65
|
+
start(): Promise<void>;
|
66
66
|
/**
|
67
67
|
* Unregister the pubsub protocol and the streams with other peers will be closed.
|
68
|
-
*
|
69
|
-
* @returns {void}
|
70
68
|
*/
|
71
|
-
stop(): void
|
69
|
+
stop(): Promise<void>;
|
72
70
|
isStarted(): boolean;
|
73
71
|
/**
|
74
72
|
* On an inbound stream opened
|
75
73
|
*/
|
76
|
-
protected _onIncomingStream(
|
74
|
+
protected _onIncomingStream(evt: CustomEvent<IncomingStreamData>): void;
|
77
75
|
/**
|
78
76
|
* Registrar notifies an established connection with pubsub protocol
|
79
77
|
*/
|
@@ -93,23 +91,23 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
93
91
|
/**
|
94
92
|
* Responsible for processing each RPC message received by other peers.
|
95
93
|
*/
|
96
|
-
_processMessages(
|
94
|
+
_processMessages(peerId: PeerId, stream: AsyncIterable<Uint8Array>, peerStreams: PeerStreams): Promise<void>;
|
97
95
|
/**
|
98
96
|
* Handles an rpc request from a peer
|
99
97
|
*/
|
100
|
-
|
98
|
+
processRpc(from: PeerId, peerStreams: PeerStreams, rpc: RPC): Promise<boolean>;
|
101
99
|
/**
|
102
100
|
* Handles a subscription change from a peer
|
103
101
|
*/
|
104
|
-
_processRpcSubOpt(id:
|
102
|
+
_processRpcSubOpt(id: PeerId, subOpt: RPCSubscription): void;
|
105
103
|
/**
|
106
104
|
* Handles an message from a peer
|
107
105
|
*/
|
108
|
-
|
106
|
+
_processMessage(msg: Message): Promise<void>;
|
109
107
|
/**
|
110
108
|
* Emit a message from a peer
|
111
109
|
*/
|
112
|
-
|
110
|
+
emitMessage(message: Message): void;
|
113
111
|
/**
|
114
112
|
* The default msgID implementation
|
115
113
|
* Child class can override this.
|
@@ -119,12 +117,12 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
119
117
|
* Whether to accept a message from a peer
|
120
118
|
* Override to create a graylist
|
121
119
|
*/
|
122
|
-
_acceptFrom(id:
|
120
|
+
_acceptFrom(id: PeerId): boolean;
|
123
121
|
/**
|
124
122
|
* Decode Uint8Array into an RPC object.
|
125
123
|
* This can be override to use a custom router protobuf.
|
126
124
|
*/
|
127
|
-
_decodeRpc(bytes: Uint8Array):
|
125
|
+
_decodeRpc(bytes: Uint8Array): RPCProto;
|
128
126
|
/**
|
129
127
|
* Encode RPC object into a Uint8Array.
|
130
128
|
* This can be override to use a custom router protobuf.
|
@@ -133,11 +131,11 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
133
131
|
/**
|
134
132
|
* Send an rpc object to a peer
|
135
133
|
*/
|
136
|
-
_sendRpc(
|
134
|
+
_sendRpc(peer: PeerId, rpc: IRPC): void;
|
137
135
|
/**
|
138
136
|
* Send subscriptions to a peer
|
139
137
|
*/
|
140
|
-
_sendSubscriptions(id:
|
138
|
+
_sendSubscriptions(id: PeerId, topics: string[], subscribe: boolean): void;
|
141
139
|
/**
|
142
140
|
* Validates the given message. The signature will be checked for authenticity.
|
143
141
|
* Throws an error on invalid messages
|
@@ -147,11 +145,11 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
147
145
|
* Normalizes the message and signs it, if signing is enabled.
|
148
146
|
* Should be used by the routers to create the message to send.
|
149
147
|
*/
|
150
|
-
protected
|
148
|
+
protected _maybeSignMessage(message: Message): Promise<Message>;
|
151
149
|
/**
|
152
150
|
* Get a list of the peer-ids that are subscribed to one topic.
|
153
151
|
*/
|
154
|
-
getSubscribers(topic: string):
|
152
|
+
getSubscribers(topic: string): PeerId[];
|
155
153
|
/**
|
156
154
|
* Publishes messages to all subscribed peers
|
157
155
|
*/
|
@@ -160,7 +158,7 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
160
158
|
* Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
|
161
159
|
* For example, a Floodsub implementation might simply publish each message to each topic for every peer
|
162
160
|
*/
|
163
|
-
abstract _publish(message:
|
161
|
+
abstract _publish(message: RPCMessage): Promise<void>;
|
164
162
|
/**
|
165
163
|
* Subscribes to a given topic.
|
166
164
|
*/
|
@@ -173,5 +171,6 @@ export declare abstract class PubsubBaseProtocol<EventMap> extends EventEmitter<
|
|
173
171
|
* Get the list of topics which the peer is subscribed to.
|
174
172
|
*/
|
175
173
|
getTopics(): string[];
|
174
|
+
getPeers(): PeerId[];
|
176
175
|
}
|
177
176
|
//# sourceMappingURL=index.d.ts.map
|
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,MAAM,oBAAoB,CAAA;AAG9D,OAAO,KAAK,MAAM,SAAS,CAAA;
|
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,12 +3,15 @@ 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 { Topology } from '@libp2p/topology';
|
7
7
|
import { codes } from './errors.js';
|
8
|
-
import {
|
9
|
-
import {
|
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 { signMessage, verifySignature } from './message/sign.js';
|
11
|
+
import { base58btc } from 'multiformats/bases/base58';
|
12
|
+
import { peerMap } from '@libp2p/peer-map';
|
13
|
+
import { peerIdFromString } from '@libp2p/peer-id';
|
14
|
+
import { RPC as RPCProto } from './message/rpc.js';
|
12
15
|
/**
|
13
16
|
* PubsubBaseProtocol handles the peers and connections logic for pubsub routers
|
14
17
|
* and specifies the API that pubsub routers should have.
|
@@ -16,16 +19,15 @@ import { signMessage, verifySignature } from './message/sign.js';
|
|
16
19
|
export class PubsubBaseProtocol extends EventEmitter {
|
17
20
|
constructor(props) {
|
18
21
|
super();
|
19
|
-
const { debugName = 'libp2p:pubsub', multicodecs = [],
|
22
|
+
const { debugName = 'libp2p:pubsub', multicodecs = [], peerId, registrar, globalSignaturePolicy = 'StrictSign', canRelayMessage = false, emitSelf = false, messageProcessingConcurrency = 10 } = props;
|
20
23
|
this.log = logger(debugName);
|
21
|
-
this.multicodecs =
|
22
|
-
this.
|
23
|
-
this.
|
24
|
-
this.peerId = libp2p.peerId;
|
24
|
+
this.multicodecs = ensureArray(multicodecs);
|
25
|
+
this.registrar = registrar;
|
26
|
+
this.peerId = peerId;
|
25
27
|
this.started = false;
|
26
28
|
this.topics = new Map();
|
27
29
|
this.subscriptions = new Set();
|
28
|
-
this.peers =
|
30
|
+
this.peers = peerMap();
|
29
31
|
this.globalSignaturePolicy = globalSignaturePolicy === 'StrictNoSign' ? 'StrictNoSign' : 'StrictSign';
|
30
32
|
this.canRelayMessage = canRelayMessage;
|
31
33
|
this.emitSelf = emitSelf;
|
@@ -41,45 +43,43 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
41
43
|
*
|
42
44
|
* @returns {void}
|
43
45
|
*/
|
44
|
-
start() {
|
46
|
+
async start() {
|
45
47
|
if (this.started) {
|
46
48
|
return;
|
47
49
|
}
|
48
50
|
this.log('starting');
|
49
51
|
// Incoming streams
|
50
52
|
// Called after a peer dials us
|
51
|
-
this.registrar.handle(this.multicodecs, this._onIncomingStream);
|
53
|
+
this._registrarHandlerId = await this.registrar.handle(this.multicodecs, this._onIncomingStream);
|
52
54
|
// register protocol with topology
|
53
55
|
// Topology callbacks called on connection manager changes
|
54
|
-
const topology = new
|
55
|
-
|
56
|
-
|
57
|
-
multicodecs: this.multicodecs,
|
58
|
-
handlers: {
|
59
|
-
onConnect: this._onPeerConnected,
|
60
|
-
onDisconnect: this._onPeerDisconnected
|
61
|
-
}
|
56
|
+
const topology = new Topology({
|
57
|
+
onConnect: this._onPeerConnected,
|
58
|
+
onDisconnect: this._onPeerDisconnected
|
62
59
|
});
|
63
|
-
this.
|
60
|
+
this._registrarTopologyId = this.registrar.register(this.multicodecs, topology);
|
64
61
|
this.log('started');
|
65
62
|
this.started = true;
|
66
63
|
}
|
67
64
|
/**
|
68
65
|
* Unregister the pubsub protocol and the streams with other peers will be closed.
|
69
|
-
*
|
70
|
-
* @returns {void}
|
71
66
|
*/
|
72
|
-
stop() {
|
67
|
+
async stop() {
|
73
68
|
if (!this.started) {
|
74
69
|
return;
|
75
70
|
}
|
76
71
|
// unregister protocol and handlers
|
77
|
-
if (this.
|
78
|
-
this.registrar.unregister(this.
|
72
|
+
if (this._registrarTopologyId != null) {
|
73
|
+
this.registrar.unregister(this._registrarTopologyId);
|
74
|
+
}
|
75
|
+
if (this._registrarHandlerId != null) {
|
76
|
+
await this.registrar.unhandle(this._registrarHandlerId);
|
79
77
|
}
|
80
78
|
this.log('stopping');
|
81
|
-
|
82
|
-
|
79
|
+
for (const peerStreams of this.peers.values()) {
|
80
|
+
peerStreams.close();
|
81
|
+
}
|
82
|
+
this.peers.clear();
|
83
83
|
this.subscriptions = new Set();
|
84
84
|
this.started = false;
|
85
85
|
this.log('stopped');
|
@@ -90,20 +90,19 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
90
90
|
/**
|
91
91
|
* On an inbound stream opened
|
92
92
|
*/
|
93
|
-
_onIncomingStream(
|
93
|
+
_onIncomingStream(evt) {
|
94
|
+
const { protocol, stream, connection } = evt.detail;
|
94
95
|
const peerId = connection.remotePeer;
|
95
|
-
const idB58Str = peerId.toString();
|
96
96
|
const peer = this._addPeer(peerId, protocol);
|
97
97
|
const inboundStream = peer.attachInboundStream(stream);
|
98
|
-
this._processMessages(
|
98
|
+
this._processMessages(peerId, inboundStream, peer)
|
99
99
|
.catch(err => this.log(err));
|
100
100
|
}
|
101
101
|
/**
|
102
102
|
* Registrar notifies an established connection with pubsub protocol
|
103
103
|
*/
|
104
104
|
async _onPeerConnected(peerId, conn) {
|
105
|
-
|
106
|
-
this.log('connected', idB58Str);
|
105
|
+
this.log('connected %p', peerId);
|
107
106
|
try {
|
108
107
|
const { stream, protocol } = await conn.newStream(this.multicodecs);
|
109
108
|
const peer = this._addPeer(peerId, protocol);
|
@@ -113,7 +112,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
113
112
|
this.log.error(err);
|
114
113
|
}
|
115
114
|
// Immediately send my own subscriptions to the newly established conn
|
116
|
-
this._sendSubscriptions(
|
115
|
+
this._sendSubscriptions(peerId, Array.from(this.subscriptions), true);
|
117
116
|
}
|
118
117
|
/**
|
119
118
|
* Registrar notifies a closing connection with pubsub protocol
|
@@ -127,19 +126,18 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
127
126
|
* Notifies the router that a peer has been connected
|
128
127
|
*/
|
129
128
|
_addPeer(peerId, protocol) {
|
130
|
-
const
|
131
|
-
const existing = this.peers.get(id);
|
129
|
+
const existing = this.peers.get(peerId);
|
132
130
|
// If peer streams already exists, do nothing
|
133
131
|
if (existing != null) {
|
134
132
|
return existing;
|
135
133
|
}
|
136
134
|
// else create a new peer streams
|
137
|
-
this.log('new peer',
|
138
|
-
const peerStreams = new
|
135
|
+
this.log('new peer %p', peerId);
|
136
|
+
const peerStreams = new PeerStreamsImpl({
|
139
137
|
id: peerId,
|
140
138
|
protocol
|
141
139
|
});
|
142
|
-
this.peers.set(
|
140
|
+
this.peers.set(peerId, peerStreams);
|
143
141
|
peerStreams.addEventListener('close', () => this._removePeer(peerId), {
|
144
142
|
once: true
|
145
143
|
});
|
@@ -150,15 +148,15 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
150
148
|
*/
|
151
149
|
_removePeer(peerId) {
|
152
150
|
const id = peerId.toString();
|
153
|
-
const peerStreams = this.peers.get(
|
151
|
+
const peerStreams = this.peers.get(peerId);
|
154
152
|
if (peerStreams == null) {
|
155
153
|
return;
|
156
154
|
}
|
157
155
|
// close peer streams
|
158
156
|
peerStreams.close();
|
159
157
|
// delete peer streams
|
160
|
-
this.log('delete peer',
|
161
|
-
this.peers.delete(
|
158
|
+
this.log('delete peer %p', peerId);
|
159
|
+
this.peers.delete(peerId);
|
162
160
|
// remove peer from topics map
|
163
161
|
for (const peers of this.topics.values()) {
|
164
162
|
peers.delete(id);
|
@@ -169,17 +167,29 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
169
167
|
/**
|
170
168
|
* Responsible for processing each RPC message received by other peers.
|
171
169
|
*/
|
172
|
-
async _processMessages(
|
170
|
+
async _processMessages(peerId, stream, peerStreams) {
|
173
171
|
try {
|
174
172
|
await pipe(stream, async (source) => {
|
175
173
|
for await (const data of source) {
|
176
|
-
const
|
177
|
-
const rpcMsg = this._decodeRpc(rpcBytes);
|
174
|
+
const rpcMsg = this._decodeRpc(data);
|
178
175
|
// Since _processRpc may be overridden entirely in unsafe ways,
|
179
176
|
// the simplest/safest option here is to wrap in a function and capture all errors
|
180
177
|
// to prevent a top-level unhandled exception
|
181
178
|
// This processing of rpc messages should happen without awaiting full validation/execution of prior messages
|
182
|
-
this.
|
179
|
+
this.processRpc(peerId, peerStreams, {
|
180
|
+
subscriptions: (rpcMsg.subscriptions).map(sub => ({
|
181
|
+
subscribe: Boolean(sub.subscribe),
|
182
|
+
topicID: sub.topicID ?? ''
|
183
|
+
})),
|
184
|
+
msgs: (rpcMsg.msgs ?? []).map(msg => ({
|
185
|
+
from: msg.from ?? peerId.multihash.bytes,
|
186
|
+
data: msg.data ?? new Uint8Array(0),
|
187
|
+
topicIDs: msg.topicIDs ?? [],
|
188
|
+
seqno: msg.seqno ?? undefined,
|
189
|
+
signature: msg.signature ?? undefined,
|
190
|
+
key: msg.key ?? undefined
|
191
|
+
}))
|
192
|
+
})
|
183
193
|
.catch(err => this.log(err));
|
184
194
|
}
|
185
195
|
});
|
@@ -191,21 +201,21 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
191
201
|
/**
|
192
202
|
* Handles an rpc request from a peer
|
193
203
|
*/
|
194
|
-
async
|
195
|
-
this.log('rpc from',
|
204
|
+
async processRpc(from, peerStreams, rpc) {
|
205
|
+
this.log('rpc from %p', from);
|
196
206
|
const subs = rpc.subscriptions;
|
197
207
|
const msgs = rpc.msgs;
|
198
208
|
if (subs.length > 0) {
|
199
209
|
// update peer subscriptions
|
200
210
|
subs.forEach((subOpt) => {
|
201
|
-
this._processRpcSubOpt(
|
211
|
+
this._processRpcSubOpt(from, subOpt);
|
202
212
|
});
|
203
213
|
this.dispatchEvent(new CustomEvent('pubsub:subscription-change', {
|
204
214
|
detail: { peerId: peerStreams.id, subscriptions: subs }
|
205
215
|
}));
|
206
216
|
}
|
207
|
-
if (!this._acceptFrom(
|
208
|
-
this.log('received message from unacceptable peer %
|
217
|
+
if (!this._acceptFrom(from)) {
|
218
|
+
this.log('received message from unacceptable peer %p', from);
|
209
219
|
return false;
|
210
220
|
}
|
211
221
|
if (msgs.length > 0) {
|
@@ -217,8 +227,11 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
217
227
|
return;
|
218
228
|
}
|
219
229
|
try {
|
220
|
-
const msg =
|
221
|
-
|
230
|
+
const msg = toMessage({
|
231
|
+
...message,
|
232
|
+
from: from.multihash.bytes
|
233
|
+
});
|
234
|
+
await this._processMessage(msg);
|
222
235
|
}
|
223
236
|
catch (err) {
|
224
237
|
this.log.error(err);
|
@@ -241,20 +254,20 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
241
254
|
topicSet = new Set();
|
242
255
|
this.topics.set(t, topicSet);
|
243
256
|
}
|
244
|
-
if (subOpt.subscribe
|
257
|
+
if (subOpt.subscribe) {
|
245
258
|
// subscribe peer to new topic
|
246
|
-
topicSet.add(id);
|
259
|
+
topicSet.add(id.toString());
|
247
260
|
}
|
248
261
|
else {
|
249
262
|
// unsubscribe from existing topic
|
250
|
-
topicSet.delete(id);
|
263
|
+
topicSet.delete(id.toString());
|
251
264
|
}
|
252
265
|
}
|
253
266
|
/**
|
254
267
|
* Handles an message from a peer
|
255
268
|
*/
|
256
|
-
async
|
257
|
-
if (
|
269
|
+
async _processMessage(msg) {
|
270
|
+
if (this.peerId.equals(msg.from) && !this.emitSelf) {
|
258
271
|
return;
|
259
272
|
}
|
260
273
|
// Ensure the message is valid before processing it
|
@@ -266,13 +279,13 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
266
279
|
return;
|
267
280
|
}
|
268
281
|
// Emit to self
|
269
|
-
this.
|
270
|
-
return await this._publish(
|
282
|
+
this.emitMessage(msg);
|
283
|
+
return await this._publish(toRpcMessage(msg));
|
271
284
|
}
|
272
285
|
/**
|
273
286
|
* Emit a message from a peer
|
274
287
|
*/
|
275
|
-
|
288
|
+
emitMessage(message) {
|
276
289
|
message.topicIDs.forEach((topic) => {
|
277
290
|
if (this.subscriptions.has(topic)) {
|
278
291
|
this.dispatchEvent(new CustomEvent(topic, {
|
@@ -289,10 +302,12 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
289
302
|
const signaturePolicy = this.globalSignaturePolicy;
|
290
303
|
switch (signaturePolicy) {
|
291
304
|
case 'StrictSign':
|
292
|
-
|
293
|
-
|
305
|
+
if (msg.seqno == null) {
|
306
|
+
throw errcode(new Error('Need seqno when signature policy is StrictSign but it was missing'), codes.ERR_MISSING_SEQNO);
|
307
|
+
}
|
308
|
+
return msgId(msg.from, msg.seqno);
|
294
309
|
case 'StrictNoSign':
|
295
|
-
return
|
310
|
+
return noSignMsgId(msg.data);
|
296
311
|
default:
|
297
312
|
throw errcode(new Error('Cannot get message id: unhandled signature policy'), codes.ERR_UNHANDLED_SIGNATURE_POLICY);
|
298
313
|
}
|
@@ -309,22 +324,22 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
309
324
|
* This can be override to use a custom router protobuf.
|
310
325
|
*/
|
311
326
|
_decodeRpc(bytes) {
|
312
|
-
return
|
327
|
+
return RPCProto.decode(bytes);
|
313
328
|
}
|
314
329
|
/**
|
315
330
|
* Encode RPC object into a Uint8Array.
|
316
331
|
* This can be override to use a custom router protobuf.
|
317
332
|
*/
|
318
333
|
_encodeRpc(rpc) {
|
319
|
-
return
|
334
|
+
return RPCProto.encode(rpc).finish();
|
320
335
|
}
|
321
336
|
/**
|
322
337
|
* Send an rpc object to a peer
|
323
338
|
*/
|
324
|
-
_sendRpc(
|
325
|
-
const peerStreams = this.peers.get(
|
326
|
-
if (
|
327
|
-
const msg = `Cannot send RPC to ${
|
339
|
+
_sendRpc(peer, rpc) {
|
340
|
+
const peerStreams = this.peers.get(peer);
|
341
|
+
if (peerStreams == null || !peerStreams.isWritable) {
|
342
|
+
const msg = `Cannot send RPC to ${peer.toString(base58btc)} as there is no open stream to it available`;
|
328
343
|
this.log.error(msg);
|
329
344
|
return;
|
330
345
|
}
|
@@ -346,9 +361,6 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
346
361
|
const signaturePolicy = this.globalSignaturePolicy;
|
347
362
|
switch (signaturePolicy) {
|
348
363
|
case 'StrictNoSign':
|
349
|
-
if (message.from != null) {
|
350
|
-
throw errcode(new Error('StrictNoSigning: from should not be present'), codes.ERR_UNEXPECTED_FROM);
|
351
|
-
}
|
352
364
|
if (message.signature != null) {
|
353
365
|
throw errcode(new Error('StrictNoSigning: signature should not be present'), codes.ERR_UNEXPECTED_SIGNATURE);
|
354
366
|
}
|
@@ -384,12 +396,11 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
384
396
|
* Normalizes the message and signs it, if signing is enabled.
|
385
397
|
* Should be used by the routers to create the message to send.
|
386
398
|
*/
|
387
|
-
async
|
399
|
+
async _maybeSignMessage(message) {
|
388
400
|
const signaturePolicy = this.globalSignaturePolicy;
|
389
401
|
switch (signaturePolicy) {
|
390
402
|
case 'StrictSign':
|
391
|
-
message.
|
392
|
-
message.seqno = utils.randomSeqno();
|
403
|
+
message.seqno = randomSeqno();
|
393
404
|
return await signMessage(this.peerId, message);
|
394
405
|
case 'StrictNoSign':
|
395
406
|
return await Promise.resolve(message);
|
@@ -412,7 +423,7 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
412
423
|
if (peersInTopic == null) {
|
413
424
|
return [];
|
414
425
|
}
|
415
|
-
return Array.from(peersInTopic);
|
426
|
+
return Array.from(peersInTopic).map(str => peerIdFromString(str));
|
416
427
|
}
|
417
428
|
/**
|
418
429
|
* Publishes messages to all subscribed peers
|
@@ -422,19 +433,17 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
422
433
|
throw new Error('Pubsub has not started');
|
423
434
|
}
|
424
435
|
this.log('publish', topic, message);
|
425
|
-
const from = this.peerId.toString();
|
426
436
|
const msgObject = {
|
427
|
-
|
437
|
+
from: this.peerId,
|
428
438
|
data: message,
|
429
439
|
topicIDs: [topic]
|
430
440
|
};
|
431
441
|
// ensure that the message follows the signature policy
|
432
|
-
const
|
433
|
-
const msg = utils.normalizeInRpcMessage(outMsg);
|
442
|
+
const msg = await this._maybeSignMessage(msgObject);
|
434
443
|
// Emit to self if I'm interested and emitSelf enabled
|
435
|
-
this.emitSelf && this.
|
444
|
+
this.emitSelf && this.emitMessage(msg);
|
436
445
|
// send to all the other peers
|
437
|
-
await this._publish(msg);
|
446
|
+
await this._publish(toRpcMessage(msg));
|
438
447
|
}
|
439
448
|
/**
|
440
449
|
* Subscribes to a given topic.
|
@@ -445,7 +454,9 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
445
454
|
}
|
446
455
|
if (!this.subscriptions.has(topic)) {
|
447
456
|
this.subscriptions.add(topic);
|
448
|
-
|
457
|
+
for (const peerId of this.peers.keys()) {
|
458
|
+
this._sendSubscriptions(peerId, [topic], true);
|
459
|
+
}
|
449
460
|
}
|
450
461
|
}
|
451
462
|
/**
|
@@ -457,7 +468,9 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
457
468
|
}
|
458
469
|
if (this.subscriptions.has(topic) && this.listenerCount(topic) === 0) {
|
459
470
|
this.subscriptions.delete(topic);
|
460
|
-
|
471
|
+
for (const peerId of this.peers.keys()) {
|
472
|
+
this._sendSubscriptions(peerId, [topic], false);
|
473
|
+
}
|
461
474
|
}
|
462
475
|
}
|
463
476
|
/**
|
@@ -469,5 +482,11 @@ export class PubsubBaseProtocol extends EventEmitter {
|
|
469
482
|
}
|
470
483
|
return Array.from(this.subscriptions);
|
471
484
|
}
|
485
|
+
getPeers() {
|
486
|
+
if (!this.started) {
|
487
|
+
throw new Error('Pubsub is not started');
|
488
|
+
}
|
489
|
+
return Array.from(this.peers.keys());
|
490
|
+
}
|
472
491
|
}
|
473
492
|
//# sourceMappingURL=index.js.map
|