@waku/core 0.0.20 → 0.0.22
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 +48 -0
- package/bundle/index.js +290 -335
- 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 +3 -5
- package/dist/index.js +3 -5
- 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 +7 -7
- package/dist/lib/connection_manager.js +152 -66
- 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} +20 -32
- package/dist/lib/filter/index.js.map +1 -0
- package/dist/lib/keep_alive_manager.d.ts +3 -6
- 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.js +3 -3
- 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 +10 -18
- package/src/index.ts +3 -9
- package/src/lib/base_protocol.ts +23 -9
- package/src/lib/connection_manager.ts +210 -98
- package/src/lib/filter/{v2/index.ts → index.ts} +27 -40
- package/src/lib/keep_alive_manager.ts +4 -8
- 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 +7 -9
- 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,12 +1,20 @@
|
|
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
|
+
IConnectionManager,
|
9
|
+
IPeersByDiscoveryEvents,
|
10
|
+
IRelay,
|
11
|
+
KeepAliveOptions,
|
12
|
+
PeersByDiscoveryResult,
|
13
|
+
} from "@waku/interfaces";
|
14
|
+
import { Libp2p, Tags } from "@waku/interfaces";
|
7
15
|
import debug from "debug";
|
8
16
|
|
9
|
-
import { KeepAliveManager
|
17
|
+
import { KeepAliveManager } from "./keep_alive_manager.js";
|
10
18
|
|
11
19
|
const log = debug("waku:connection-manager");
|
12
20
|
|
@@ -14,11 +22,14 @@ export const DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED = 1;
|
|
14
22
|
export const DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER = 3;
|
15
23
|
export const DEFAULT_MAX_PARALLEL_DIALS = 3;
|
16
24
|
|
17
|
-
export class ConnectionManager
|
25
|
+
export class ConnectionManager
|
26
|
+
extends EventEmitter<IPeersByDiscoveryEvents>
|
27
|
+
implements IConnectionManager
|
28
|
+
{
|
18
29
|
private static instances = new Map<string, ConnectionManager>();
|
19
30
|
private keepAliveManager: KeepAliveManager;
|
20
31
|
private options: ConnectionManagerOptions;
|
21
|
-
private
|
32
|
+
private libp2p: Libp2p;
|
22
33
|
private dialAttemptsForPeer: Map<string, number> = new Map();
|
23
34
|
private dialErrorsForPeer: Map<string, any> = new Map();
|
24
35
|
|
@@ -46,13 +57,58 @@ export class ConnectionManager {
|
|
46
57
|
return instance;
|
47
58
|
}
|
48
59
|
|
60
|
+
public async getPeersByDiscovery(): Promise<PeersByDiscoveryResult> {
|
61
|
+
const peersDiscovered = await this.libp2p.peerStore.all();
|
62
|
+
const peersConnected = this.libp2p
|
63
|
+
.getConnections()
|
64
|
+
.map((conn) => conn.remotePeer);
|
65
|
+
|
66
|
+
const peersDiscoveredByBootstrap: Peer[] = [];
|
67
|
+
const peersDiscoveredByPeerExchange: Peer[] = [];
|
68
|
+
const peersConnectedByBootstrap: Peer[] = [];
|
69
|
+
const peersConnectedByPeerExchange: Peer[] = [];
|
70
|
+
|
71
|
+
for (const peer of peersDiscovered) {
|
72
|
+
const tags = await this.getTagNamesForPeer(peer.id);
|
73
|
+
|
74
|
+
if (tags.includes(Tags.BOOTSTRAP)) {
|
75
|
+
peersDiscoveredByBootstrap.push(peer);
|
76
|
+
} else if (tags.includes(Tags.PEER_EXCHANGE)) {
|
77
|
+
peersDiscoveredByPeerExchange.push(peer);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
for (const peerId of peersConnected) {
|
82
|
+
const peer = await this.libp2p.peerStore.get(peerId);
|
83
|
+
const tags = await this.getTagNamesForPeer(peerId);
|
84
|
+
|
85
|
+
if (tags.includes(Tags.BOOTSTRAP)) {
|
86
|
+
peersConnectedByBootstrap.push(peer);
|
87
|
+
} else if (tags.includes(Tags.PEER_EXCHANGE)) {
|
88
|
+
peersConnectedByPeerExchange.push(peer);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
return {
|
93
|
+
DISCOVERED: {
|
94
|
+
[Tags.BOOTSTRAP]: peersDiscoveredByBootstrap,
|
95
|
+
[Tags.PEER_EXCHANGE]: peersDiscoveredByPeerExchange,
|
96
|
+
},
|
97
|
+
CONNECTED: {
|
98
|
+
[Tags.BOOTSTRAP]: peersConnectedByBootstrap,
|
99
|
+
[Tags.PEER_EXCHANGE]: peersConnectedByPeerExchange,
|
100
|
+
},
|
101
|
+
};
|
102
|
+
}
|
103
|
+
|
49
104
|
private constructor(
|
50
|
-
|
105
|
+
libp2p: Libp2p,
|
51
106
|
keepAliveOptions: KeepAliveOptions,
|
52
107
|
relay?: IRelay,
|
53
108
|
options?: Partial<ConnectionManagerOptions>
|
54
109
|
) {
|
55
|
-
|
110
|
+
super();
|
111
|
+
this.libp2p = libp2p;
|
56
112
|
this.options = {
|
57
113
|
maxDialAttemptsForPeer: DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER,
|
58
114
|
maxBootstrapPeersAllowed: DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED,
|
@@ -69,17 +125,17 @@ export class ConnectionManager {
|
|
69
125
|
// libp2p emits `peer:discovery` events during its initialization
|
70
126
|
// which means that before the ConnectionManager is initialized, some peers may have been discovered
|
71
127
|
// we will dial the peers in peerStore ONCE before we start to listen to the `peer:discovery` events within the ConnectionManager
|
72
|
-
this.dialPeerStorePeers()
|
128
|
+
this.dialPeerStorePeers().catch((error) =>
|
129
|
+
log(`Unexpected error while dialing peer store peers`, error)
|
130
|
+
);
|
73
131
|
}
|
74
132
|
|
75
133
|
private async dialPeerStorePeers(): Promise<void> {
|
76
|
-
const peerInfos = await this.
|
134
|
+
const peerInfos = await this.libp2p.peerStore.all();
|
77
135
|
const dialPromises = [];
|
78
136
|
for (const peerInfo of peerInfos) {
|
79
137
|
if (
|
80
|
-
this.
|
81
|
-
.getConnections()
|
82
|
-
.find((c) => c.remotePeer === peerInfo.id)
|
138
|
+
this.libp2p.getConnections().find((c) => c.remotePeer === peerInfo.id)
|
83
139
|
)
|
84
140
|
continue;
|
85
141
|
|
@@ -101,15 +157,15 @@ export class ConnectionManager {
|
|
101
157
|
|
102
158
|
stop(): void {
|
103
159
|
this.keepAliveManager.stopAll();
|
104
|
-
this.
|
160
|
+
this.libp2p.removeEventListener(
|
105
161
|
"peer:connect",
|
106
162
|
this.onEventHandlers["peer:connect"]
|
107
163
|
);
|
108
|
-
this.
|
164
|
+
this.libp2p.removeEventListener(
|
109
165
|
"peer:disconnect",
|
110
166
|
this.onEventHandlers["peer:disconnect"]
|
111
167
|
);
|
112
|
-
this.
|
168
|
+
this.libp2p.removeEventListener(
|
113
169
|
"peer:discovery",
|
114
170
|
this.onEventHandlers["peer:discovery"]
|
115
171
|
);
|
@@ -118,57 +174,74 @@ export class ConnectionManager {
|
|
118
174
|
private async dialPeer(peerId: PeerId): Promise<void> {
|
119
175
|
this.currentActiveDialCount += 1;
|
120
176
|
let dialAttempt = 0;
|
121
|
-
while (dialAttempt
|
177
|
+
while (dialAttempt < this.options.maxDialAttemptsForPeer) {
|
122
178
|
try {
|
123
|
-
log(`Dialing peer ${peerId.toString()}`);
|
124
|
-
await this.
|
179
|
+
log(`Dialing peer ${peerId.toString()} on attempt ${dialAttempt + 1}`);
|
180
|
+
await this.libp2p.dial(peerId);
|
125
181
|
|
126
182
|
const tags = await this.getTagNamesForPeer(peerId);
|
127
183
|
// add tag to connection describing discovery mechanism
|
128
184
|
// don't add duplicate tags
|
129
|
-
this.
|
130
|
-
.
|
131
|
-
|
132
|
-
(conn) => (conn.tags = Array.from(new Set([...conn.tags, ...tags])))
|
133
|
-
);
|
185
|
+
this.libp2p.getConnections(peerId).forEach((conn) => {
|
186
|
+
conn.tags = Array.from(new Set([...conn.tags, ...tags]));
|
187
|
+
});
|
134
188
|
|
135
189
|
this.dialAttemptsForPeer.delete(peerId.toString());
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
190
|
+
// Dialing succeeded, break the loop
|
191
|
+
break;
|
192
|
+
} catch (error) {
|
193
|
+
if (error instanceof AggregateError) {
|
194
|
+
// Handle AggregateError
|
195
|
+
log(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
|
196
|
+
} else {
|
197
|
+
// Handle generic error
|
198
|
+
log(
|
199
|
+
`Error dialing peer ${peerId.toString()} - ${
|
200
|
+
(error as any).message
|
201
|
+
}`
|
202
|
+
);
|
203
|
+
}
|
140
204
|
this.dialErrorsForPeer.set(peerId.toString(), error);
|
141
|
-
log(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
|
142
205
|
|
143
|
-
dialAttempt
|
144
|
-
this.dialAttemptsForPeer.set(peerId.toString(), dialAttempt
|
145
|
-
|
146
|
-
if (dialAttempt <= this.options.maxDialAttemptsForPeer) {
|
147
|
-
log(`Reattempting dial (${dialAttempt})`);
|
148
|
-
}
|
206
|
+
dialAttempt++;
|
207
|
+
this.dialAttemptsForPeer.set(peerId.toString(), dialAttempt);
|
149
208
|
}
|
150
209
|
}
|
151
210
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
211
|
+
// Always decrease the active dial count and process the dial queue
|
212
|
+
this.currentActiveDialCount--;
|
213
|
+
this.processDialQueue();
|
214
|
+
|
215
|
+
// If max dial attempts reached and dialing failed, delete the peer
|
216
|
+
if (dialAttempt === this.options.maxDialAttemptsForPeer) {
|
217
|
+
try {
|
218
|
+
const error = this.dialErrorsForPeer.get(peerId.toString());
|
219
|
+
|
220
|
+
let errorMessage;
|
221
|
+
if (error instanceof AggregateError) {
|
222
|
+
errorMessage = JSON.stringify(error.errors[0]);
|
223
|
+
} else {
|
224
|
+
errorMessage = error.message;
|
225
|
+
}
|
226
|
+
|
227
|
+
log(
|
228
|
+
`Deleting undialable peer ${peerId.toString()} from peer store. Error: ${errorMessage}`
|
229
|
+
);
|
230
|
+
|
231
|
+
this.dialErrorsForPeer.delete(peerId.toString());
|
232
|
+
await this.libp2p.peerStore.delete(peerId);
|
233
|
+
} catch (error) {
|
234
|
+
throw new Error(
|
235
|
+
`Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`
|
236
|
+
);
|
237
|
+
}
|
166
238
|
}
|
167
239
|
}
|
168
240
|
|
169
|
-
async dropConnection(peerId: PeerId): Promise<void> {
|
241
|
+
private async dropConnection(peerId: PeerId): Promise<void> {
|
170
242
|
try {
|
171
|
-
|
243
|
+
this.keepAliveManager.stop(peerId);
|
244
|
+
await this.libp2p.hangUp(peerId);
|
172
245
|
log(`Dropped connection with peer ${peerId.toString()}`);
|
173
246
|
} catch (error) {
|
174
247
|
log(
|
@@ -177,7 +250,7 @@ export class ConnectionManager {
|
|
177
250
|
}
|
178
251
|
}
|
179
252
|
|
180
|
-
private
|
253
|
+
private processDialQueue(): void {
|
181
254
|
if (
|
182
255
|
this.pendingPeerDialQueue.length > 0 &&
|
183
256
|
this.currentActiveDialCount < this.options.maxParallelDials
|
@@ -191,14 +264,14 @@ export class ConnectionManager {
|
|
191
264
|
}
|
192
265
|
|
193
266
|
private startPeerDiscoveryListener(): void {
|
194
|
-
this.
|
195
|
-
"peer",
|
267
|
+
this.libp2p.addEventListener(
|
268
|
+
"peer:discovery",
|
196
269
|
this.onEventHandlers["peer:discovery"]
|
197
270
|
);
|
198
271
|
}
|
199
272
|
|
200
273
|
private startPeerConnectionListener(): void {
|
201
|
-
this.
|
274
|
+
this.libp2p.addEventListener(
|
202
275
|
"peer:connect",
|
203
276
|
this.onEventHandlers["peer:connect"]
|
204
277
|
);
|
@@ -217,7 +290,7 @@ export class ConnectionManager {
|
|
217
290
|
* >this event will **only** be triggered when the last connection is closed.
|
218
291
|
* @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
|
219
292
|
*/
|
220
|
-
this.
|
293
|
+
this.libp2p.addEventListener(
|
221
294
|
"peer:disconnect",
|
222
295
|
this.onEventHandlers["peer:disconnect"]
|
223
296
|
);
|
@@ -237,41 +310,77 @@ export class ConnectionManager {
|
|
237
310
|
}
|
238
311
|
|
239
312
|
private onEventHandlers = {
|
240
|
-
"peer:discovery":
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
313
|
+
"peer:discovery": (evt: CustomEvent<PeerInfo>): void => {
|
314
|
+
void (async () => {
|
315
|
+
const { id: peerId } = evt.detail;
|
316
|
+
|
317
|
+
const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(
|
318
|
+
Tags.BOOTSTRAP
|
319
|
+
);
|
320
|
+
|
321
|
+
this.dispatchEvent(
|
322
|
+
new CustomEvent<PeerId>(
|
323
|
+
isBootstrap
|
324
|
+
? EPeersByDiscoveryEvents.PEER_DISCOVERY_BOOTSTRAP
|
325
|
+
: EPeersByDiscoveryEvents.PEER_DISCOVERY_PEER_EXCHANGE,
|
326
|
+
{
|
327
|
+
detail: peerId,
|
328
|
+
}
|
329
|
+
)
|
330
|
+
);
|
331
|
+
|
332
|
+
try {
|
333
|
+
await this.attemptDial(peerId);
|
334
|
+
} catch (error) {
|
335
|
+
log(`Error dialing peer ${peerId.toString()} : ${error}`);
|
336
|
+
}
|
337
|
+
})();
|
246
338
|
},
|
247
|
-
"peer:connect":
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
peerId,
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
339
|
+
"peer:connect": (evt: CustomEvent<PeerId>): void => {
|
340
|
+
void (async () => {
|
341
|
+
const peerId = evt.detail;
|
342
|
+
|
343
|
+
this.keepAliveManager.start(peerId, this.libp2p.services.ping);
|
344
|
+
|
345
|
+
const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(
|
346
|
+
Tags.BOOTSTRAP
|
347
|
+
);
|
348
|
+
|
349
|
+
if (isBootstrap) {
|
350
|
+
const bootstrapConnections = this.libp2p
|
351
|
+
.getConnections()
|
352
|
+
.filter((conn) => conn.tags.includes(Tags.BOOTSTRAP));
|
353
|
+
|
354
|
+
// If we have too many bootstrap connections, drop one
|
355
|
+
if (
|
356
|
+
bootstrapConnections.length > this.options.maxBootstrapPeersAllowed
|
357
|
+
) {
|
358
|
+
await this.dropConnection(peerId);
|
359
|
+
} else {
|
360
|
+
this.dispatchEvent(
|
361
|
+
new CustomEvent<PeerId>(
|
362
|
+
EPeersByDiscoveryEvents.PEER_CONNECT_BOOTSTRAP,
|
363
|
+
{
|
364
|
+
detail: peerId,
|
365
|
+
}
|
366
|
+
)
|
367
|
+
);
|
368
|
+
}
|
369
|
+
} else {
|
370
|
+
this.dispatchEvent(
|
371
|
+
new CustomEvent<PeerId>(
|
372
|
+
EPeersByDiscoveryEvents.PEER_CONNECT_PEER_EXCHANGE,
|
373
|
+
{
|
374
|
+
detail: peerId,
|
375
|
+
}
|
376
|
+
)
|
377
|
+
);
|
269
378
|
}
|
270
|
-
}
|
379
|
+
})();
|
271
380
|
},
|
272
381
|
"peer:disconnect": () => {
|
273
|
-
return (evt: CustomEvent<
|
274
|
-
this.keepAliveManager.stop(evt.detail
|
382
|
+
return (evt: CustomEvent<PeerId>): void => {
|
383
|
+
this.keepAliveManager.stop(evt.detail);
|
275
384
|
};
|
276
385
|
},
|
277
386
|
};
|
@@ -282,19 +391,19 @@ export class ConnectionManager {
|
|
282
391
|
* 2. If the peer is not a bootstrap peer
|
283
392
|
*/
|
284
393
|
private async shouldDialPeer(peerId: PeerId): Promise<boolean> {
|
285
|
-
const isConnected = this.
|
394
|
+
const isConnected = this.libp2p.getConnections(peerId).length > 0;
|
286
395
|
|
287
396
|
if (isConnected) return false;
|
288
397
|
|
289
|
-
const
|
290
|
-
|
291
|
-
);
|
398
|
+
const tagNames = await this.getTagNamesForPeer(peerId);
|
399
|
+
|
400
|
+
const isBootstrap = tagNames.some((tagName) => tagName === Tags.BOOTSTRAP);
|
292
401
|
|
293
402
|
if (isBootstrap) {
|
294
|
-
const currentBootstrapConnections = this.
|
403
|
+
const currentBootstrapConnections = this.libp2p
|
295
404
|
.getConnections()
|
296
405
|
.filter((conn) => {
|
297
|
-
conn.tags.find((name) => name === Tags.BOOTSTRAP);
|
406
|
+
return conn.tags.find((name) => name === Tags.BOOTSTRAP);
|
298
407
|
}).length;
|
299
408
|
if (currentBootstrapConnections < this.options.maxBootstrapPeersAllowed)
|
300
409
|
return true;
|
@@ -309,9 +418,12 @@ export class ConnectionManager {
|
|
309
418
|
* Fetches the tag names for a given peer
|
310
419
|
*/
|
311
420
|
private async getTagNamesForPeer(peerId: PeerId): Promise<string[]> {
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
421
|
+
try {
|
422
|
+
const peer = await this.libp2p.peerStore.get(peerId);
|
423
|
+
return Array.from(peer.tags.keys());
|
424
|
+
} catch (error) {
|
425
|
+
log(`Failed to get peer ${peerId}, error: ${error}`);
|
426
|
+
return [];
|
427
|
+
}
|
316
428
|
}
|
317
429
|
}
|
@@ -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>(
|
@@ -390,24 +384,17 @@ async function pushMessage<T extends IDecodedMessage>(
|
|
390
384
|
return;
|
391
385
|
}
|
392
386
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
if (didDecodeMsg) return;
|
399
|
-
const decoded = await dec.fromProtoObj(
|
400
|
-
pubSubTopic,
|
401
|
-
message as IProtoMessage
|
387
|
+
try {
|
388
|
+
const decodePromises = decoders.map((dec) =>
|
389
|
+
dec
|
390
|
+
.fromProtoObj(pubSubTopic, message as IProtoMessage)
|
391
|
+
.then((decoded) => decoded || Promise.reject("Decoding failed"))
|
402
392
|
);
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
didDecodeMsg = Boolean(decoded);
|
411
|
-
await callback(decoded);
|
412
|
-
});
|
393
|
+
|
394
|
+
const decodedMessage = await Promise.any(decodePromises);
|
395
|
+
|
396
|
+
await callback(decodedMessage);
|
397
|
+
} catch (e) {
|
398
|
+
log("Error decoding message", e);
|
399
|
+
}
|
413
400
|
}
|
@@ -1,18 +1,14 @@
|
|
1
1
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
2
2
|
import type { IRelay } from "@waku/interfaces";
|
3
|
+
import type { KeepAliveOptions } from "@waku/interfaces";
|
3
4
|
import debug from "debug";
|
4
|
-
import type {
|
5
|
+
import type { PingService } from "libp2p/ping";
|
5
6
|
|
6
7
|
import { createEncoder } from "../index.js";
|
7
8
|
|
8
9
|
export const RelayPingContentTopic = "/relay-ping/1/ping/null";
|
9
10
|
const log = debug("waku:keep-alive");
|
10
11
|
|
11
|
-
export interface KeepAliveOptions {
|
12
|
-
pingKeepAlive: number;
|
13
|
-
relayKeepAlive: number;
|
14
|
-
}
|
15
|
-
|
16
12
|
export class KeepAliveManager {
|
17
13
|
private pingKeepAliveTimers: Map<string, ReturnType<typeof setInterval>>;
|
18
14
|
private relayKeepAliveTimers: Map<PeerId, ReturnType<typeof setInterval>>;
|
@@ -26,7 +22,7 @@ export class KeepAliveManager {
|
|
26
22
|
this.relay = relay;
|
27
23
|
}
|
28
24
|
|
29
|
-
public start(peerId: PeerId, libp2pPing:
|
25
|
+
public start(peerId: PeerId, libp2pPing: PingService): void {
|
30
26
|
// Just in case a timer already exist for this peer
|
31
27
|
this.stop(peerId);
|
32
28
|
|
@@ -37,7 +33,7 @@ export class KeepAliveManager {
|
|
37
33
|
|
38
34
|
if (pingPeriodSecs !== 0) {
|
39
35
|
const interval = setInterval(() => {
|
40
|
-
libp2pPing(peerId).catch((e) => {
|
36
|
+
libp2pPing.ping(peerId).catch((e) => {
|
41
37
|
log(`Ping failed (${peerIdStr})`, e);
|
42
38
|
});
|
43
39
|
}, 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
|
},
|