@waku/core 0.0.19 → 0.0.21
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/CHANGELOG.md +47 -0
- package/bundle/index.js +404 -350
- package/bundle/lib/base_protocol.js +11 -6
- package/bundle/lib/message/version_0.js +1 -1
- package/bundle/lib/predefined_bootstrap_nodes.js +6 -6
- package/bundle/{version_0-9c941081.js → version_0-86411fdf.js} +3 -3
- package/dist/index.d.ts +2 -4
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/base_protocol.d.ts +9 -5
- package/dist/lib/base_protocol.js +11 -6
- package/dist/lib/base_protocol.js.map +1 -1
- package/dist/lib/connection_manager.d.ts +14 -4
- package/dist/lib/connection_manager.js +174 -28
- package/dist/lib/connection_manager.js.map +1 -1
- package/dist/lib/filter/filter_rpc.js.map +1 -0
- package/dist/lib/filter/index.d.ts +2 -0
- package/dist/lib/filter/{v2/index.js → index.js} +14 -19
- package/dist/lib/filter/index.js.map +1 -0
- package/dist/lib/keep_alive_manager.d.ts +2 -2
- package/dist/lib/keep_alive_manager.js +1 -1
- package/dist/lib/keep_alive_manager.js.map +1 -1
- package/dist/lib/light_push/index.d.ts +1 -2
- package/dist/lib/light_push/index.js +1 -3
- package/dist/lib/light_push/index.js.map +1 -1
- package/dist/lib/predefined_bootstrap_nodes.js +6 -6
- package/dist/lib/predefined_bootstrap_nodes.js.map +1 -1
- package/dist/lib/store/index.d.ts +1 -2
- package/dist/lib/store/index.js +1 -3
- package/dist/lib/store/index.js.map +1 -1
- package/dist/lib/wait_for_remote_peer.d.ts +1 -1
- package/dist/lib/wait_for_remote_peer.js +4 -4
- package/dist/lib/wait_for_remote_peer.js.map +1 -1
- package/dist/lib/waku.d.ts +3 -4
- package/dist/lib/waku.js.map +1 -1
- package/package.json +11 -19
- package/src/index.ts +2 -5
- package/src/lib/base_protocol.ts +23 -9
- package/src/lib/connection_manager.ts +230 -42
- package/src/lib/filter/{v2/index.ts → index.ts} +19 -26
- package/src/lib/keep_alive_manager.ts +3 -3
- package/src/lib/light_push/index.ts +3 -3
- package/src/lib/predefined_bootstrap_nodes.ts +6 -6
- package/src/lib/store/index.ts +3 -3
- package/src/lib/wait_for_remote_peer.ts +8 -10
- package/src/lib/waku.ts +3 -4
- package/dist/lib/filter/v1/filter_rpc.d.ts +0 -23
- package/dist/lib/filter/v1/filter_rpc.js +0 -45
- package/dist/lib/filter/v1/filter_rpc.js.map +0 -1
- package/dist/lib/filter/v1/index.d.ts +0 -6
- package/dist/lib/filter/v1/index.js +0 -153
- package/dist/lib/filter/v1/index.js.map +0 -1
- package/dist/lib/filter/v2/filter_rpc.js.map +0 -1
- package/dist/lib/filter/v2/index.d.ts +0 -3
- package/dist/lib/filter/v2/index.js.map +0 -1
- package/src/lib/filter/v1/filter_rpc.ts +0 -53
- package/src/lib/filter/v1/index.ts +0 -248
- /package/dist/lib/filter/{v2/filter_rpc.d.ts → filter_rpc.d.ts} +0 -0
- /package/dist/lib/filter/{v2/filter_rpc.js → filter_rpc.js} +0 -0
- /package/src/lib/filter/{v2/filter_rpc.ts → filter_rpc.ts} +0 -0
@@ -1,9 +1,15 @@
|
|
1
|
-
import type { Connection } from "@libp2p/interface-connection";
|
2
|
-
import type { Libp2p } from "@libp2p/interface-libp2p";
|
3
1
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
4
2
|
import type { PeerInfo } from "@libp2p/interface-peer-info";
|
5
|
-
import type {
|
6
|
-
import {
|
3
|
+
import type { Peer } from "@libp2p/interface-peer-store";
|
4
|
+
import { CustomEvent, EventEmitter } from "@libp2p/interfaces/events";
|
5
|
+
import {
|
6
|
+
ConnectionManagerOptions,
|
7
|
+
EPeersByDiscoveryEvents,
|
8
|
+
IPeersByDiscoveryEvents,
|
9
|
+
IRelay,
|
10
|
+
PeersByDiscoveryResult,
|
11
|
+
} from "@waku/interfaces";
|
12
|
+
import { Libp2p, Tags } from "@waku/interfaces";
|
7
13
|
import debug from "debug";
|
8
14
|
|
9
15
|
import { KeepAliveManager, KeepAliveOptions } from "./keep_alive_manager.js";
|
@@ -12,15 +18,19 @@ const log = debug("waku:connection-manager");
|
|
12
18
|
|
13
19
|
export const DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED = 1;
|
14
20
|
export const DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER = 3;
|
21
|
+
export const DEFAULT_MAX_PARALLEL_DIALS = 3;
|
15
22
|
|
16
|
-
export class ConnectionManager {
|
23
|
+
export class ConnectionManager extends EventEmitter<IPeersByDiscoveryEvents> {
|
17
24
|
private static instances = new Map<string, ConnectionManager>();
|
18
25
|
private keepAliveManager: KeepAliveManager;
|
19
26
|
private options: ConnectionManagerOptions;
|
20
|
-
private
|
27
|
+
private libp2p: Libp2p;
|
21
28
|
private dialAttemptsForPeer: Map<string, number> = new Map();
|
22
29
|
private dialErrorsForPeer: Map<string, any> = new Map();
|
23
30
|
|
31
|
+
private currentActiveDialCount = 0;
|
32
|
+
private pendingPeerDialQueue: Array<PeerId> = [];
|
33
|
+
|
24
34
|
public static create(
|
25
35
|
peerId: string,
|
26
36
|
libp2p: Libp2p,
|
@@ -42,16 +52,62 @@ export class ConnectionManager {
|
|
42
52
|
return instance;
|
43
53
|
}
|
44
54
|
|
55
|
+
public async getPeersByDiscovery(): Promise<PeersByDiscoveryResult> {
|
56
|
+
const peersDiscovered = await this.libp2p.peerStore.all();
|
57
|
+
const peersConnected = this.libp2p
|
58
|
+
.getConnections()
|
59
|
+
.map((conn) => conn.remotePeer);
|
60
|
+
|
61
|
+
const peersDiscoveredByBootstrap: Peer[] = [];
|
62
|
+
const peersDiscoveredByPeerExchange: Peer[] = [];
|
63
|
+
const peersConnectedByBootstrap: Peer[] = [];
|
64
|
+
const peersConnectedByPeerExchange: Peer[] = [];
|
65
|
+
|
66
|
+
for (const peer of peersDiscovered) {
|
67
|
+
const tags = await this.getTagNamesForPeer(peer.id);
|
68
|
+
|
69
|
+
if (tags.includes(Tags.BOOTSTRAP)) {
|
70
|
+
peersDiscoveredByBootstrap.push(peer);
|
71
|
+
} else if (tags.includes(Tags.PEER_EXCHANGE)) {
|
72
|
+
peersDiscoveredByPeerExchange.push(peer);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
for (const peerId of peersConnected) {
|
77
|
+
const peer = await this.libp2p.peerStore.get(peerId);
|
78
|
+
const tags = await this.getTagNamesForPeer(peerId);
|
79
|
+
|
80
|
+
if (tags.includes(Tags.BOOTSTRAP)) {
|
81
|
+
peersConnectedByBootstrap.push(peer);
|
82
|
+
} else if (tags.includes(Tags.PEER_EXCHANGE)) {
|
83
|
+
peersConnectedByPeerExchange.push(peer);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
return {
|
88
|
+
DISCOVERED: {
|
89
|
+
[Tags.BOOTSTRAP]: peersDiscoveredByBootstrap,
|
90
|
+
[Tags.PEER_EXCHANGE]: peersDiscoveredByPeerExchange,
|
91
|
+
},
|
92
|
+
CONNECTED: {
|
93
|
+
[Tags.BOOTSTRAP]: peersConnectedByBootstrap,
|
94
|
+
[Tags.PEER_EXCHANGE]: peersConnectedByPeerExchange,
|
95
|
+
},
|
96
|
+
};
|
97
|
+
}
|
98
|
+
|
45
99
|
private constructor(
|
46
|
-
|
100
|
+
libp2p: Libp2p,
|
47
101
|
keepAliveOptions: KeepAliveOptions,
|
48
102
|
relay?: IRelay,
|
49
103
|
options?: Partial<ConnectionManagerOptions>
|
50
104
|
) {
|
51
|
-
|
105
|
+
super();
|
106
|
+
this.libp2p = libp2p;
|
52
107
|
this.options = {
|
53
108
|
maxDialAttemptsForPeer: DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER,
|
54
109
|
maxBootstrapPeersAllowed: DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED,
|
110
|
+
maxParallelDials: DEFAULT_MAX_PARALLEL_DIALS,
|
55
111
|
...options,
|
56
112
|
};
|
57
113
|
|
@@ -60,6 +116,31 @@ export class ConnectionManager {
|
|
60
116
|
this.run()
|
61
117
|
.then(() => log(`Connection Manager is now running`))
|
62
118
|
.catch((error) => log(`Unexpected error while running service`, error));
|
119
|
+
|
120
|
+
// libp2p emits `peer:discovery` events during its initialization
|
121
|
+
// which means that before the ConnectionManager is initialized, some peers may have been discovered
|
122
|
+
// we will dial the peers in peerStore ONCE before we start to listen to the `peer:discovery` events within the ConnectionManager
|
123
|
+
this.dialPeerStorePeers().catch((error) =>
|
124
|
+
log(`Unexpected error while dialing peer store peers`, error)
|
125
|
+
);
|
126
|
+
}
|
127
|
+
|
128
|
+
private async dialPeerStorePeers(): Promise<void> {
|
129
|
+
const peerInfos = await this.libp2p.peerStore.all();
|
130
|
+
const dialPromises = [];
|
131
|
+
for (const peerInfo of peerInfos) {
|
132
|
+
if (
|
133
|
+
this.libp2p.getConnections().find((c) => c.remotePeer === peerInfo.id)
|
134
|
+
)
|
135
|
+
continue;
|
136
|
+
|
137
|
+
dialPromises.push(this.attemptDial(peerInfo.id));
|
138
|
+
}
|
139
|
+
try {
|
140
|
+
await Promise.all(dialPromises);
|
141
|
+
} catch (error) {
|
142
|
+
log(`Unexpected error while dialing peer store peers`, error);
|
143
|
+
}
|
63
144
|
}
|
64
145
|
|
65
146
|
private async run(): Promise<void> {
|
@@ -71,31 +152,32 @@ export class ConnectionManager {
|
|
71
152
|
|
72
153
|
stop(): void {
|
73
154
|
this.keepAliveManager.stopAll();
|
74
|
-
this.
|
155
|
+
this.libp2p.removeEventListener(
|
75
156
|
"peer:connect",
|
76
157
|
this.onEventHandlers["peer:connect"]
|
77
158
|
);
|
78
|
-
this.
|
159
|
+
this.libp2p.removeEventListener(
|
79
160
|
"peer:disconnect",
|
80
161
|
this.onEventHandlers["peer:disconnect"]
|
81
162
|
);
|
82
|
-
this.
|
163
|
+
this.libp2p.removeEventListener(
|
83
164
|
"peer:discovery",
|
84
165
|
this.onEventHandlers["peer:discovery"]
|
85
166
|
);
|
86
167
|
}
|
87
168
|
|
88
169
|
private async dialPeer(peerId: PeerId): Promise<void> {
|
170
|
+
this.currentActiveDialCount += 1;
|
89
171
|
let dialAttempt = 0;
|
90
172
|
while (dialAttempt <= this.options.maxDialAttemptsForPeer) {
|
91
173
|
try {
|
92
174
|
log(`Dialing peer ${peerId.toString()}`);
|
93
|
-
await this.
|
175
|
+
await this.libp2p.dial(peerId);
|
94
176
|
|
95
177
|
const tags = await this.getTagNamesForPeer(peerId);
|
96
178
|
// add tag to connection describing discovery mechanism
|
97
179
|
// don't add duplicate tags
|
98
|
-
this.
|
180
|
+
this.libp2p
|
99
181
|
.getConnections(peerId)
|
100
182
|
.forEach(
|
101
183
|
(conn) => (conn.tags = Array.from(new Set([...conn.tags, ...tags])))
|
@@ -105,6 +187,7 @@ export class ConnectionManager {
|
|
105
187
|
return;
|
106
188
|
} catch (e) {
|
107
189
|
const error = e as AggregateError;
|
190
|
+
|
108
191
|
this.dialErrorsForPeer.set(peerId.toString(), error);
|
109
192
|
log(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
|
110
193
|
|
@@ -125,21 +208,49 @@ export class ConnectionManager {
|
|
125
208
|
}`
|
126
209
|
);
|
127
210
|
this.dialErrorsForPeer.delete(peerId.toString());
|
128
|
-
return await this.
|
211
|
+
return await this.libp2p.peerStore.delete(peerId);
|
129
212
|
} catch (error) {
|
130
213
|
throw `Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`;
|
214
|
+
} finally {
|
215
|
+
this.currentActiveDialCount -= 1;
|
216
|
+
this.processDialQueue();
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
async dropConnection(peerId: PeerId): Promise<void> {
|
221
|
+
try {
|
222
|
+
this.keepAliveManager.stop(peerId);
|
223
|
+
await this.libp2p.hangUp(peerId);
|
224
|
+
log(`Dropped connection with peer ${peerId.toString()}`);
|
225
|
+
} catch (error) {
|
226
|
+
log(
|
227
|
+
`Error dropping connection with peer ${peerId.toString()} - ${error}`
|
228
|
+
);
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
private processDialQueue(): void {
|
233
|
+
if (
|
234
|
+
this.pendingPeerDialQueue.length > 0 &&
|
235
|
+
this.currentActiveDialCount < this.options.maxParallelDials
|
236
|
+
) {
|
237
|
+
const peerId = this.pendingPeerDialQueue.shift();
|
238
|
+
if (!peerId) return;
|
239
|
+
this.attemptDial(peerId).catch((error) => {
|
240
|
+
log(error);
|
241
|
+
});
|
131
242
|
}
|
132
243
|
}
|
133
244
|
|
134
245
|
private startPeerDiscoveryListener(): void {
|
135
|
-
this.
|
136
|
-
"peer",
|
246
|
+
this.libp2p.addEventListener(
|
247
|
+
"peer:discovery",
|
137
248
|
this.onEventHandlers["peer:discovery"]
|
138
249
|
);
|
139
250
|
}
|
140
251
|
|
141
252
|
private startPeerConnectionListener(): void {
|
142
|
-
this.
|
253
|
+
this.libp2p.addEventListener(
|
143
254
|
"peer:connect",
|
144
255
|
this.onEventHandlers["peer:connect"]
|
145
256
|
);
|
@@ -158,32 +269,106 @@ export class ConnectionManager {
|
|
158
269
|
* >this event will **only** be triggered when the last connection is closed.
|
159
270
|
* @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
|
160
271
|
*/
|
161
|
-
this.
|
272
|
+
this.libp2p.addEventListener(
|
162
273
|
"peer:disconnect",
|
163
274
|
this.onEventHandlers["peer:disconnect"]
|
164
275
|
);
|
165
276
|
}
|
166
277
|
|
278
|
+
private async attemptDial(peerId: PeerId): Promise<void> {
|
279
|
+
if (this.currentActiveDialCount >= this.options.maxParallelDials) {
|
280
|
+
this.pendingPeerDialQueue.push(peerId);
|
281
|
+
return;
|
282
|
+
}
|
283
|
+
|
284
|
+
if (!(await this.shouldDialPeer(peerId))) return;
|
285
|
+
|
286
|
+
this.dialPeer(peerId).catch((err) => {
|
287
|
+
throw `Error dialing peer ${peerId.toString()} : ${err}`;
|
288
|
+
});
|
289
|
+
}
|
290
|
+
|
167
291
|
private onEventHandlers = {
|
168
|
-
"peer:discovery":
|
169
|
-
|
170
|
-
|
292
|
+
"peer:discovery": (evt: CustomEvent<PeerInfo>): void => {
|
293
|
+
void (async () => {
|
294
|
+
const { id: peerId } = evt.detail;
|
171
295
|
|
172
|
-
|
173
|
-
|
174
|
-
|
296
|
+
const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(
|
297
|
+
Tags.BOOTSTRAP
|
298
|
+
);
|
299
|
+
|
300
|
+
if (isBootstrap) {
|
301
|
+
this.dispatchEvent(
|
302
|
+
new CustomEvent<PeerId>(
|
303
|
+
EPeersByDiscoveryEvents.PEER_DISCOVERY_BOOTSTRAP,
|
304
|
+
{
|
305
|
+
detail: peerId,
|
306
|
+
}
|
307
|
+
)
|
308
|
+
);
|
309
|
+
} else {
|
310
|
+
this.dispatchEvent(
|
311
|
+
new CustomEvent<PeerId>(
|
312
|
+
EPeersByDiscoveryEvents.PEER_DISCOVERY_PEER_EXCHANGE,
|
313
|
+
{
|
314
|
+
detail: peerId,
|
315
|
+
}
|
316
|
+
)
|
317
|
+
);
|
318
|
+
}
|
319
|
+
|
320
|
+
try {
|
321
|
+
await this.attemptDial(peerId);
|
322
|
+
} catch (error) {
|
323
|
+
log(`Error dialing peer ${peerId.toString()} : ${error}`);
|
324
|
+
}
|
325
|
+
})();
|
175
326
|
},
|
176
|
-
"peer:connect": (evt: CustomEvent<
|
177
|
-
{
|
178
|
-
|
179
|
-
|
180
|
-
|
327
|
+
"peer:connect": (evt: CustomEvent<PeerId>): void => {
|
328
|
+
void (async () => {
|
329
|
+
const peerId = evt.detail;
|
330
|
+
|
331
|
+
this.keepAliveManager.start(peerId, this.libp2p.services.ping);
|
332
|
+
|
333
|
+
const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(
|
334
|
+
Tags.BOOTSTRAP
|
181
335
|
);
|
182
|
-
|
336
|
+
|
337
|
+
if (isBootstrap) {
|
338
|
+
const bootstrapConnections = this.libp2p
|
339
|
+
.getConnections()
|
340
|
+
.filter((conn) => conn.tags.includes(Tags.BOOTSTRAP));
|
341
|
+
|
342
|
+
// If we have too many bootstrap connections, drop one
|
343
|
+
if (
|
344
|
+
bootstrapConnections.length > this.options.maxBootstrapPeersAllowed
|
345
|
+
) {
|
346
|
+
await this.dropConnection(peerId);
|
347
|
+
} else {
|
348
|
+
this.dispatchEvent(
|
349
|
+
new CustomEvent<PeerId>(
|
350
|
+
EPeersByDiscoveryEvents.PEER_CONNECT_BOOTSTRAP,
|
351
|
+
{
|
352
|
+
detail: peerId,
|
353
|
+
}
|
354
|
+
)
|
355
|
+
);
|
356
|
+
}
|
357
|
+
} else {
|
358
|
+
this.dispatchEvent(
|
359
|
+
new CustomEvent<PeerId>(
|
360
|
+
EPeersByDiscoveryEvents.PEER_CONNECT_PEER_EXCHANGE,
|
361
|
+
{
|
362
|
+
detail: peerId,
|
363
|
+
}
|
364
|
+
)
|
365
|
+
);
|
366
|
+
}
|
367
|
+
})();
|
183
368
|
},
|
184
369
|
"peer:disconnect": () => {
|
185
|
-
return (evt: CustomEvent<
|
186
|
-
this.keepAliveManager.stop(evt.detail
|
370
|
+
return (evt: CustomEvent<PeerId>): void => {
|
371
|
+
this.keepAliveManager.stop(evt.detail);
|
187
372
|
};
|
188
373
|
},
|
189
374
|
};
|
@@ -194,19 +379,19 @@ export class ConnectionManager {
|
|
194
379
|
* 2. If the peer is not a bootstrap peer
|
195
380
|
*/
|
196
381
|
private async shouldDialPeer(peerId: PeerId): Promise<boolean> {
|
197
|
-
const isConnected = this.
|
382
|
+
const isConnected = this.libp2p.getConnections(peerId).length > 0;
|
198
383
|
|
199
384
|
if (isConnected) return false;
|
200
385
|
|
201
|
-
const
|
202
|
-
|
203
|
-
);
|
386
|
+
const tagNames = await this.getTagNamesForPeer(peerId);
|
387
|
+
|
388
|
+
const isBootstrap = tagNames.some((tagName) => tagName === Tags.BOOTSTRAP);
|
204
389
|
|
205
390
|
if (isBootstrap) {
|
206
|
-
const currentBootstrapConnections = this.
|
391
|
+
const currentBootstrapConnections = this.libp2p
|
207
392
|
.getConnections()
|
208
393
|
.filter((conn) => {
|
209
|
-
conn.tags.find((name) => name === Tags.BOOTSTRAP);
|
394
|
+
return conn.tags.find((name) => name === Tags.BOOTSTRAP);
|
210
395
|
}).length;
|
211
396
|
if (currentBootstrapConnections < this.options.maxBootstrapPeersAllowed)
|
212
397
|
return true;
|
@@ -221,9 +406,12 @@ export class ConnectionManager {
|
|
221
406
|
* Fetches the tag names for a given peer
|
222
407
|
*/
|
223
408
|
private async getTagNamesForPeer(peerId: PeerId): Promise<string[]> {
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
409
|
+
try {
|
410
|
+
const peer = await this.libp2p.peerStore.get(peerId);
|
411
|
+
return Array.from(peer.tags.keys());
|
412
|
+
} catch (error) {
|
413
|
+
log(`Failed to get peer ${peerId}, error: ${error}`);
|
414
|
+
return [];
|
415
|
+
}
|
228
416
|
}
|
229
417
|
}
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { Stream } from "@libp2p/interface-connection";
|
2
|
-
import type { Libp2p } from "@libp2p/interface-libp2p";
|
3
2
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
4
3
|
import type { Peer } from "@libp2p/interface-peer-store";
|
5
4
|
import type { IncomingStreamData } from "@libp2p/interface-registrar";
|
@@ -9,9 +8,10 @@ import type {
|
|
9
8
|
IAsyncIterator,
|
10
9
|
IDecodedMessage,
|
11
10
|
IDecoder,
|
12
|
-
|
11
|
+
IFilter,
|
13
12
|
IProtoMessage,
|
14
13
|
IReceiver,
|
14
|
+
Libp2p,
|
15
15
|
PeerIdStr,
|
16
16
|
ProtocolCreateOptions,
|
17
17
|
ProtocolOptions,
|
@@ -25,8 +25,8 @@ import all from "it-all";
|
|
25
25
|
import * as lp from "it-length-prefixed";
|
26
26
|
import { pipe } from "it-pipe";
|
27
27
|
|
28
|
-
import { BaseProtocol } from "
|
29
|
-
import { DefaultPubSubTopic } from "
|
28
|
+
import { BaseProtocol } from "../base_protocol.js";
|
29
|
+
import { DefaultPubSubTopic } from "../constants.js";
|
30
30
|
|
31
31
|
import {
|
32
32
|
FilterPushRpc,
|
@@ -41,7 +41,7 @@ type SubscriptionCallback<T extends IDecodedMessage> = {
|
|
41
41
|
callback: Callback<T>;
|
42
42
|
};
|
43
43
|
|
44
|
-
const
|
44
|
+
const FilterCodecs = {
|
45
45
|
SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
|
46
46
|
PUSH: "/vac/waku/filter-push/2.0.0-beta1",
|
47
47
|
};
|
@@ -225,7 +225,7 @@ class Subscription {
|
|
225
225
|
}
|
226
226
|
}
|
227
227
|
|
228
|
-
class
|
228
|
+
class Filter extends BaseProtocol implements IReceiver {
|
229
229
|
private readonly options: ProtocolCreateOptions;
|
230
230
|
private activeSubscriptions = new Map<string, Subscription>();
|
231
231
|
|
@@ -245,18 +245,12 @@ class FilterV2 extends BaseProtocol implements IReceiver {
|
|
245
245
|
return subscription;
|
246
246
|
}
|
247
247
|
|
248
|
-
constructor(
|
249
|
-
super(
|
250
|
-
FilterV2Codecs.SUBSCRIBE,
|
251
|
-
libp2p.peerStore,
|
252
|
-
libp2p.getConnections.bind(libp2p)
|
253
|
-
);
|
248
|
+
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
249
|
+
super(FilterCodecs.SUBSCRIBE, libp2p.components);
|
254
250
|
|
255
|
-
this.
|
256
|
-
|
257
|
-
|
258
|
-
log("Failed to register ", FilterV2Codecs.PUSH, e);
|
259
|
-
});
|
251
|
+
libp2p.handle(FilterCodecs.PUSH, this.onRequest.bind(this)).catch((e) => {
|
252
|
+
log("Failed to register ", FilterCodecs.PUSH, e);
|
253
|
+
});
|
260
254
|
|
261
255
|
this.activeSubscriptions = new Map();
|
262
256
|
|
@@ -312,7 +306,7 @@ class FilterV2 extends BaseProtocol implements IReceiver {
|
|
312
306
|
): Promise<Unsubscribe> {
|
313
307
|
const subscription = await this.createSubscription(undefined, opts?.peerId);
|
314
308
|
|
315
|
-
subscription.subscribe(decoders, callback);
|
309
|
+
await subscription.subscribe(decoders, callback);
|
316
310
|
|
317
311
|
const contentTopics = Array.from(
|
318
312
|
groupByContentTopic(
|
@@ -371,10 +365,10 @@ class FilterV2 extends BaseProtocol implements IReceiver {
|
|
371
365
|
}
|
372
366
|
}
|
373
367
|
|
374
|
-
export function
|
368
|
+
export function wakuFilter(
|
375
369
|
init: Partial<ProtocolCreateOptions> = {}
|
376
|
-
): (libp2p: Libp2p) =>
|
377
|
-
return (libp2p: Libp2p) => new
|
370
|
+
): (libp2p: Libp2p) => IFilter {
|
371
|
+
return (libp2p: Libp2p) => new Filter(libp2p, init);
|
378
372
|
}
|
379
373
|
|
380
374
|
async function pushMessage<T extends IDecodedMessage>(
|
@@ -394,20 +388,19 @@ async function pushMessage<T extends IDecodedMessage>(
|
|
394
388
|
// We don't want to wait for decoding failure, just attempt to decode
|
395
389
|
// all messages and do the call back on the one that works
|
396
390
|
// noinspection ES6MissingAwait
|
397
|
-
|
398
|
-
if (didDecodeMsg)
|
391
|
+
for (const dec of decoders) {
|
392
|
+
if (didDecodeMsg) break;
|
399
393
|
const decoded = await dec.fromProtoObj(
|
400
394
|
pubSubTopic,
|
401
395
|
message as IProtoMessage
|
402
396
|
);
|
403
|
-
// const decoded = await dec.fromProtoObj(pubSubTopic, message);
|
404
397
|
if (!decoded) {
|
405
398
|
log("Not able to decode message");
|
406
|
-
|
399
|
+
continue;
|
407
400
|
}
|
408
401
|
// This is just to prevent more decoding attempt
|
409
402
|
// TODO: Could be better if we were to abort promises
|
410
403
|
didDecodeMsg = Boolean(decoded);
|
411
404
|
await callback(decoded);
|
412
|
-
}
|
405
|
+
}
|
413
406
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
2
2
|
import type { IRelay } from "@waku/interfaces";
|
3
3
|
import debug from "debug";
|
4
|
-
import type {
|
4
|
+
import type { PingService } from "libp2p/ping";
|
5
5
|
|
6
6
|
import { createEncoder } from "../index.js";
|
7
7
|
|
@@ -26,7 +26,7 @@ export class KeepAliveManager {
|
|
26
26
|
this.relay = relay;
|
27
27
|
}
|
28
28
|
|
29
|
-
public start(peerId: PeerId, libp2pPing:
|
29
|
+
public start(peerId: PeerId, libp2pPing: PingService): void {
|
30
30
|
// Just in case a timer already exist for this peer
|
31
31
|
this.stop(peerId);
|
32
32
|
|
@@ -37,7 +37,7 @@ export class KeepAliveManager {
|
|
37
37
|
|
38
38
|
if (pingPeriodSecs !== 0) {
|
39
39
|
const interval = setInterval(() => {
|
40
|
-
libp2pPing(peerId).catch((e) => {
|
40
|
+
libp2pPing.ping(peerId).catch((e) => {
|
41
41
|
log(`Ping failed (${peerIdStr})`, e);
|
42
42
|
});
|
43
43
|
}, pingPeriodSecs * 1000);
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import type { Libp2p } from "@libp2p/interface-libp2p";
|
2
1
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
3
2
|
import {
|
4
3
|
IEncoder,
|
5
4
|
ILightPush,
|
6
5
|
IMessage,
|
6
|
+
Libp2p,
|
7
7
|
ProtocolCreateOptions,
|
8
8
|
ProtocolOptions,
|
9
9
|
SendError,
|
@@ -33,8 +33,8 @@ export { PushResponse };
|
|
33
33
|
class LightPush extends BaseProtocol implements ILightPush {
|
34
34
|
options: ProtocolCreateOptions;
|
35
35
|
|
36
|
-
constructor(
|
37
|
-
super(LightPushCodec, libp2p.
|
36
|
+
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
37
|
+
super(LightPushCodec, libp2p.components);
|
38
38
|
this.options = options || {};
|
39
39
|
}
|
40
40
|
|
@@ -47,21 +47,21 @@ export const fleets = {
|
|
47
47
|
"wakuv2.prod": {
|
48
48
|
"waku-websocket": {
|
49
49
|
"node-01.ac-cn-hongkong-c.wakuv2.prod":
|
50
|
-
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/
|
50
|
+
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
|
51
51
|
"node-01.do-ams3.wakuv2.prod":
|
52
|
-
"/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/
|
52
|
+
"/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
|
53
53
|
"node-01.gc-us-central1-a.wakuv2.prod":
|
54
|
-
"/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/
|
54
|
+
"/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA",
|
55
55
|
},
|
56
56
|
},
|
57
57
|
"wakuv2.test": {
|
58
58
|
"waku-websocket": {
|
59
59
|
"node-01.ac-cn-hongkong-c.wakuv2.test":
|
60
|
-
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/
|
60
|
+
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
|
61
61
|
"node-01.do-ams3.wakuv2.test":
|
62
|
-
"/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/
|
62
|
+
"/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
|
63
63
|
"node-01.gc-us-central1-a.wakuv2.test":
|
64
|
-
"/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/
|
64
|
+
"/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
|
65
65
|
},
|
66
66
|
},
|
67
67
|
},
|
package/src/lib/store/index.ts
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import type { Stream } from "@libp2p/interface-connection";
|
2
|
-
import type { Libp2p } from "@libp2p/interface-libp2p";
|
3
2
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
4
3
|
import { sha256 } from "@noble/hashes/sha256";
|
5
4
|
import {
|
@@ -7,6 +6,7 @@ import {
|
|
7
6
|
IDecodedMessage,
|
8
7
|
IDecoder,
|
9
8
|
IStore,
|
9
|
+
Libp2p,
|
10
10
|
ProtocolCreateOptions,
|
11
11
|
} from "@waku/interfaces";
|
12
12
|
import { proto_store as proto } from "@waku/proto";
|
@@ -81,8 +81,8 @@ export interface QueryOptions {
|
|
81
81
|
class Store extends BaseProtocol implements IStore {
|
82
82
|
options: ProtocolCreateOptions;
|
83
83
|
|
84
|
-
constructor(
|
85
|
-
super(StoreCodec, libp2p.
|
84
|
+
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
85
|
+
super(StoreCodec, libp2p.components);
|
86
86
|
this.options = options ?? {};
|
87
87
|
}
|
88
88
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import type {
|
2
|
-
import type {
|
1
|
+
import type { IdentifyResult } from "@libp2p/interface-libp2p";
|
2
|
+
import type { IBaseProtocol, IRelay, Waku } from "@waku/interfaces";
|
3
3
|
import { Protocols } from "@waku/interfaces";
|
4
4
|
import debug from "debug";
|
5
5
|
import { pEvent } from "p-event";
|
@@ -10,7 +10,7 @@ const log = debug("waku:wait-for-remote-peer");
|
|
10
10
|
* Wait for a remote peer to be ready given the passed protocols.
|
11
11
|
* Must be used after attempting to connect to nodes, using
|
12
12
|
* {@link @waku/core.WakuNode.dial} or a bootstrap method with
|
13
|
-
* {@link @waku/
|
13
|
+
* {@link @waku/sdk.createLightNode}.
|
14
14
|
*
|
15
15
|
* If the passed protocols is a GossipSub protocol, then it resolves only once
|
16
16
|
* a peer is in a mesh, to help ensure that other peers will send and receive
|
@@ -74,9 +74,7 @@ export async function waitForRemotePeer(
|
|
74
74
|
/**
|
75
75
|
* Wait for a peer with the given protocol to be connected.
|
76
76
|
*/
|
77
|
-
async function waitForConnectedPeer(
|
78
|
-
protocol: PointToPointProtocol
|
79
|
-
): Promise<void> {
|
77
|
+
async function waitForConnectedPeer(protocol: IBaseProtocol): Promise<void> {
|
80
78
|
const codec = protocol.multicodec;
|
81
79
|
const peers = await protocol.peers();
|
82
80
|
|
@@ -86,14 +84,14 @@ async function waitForConnectedPeer(
|
|
86
84
|
}
|
87
85
|
|
88
86
|
await new Promise<void>((resolve) => {
|
89
|
-
const cb = (evt: CustomEvent<
|
90
|
-
if (evt.detail
|
87
|
+
const cb = (evt: CustomEvent<IdentifyResult>): void => {
|
88
|
+
if (evt.detail?.protocols?.includes(codec)) {
|
91
89
|
log("Resolving for", codec, evt.detail.protocols);
|
92
|
-
protocol.
|
90
|
+
protocol.removeLibp2pEventListener("peer:identify", cb);
|
93
91
|
resolve();
|
94
92
|
}
|
95
93
|
};
|
96
|
-
protocol.
|
94
|
+
protocol.addLibp2pEventListener("peer:identify", cb);
|
97
95
|
});
|
98
96
|
}
|
99
97
|
|