@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
@@ -9,15 +9,19 @@ import debug from "debug";
|
|
9
9
|
const log = debug("waku:message:topic-only");
|
10
10
|
|
11
11
|
export class TopicOnlyMessage implements IDecodedMessage {
|
12
|
-
public payload:
|
12
|
+
public payload: Uint8Array = new Uint8Array();
|
13
13
|
public rateLimitProof: undefined;
|
14
14
|
public timestamp: undefined;
|
15
|
+
public meta: undefined;
|
15
16
|
public ephemeral: undefined;
|
16
17
|
|
17
|
-
constructor(
|
18
|
+
constructor(
|
19
|
+
public pubSubTopic: string,
|
20
|
+
private proto: ProtoTopicOnlyMessage
|
21
|
+
) {}
|
18
22
|
|
19
23
|
get contentTopic(): string {
|
20
|
-
return this.proto.contentTopic
|
24
|
+
return this.proto.contentTopic;
|
21
25
|
}
|
22
26
|
}
|
23
27
|
|
@@ -29,17 +33,19 @@ export class TopicOnlyDecoder implements IDecoder<TopicOnlyMessage> {
|
|
29
33
|
log("Message decoded", protoMessage);
|
30
34
|
return Promise.resolve({
|
31
35
|
contentTopic: protoMessage.contentTopic,
|
32
|
-
payload:
|
36
|
+
payload: new Uint8Array(),
|
33
37
|
rateLimitProof: undefined,
|
34
38
|
timestamp: undefined,
|
39
|
+
meta: undefined,
|
35
40
|
version: undefined,
|
36
41
|
ephemeral: undefined,
|
37
42
|
});
|
38
43
|
}
|
39
44
|
|
40
45
|
async fromProtoObj(
|
46
|
+
pubSubTopic: string,
|
41
47
|
proto: IProtoMessage
|
42
48
|
): Promise<TopicOnlyMessage | undefined> {
|
43
|
-
return new TopicOnlyMessage(proto);
|
49
|
+
return new TopicOnlyMessage(pubSubTopic, proto);
|
44
50
|
}
|
45
51
|
}
|
@@ -1,4 +1,6 @@
|
|
1
|
+
import { IMetaSetter } from "@waku/interfaces";
|
1
2
|
import type {
|
3
|
+
EncoderOptions,
|
2
4
|
IDecodedMessage,
|
3
5
|
IDecoder,
|
4
6
|
IEncoder,
|
@@ -16,24 +18,17 @@ export const Version = 0;
|
|
16
18
|
export { proto };
|
17
19
|
|
18
20
|
export class DecodedMessage implements IDecodedMessage {
|
19
|
-
constructor(protected proto: proto.WakuMessage) {}
|
20
|
-
|
21
|
-
get _rawPayload(): Uint8Array | undefined {
|
22
|
-
if (this.proto.payload) {
|
23
|
-
return new Uint8Array(this.proto.payload);
|
24
|
-
}
|
25
|
-
return;
|
26
|
-
}
|
21
|
+
constructor(public pubSubTopic: string, protected proto: proto.WakuMessage) {}
|
27
22
|
|
28
23
|
get ephemeral(): boolean {
|
29
24
|
return Boolean(this.proto.ephemeral);
|
30
25
|
}
|
31
26
|
|
32
|
-
get payload(): Uint8Array
|
33
|
-
return this.
|
27
|
+
get payload(): Uint8Array {
|
28
|
+
return this.proto.payload;
|
34
29
|
}
|
35
30
|
|
36
|
-
get contentTopic(): string
|
31
|
+
get contentTopic(): string {
|
37
32
|
return this.proto.contentTopic;
|
38
33
|
}
|
39
34
|
|
@@ -50,18 +45,19 @@ export class DecodedMessage implements IDecodedMessage {
|
|
50
45
|
const timestamp = this.proto.timestamp / OneMillion;
|
51
46
|
return new Date(Number(timestamp));
|
52
47
|
}
|
53
|
-
|
54
|
-
if (this.proto.timestampDeprecated) {
|
55
|
-
return new Date(this.proto.timestampDeprecated * 1000);
|
56
|
-
}
|
48
|
+
return;
|
57
49
|
} catch (e) {
|
58
50
|
return;
|
59
51
|
}
|
60
|
-
|
52
|
+
}
|
53
|
+
|
54
|
+
get meta(): Uint8Array | undefined {
|
55
|
+
return this.proto.meta;
|
61
56
|
}
|
62
57
|
|
63
58
|
get version(): number {
|
64
|
-
// https://
|
59
|
+
// https://rfc.vac.dev/spec/14/
|
60
|
+
// > If omitted, the value SHOULD be interpreted as version 0.
|
65
61
|
return this.proto.version ?? 0;
|
66
62
|
}
|
67
63
|
|
@@ -71,7 +67,11 @@ export class DecodedMessage implements IDecodedMessage {
|
|
71
67
|
}
|
72
68
|
|
73
69
|
export class Encoder implements IEncoder {
|
74
|
-
constructor(
|
70
|
+
constructor(
|
71
|
+
public contentTopic: string,
|
72
|
+
public ephemeral: boolean = false,
|
73
|
+
public metaSetter?: IMetaSetter
|
74
|
+
) {}
|
75
75
|
|
76
76
|
async toWire(message: IMessage): Promise<Uint8Array> {
|
77
77
|
return proto.WakuMessage.encode(await this.toProtoObj(message));
|
@@ -80,14 +80,22 @@ export class Encoder implements IEncoder {
|
|
80
80
|
async toProtoObj(message: IMessage): Promise<IProtoMessage> {
|
81
81
|
const timestamp = message.timestamp ?? new Date();
|
82
82
|
|
83
|
-
|
83
|
+
const protoMessage = {
|
84
84
|
payload: message.payload,
|
85
85
|
version: Version,
|
86
86
|
contentTopic: this.contentTopic,
|
87
87
|
timestamp: BigInt(timestamp.valueOf()) * OneMillion,
|
88
|
+
meta: undefined,
|
88
89
|
rateLimitProof: message.rateLimitProof,
|
89
90
|
ephemeral: this.ephemeral,
|
90
91
|
};
|
92
|
+
|
93
|
+
if (this.metaSetter) {
|
94
|
+
const meta = this.metaSetter(protoMessage);
|
95
|
+
return { ...protoMessage, meta };
|
96
|
+
}
|
97
|
+
|
98
|
+
return protoMessage;
|
91
99
|
}
|
92
100
|
}
|
93
101
|
|
@@ -99,15 +107,13 @@ export class Encoder implements IEncoder {
|
|
99
107
|
* pass to { @link @waku/interfaces.LightPush.push } or
|
100
108
|
* { @link @waku/interfaces.Relay.send } to automatically encode outgoing
|
101
109
|
* messages.
|
102
|
-
*
|
103
|
-
* @param contentTopic The content topic to set on outgoing messages.
|
104
|
-
* @param ephemeral An optional flag to mark message as ephemeral, ie, not to be stored by Waku Store nodes.
|
105
110
|
*/
|
106
|
-
export function createEncoder(
|
107
|
-
contentTopic
|
108
|
-
ephemeral
|
109
|
-
|
110
|
-
|
111
|
+
export function createEncoder({
|
112
|
+
contentTopic,
|
113
|
+
ephemeral,
|
114
|
+
metaSetter,
|
115
|
+
}: EncoderOptions): Encoder {
|
116
|
+
return new Encoder(contentTopic, ephemeral, metaSetter);
|
111
117
|
}
|
112
118
|
|
113
119
|
export class Decoder implements IDecoder<DecodedMessage> {
|
@@ -117,24 +123,23 @@ export class Decoder implements IDecoder<DecodedMessage> {
|
|
117
123
|
const protoMessage = proto.WakuMessage.decode(bytes);
|
118
124
|
log("Message decoded", protoMessage);
|
119
125
|
return Promise.resolve({
|
120
|
-
payload: protoMessage.payload
|
121
|
-
contentTopic: protoMessage.contentTopic
|
126
|
+
payload: protoMessage.payload,
|
127
|
+
contentTopic: protoMessage.contentTopic,
|
122
128
|
version: protoMessage.version ?? undefined,
|
123
129
|
timestamp: protoMessage.timestamp ?? undefined,
|
130
|
+
meta: protoMessage.meta ?? undefined,
|
124
131
|
rateLimitProof: protoMessage.rateLimitProof ?? undefined,
|
125
132
|
ephemeral: protoMessage.ephemeral ?? false,
|
126
133
|
});
|
127
134
|
}
|
128
135
|
|
129
136
|
async fromProtoObj(
|
137
|
+
pubSubTopic: string,
|
130
138
|
proto: IProtoMessage
|
131
139
|
): Promise<DecodedMessage | undefined> {
|
132
|
-
// https://
|
133
|
-
|
134
|
-
|
135
|
-
}
|
136
|
-
|
137
|
-
if (proto.version !== Version) {
|
140
|
+
// https://rfc.vac.dev/spec/14/
|
141
|
+
// > If omitted, the value SHOULD be interpreted as version 0.
|
142
|
+
if (proto.version ?? 0 !== Version) {
|
138
143
|
log(
|
139
144
|
"Failed to decode due to incorrect version, expected:",
|
140
145
|
Version,
|
@@ -144,12 +149,12 @@ export class Decoder implements IDecoder<DecodedMessage> {
|
|
144
149
|
return Promise.resolve(undefined);
|
145
150
|
}
|
146
151
|
|
147
|
-
return new DecodedMessage(proto);
|
152
|
+
return new DecodedMessage(pubSubTopic, proto);
|
148
153
|
}
|
149
154
|
}
|
150
155
|
|
151
156
|
/**
|
152
|
-
* Creates
|
157
|
+
* Creates a decoder that decode messages without Waku level encryption.
|
153
158
|
*
|
154
159
|
* A decoder is used to decode messages from the [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/)
|
155
160
|
* format when received from the Waku network. The resulting decoder can then be
|
package/src/lib/relay/index.ts
CHANGED
@@ -7,14 +7,16 @@ import {
|
|
7
7
|
import type { PeerIdStr, TopicStr } from "@chainsafe/libp2p-gossipsub/types";
|
8
8
|
import { SignaturePolicy } from "@chainsafe/libp2p-gossipsub/types";
|
9
9
|
import type {
|
10
|
+
ActiveSubscriptions,
|
10
11
|
Callback,
|
12
|
+
IDecodedMessage,
|
11
13
|
IDecoder,
|
12
14
|
IEncoder,
|
13
15
|
IMessage,
|
14
16
|
IRelay,
|
17
|
+
ProtocolCreateOptions,
|
15
18
|
SendResult,
|
16
19
|
} from "@waku/interfaces";
|
17
|
-
import { IDecodedMessage } from "@waku/interfaces";
|
18
20
|
import debug from "debug";
|
19
21
|
|
20
22
|
import { DefaultPubSubTopic } from "../constants.js";
|
@@ -22,6 +24,7 @@ import { TopicOnlyDecoder } from "../message/topic_only_message.js";
|
|
22
24
|
import { pushOrInitMapSet } from "../push_or_init_map.js";
|
23
25
|
|
24
26
|
import * as constants from "./constants.js";
|
27
|
+
import { messageValidator } from "./message_validator.js";
|
25
28
|
|
26
29
|
const log = debug("waku:relay");
|
27
30
|
|
@@ -30,22 +33,8 @@ export type Observer<T extends IDecodedMessage> = {
|
|
30
33
|
callback: Callback<T>;
|
31
34
|
};
|
32
35
|
|
33
|
-
export
|
34
|
-
|
35
|
-
* The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}.
|
36
|
-
*
|
37
|
-
* One and only one pubsub topic is used by Waku. This is used by:
|
38
|
-
* - WakuRelay to receive, route and send messages,
|
39
|
-
* - WakuLightPush to send messages,
|
40
|
-
* - WakuStore to retrieve messages.
|
41
|
-
*
|
42
|
-
* The usage of the default pubsub topic is recommended.
|
43
|
-
* See [Waku v2 Topic Usage Recommendations](https://rfc.vac.dev/spec/23/) for details.
|
44
|
-
*
|
45
|
-
* @default {@link DefaultPubSubTopic}
|
46
|
-
*/
|
47
|
-
pubSubTopic?: string;
|
48
|
-
}
|
36
|
+
export type RelayCreateOptions = ProtocolCreateOptions & GossipsubOpts;
|
37
|
+
export type ContentTopic = string;
|
49
38
|
|
50
39
|
/**
|
51
40
|
* Implements the [Waku v2 Relay protocol](https://rfc.vac.dev/spec/11/).
|
@@ -54,7 +43,7 @@ export interface RelayCreateOptions extends GossipsubOpts {
|
|
54
43
|
* @implements {require('libp2p-interfaces/src/pubsub')}
|
55
44
|
*/
|
56
45
|
class Relay extends GossipSub implements IRelay {
|
57
|
-
pubSubTopic: string;
|
46
|
+
private readonly pubSubTopic: string;
|
58
47
|
defaultDecoder: IDecoder<IDecodedMessage>;
|
59
48
|
public static multicodec: string = constants.RelayCodecs[0];
|
60
49
|
|
@@ -62,7 +51,7 @@ class Relay extends GossipSub implements IRelay {
|
|
62
51
|
* observers called when receiving new message.
|
63
52
|
* Observers under key `""` are always called.
|
64
53
|
*/
|
65
|
-
|
54
|
+
private observers: Map<ContentTopic, Set<unknown>>;
|
66
55
|
|
67
56
|
constructor(
|
68
57
|
components: GossipSubComponents,
|
@@ -73,13 +62,14 @@ class Relay extends GossipSub implements IRelay {
|
|
73
62
|
globalSignaturePolicy: SignaturePolicy.StrictNoSign,
|
74
63
|
fallbackToFloodsub: false,
|
75
64
|
});
|
65
|
+
|
76
66
|
super(components, options);
|
77
67
|
this.multicodecs = constants.RelayCodecs;
|
78
68
|
|
79
|
-
this.observers = new Map();
|
80
|
-
|
81
69
|
this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic;
|
82
70
|
|
71
|
+
this.observers = new Map();
|
72
|
+
|
83
73
|
// TODO: User might want to decide what decoder should be used (e.g. for RLN)
|
84
74
|
this.defaultDecoder = new TopicOnlyDecoder();
|
85
75
|
}
|
@@ -105,6 +95,7 @@ class Relay extends GossipSub implements IRelay {
|
|
105
95
|
log("Failed to encode message, aborting publish");
|
106
96
|
return { recipients: [] };
|
107
97
|
}
|
98
|
+
|
108
99
|
return this.publish(this.pubSubTopic, msg);
|
109
100
|
}
|
110
101
|
|
@@ -121,16 +112,57 @@ class Relay extends GossipSub implements IRelay {
|
|
121
112
|
decoder,
|
122
113
|
callback,
|
123
114
|
};
|
124
|
-
|
115
|
+
const contentTopic = decoder.contentTopic;
|
116
|
+
|
117
|
+
pushOrInitMapSet(this.observers, contentTopic, observer);
|
125
118
|
|
126
119
|
return () => {
|
127
|
-
const observers = this.observers.get(
|
120
|
+
const observers = this.observers.get(contentTopic);
|
128
121
|
if (observers) {
|
129
122
|
observers.delete(observer);
|
130
123
|
}
|
131
124
|
};
|
132
125
|
}
|
133
126
|
|
127
|
+
public getActiveSubscriptions(): ActiveSubscriptions {
|
128
|
+
const map = new Map();
|
129
|
+
map.set(this.pubSubTopic, this.observers.keys());
|
130
|
+
return map;
|
131
|
+
}
|
132
|
+
|
133
|
+
private async processIncomingMessage<T extends IDecodedMessage>(
|
134
|
+
pubSubTopic: string,
|
135
|
+
bytes: Uint8Array
|
136
|
+
): Promise<void> {
|
137
|
+
const topicOnlyMsg = await this.defaultDecoder.fromWireToProtoObj(bytes);
|
138
|
+
if (!topicOnlyMsg || !topicOnlyMsg.contentTopic) {
|
139
|
+
log("Message does not have a content topic, skipping");
|
140
|
+
return;
|
141
|
+
}
|
142
|
+
|
143
|
+
const observers = this.observers.get(topicOnlyMsg.contentTopic) as Set<
|
144
|
+
Observer<T>
|
145
|
+
>;
|
146
|
+
if (!observers) {
|
147
|
+
return;
|
148
|
+
}
|
149
|
+
await Promise.all(
|
150
|
+
Array.from(observers).map(async ({ decoder, callback }) => {
|
151
|
+
const protoMsg = await decoder.fromWireToProtoObj(bytes);
|
152
|
+
if (!protoMsg) {
|
153
|
+
log("Internal error: message previously decoded failed on 2nd pass.");
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
const msg = await decoder.fromProtoObj(pubSubTopic, protoMsg);
|
157
|
+
if (msg) {
|
158
|
+
callback(msg);
|
159
|
+
} else {
|
160
|
+
log("Failed to decode messages on", topicOnlyMsg.contentTopic);
|
161
|
+
}
|
162
|
+
})
|
163
|
+
);
|
164
|
+
}
|
165
|
+
|
134
166
|
/**
|
135
167
|
* Subscribe to a pubsub topic and start emitting Waku messages to observers.
|
136
168
|
*
|
@@ -143,43 +175,22 @@ class Relay extends GossipSub implements IRelay {
|
|
143
175
|
if (event.detail.msg.topic !== pubSubTopic) return;
|
144
176
|
log(`Message received on ${pubSubTopic}`);
|
145
177
|
|
146
|
-
|
178
|
+
this.processIncomingMessage(
|
179
|
+
event.detail.msg.topic,
|
147
180
|
event.detail.msg.data
|
148
|
-
);
|
149
|
-
if (!topicOnlyMsg || !topicOnlyMsg.contentTopic) {
|
150
|
-
log("Message does not have a content topic, skipping");
|
151
|
-
return;
|
152
|
-
}
|
153
|
-
|
154
|
-
const observers = this.observers.get(topicOnlyMsg.contentTopic);
|
155
|
-
if (!observers) {
|
156
|
-
return;
|
157
|
-
}
|
158
|
-
await Promise.all(
|
159
|
-
Array.from(observers).map(async ({ decoder, callback }) => {
|
160
|
-
const protoMsg = await decoder.fromWireToProtoObj(
|
161
|
-
event.detail.msg.data
|
162
|
-
);
|
163
|
-
if (!protoMsg) {
|
164
|
-
log(
|
165
|
-
"Internal error: message previously decoded failed on 2nd pass."
|
166
|
-
);
|
167
|
-
return;
|
168
|
-
}
|
169
|
-
const msg = await decoder.fromProtoObj(protoMsg);
|
170
|
-
if (msg) {
|
171
|
-
callback(msg);
|
172
|
-
} else {
|
173
|
-
log("Failed to decode messages on", topicOnlyMsg.contentTopic);
|
174
|
-
}
|
175
|
-
})
|
176
|
-
);
|
181
|
+
).catch((e) => log("Failed to process incoming message", e));
|
177
182
|
}
|
178
183
|
);
|
179
184
|
|
185
|
+
this.topicValidators.set(pubSubTopic, messageValidator);
|
180
186
|
super.subscribe(pubSubTopic);
|
181
187
|
}
|
182
188
|
|
189
|
+
unsubscribe(pubSubTopic: TopicStr): void {
|
190
|
+
super.unsubscribe(pubSubTopic);
|
191
|
+
this.topicValidators.delete(pubSubTopic);
|
192
|
+
}
|
193
|
+
|
183
194
|
getMeshPeers(topic?: TopicStr): PeerIdStr[] {
|
184
195
|
return super.getMeshPeers(topic ?? this.pubSubTopic);
|
185
196
|
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import type { PeerId } from "@libp2p/interface-peer-id";
|
2
|
+
import type { Message } from "@libp2p/interface-pubsub";
|
3
|
+
import { TopicValidatorResult } from "@libp2p/interface-pubsub";
|
4
|
+
import { proto_message as proto } from "@waku/proto";
|
5
|
+
import debug from "debug";
|
6
|
+
|
7
|
+
const log = debug("waku:relay");
|
8
|
+
|
9
|
+
export function messageValidator(
|
10
|
+
peer: PeerId,
|
11
|
+
message: Message
|
12
|
+
): TopicValidatorResult {
|
13
|
+
const startTime = performance.now();
|
14
|
+
log(`validating message from ${peer} received on ${message.topic}`);
|
15
|
+
let result = TopicValidatorResult.Accept;
|
16
|
+
|
17
|
+
try {
|
18
|
+
const protoMessage = proto.WakuMessage.decode(message.data);
|
19
|
+
|
20
|
+
if (
|
21
|
+
!protoMessage.contentTopic ||
|
22
|
+
!protoMessage.contentTopic.length ||
|
23
|
+
!protoMessage.payload ||
|
24
|
+
!protoMessage.payload.length
|
25
|
+
) {
|
26
|
+
result = TopicValidatorResult.Reject;
|
27
|
+
}
|
28
|
+
} catch (e) {
|
29
|
+
result = TopicValidatorResult.Reject;
|
30
|
+
}
|
31
|
+
|
32
|
+
const endTime = performance.now();
|
33
|
+
log(`Validation time (must be <100ms): ${endTime - startTime}ms`);
|
34
|
+
return result;
|
35
|
+
}
|
@@ -19,8 +19,8 @@ export interface Params {
|
|
19
19
|
cursor?: proto.Index;
|
20
20
|
}
|
21
21
|
|
22
|
-
export class
|
23
|
-
private constructor(public readonly proto: proto.
|
22
|
+
export class HistoryRpc {
|
23
|
+
private constructor(public readonly proto: proto.HistoryRpc) {}
|
24
24
|
|
25
25
|
get query(): proto.HistoryQuery | undefined {
|
26
26
|
return this.proto.query;
|
@@ -33,7 +33,7 @@ export class HistoryRPC {
|
|
33
33
|
/**
|
34
34
|
* Create History Query.
|
35
35
|
*/
|
36
|
-
static createQuery(params: Params):
|
36
|
+
static createQuery(params: Params): HistoryRpc {
|
37
37
|
const contentFilters = params.contentTopics.map((contentTopic) => {
|
38
38
|
return { contentTopic };
|
39
39
|
});
|
@@ -56,10 +56,10 @@ export class HistoryRPC {
|
|
56
56
|
// milliseconds 10^-3 to nanoseconds 10^-9
|
57
57
|
endTime = BigInt(params.endTime.valueOf()) * OneMillion;
|
58
58
|
}
|
59
|
-
return new
|
59
|
+
return new HistoryRpc({
|
60
60
|
requestId: uuid(),
|
61
61
|
query: {
|
62
|
-
|
62
|
+
pubsubTopic: params.pubSubTopic,
|
63
63
|
contentFilters,
|
64
64
|
pagingInfo,
|
65
65
|
startTime,
|
@@ -69,13 +69,13 @@ export class HistoryRPC {
|
|
69
69
|
});
|
70
70
|
}
|
71
71
|
|
72
|
-
decode(bytes: Uint8ArrayList):
|
73
|
-
const res = proto.
|
74
|
-
return new
|
72
|
+
decode(bytes: Uint8ArrayList): HistoryRpc {
|
73
|
+
const res = proto.HistoryRpc.decode(bytes);
|
74
|
+
return new HistoryRpc(res);
|
75
75
|
}
|
76
76
|
|
77
77
|
encode(): Uint8Array {
|
78
|
-
return proto.
|
78
|
+
return proto.HistoryRpc.encode(this.proto);
|
79
79
|
}
|
80
80
|
}
|
81
81
|
|
@@ -84,10 +84,10 @@ function directionToProto(
|
|
84
84
|
): proto.PagingInfo.Direction {
|
85
85
|
switch (pageDirection) {
|
86
86
|
case PageDirection.BACKWARD:
|
87
|
-
return proto.PagingInfo.Direction.
|
87
|
+
return proto.PagingInfo.Direction.BACKWARD;
|
88
88
|
case PageDirection.FORWARD:
|
89
|
-
return proto.PagingInfo.Direction.
|
89
|
+
return proto.PagingInfo.Direction.FORWARD;
|
90
90
|
default:
|
91
|
-
return proto.PagingInfo.Direction.
|
91
|
+
return proto.PagingInfo.Direction.BACKWARD;
|
92
92
|
}
|
93
93
|
}
|