@waku/core 0.0.10 → 0.0.12
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 +85 -1
- package/README.md +2 -3
- package/bundle/browser-2f1afe46.js +726 -0
- package/bundle/index.js +9190 -12103
- package/bundle/lib/base_protocol.js +108 -0
- package/bundle/lib/message/topic_only_message.js +3 -2
- package/bundle/lib/message/version_0.js +3 -2
- package/bundle/peer_exchange-1229c8b0.js +4302 -0
- package/bundle/{topic_only_message-b1eddea1.js → topic_only_message-e8406994.js} +12 -8
- package/bundle/{version_0-862a05e0.js → version_0-e9a6cfb0.js} +35 -35
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/base_protocol.d.ts +21 -0
- package/dist/lib/base_protocol.js +33 -0
- package/dist/lib/base_protocol.js.map +1 -0
- package/dist/lib/connection_manager.d.ts +31 -0
- package/dist/lib/connection_manager.js +146 -0
- package/dist/lib/connection_manager.js.map +1 -0
- package/dist/lib/filter/filter_rpc.d.ts +8 -8
- package/dist/lib/filter/filter_rpc.js +6 -6
- package/dist/lib/filter/index.d.ts +5 -22
- package/dist/lib/filter/index.js +31 -86
- package/dist/lib/filter/index.js.map +1 -1
- package/dist/lib/group_by.d.ts +1 -1
- package/dist/lib/group_by.js.map +1 -1
- package/dist/lib/keep_alive_manager.d.ts +17 -0
- package/dist/lib/keep_alive_manager.js +62 -0
- package/dist/lib/keep_alive_manager.js.map +1 -0
- package/dist/lib/light_push/index.d.ts +3 -19
- package/dist/lib/light_push/index.js +14 -40
- package/dist/lib/light_push/index.js.map +1 -1
- package/dist/lib/light_push/push_rpc.d.ts +5 -5
- package/dist/lib/light_push/push_rpc.js +6 -6
- package/dist/lib/message/topic_only_message.d.ts +5 -3
- package/dist/lib/message/topic_only_message.js +8 -5
- package/dist/lib/message/topic_only_message.js.map +1 -1
- package/dist/lib/message/version_0.d.ts +12 -12
- package/dist/lib/message/version_0.js +29 -30
- package/dist/lib/message/version_0.js.map +1 -1
- package/dist/lib/predefined_bootstrap_nodes.js +1 -1
- package/dist/lib/predefined_bootstrap_nodes.js.map +1 -1
- package/dist/lib/relay/index.d.ts +4 -19
- package/dist/lib/relay/index.js +41 -26
- package/dist/lib/relay/index.js.map +1 -1
- package/dist/lib/relay/message_validator.d.ts +4 -0
- package/dist/lib/relay/message_validator.js +25 -0
- package/dist/lib/relay/message_validator.js.map +1 -0
- package/dist/lib/store/history_rpc.d.ts +4 -4
- package/dist/lib/store/history_rpc.js +9 -9
- package/dist/lib/store/history_rpc.js.map +1 -1
- package/dist/lib/store/index.d.ts +4 -26
- package/dist/lib/store/index.js +21 -40
- package/dist/lib/store/index.js.map +1 -1
- package/dist/lib/to_proto_message.js +3 -2
- package/dist/lib/to_proto_message.js.map +1 -1
- package/dist/lib/wait_for_remote_peer.js +12 -23
- package/dist/lib/wait_for_remote_peer.js.map +1 -1
- package/dist/lib/waku.d.ts +8 -15
- package/dist/lib/waku.js +34 -97
- package/dist/lib/waku.js.map +1 -1
- package/package.json +50 -61
- package/src/index.ts +11 -3
- package/src/lib/base_protocol.ts +47 -0
- package/src/lib/connection_manager.ts +220 -0
- package/src/lib/filter/filter_rpc.ts +10 -10
- package/src/lib/filter/index.ts +52 -147
- package/src/lib/group_by.ts +1 -1
- package/src/lib/keep_alive_manager.ts +89 -0
- package/src/lib/light_push/index.ts +18 -79
- package/src/lib/light_push/push_rpc.ts +9 -9
- package/src/lib/message/topic_only_message.ts +11 -5
- package/src/lib/message/version_0.ts +42 -37
- package/src/lib/predefined_bootstrap_nodes.ts +1 -1
- package/src/lib/relay/index.ts +64 -53
- package/src/lib/relay/message_validator.ts +35 -0
- package/src/lib/store/history_rpc.ts +12 -12
- package/src/lib/store/index.ts +31 -88
- package/src/lib/to_proto_message.ts +3 -2
- package/src/lib/wait_for_remote_peer.ts +13 -29
- package/src/lib/waku.ts +54 -136
- package/bundle/peer_exchange-df95c3a7.js +0 -11801
- package/dist/lib/random_subset.d.ts +0 -4
- package/dist/lib/random_subset.js +0 -25
- package/dist/lib/random_subset.js.map +0 -1
- package/src/lib/random_subset.ts +0 -30
package/src/lib/store/index.ts
CHANGED
@@ -1,32 +1,28 @@
|
|
1
|
-
import type {
|
2
|
-
import type {
|
1
|
+
import type { Stream } from "@libp2p/interface-connection";
|
2
|
+
import type { Libp2p } from "@libp2p/interface-libp2p";
|
3
3
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
4
|
-
import type { Peer, PeerStore } from "@libp2p/interface-peer-store";
|
5
4
|
import { sha256 } from "@noble/hashes/sha256";
|
6
|
-
import { concat, utf8ToBytes } from "@waku/byte-utils";
|
7
5
|
import {
|
8
6
|
Cursor,
|
9
7
|
IDecodedMessage,
|
10
8
|
IDecoder,
|
11
|
-
Index,
|
12
9
|
IStore,
|
10
|
+
ProtocolCreateOptions,
|
13
11
|
} from "@waku/interfaces";
|
14
|
-
import {
|
15
|
-
getPeersForProtocol,
|
16
|
-
selectConnection,
|
17
|
-
selectPeerForProtocol,
|
18
|
-
} from "@waku/libp2p-utils";
|
19
12
|
import { proto_store as proto } from "@waku/proto";
|
13
|
+
import { isDefined } from "@waku/utils";
|
14
|
+
import { concat, utf8ToBytes } from "@waku/utils/bytes";
|
20
15
|
import debug from "debug";
|
21
16
|
import all from "it-all";
|
22
17
|
import * as lp from "it-length-prefixed";
|
23
18
|
import { pipe } from "it-pipe";
|
24
19
|
import { Uint8ArrayList } from "uint8arraylist";
|
25
20
|
|
21
|
+
import { BaseProtocol } from "../base_protocol.js";
|
26
22
|
import { DefaultPubSubTopic } from "../constants.js";
|
27
23
|
import { toProtoMessage } from "../to_proto_message.js";
|
28
24
|
|
29
|
-
import {
|
25
|
+
import { HistoryRpc, PageDirection, Params } from "./history_rpc.js";
|
30
26
|
|
31
27
|
import HistoryError = proto.HistoryResponse.HistoryError;
|
32
28
|
|
@@ -38,23 +34,6 @@ export const DefaultPageSize = 10;
|
|
38
34
|
|
39
35
|
export { PageDirection };
|
40
36
|
|
41
|
-
export interface StoreComponents {
|
42
|
-
peerStore: PeerStore;
|
43
|
-
connectionManager: ConnectionManager;
|
44
|
-
}
|
45
|
-
|
46
|
-
export interface CreateOptions {
|
47
|
-
/**
|
48
|
-
* The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}.
|
49
|
-
*
|
50
|
-
* The usage of the default pubsub topic is recommended.
|
51
|
-
* See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details.
|
52
|
-
*
|
53
|
-
* @default {@link DefaultPubSubTopic}
|
54
|
-
*/
|
55
|
-
pubSubTopic?: string;
|
56
|
-
}
|
57
|
-
|
58
37
|
export interface TimeFilter {
|
59
38
|
startTime: Date;
|
60
39
|
endTime: Date;
|
@@ -65,11 +44,6 @@ export interface QueryOptions {
|
|
65
44
|
* The peer to query. If undefined, a pseudo-random peer is selected from the connected Waku Store peers.
|
66
45
|
*/
|
67
46
|
peerId?: PeerId;
|
68
|
-
/**
|
69
|
-
* The pubsub topic to pass to the query.
|
70
|
-
* See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/).
|
71
|
-
*/
|
72
|
-
pubSubTopic?: string;
|
73
47
|
/**
|
74
48
|
* The direction in which pages are retrieved:
|
75
49
|
* - { @link PageDirection.BACKWARD }: Most recent page first.
|
@@ -104,11 +78,12 @@ export interface QueryOptions {
|
|
104
78
|
*
|
105
79
|
* The Waku Store protocol can be used to retrieved historical messages.
|
106
80
|
*/
|
107
|
-
class Store implements IStore {
|
108
|
-
|
81
|
+
class Store extends BaseProtocol implements IStore {
|
82
|
+
options: ProtocolCreateOptions;
|
109
83
|
|
110
|
-
constructor(public
|
111
|
-
|
84
|
+
constructor(public libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
85
|
+
super(StoreCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p));
|
86
|
+
this.options = options ?? {};
|
112
87
|
}
|
113
88
|
|
114
89
|
/**
|
@@ -219,6 +194,8 @@ class Store implements IStore {
|
|
219
194
|
decoders: IDecoder<T>[],
|
220
195
|
options?: QueryOptions
|
221
196
|
): AsyncGenerator<Promise<T | undefined>[]> {
|
197
|
+
const { pubSubTopic = DefaultPubSubTopic } = this.options;
|
198
|
+
|
222
199
|
let startTime, endTime;
|
223
200
|
|
224
201
|
if (options?.timeFilter) {
|
@@ -240,7 +217,7 @@ class Store implements IStore {
|
|
240
217
|
|
241
218
|
const queryOpts = Object.assign(
|
242
219
|
{
|
243
|
-
pubSubTopic:
|
220
|
+
pubSubTopic: pubSubTopic,
|
244
221
|
pageDirection: PageDirection.BACKWARD,
|
245
222
|
pageSize: DefaultPageSize,
|
246
223
|
},
|
@@ -253,27 +230,10 @@ class Store implements IStore {
|
|
253
230
|
peerId: options?.peerId?.toString(),
|
254
231
|
});
|
255
232
|
|
256
|
-
const
|
257
|
-
this.components.peerStore,
|
258
|
-
[StoreCodec],
|
259
|
-
options?.peerId
|
260
|
-
);
|
261
|
-
|
262
|
-
if (!res) {
|
263
|
-
throw new Error("Failed to get a peer");
|
264
|
-
}
|
265
|
-
const { peer, protocol } = res;
|
266
|
-
|
267
|
-
const connections = this.components.connectionManager.getConnections(
|
268
|
-
peer.id
|
269
|
-
);
|
270
|
-
const connection = selectConnection(connections);
|
271
|
-
|
272
|
-
if (!connection) throw "Failed to get a connection to the peer";
|
233
|
+
const peer = await this.getPeer(options?.peerId);
|
273
234
|
|
274
235
|
for await (const messages of paginate<T>(
|
275
|
-
|
276
|
-
protocol,
|
236
|
+
this.newStream.bind(this, peer),
|
277
237
|
queryOpts,
|
278
238
|
decodersAsMap,
|
279
239
|
options?.cursor
|
@@ -281,23 +241,10 @@ class Store implements IStore {
|
|
281
241
|
yield messages;
|
282
242
|
}
|
283
243
|
}
|
284
|
-
|
285
|
-
/**
|
286
|
-
* Returns known peers from the address book (`libp2p.peerStore`) that support
|
287
|
-
* store protocol. Waku may or may not be currently connected to these peers.
|
288
|
-
*/
|
289
|
-
async peers(): Promise<Peer[]> {
|
290
|
-
return getPeersForProtocol(this.components.peerStore, [StoreCodec]);
|
291
|
-
}
|
292
|
-
|
293
|
-
get peerStore(): PeerStore {
|
294
|
-
return this.components.peerStore;
|
295
|
-
}
|
296
244
|
}
|
297
245
|
|
298
246
|
async function* paginate<T extends IDecodedMessage>(
|
299
|
-
|
300
|
-
protocol: string,
|
247
|
+
streamFactory: () => Promise<Stream>,
|
301
248
|
queryOpts: Params,
|
302
249
|
decoders: Map<string, IDecoder<T>>,
|
303
250
|
cursor?: Cursor
|
@@ -315,16 +262,16 @@ async function* paginate<T extends IDecodedMessage>(
|
|
315
262
|
while (true) {
|
316
263
|
queryOpts.cursor = currentCursor;
|
317
264
|
|
318
|
-
const
|
319
|
-
const historyRpcQuery = HistoryRPC.createQuery(queryOpts);
|
265
|
+
const historyRpcQuery = HistoryRpc.createQuery(queryOpts);
|
320
266
|
|
321
267
|
log(
|
322
268
|
"Querying store peer",
|
323
|
-
connection.remoteAddr.toString(),
|
324
269
|
`for (${queryOpts.pubSubTopic})`,
|
325
270
|
queryOpts.contentTopics
|
326
271
|
);
|
327
272
|
|
273
|
+
const stream = await streamFactory();
|
274
|
+
|
328
275
|
const res = await pipe(
|
329
276
|
[historyRpcQuery.encode()],
|
330
277
|
lp.encode(),
|
@@ -347,10 +294,7 @@ async function* paginate<T extends IDecodedMessage>(
|
|
347
294
|
|
348
295
|
const response = reply.response as proto.HistoryResponse;
|
349
296
|
|
350
|
-
if (
|
351
|
-
response.error &&
|
352
|
-
response.error !== HistoryError.ERROR_NONE_UNSPECIFIED
|
353
|
-
) {
|
297
|
+
if (response.error && response.error !== HistoryError.NONE) {
|
354
298
|
throw "History response contains an Error: " + response.error;
|
355
299
|
}
|
356
300
|
|
@@ -368,7 +312,10 @@ async function* paginate<T extends IDecodedMessage>(
|
|
368
312
|
if (typeof contentTopic !== "undefined") {
|
369
313
|
const decoder = decoders.get(contentTopic);
|
370
314
|
if (decoder) {
|
371
|
-
return decoder.fromProtoObj(
|
315
|
+
return decoder.fromProtoObj(
|
316
|
+
queryOpts.pubSubTopic,
|
317
|
+
toProtoMessage(protoMsg)
|
318
|
+
);
|
372
319
|
}
|
373
320
|
}
|
374
321
|
return Promise.resolve(undefined);
|
@@ -399,14 +346,10 @@ async function* paginate<T extends IDecodedMessage>(
|
|
399
346
|
}
|
400
347
|
}
|
401
348
|
|
402
|
-
export function isDefined<T>(msg: T | undefined): msg is T {
|
403
|
-
return !!msg;
|
404
|
-
}
|
405
|
-
|
406
349
|
export async function createCursor(
|
407
350
|
message: IDecodedMessage,
|
408
351
|
pubsubTopic: string = DefaultPubSubTopic
|
409
|
-
): Promise<
|
352
|
+
): Promise<Cursor> {
|
410
353
|
if (
|
411
354
|
!message ||
|
412
355
|
!message.timestamp ||
|
@@ -426,12 +369,12 @@ export async function createCursor(
|
|
426
369
|
digest,
|
427
370
|
pubsubTopic,
|
428
371
|
senderTime: messageTime,
|
429
|
-
|
372
|
+
receiverTime: messageTime,
|
430
373
|
};
|
431
374
|
}
|
432
375
|
|
433
376
|
export function wakuStore(
|
434
|
-
init: Partial<
|
435
|
-
): (
|
436
|
-
return (
|
377
|
+
init: Partial<ProtocolCreateOptions> = {}
|
378
|
+
): (libp2p: Libp2p) => IStore {
|
379
|
+
return (libp2p: Libp2p) => new Store(libp2p, init);
|
437
380
|
}
|
@@ -2,10 +2,11 @@ import { IProtoMessage } from "@waku/interfaces";
|
|
2
2
|
import { WakuMessage as WakuMessageProto } from "@waku/proto";
|
3
3
|
|
4
4
|
const EmptyMessage: IProtoMessage = {
|
5
|
-
payload:
|
6
|
-
contentTopic:
|
5
|
+
payload: new Uint8Array(),
|
6
|
+
contentTopic: "",
|
7
7
|
version: undefined,
|
8
8
|
timestamp: undefined,
|
9
|
+
meta: undefined,
|
9
10
|
rateLimitProof: undefined,
|
10
11
|
ephemeral: undefined,
|
11
12
|
};
|
@@ -1,14 +1,9 @@
|
|
1
|
-
import { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
|
1
|
+
import type { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
|
2
2
|
import type { IRelay, PointToPointProtocol, Waku } from "@waku/interfaces";
|
3
3
|
import { Protocols } from "@waku/interfaces";
|
4
|
-
import { PeerExchangeCodec } from "@waku/peer-exchange";
|
5
4
|
import debug from "debug";
|
6
5
|
import { pEvent } from "p-event";
|
7
6
|
|
8
|
-
import { FilterCodec } from "./filter/index.js";
|
9
|
-
import { LightPushCodec } from "./light_push/index.js";
|
10
|
-
import { StoreCodec } from "./store/index.js";
|
11
|
-
|
12
7
|
const log = debug("waku:wait-for-remote-peer");
|
13
8
|
|
14
9
|
/**
|
@@ -50,27 +45,19 @@ export async function waitForRemotePeer(
|
|
50
45
|
if (protocols.includes(Protocols.Store)) {
|
51
46
|
if (!waku.store)
|
52
47
|
throw new Error("Cannot wait for Store peer: protocol not mounted");
|
53
|
-
promises.push(waitForConnectedPeer(waku.store
|
48
|
+
promises.push(waitForConnectedPeer(waku.store));
|
54
49
|
}
|
55
50
|
|
56
51
|
if (protocols.includes(Protocols.LightPush)) {
|
57
52
|
if (!waku.lightPush)
|
58
53
|
throw new Error("Cannot wait for LightPush peer: protocol not mounted");
|
59
|
-
promises.push(waitForConnectedPeer(waku.lightPush
|
54
|
+
promises.push(waitForConnectedPeer(waku.lightPush));
|
60
55
|
}
|
61
56
|
|
62
57
|
if (protocols.includes(Protocols.Filter)) {
|
63
58
|
if (!waku.filter)
|
64
59
|
throw new Error("Cannot wait for Filter peer: protocol not mounted");
|
65
|
-
promises.push(waitForConnectedPeer(waku.filter
|
66
|
-
}
|
67
|
-
|
68
|
-
if (protocols.includes(Protocols.PeerExchange)) {
|
69
|
-
if (!waku.peerExchange)
|
70
|
-
throw new Error(
|
71
|
-
"Cannot wait for Peer Exchange peer: protocol not mounted"
|
72
|
-
);
|
73
|
-
promises.push(waitForConnectedPeer(waku.peerExchange, [PeerExchangeCodec]));
|
60
|
+
promises.push(waitForConnectedPeer(waku.filter));
|
74
61
|
}
|
75
62
|
|
76
63
|
if (timeoutMs) {
|
@@ -88,28 +75,25 @@ export async function waitForRemotePeer(
|
|
88
75
|
* Wait for a peer with the given protocol to be connected.
|
89
76
|
*/
|
90
77
|
async function waitForConnectedPeer(
|
91
|
-
|
92
|
-
codecs: string[]
|
78
|
+
protocol: PointToPointProtocol
|
93
79
|
): Promise<void> {
|
94
|
-
const
|
80
|
+
const codec = protocol.multicodec;
|
81
|
+
const peers = await protocol.peers();
|
95
82
|
|
96
83
|
if (peers.length) {
|
97
|
-
log(`${
|
84
|
+
log(`${codec} peer found: `, peers[0].id.toString());
|
98
85
|
return;
|
99
86
|
}
|
100
87
|
|
101
88
|
await new Promise<void>((resolve) => {
|
102
89
|
const cb = (evt: CustomEvent<PeerProtocolsChangeData>): void => {
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
resolve();
|
108
|
-
break;
|
109
|
-
}
|
90
|
+
if (evt.detail.protocols.includes(codec)) {
|
91
|
+
log("Resolving for", codec, evt.detail.protocols);
|
92
|
+
protocol.peerStore.removeEventListener("change:protocols", cb);
|
93
|
+
resolve();
|
110
94
|
}
|
111
95
|
};
|
112
|
-
|
96
|
+
protocol.peerStore.addEventListener("change:protocols", cb);
|
113
97
|
});
|
114
98
|
}
|
115
99
|
|
package/src/lib/waku.ts
CHANGED
@@ -1,27 +1,20 @@
|
|
1
1
|
import type { Stream } from "@libp2p/interface-connection";
|
2
|
+
import type { Libp2p } from "@libp2p/interface-libp2p";
|
2
3
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
3
4
|
import type { PubSub } from "@libp2p/interface-pubsub";
|
4
5
|
import type { Multiaddr } from "@multiformats/multiaddr";
|
5
6
|
import type {
|
6
7
|
IFilter,
|
7
8
|
ILightPush,
|
8
|
-
IPeerExchange,
|
9
9
|
IRelay,
|
10
10
|
IStore,
|
11
|
-
PeerExchangeComponents,
|
12
11
|
Waku,
|
13
12
|
} from "@waku/interfaces";
|
14
13
|
import { Protocols } from "@waku/interfaces";
|
15
|
-
import { PeerExchangeCodec } from "@waku/peer-exchange";
|
16
14
|
import debug from "debug";
|
17
|
-
import type { Libp2p } from "libp2p";
|
18
15
|
|
19
|
-
import {
|
20
|
-
import { LightPushCodec, LightPushComponents } from "./light_push/index.js";
|
21
|
-
import { createEncoder } from "./message/version_0.js";
|
16
|
+
import { ConnectionManager } from "./connection_manager.js";
|
22
17
|
import * as relayConstants from "./relay/constants.js";
|
23
|
-
import { RelayCodecs, RelayPingContentTopic } from "./relay/constants.js";
|
24
|
-
import { StoreCodec, StoreComponents } from "./store/index.js";
|
25
18
|
|
26
19
|
export const DefaultPingKeepAliveValueSecs = 0;
|
27
20
|
export const DefaultRelayKeepAliveValueSecs = 5 * 60;
|
@@ -34,19 +27,19 @@ export interface WakuOptions {
|
|
34
27
|
* Set keep alive frequency in seconds: Waku will send a `/ipfs/ping/1.0.0`
|
35
28
|
* request to each peer after the set number of seconds. Set to 0 to disable.
|
36
29
|
*
|
37
|
-
* @default {@link DefaultPingKeepAliveValueSecs}
|
30
|
+
* @default {@link @waku/core.DefaultPingKeepAliveValueSecs}
|
38
31
|
*/
|
39
32
|
pingKeepAlive?: number;
|
40
33
|
/**
|
41
34
|
* Set keep alive frequency in seconds: Waku will send a ping message over
|
42
35
|
* relay to each peer after the set number of seconds. Set to 0 to disable.
|
43
36
|
*
|
44
|
-
* @default {@link DefaultRelayKeepAliveValueSecs}
|
37
|
+
* @default {@link @waku/core.DefaultRelayKeepAliveValueSecs}
|
45
38
|
*/
|
46
39
|
relayKeepAlive?: number;
|
47
40
|
/**
|
48
41
|
* Set the user agent string to be used in identification of the node.
|
49
|
-
* @default {@link DefaultUserAgent}
|
42
|
+
* @default {@link @waku/core.DefaultUserAgent}
|
50
43
|
*/
|
51
44
|
userAgent?: string;
|
52
45
|
}
|
@@ -57,90 +50,52 @@ export class WakuNode implements Waku {
|
|
57
50
|
public store?: IStore;
|
58
51
|
public filter?: IFilter;
|
59
52
|
public lightPush?: ILightPush;
|
60
|
-
public
|
61
|
-
|
62
|
-
private pingKeepAliveTimers: {
|
63
|
-
[peer: string]: ReturnType<typeof setInterval>;
|
64
|
-
};
|
65
|
-
private relayKeepAliveTimers: {
|
66
|
-
[peer: string]: ReturnType<typeof setInterval>;
|
67
|
-
};
|
53
|
+
public connectionManager: ConnectionManager;
|
68
54
|
|
69
55
|
constructor(
|
70
56
|
options: WakuOptions,
|
71
57
|
libp2p: Libp2p,
|
72
|
-
store?: (
|
73
|
-
lightPush?: (
|
74
|
-
filter?: (
|
75
|
-
peerExchange?: (components: PeerExchangeComponents) => IPeerExchange
|
58
|
+
store?: (libp2p: Libp2p) => IStore,
|
59
|
+
lightPush?: (libp2p: Libp2p) => ILightPush,
|
60
|
+
filter?: (libp2p: Libp2p) => IFilter
|
76
61
|
) {
|
77
62
|
this.libp2p = libp2p;
|
78
63
|
|
79
|
-
const { peerStore, connectionManager, registrar } = libp2p;
|
80
|
-
const components = { peerStore, connectionManager, registrar };
|
81
|
-
|
82
64
|
if (store) {
|
83
|
-
this.store = store(
|
65
|
+
this.store = store(libp2p);
|
84
66
|
}
|
85
67
|
if (filter) {
|
86
|
-
this.filter = filter(
|
68
|
+
this.filter = filter(libp2p);
|
87
69
|
}
|
88
70
|
if (lightPush) {
|
89
|
-
this.lightPush = lightPush(
|
90
|
-
}
|
91
|
-
|
92
|
-
if (peerExchange) {
|
93
|
-
this.peerExchange = peerExchange(components);
|
71
|
+
this.lightPush = lightPush(libp2p);
|
94
72
|
}
|
95
73
|
|
96
74
|
if (isRelay(libp2p.pubsub)) {
|
97
75
|
this.relay = libp2p.pubsub;
|
98
76
|
}
|
99
77
|
|
100
|
-
log(
|
101
|
-
"Waku node created",
|
102
|
-
this.libp2p.peerId.toString(),
|
103
|
-
`relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
|
104
|
-
.lightPush}, filter: ${!!this.filter}, peer exchange: ${!!this
|
105
|
-
.peerExchange} `
|
106
|
-
);
|
107
|
-
|
108
|
-
this.pingKeepAliveTimers = {};
|
109
|
-
this.relayKeepAliveTimers = {};
|
110
|
-
|
111
78
|
const pingKeepAlive =
|
112
79
|
options.pingKeepAlive || DefaultPingKeepAliveValueSecs;
|
113
80
|
const relayKeepAlive = this.relay
|
114
81
|
? options.relayKeepAlive || DefaultRelayKeepAliveValueSecs
|
115
82
|
: 0;
|
116
83
|
|
117
|
-
libp2p.
|
118
|
-
this.startKeepAlive(evt.detail.remotePeer, pingKeepAlive, relayKeepAlive);
|
119
|
-
});
|
84
|
+
const peerId = this.libp2p.peerId.toString();
|
120
85
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
* >regardless of the circumstances of that disconnection.
|
128
|
-
* >If we happen to have multiple connections to a peer,
|
129
|
-
* >this event will **only** be triggered when the last connection is closed.
|
130
|
-
* @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
|
131
|
-
*/
|
132
|
-
libp2p.connectionManager.addEventListener("peer:disconnect", (evt) => {
|
133
|
-
this.stopKeepAlive(evt.detail.remotePeer);
|
134
|
-
});
|
86
|
+
this.connectionManager = ConnectionManager.create(
|
87
|
+
peerId,
|
88
|
+
libp2p,
|
89
|
+
{ pingKeepAlive, relayKeepAlive },
|
90
|
+
this.relay
|
91
|
+
);
|
135
92
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
});
|
143
|
-
});
|
93
|
+
log(
|
94
|
+
"Waku node created",
|
95
|
+
peerId,
|
96
|
+
`relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
|
97
|
+
.lightPush}, filter: ${!!this.filter}`
|
98
|
+
);
|
144
99
|
}
|
145
100
|
|
146
101
|
/**
|
@@ -160,25 +115,44 @@ export class WakuNode implements Waku {
|
|
160
115
|
this.store && _protocols.push(Protocols.Store);
|
161
116
|
this.filter && _protocols.push(Protocols.Filter);
|
162
117
|
this.lightPush && _protocols.push(Protocols.LightPush);
|
163
|
-
this.peerExchange && _protocols.push(Protocols.PeerExchange);
|
164
118
|
}
|
165
119
|
|
166
120
|
const codecs: string[] = [];
|
167
121
|
if (_protocols.includes(Protocols.Relay)) {
|
168
|
-
|
122
|
+
if (this.relay) {
|
123
|
+
this.relay.multicodecs.forEach((codec) => codecs.push(codec));
|
124
|
+
} else {
|
125
|
+
log(
|
126
|
+
"Relay codec not included in dial codec: protocol not mounted locally"
|
127
|
+
);
|
128
|
+
}
|
169
129
|
}
|
170
130
|
if (_protocols.includes(Protocols.Store)) {
|
171
|
-
|
131
|
+
if (this.store) {
|
132
|
+
codecs.push(this.store.multicodec);
|
133
|
+
} else {
|
134
|
+
log(
|
135
|
+
"Store codec not included in dial codec: protocol not mounted locally"
|
136
|
+
);
|
137
|
+
}
|
172
138
|
}
|
173
139
|
if (_protocols.includes(Protocols.LightPush)) {
|
174
|
-
|
140
|
+
if (this.lightPush) {
|
141
|
+
codecs.push(this.lightPush.multicodec);
|
142
|
+
} else {
|
143
|
+
log(
|
144
|
+
"Light Push codec not included in dial codec: protocol not mounted locally"
|
145
|
+
);
|
146
|
+
}
|
175
147
|
}
|
176
148
|
if (_protocols.includes(Protocols.Filter)) {
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
149
|
+
if (this.filter) {
|
150
|
+
codecs.push(this.filter.multicodec);
|
151
|
+
} else {
|
152
|
+
log(
|
153
|
+
"Filter codec not included in dial codec: protocol not mounted locally"
|
154
|
+
);
|
155
|
+
}
|
182
156
|
}
|
183
157
|
|
184
158
|
log(`Dialing to ${peer.toString()} with protocols ${_protocols}`);
|
@@ -191,7 +165,7 @@ export class WakuNode implements Waku {
|
|
191
165
|
}
|
192
166
|
|
193
167
|
async stop(): Promise<void> {
|
194
|
-
this.
|
168
|
+
this.connectionManager.stop();
|
195
169
|
await this.libp2p.stop();
|
196
170
|
}
|
197
171
|
|
@@ -213,62 +187,6 @@ export class WakuNode implements Waku {
|
|
213
187
|
}
|
214
188
|
return localMultiaddr + "/p2p/" + this.libp2p.peerId.toString();
|
215
189
|
}
|
216
|
-
|
217
|
-
private startKeepAlive(
|
218
|
-
peerId: PeerId,
|
219
|
-
pingPeriodSecs: number,
|
220
|
-
relayPeriodSecs: number
|
221
|
-
): void {
|
222
|
-
// Just in case a timer already exist for this peer
|
223
|
-
this.stopKeepAlive(peerId);
|
224
|
-
|
225
|
-
const peerIdStr = peerId.toString();
|
226
|
-
|
227
|
-
if (pingPeriodSecs !== 0) {
|
228
|
-
this.pingKeepAliveTimers[peerIdStr] = setInterval(() => {
|
229
|
-
this.libp2p.ping(peerId).catch((e) => {
|
230
|
-
log(`Ping failed (${peerIdStr})`, e);
|
231
|
-
});
|
232
|
-
}, pingPeriodSecs * 1000);
|
233
|
-
}
|
234
|
-
|
235
|
-
const relay = this.relay;
|
236
|
-
if (relay && relayPeriodSecs !== 0) {
|
237
|
-
const encoder = createEncoder(RelayPingContentTopic, true);
|
238
|
-
this.relayKeepAliveTimers[peerIdStr] = setInterval(() => {
|
239
|
-
log("Sending Waku Relay ping message");
|
240
|
-
relay
|
241
|
-
.send(encoder, { payload: new Uint8Array() })
|
242
|
-
.catch((e) => log("Failed to send relay ping", e));
|
243
|
-
}, relayPeriodSecs * 1000);
|
244
|
-
}
|
245
|
-
}
|
246
|
-
|
247
|
-
private stopKeepAlive(peerId: PeerId): void {
|
248
|
-
const peerIdStr = peerId.toString();
|
249
|
-
|
250
|
-
if (this.pingKeepAliveTimers[peerIdStr]) {
|
251
|
-
clearInterval(this.pingKeepAliveTimers[peerIdStr]);
|
252
|
-
delete this.pingKeepAliveTimers[peerIdStr];
|
253
|
-
}
|
254
|
-
|
255
|
-
if (this.relayKeepAliveTimers[peerIdStr]) {
|
256
|
-
clearInterval(this.relayKeepAliveTimers[peerIdStr]);
|
257
|
-
delete this.relayKeepAliveTimers[peerIdStr];
|
258
|
-
}
|
259
|
-
}
|
260
|
-
|
261
|
-
private stopAllKeepAlives(): void {
|
262
|
-
for (const timer of [
|
263
|
-
...Object.values(this.pingKeepAliveTimers),
|
264
|
-
...Object.values(this.relayKeepAliveTimers),
|
265
|
-
]) {
|
266
|
-
clearInterval(timer);
|
267
|
-
}
|
268
|
-
|
269
|
-
this.pingKeepAliveTimers = {};
|
270
|
-
this.relayKeepAliveTimers = {};
|
271
|
-
}
|
272
190
|
}
|
273
191
|
|
274
192
|
function isRelay(pubsub: PubSub): pubsub is IRelay {
|