@waku/core 0.0.10 → 0.0.11
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 +66 -1
- package/bundle/browser-2f1afe46.js +726 -0
- package/bundle/index.js +9166 -12074
- 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 +13 -39
- 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 -18
- package/dist/lib/relay/index.js +47 -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 -25
- package/dist/lib/store/index.js +20 -37
- 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 +17 -78
- 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 +77 -52
- package/src/lib/relay/message_validator.ts +35 -0
- package/src/lib/store/history_rpc.ts +12 -12
- package/src/lib/store/index.ts +30 -84
- 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
@@ -6,12 +6,14 @@ import {
|
|
6
6
|
} from "@chainsafe/libp2p-gossipsub";
|
7
7
|
import type { PeerIdStr, TopicStr } from "@chainsafe/libp2p-gossipsub/types";
|
8
8
|
import { SignaturePolicy } from "@chainsafe/libp2p-gossipsub/types";
|
9
|
+
import { CustomEvent } from "@libp2p/interfaces/events";
|
9
10
|
import type {
|
10
11
|
Callback,
|
11
12
|
IDecoder,
|
12
13
|
IEncoder,
|
13
14
|
IMessage,
|
14
15
|
IRelay,
|
16
|
+
ProtocolCreateOptions,
|
15
17
|
SendResult,
|
16
18
|
} from "@waku/interfaces";
|
17
19
|
import { IDecodedMessage } from "@waku/interfaces";
|
@@ -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,12 @@ export type Observer<T extends IDecodedMessage> = {
|
|
30
33
|
callback: Callback<T>;
|
31
34
|
};
|
32
35
|
|
33
|
-
export
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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;
|
38
|
+
|
39
|
+
type BasicEventPayload = {
|
40
|
+
contentTopic: string;
|
41
|
+
};
|
49
42
|
|
50
43
|
/**
|
51
44
|
* Implements the [Waku v2 Relay protocol](https://rfc.vac.dev/spec/11/).
|
@@ -54,7 +47,7 @@ export interface RelayCreateOptions extends GossipsubOpts {
|
|
54
47
|
* @implements {require('libp2p-interfaces/src/pubsub')}
|
55
48
|
*/
|
56
49
|
class Relay extends GossipSub implements IRelay {
|
57
|
-
pubSubTopic: string;
|
50
|
+
private readonly pubSubTopic: string;
|
58
51
|
defaultDecoder: IDecoder<IDecodedMessage>;
|
59
52
|
public static multicodec: string = constants.RelayCodecs[0];
|
60
53
|
|
@@ -62,7 +55,7 @@ class Relay extends GossipSub implements IRelay {
|
|
62
55
|
* observers called when receiving new message.
|
63
56
|
* Observers under key `""` are always called.
|
64
57
|
*/
|
65
|
-
|
58
|
+
private observers: Map<ContentTopic, Set<unknown>>;
|
66
59
|
|
67
60
|
constructor(
|
68
61
|
components: GossipSubComponents,
|
@@ -73,13 +66,14 @@ class Relay extends GossipSub implements IRelay {
|
|
73
66
|
globalSignaturePolicy: SignaturePolicy.StrictNoSign,
|
74
67
|
fallbackToFloodsub: false,
|
75
68
|
});
|
69
|
+
|
76
70
|
super(components, options);
|
77
71
|
this.multicodecs = constants.RelayCodecs;
|
78
72
|
|
79
|
-
this.observers = new Map();
|
80
|
-
|
81
73
|
this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic;
|
82
74
|
|
75
|
+
this.observers = new Map();
|
76
|
+
|
83
77
|
// TODO: User might want to decide what decoder should be used (e.g. for RLN)
|
84
78
|
this.defaultDecoder = new TopicOnlyDecoder();
|
85
79
|
}
|
@@ -105,6 +99,7 @@ class Relay extends GossipSub implements IRelay {
|
|
105
99
|
log("Failed to encode message, aborting publish");
|
106
100
|
return { recipients: [] };
|
107
101
|
}
|
102
|
+
|
108
103
|
return this.publish(this.pubSubTopic, msg);
|
109
104
|
}
|
110
105
|
|
@@ -121,16 +116,67 @@ class Relay extends GossipSub implements IRelay {
|
|
121
116
|
decoder,
|
122
117
|
callback,
|
123
118
|
};
|
124
|
-
|
119
|
+
const contentTopic = decoder.contentTopic;
|
120
|
+
|
121
|
+
pushOrInitMapSet(this.observers, contentTopic, observer);
|
122
|
+
|
123
|
+
this.dispatchEvent(
|
124
|
+
new CustomEvent<BasicEventPayload>("observer:added", {
|
125
|
+
detail: {
|
126
|
+
contentTopic,
|
127
|
+
},
|
128
|
+
})
|
129
|
+
);
|
125
130
|
|
126
131
|
return () => {
|
127
|
-
const observers = this.observers.get(
|
132
|
+
const observers = this.observers.get(contentTopic);
|
128
133
|
if (observers) {
|
129
134
|
observers.delete(observer);
|
135
|
+
|
136
|
+
this.dispatchEvent(
|
137
|
+
new CustomEvent<BasicEventPayload>("observer:removed", {
|
138
|
+
detail: {
|
139
|
+
contentTopic,
|
140
|
+
},
|
141
|
+
})
|
142
|
+
);
|
130
143
|
}
|
131
144
|
};
|
132
145
|
}
|
133
146
|
|
147
|
+
private async processIncomingMessage<T extends IDecodedMessage>(
|
148
|
+
pubSubTopic: string,
|
149
|
+
bytes: Uint8Array
|
150
|
+
): Promise<void> {
|
151
|
+
const topicOnlyMsg = await this.defaultDecoder.fromWireToProtoObj(bytes);
|
152
|
+
if (!topicOnlyMsg || !topicOnlyMsg.contentTopic) {
|
153
|
+
log("Message does not have a content topic, skipping");
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
|
157
|
+
const observers = this.observers.get(topicOnlyMsg.contentTopic) as Set<
|
158
|
+
Observer<T>
|
159
|
+
>;
|
160
|
+
if (!observers) {
|
161
|
+
return;
|
162
|
+
}
|
163
|
+
await Promise.all(
|
164
|
+
Array.from(observers).map(async ({ decoder, callback }) => {
|
165
|
+
const protoMsg = await decoder.fromWireToProtoObj(bytes);
|
166
|
+
if (!protoMsg) {
|
167
|
+
log("Internal error: message previously decoded failed on 2nd pass.");
|
168
|
+
return;
|
169
|
+
}
|
170
|
+
const msg = await decoder.fromProtoObj(pubSubTopic, protoMsg);
|
171
|
+
if (msg) {
|
172
|
+
callback(msg);
|
173
|
+
} else {
|
174
|
+
log("Failed to decode messages on", topicOnlyMsg.contentTopic);
|
175
|
+
}
|
176
|
+
})
|
177
|
+
);
|
178
|
+
}
|
179
|
+
|
134
180
|
/**
|
135
181
|
* Subscribe to a pubsub topic and start emitting Waku messages to observers.
|
136
182
|
*
|
@@ -143,43 +189,22 @@ class Relay extends GossipSub implements IRelay {
|
|
143
189
|
if (event.detail.msg.topic !== pubSubTopic) return;
|
144
190
|
log(`Message received on ${pubSubTopic}`);
|
145
191
|
|
146
|
-
|
192
|
+
this.processIncomingMessage(
|
193
|
+
event.detail.msg.topic,
|
147
194
|
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
|
-
);
|
195
|
+
).catch((e) => log("Failed to process incoming message", e));
|
177
196
|
}
|
178
197
|
);
|
179
198
|
|
199
|
+
this.topicValidators.set(pubSubTopic, messageValidator);
|
180
200
|
super.subscribe(pubSubTopic);
|
181
201
|
}
|
182
202
|
|
203
|
+
unsubscribe(pubSubTopic: TopicStr): void {
|
204
|
+
super.unsubscribe(pubSubTopic);
|
205
|
+
this.topicValidators.delete(pubSubTopic);
|
206
|
+
}
|
207
|
+
|
183
208
|
getMeshPeers(topic?: TopicStr): PeerIdStr[] {
|
184
209
|
return super.getMeshPeers(topic ?? this.pubSubTopic);
|
185
210
|
}
|
@@ -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
|
}
|