@waku/core 0.0.26 → 0.0.28-434be7b.0
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 +26 -0
- package/bundle/{base_protocol-pDODy0G6.js → base_protocol-BCwLeb-A.js} +134 -89
- package/bundle/{browser-mTOOnVZp.js → browser-DoQRY-an.js} +518 -712
- package/bundle/{index-cmONXM-V.js → index-vlQahmUj.js} +98 -41
- package/bundle/index.js +3081 -21642
- package/bundle/lib/base_protocol.js +3 -3
- package/bundle/lib/message/version_0.js +3 -3
- package/bundle/lib/predefined_bootstrap_nodes.js +1 -1
- package/bundle/{version_0-LQTFNC7k.js → version_0-DiakMc1A.js} +1246 -2444
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/base_protocol.d.ts +15 -13
- package/dist/lib/base_protocol.js +35 -22
- package/dist/lib/base_protocol.js.map +1 -1
- package/dist/lib/connection_manager.d.ts +2 -2
- package/dist/lib/connection_manager.js +16 -6
- package/dist/lib/connection_manager.js.map +1 -1
- package/dist/lib/filter/index.d.ts +1 -1
- package/dist/lib/filter/index.js +144 -82
- package/dist/lib/filter/index.js.map +1 -1
- package/dist/lib/filterPeers.d.ts +8 -5
- package/dist/lib/filterPeers.js +12 -5
- package/dist/lib/filterPeers.js.map +1 -1
- package/dist/lib/keep_alive_manager.d.ts +2 -3
- package/dist/lib/keep_alive_manager.js.map +1 -1
- package/dist/lib/light_push/index.d.ts +12 -2
- package/dist/lib/light_push/index.js +80 -80
- package/dist/lib/light_push/index.js.map +1 -1
- package/dist/lib/metadata/index.d.ts +2 -2
- package/dist/lib/metadata/index.js +58 -16
- package/dist/lib/metadata/index.js.map +1 -1
- package/dist/lib/store/index.js +1 -3
- package/dist/lib/store/index.js.map +1 -1
- package/dist/lib/stream_manager.d.ts +2 -2
- package/dist/lib/stream_manager.js.map +1 -1
- package/dist/lib/wait_for_remote_peer.d.ts +1 -1
- package/dist/lib/wait_for_remote_peer.js +42 -10
- package/dist/lib/wait_for_remote_peer.js.map +1 -1
- package/package.json +1 -127
- package/src/index.ts +1 -6
- package/src/lib/base_protocol.ts +57 -37
- package/src/lib/connection_manager.ts +17 -10
- package/src/lib/filter/index.ts +234 -136
- package/src/lib/filterPeers.ts +15 -7
- package/src/lib/keep_alive_manager.ts +2 -3
- package/src/lib/light_push/index.ts +104 -124
- package/src/lib/metadata/index.ts +92 -30
- package/src/lib/store/index.ts +3 -6
- package/src/lib/stream_manager.ts +2 -3
- package/src/lib/wait_for_remote_peer.ts +68 -12
- package/dist/lib/waku.d.ts +0 -57
- package/dist/lib/waku.js +0 -130
- package/dist/lib/waku.js.map +0 -1
- package/src/lib/waku.ts +0 -214
package/src/lib/filter/index.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { Stream } from "@libp2p/interface
|
2
|
-
import type { Peer } from "@libp2p/interface
|
3
|
-
import type { IncomingStreamData } from "@libp2p/interface-internal
|
1
|
+
import { Stream } from "@libp2p/interface";
|
2
|
+
import type { Peer } from "@libp2p/interface";
|
3
|
+
import type { IncomingStreamData } from "@libp2p/interface-internal";
|
4
4
|
import type {
|
5
5
|
Callback,
|
6
6
|
ContentTopic,
|
@@ -11,13 +11,13 @@ import type {
|
|
11
11
|
IProtoMessage,
|
12
12
|
IReceiver,
|
13
13
|
Libp2p,
|
14
|
-
PeerIdStr,
|
15
14
|
ProtocolCreateOptions,
|
16
15
|
PubsubTopic,
|
17
16
|
SingleShardInfo,
|
18
17
|
Unsubscribe
|
19
18
|
} from "@waku/interfaces";
|
20
19
|
import { DefaultPubsubTopic } from "@waku/interfaces";
|
20
|
+
import { messageHashStr } from "@waku/message-hash";
|
21
21
|
import { WakuMessage } from "@waku/proto";
|
22
22
|
import {
|
23
23
|
ensurePubsubTopicIsConfigured,
|
@@ -50,10 +50,14 @@ export const FilterCodecs = {
|
|
50
50
|
PUSH: "/vac/waku/filter-push/2.0.0-beta1"
|
51
51
|
};
|
52
52
|
|
53
|
+
/**
|
54
|
+
* A subscription object refers to a subscription to a given pubsub topic.
|
55
|
+
*/
|
53
56
|
class Subscription {
|
54
|
-
|
57
|
+
readonly peers: Peer[];
|
55
58
|
private readonly pubsubTopic: PubsubTopic;
|
56
59
|
private newStream: (peer: Peer) => Promise<Stream>;
|
60
|
+
readonly receivedMessagesHashStr: string[] = [];
|
57
61
|
|
58
62
|
private subscriptionCallbacks: Map<
|
59
63
|
ContentTopic,
|
@@ -62,10 +66,10 @@ class Subscription {
|
|
62
66
|
|
63
67
|
constructor(
|
64
68
|
pubsubTopic: PubsubTopic,
|
65
|
-
|
69
|
+
remotePeers: Peer[],
|
66
70
|
newStream: (peer: Peer) => Promise<Stream>
|
67
71
|
) {
|
68
|
-
this.
|
72
|
+
this.peers = remotePeers;
|
69
73
|
this.pubsubTopic = pubsubTopic;
|
70
74
|
this.newStream = newStream;
|
71
75
|
this.subscriptionCallbacks = new Map();
|
@@ -89,53 +93,59 @@ class Subscription {
|
|
89
93
|
const decodersGroupedByCT = groupByContentTopic(decodersArray);
|
90
94
|
const contentTopics = Array.from(decodersGroupedByCT.keys());
|
91
95
|
|
92
|
-
const
|
96
|
+
const promises = this.peers.map(async (peer) => {
|
97
|
+
const stream = await this.newStream(peer);
|
93
98
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
);
|
98
|
-
|
99
|
-
try {
|
100
|
-
const res = await pipe(
|
101
|
-
[request.encode()],
|
102
|
-
lp.encode,
|
103
|
-
stream,
|
104
|
-
lp.decode,
|
105
|
-
async (source) => await all(source)
|
99
|
+
const request = FilterSubscribeRpc.createSubscribeRequest(
|
100
|
+
this.pubsubTopic,
|
101
|
+
contentTopics
|
106
102
|
);
|
107
103
|
|
108
|
-
|
109
|
-
|
110
|
-
|
104
|
+
try {
|
105
|
+
const res = await pipe(
|
106
|
+
[request.encode()],
|
107
|
+
lp.encode,
|
108
|
+
stream,
|
109
|
+
lp.decode,
|
110
|
+
async (source) => await all(source)
|
111
111
|
);
|
112
|
-
}
|
113
112
|
|
114
|
-
|
115
|
-
|
113
|
+
if (!res || !res.length) {
|
114
|
+
throw Error(
|
115
|
+
`No response received for request ${request.requestId}: ${res}`
|
116
|
+
);
|
117
|
+
}
|
118
|
+
|
119
|
+
const { statusCode, requestId, statusDesc } =
|
120
|
+
FilterSubscribeResponse.decode(res[0].slice());
|
121
|
+
|
122
|
+
if (statusCode < 200 || statusCode >= 300) {
|
123
|
+
throw new Error(
|
124
|
+
`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`
|
125
|
+
);
|
126
|
+
}
|
116
127
|
|
117
|
-
|
128
|
+
log.info(
|
129
|
+
"Subscribed to peer ",
|
130
|
+
peer.id.toString(),
|
131
|
+
"for content topics",
|
132
|
+
contentTopics
|
133
|
+
);
|
134
|
+
} catch (e) {
|
118
135
|
throw new Error(
|
119
|
-
|
136
|
+
"Error subscribing to peer: " +
|
137
|
+
peer.id.toString() +
|
138
|
+
" for content topics: " +
|
139
|
+
contentTopics +
|
140
|
+
": " +
|
141
|
+
e
|
120
142
|
);
|
121
143
|
}
|
144
|
+
});
|
122
145
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
"for content topics",
|
127
|
-
contentTopics
|
128
|
-
);
|
129
|
-
} catch (e) {
|
130
|
-
throw new Error(
|
131
|
-
"Error subscribing to peer: " +
|
132
|
-
this.peer.id.toString() +
|
133
|
-
" for content topics: " +
|
134
|
-
contentTopics +
|
135
|
-
": " +
|
136
|
-
e
|
137
|
-
);
|
138
|
-
}
|
146
|
+
const results = await Promise.allSettled(promises);
|
147
|
+
|
148
|
+
this.handleErrors(results, "subscribe");
|
139
149
|
|
140
150
|
// Save the callback functions by content topics so they
|
141
151
|
// can easily be removed (reciprocally replaced) if `unsubscribe` (reciprocally `subscribe`)
|
@@ -155,133 +165,213 @@ class Subscription {
|
|
155
165
|
}
|
156
166
|
|
157
167
|
async unsubscribe(contentTopics: ContentTopic[]): Promise<void> {
|
158
|
-
const
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
168
|
+
const promises = this.peers.map(async (peer) => {
|
169
|
+
const stream = await this.newStream(peer);
|
170
|
+
const unsubscribeRequest = FilterSubscribeRpc.createUnsubscribeRequest(
|
171
|
+
this.pubsubTopic,
|
172
|
+
contentTopics
|
173
|
+
);
|
163
174
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
175
|
+
try {
|
176
|
+
await pipe([unsubscribeRequest.encode()], lp.encode, stream.sink);
|
177
|
+
} catch (error) {
|
178
|
+
throw new Error("Error unsubscribing: " + error);
|
179
|
+
}
|
169
180
|
|
170
|
-
|
171
|
-
|
181
|
+
contentTopics.forEach((contentTopic: string) => {
|
182
|
+
this.subscriptionCallbacks.delete(contentTopic);
|
183
|
+
});
|
172
184
|
});
|
185
|
+
|
186
|
+
const results = await Promise.allSettled(promises);
|
187
|
+
|
188
|
+
this.handleErrors(results, "unsubscribe");
|
173
189
|
}
|
174
190
|
|
175
191
|
async ping(): Promise<void> {
|
176
|
-
const
|
192
|
+
const promises = this.peers.map(async (peer) => {
|
193
|
+
const stream = await this.newStream(peer);
|
194
|
+
|
195
|
+
const request = FilterSubscribeRpc.createSubscriberPingRequest();
|
196
|
+
|
197
|
+
try {
|
198
|
+
const res = await pipe(
|
199
|
+
[request.encode()],
|
200
|
+
lp.encode,
|
201
|
+
stream,
|
202
|
+
lp.decode,
|
203
|
+
async (source) => await all(source)
|
204
|
+
);
|
177
205
|
|
178
|
-
|
206
|
+
if (!res || !res.length) {
|
207
|
+
throw Error(
|
208
|
+
`No response received for request ${request.requestId}: ${res}`
|
209
|
+
);
|
210
|
+
}
|
179
211
|
|
180
|
-
|
181
|
-
|
182
|
-
[request.encode()],
|
183
|
-
lp.encode,
|
184
|
-
stream,
|
185
|
-
lp.decode,
|
186
|
-
async (source) => await all(source)
|
187
|
-
);
|
212
|
+
const { statusCode, requestId, statusDesc } =
|
213
|
+
FilterSubscribeResponse.decode(res[0].slice());
|
188
214
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
215
|
+
if (statusCode < 200 || statusCode >= 300) {
|
216
|
+
throw new Error(
|
217
|
+
`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`
|
218
|
+
);
|
219
|
+
}
|
220
|
+
log.info(`Ping successful for peer ${peer.id.toString()}`);
|
221
|
+
} catch (error) {
|
222
|
+
log.error("Error pinging: ", error);
|
223
|
+
throw error; // Rethrow the actual error instead of wrapping it
|
193
224
|
}
|
225
|
+
});
|
194
226
|
|
195
|
-
|
196
|
-
FilterSubscribeResponse.decode(res[0].slice());
|
197
|
-
|
198
|
-
if (statusCode < 200 || statusCode >= 300) {
|
199
|
-
throw new Error(
|
200
|
-
`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`
|
201
|
-
);
|
202
|
-
}
|
227
|
+
const results = await Promise.allSettled(promises);
|
203
228
|
|
204
|
-
|
205
|
-
} catch (error) {
|
206
|
-
log.error("Error pinging: ", error);
|
207
|
-
throw new Error("Error pinging: " + error);
|
208
|
-
}
|
229
|
+
this.handleErrors(results, "ping");
|
209
230
|
}
|
210
231
|
|
211
232
|
async unsubscribeAll(): Promise<void> {
|
212
|
-
const
|
213
|
-
|
214
|
-
const request = FilterSubscribeRpc.createUnsubscribeAllRequest(
|
215
|
-
this.pubsubTopic
|
216
|
-
);
|
233
|
+
const promises = this.peers.map(async (peer) => {
|
234
|
+
const stream = await this.newStream(peer);
|
217
235
|
|
218
|
-
|
219
|
-
|
220
|
-
[request.encode()],
|
221
|
-
lp.encode,
|
222
|
-
stream,
|
223
|
-
lp.decode,
|
224
|
-
async (source) => await all(source)
|
236
|
+
const request = FilterSubscribeRpc.createUnsubscribeAllRequest(
|
237
|
+
this.pubsubTopic
|
225
238
|
);
|
226
239
|
|
227
|
-
|
228
|
-
|
229
|
-
|
240
|
+
try {
|
241
|
+
const res = await pipe(
|
242
|
+
[request.encode()],
|
243
|
+
lp.encode,
|
244
|
+
stream,
|
245
|
+
lp.decode,
|
246
|
+
async (source) => await all(source)
|
230
247
|
);
|
231
|
-
}
|
232
248
|
|
233
|
-
|
234
|
-
|
249
|
+
if (!res || !res.length) {
|
250
|
+
throw Error(
|
251
|
+
`No response received for request ${request.requestId}: ${res}`
|
252
|
+
);
|
253
|
+
}
|
254
|
+
|
255
|
+
const { statusCode, requestId, statusDesc } =
|
256
|
+
FilterSubscribeResponse.decode(res[0].slice());
|
235
257
|
|
236
|
-
|
258
|
+
if (statusCode < 200 || statusCode >= 300) {
|
259
|
+
throw new Error(
|
260
|
+
`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`
|
261
|
+
);
|
262
|
+
}
|
263
|
+
|
264
|
+
this.subscriptionCallbacks.clear();
|
265
|
+
log.info(
|
266
|
+
`Unsubscribed from all content topics for pubsub topic ${this.pubsubTopic}`
|
267
|
+
);
|
268
|
+
} catch (error) {
|
237
269
|
throw new Error(
|
238
|
-
|
270
|
+
"Error unsubscribing from all content topics: " + error
|
239
271
|
);
|
240
272
|
}
|
273
|
+
});
|
241
274
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
throw new Error("Error unsubscribing from all content topics: " + error);
|
246
|
-
}
|
275
|
+
const results = await Promise.allSettled(promises);
|
276
|
+
|
277
|
+
this.handleErrors(results, "unsubscribeAll");
|
247
278
|
}
|
248
279
|
|
249
280
|
async processMessage(message: WakuMessage): Promise<void> {
|
250
|
-
const
|
281
|
+
const hashedMessageStr = messageHashStr(
|
282
|
+
this.pubsubTopic,
|
283
|
+
message as IProtoMessage
|
284
|
+
);
|
285
|
+
if (this.receivedMessagesHashStr.includes(hashedMessageStr)) {
|
286
|
+
log.info("Message already received, skipping");
|
287
|
+
return;
|
288
|
+
}
|
289
|
+
this.receivedMessagesHashStr.push(hashedMessageStr);
|
290
|
+
|
291
|
+
const { contentTopic } = message;
|
251
292
|
const subscriptionCallback = this.subscriptionCallbacks.get(contentTopic);
|
252
293
|
if (!subscriptionCallback) {
|
253
294
|
log.error("No subscription callback available for ", contentTopic);
|
254
295
|
return;
|
255
296
|
}
|
297
|
+
log.info(
|
298
|
+
"Processing message with content topic ",
|
299
|
+
contentTopic,
|
300
|
+
" on pubsub topic ",
|
301
|
+
this.pubsubTopic
|
302
|
+
);
|
256
303
|
await pushMessage(subscriptionCallback, this.pubsubTopic, message);
|
257
304
|
}
|
305
|
+
|
306
|
+
// Filter out only the rejected promises and extract & handle their reasons
|
307
|
+
private handleErrors(
|
308
|
+
results: PromiseSettledResult<void>[],
|
309
|
+
type: "ping" | "subscribe" | "unsubscribe" | "unsubscribeAll"
|
310
|
+
): void {
|
311
|
+
const errors = results
|
312
|
+
.filter(
|
313
|
+
(result): result is PromiseRejectedResult =>
|
314
|
+
result.status === "rejected"
|
315
|
+
)
|
316
|
+
.map((rejectedResult) => rejectedResult.reason);
|
317
|
+
|
318
|
+
if (errors.length === this.peers.length) {
|
319
|
+
const errorCounts = new Map<string, number>();
|
320
|
+
// TODO: streamline error logging with https://github.com/orgs/waku-org/projects/2/views/1?pane=issue&itemId=42849952
|
321
|
+
errors.forEach((error) => {
|
322
|
+
const message = error instanceof Error ? error.message : String(error);
|
323
|
+
errorCounts.set(message, (errorCounts.get(message) || 0) + 1);
|
324
|
+
});
|
325
|
+
|
326
|
+
const uniqueErrorMessages = Array.from(
|
327
|
+
errorCounts,
|
328
|
+
([message, count]) => `${message} (occurred ${count} times)`
|
329
|
+
).join(", ");
|
330
|
+
throw new Error(`Error ${type} all peers: ${uniqueErrorMessages}`);
|
331
|
+
} else if (errors.length > 0) {
|
332
|
+
// TODO: handle renewing faulty peers with new peers (https://github.com/waku-org/js-waku/issues/1463)
|
333
|
+
log.warn(
|
334
|
+
`Some ${type} failed. These will be refreshed with new peers`,
|
335
|
+
errors
|
336
|
+
);
|
337
|
+
} else {
|
338
|
+
log.info(`${type} successful for all peers`);
|
339
|
+
}
|
340
|
+
}
|
258
341
|
}
|
259
342
|
|
343
|
+
const DEFAULT_NUM_PEERS = 3;
|
344
|
+
|
260
345
|
class Filter extends BaseProtocol implements IReceiver {
|
261
|
-
private readonly pubsubTopics: PubsubTopic[] = [];
|
262
346
|
private activeSubscriptions = new Map<string, Subscription>();
|
263
|
-
private readonly NUM_PEERS_PROTOCOL = 1;
|
264
347
|
|
265
348
|
private getActiveSubscription(
|
266
|
-
pubsubTopic: PubsubTopic
|
267
|
-
peerIdStr: PeerIdStr
|
349
|
+
pubsubTopic: PubsubTopic
|
268
350
|
): Subscription | undefined {
|
269
|
-
return this.activeSubscriptions.get(
|
351
|
+
return this.activeSubscriptions.get(pubsubTopic);
|
270
352
|
}
|
271
353
|
|
272
354
|
private setActiveSubscription(
|
273
355
|
pubsubTopic: PubsubTopic,
|
274
|
-
peerIdStr: PeerIdStr,
|
275
356
|
subscription: Subscription
|
276
357
|
): Subscription {
|
277
|
-
this.activeSubscriptions.set(
|
358
|
+
this.activeSubscriptions.set(pubsubTopic, subscription);
|
278
359
|
return subscription;
|
279
360
|
}
|
280
361
|
|
362
|
+
//TODO: Remove when FilterCore and FilterSDK are introduced
|
363
|
+
private readonly numPeersToUse: number;
|
364
|
+
|
281
365
|
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
282
|
-
super(
|
366
|
+
super(
|
367
|
+
FilterCodecs.SUBSCRIBE,
|
368
|
+
libp2p.components,
|
369
|
+
log,
|
370
|
+
options!.pubsubTopics!,
|
371
|
+
options
|
372
|
+
);
|
283
373
|
|
284
|
-
this.
|
374
|
+
this.numPeersToUse = options?.numPeersToUse ?? DEFAULT_NUM_PEERS;
|
285
375
|
|
286
376
|
libp2p.handle(FilterCodecs.PUSH, this.onRequest.bind(this)).catch((e) => {
|
287
377
|
log.error("Failed to register ", FilterCodecs.PUSH, e);
|
@@ -290,6 +380,12 @@ class Filter extends BaseProtocol implements IReceiver {
|
|
290
380
|
this.activeSubscriptions = new Map();
|
291
381
|
}
|
292
382
|
|
383
|
+
/**
|
384
|
+
* Creates a new subscription to the given pubsub topic.
|
385
|
+
* The subscription is made to multiple peers for decentralization.
|
386
|
+
* @param pubsubTopicShardInfo The pubsub topic to subscribe to.
|
387
|
+
* @returns The subscription object.
|
388
|
+
*/
|
293
389
|
async createSubscription(
|
294
390
|
pubsubTopicShardInfo: SingleShardInfo | PubsubTopic = DefaultPubsubTopic
|
295
391
|
): Promise<Subscription> {
|
@@ -300,21 +396,24 @@ class Filter extends BaseProtocol implements IReceiver {
|
|
300
396
|
|
301
397
|
ensurePubsubTopicIsConfigured(pubsubTopic, this.pubsubTopics);
|
302
398
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
399
|
+
const peers = await this.getPeers({
|
400
|
+
maxBootstrapPeers: 1,
|
401
|
+
numPeers: this.numPeersToUse
|
402
|
+
});
|
403
|
+
if (peers.length === 0) {
|
404
|
+
throw new Error("No peer found to initiate subscription.");
|
405
|
+
}
|
406
|
+
|
407
|
+
log.info(
|
408
|
+
`Creating filter subscription with ${peers.length} peers: `,
|
409
|
+
peers.map((peer) => peer.id.toString())
|
410
|
+
);
|
311
411
|
|
312
412
|
const subscription =
|
313
|
-
this.getActiveSubscription(pubsubTopic
|
413
|
+
this.getActiveSubscription(pubsubTopic) ??
|
314
414
|
this.setActiveSubscription(
|
315
415
|
pubsubTopic,
|
316
|
-
|
317
|
-
new Subscription(pubsubTopic, peer, this.getStream.bind(this, peer))
|
416
|
+
new Subscription(pubsubTopic, peers, this.getStream.bind(this))
|
318
417
|
);
|
319
418
|
|
320
419
|
return subscription;
|
@@ -361,8 +460,11 @@ class Filter extends BaseProtocol implements IReceiver {
|
|
361
460
|
}
|
362
461
|
|
363
462
|
private onRequest(streamData: IncomingStreamData): void {
|
463
|
+
const { connection, stream } = streamData;
|
464
|
+
const { remotePeer } = connection;
|
465
|
+
log.info(`Received message from ${remotePeer.toString()}`);
|
364
466
|
try {
|
365
|
-
pipe(
|
467
|
+
pipe(stream, lp.decode, async (source) => {
|
366
468
|
for await (const bytes of source) {
|
367
469
|
const response = FilterPushRpc.decode(bytes.slice());
|
368
470
|
|
@@ -378,11 +480,7 @@ class Filter extends BaseProtocol implements IReceiver {
|
|
378
480
|
return;
|
379
481
|
}
|
380
482
|
|
381
|
-
const
|
382
|
-
const subscription = this.getActiveSubscription(
|
383
|
-
pubsubTopic,
|
384
|
-
peerIdStr
|
385
|
-
);
|
483
|
+
const subscription = this.getActiveSubscription(pubsubTopic);
|
386
484
|
|
387
485
|
if (!subscription) {
|
388
486
|
log.error(
|
@@ -408,7 +506,7 @@ class Filter extends BaseProtocol implements IReceiver {
|
|
408
506
|
}
|
409
507
|
|
410
508
|
export function wakuFilter(
|
411
|
-
init:
|
509
|
+
init: ProtocolCreateOptions = { pubsubTopics: [] }
|
412
510
|
): (libp2p: Libp2p) => IFilter {
|
413
511
|
return (libp2p: Libp2p) => new Filter(libp2p, init);
|
414
512
|
}
|
package/src/lib/filterPeers.ts
CHANGED
@@ -1,24 +1,32 @@
|
|
1
|
-
import { Peer } from "@libp2p/interface
|
1
|
+
import { Peer } from "@libp2p/interface";
|
2
2
|
import { Tags } from "@waku/interfaces";
|
3
3
|
|
4
4
|
/**
|
5
|
-
* Retrieves a list of peers based on the specified criteria
|
5
|
+
* Retrieves a list of peers based on the specified criteria:
|
6
|
+
* 1. If numPeers is 0, return all peers
|
7
|
+
* 2. Bootstrap peers are prioritized
|
8
|
+
* 3. Non-bootstrap peers are randomly selected to fill up to numPeers
|
6
9
|
*
|
7
10
|
* @param peers - The list of peers to filter from.
|
8
|
-
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned
|
11
|
+
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned, irrespective of `maxBootstrapPeers`.
|
9
12
|
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
10
|
-
* @returns
|
13
|
+
* @returns An array of peers based on the specified criteria.
|
11
14
|
*/
|
12
|
-
export
|
15
|
+
export function filterPeersByDiscovery(
|
13
16
|
peers: Peer[],
|
14
17
|
numPeers: number,
|
15
18
|
maxBootstrapPeers: number
|
16
|
-
):
|
19
|
+
): Peer[] {
|
17
20
|
// Collect the bootstrap peers up to the specified maximum
|
18
|
-
|
21
|
+
let bootstrapPeers = peers
|
19
22
|
.filter((peer) => peer.tags.has(Tags.BOOTSTRAP))
|
20
23
|
.slice(0, maxBootstrapPeers);
|
21
24
|
|
25
|
+
// If numPeers is less than the number of bootstrap peers, adjust the bootstrapPeers array
|
26
|
+
if (numPeers > 0 && numPeers < bootstrapPeers.length) {
|
27
|
+
bootstrapPeers = bootstrapPeers.slice(0, numPeers);
|
28
|
+
}
|
29
|
+
|
22
30
|
// Collect non-bootstrap peers
|
23
31
|
const nonBootstrapPeers = peers.filter(
|
24
32
|
(peer) => !peer.tags.has(Tags.BOOTSTRAP)
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import type { PeerId } from "@libp2p/interface
|
2
|
-
import type {
|
1
|
+
import type { PeerId, PeerStore } from "@libp2p/interface";
|
2
|
+
import type { PingService } from "@libp2p/ping";
|
3
3
|
import type { IRelay, PeerIdStr } from "@waku/interfaces";
|
4
4
|
import type { KeepAliveOptions } from "@waku/interfaces";
|
5
5
|
import { Logger, pubsubTopicToSingleShardInfo } from "@waku/utils";
|
6
6
|
import { utf8ToBytes } from "@waku/utils/bytes";
|
7
|
-
import type { PingService } from "libp2p/ping";
|
8
7
|
|
9
8
|
import { createEncoder } from "./message/version_0.js";
|
10
9
|
|