Skip to content

Commit 8aa9b43

Browse files
committed
feat!: split outgoing and incoming message interface
While the data structure are similar, they serve different purposes. Having the same type has show to confuse API consumers Resolves #979
1 parent de6415f commit 8aa9b43

File tree

9 files changed

+78
-47
lines changed

9 files changed

+78
-47
lines changed

packages/core/src/lib/waku_filter/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { Peer } from "@libp2p/interface-peer-store";
44
import type { IncomingStreamData } from "@libp2p/interface-registrar";
55
import type {
66
Callback,
7+
DecodedMessage,
78
Decoder,
89
Filter,
910
Message,
@@ -77,7 +78,7 @@ export class WakuFilter implements Filter {
7778
* @param opts The FilterSubscriptionOpts used to narrow which messages are returned, and which peer to connect to.
7879
* @returns Unsubscribe function that can be used to end the subscription.
7980
*/
80-
async subscribe<T extends Message>(
81+
async subscribe<T extends DecodedMessage>(
8182
decoders: Decoder<T>[],
8283
callback: Callback<T>,
8384
opts?: ProtocolOptions
@@ -211,7 +212,7 @@ export class WakuFilter implements Filter {
211212
this.subscriptions.delete(requestId);
212213
}
213214

214-
private addDecoders<T extends Message>(
215+
private addDecoders<T extends DecodedMessage>(
215216
decoders: Map<string, Array<Decoder<T>>>
216217
): void {
217218
decoders.forEach((decoders, contentTopic) => {
@@ -224,7 +225,7 @@ export class WakuFilter implements Filter {
224225
});
225226
}
226227

227-
private deleteDecoders<T extends Message>(
228+
private deleteDecoders<T extends DecodedMessage>(
228229
decoders: Map<string, Array<Decoder<T>>>
229230
): void {
230231
decoders.forEach((decoders, contentTopic) => {

packages/core/src/lib/waku_message/version_0.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type {
2+
DecodedMessage,
23
Decoder,
34
Encoder,
45
Message,
@@ -15,7 +16,7 @@ const OneMillion = BigInt(1_000_000);
1516
export const Version = 0;
1617
export { proto };
1718

18-
export class MessageV0 implements Message {
19+
export class MessageV0 implements DecodedMessage {
1920
constructor(protected proto: proto.WakuMessage) {}
2021

2122
get _rawPayload(): Uint8Array | undefined {
@@ -79,7 +80,7 @@ export class EncoderV0 implements Encoder {
7980
return {
8081
payload: message.payload,
8182
version: Version,
82-
contentTopic: message.contentTopic ?? this.contentTopic,
83+
contentTopic: this.contentTopic,
8384
timestamp: BigInt(timestamp.valueOf()) * OneMillion,
8485
rateLimitProof: message.rateLimitProof,
8586
};

packages/core/src/lib/waku_relay/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
Relay,
1717
SendResult,
1818
} from "@waku/interfaces";
19+
import { DecodedMessage } from "@waku/interfaces";
1920
import debug from "debug";
2021

2122
import { DefaultPubSubTopic } from "../constants";
@@ -26,7 +27,7 @@ import * as constants from "./constants";
2627

2728
const log = debug("waku:relay");
2829

29-
export type Observer<T extends Message> = {
30+
export type Observer<T extends DecodedMessage> = {
3031
decoder: Decoder<T>;
3132
callback: Callback<T>;
3233
};
@@ -56,7 +57,7 @@ export type CreateOptions = {
5657
*/
5758
export class WakuRelay extends GossipSub implements Relay {
5859
pubSubTopic: string;
59-
defaultDecoder: Decoder<Message>;
60+
defaultDecoder: Decoder<DecodedMessage>;
6061
public static multicodec: string = constants.RelayCodecs[0];
6162

6263
/**
@@ -114,7 +115,7 @@ export class WakuRelay extends GossipSub implements Relay {
114115
*
115116
* @returns Function to delete the observer
116117
*/
117-
addObserver<T extends Message>(
118+
addObserver<T extends DecodedMessage>(
118119
decoder: Decoder<T>,
119120
callback: Callback<T>
120121
): () => void {

packages/core/src/lib/waku_store/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Connection } from "@libp2p/interface-connection";
22
import type { PeerId } from "@libp2p/interface-peer-id";
33
import { Peer } from "@libp2p/interface-peer-store";
4-
import { Decoder, Message } from "@waku/interfaces";
4+
import { DecodedMessage, Decoder } from "@waku/interfaces";
55
import debug from "debug";
66
import all from "it-all";
77
import * as lp from "it-length-prefixed";
@@ -106,7 +106,7 @@ export class WakuStore {
106106
* or if an error is encountered when processing the reply,
107107
* or if two decoders with the same content topic are passed.
108108
*/
109-
async queryOrderedCallback<T extends Message>(
109+
async queryOrderedCallback<T extends DecodedMessage>(
110110
decoders: Decoder<T>[],
111111
callback: (message: T) => Promise<void | boolean> | boolean | void,
112112
options?: QueryOptions
@@ -155,7 +155,7 @@ export class WakuStore {
155155
* or if an error is encountered when processing the reply,
156156
* or if two decoders with the same content topic are passed.
157157
*/
158-
async queryCallbackOnPromise<T extends Message>(
158+
async queryCallbackOnPromise<T extends DecodedMessage>(
159159
decoders: Decoder<T>[],
160160
callback: (
161161
message: Promise<T | undefined>
@@ -193,7 +193,7 @@ export class WakuStore {
193193
* or if an error is encountered when processing the reply,
194194
* or if two decoders with the same content topic are passed.
195195
*/
196-
async *queryGenerator<T extends Message>(
196+
async *queryGenerator<T extends DecodedMessage>(
197197
decoders: Decoder<T>[],
198198
options?: QueryOptions
199199
): AsyncGenerator<Promise<T | undefined>[]> {
@@ -266,7 +266,7 @@ export class WakuStore {
266266
}
267267
}
268268

269-
async function* paginate<T extends Message>(
269+
async function* paginate<T extends DecodedMessage>(
270270
connection: Connection,
271271
protocol: string,
272272
queryOpts: Params,

packages/interfaces/src/index.ts

+27-14
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export type ProtocolOptions = {
2828
export type Callback<T extends Message> = (msg: T) => void | Promise<void>;
2929

3030
export interface Filter extends PointToPointProtocol {
31-
subscribe: <T extends Message>(
31+
subscribe: <T extends DecodedMessage>(
3232
decoders: Decoder<T>[],
3333
callback: Callback<T>,
3434
opts?: ProtocolOptions
@@ -38,7 +38,7 @@ export interface Filter extends PointToPointProtocol {
3838
export interface LightPush extends PointToPointProtocol {
3939
push: (
4040
encoder: Encoder,
41-
message: Partial<Message>,
41+
message: Message,
4242
opts?: ProtocolOptions
4343
) => Promise<SendResult>;
4444
}
@@ -76,27 +76,27 @@ export type StoreQueryOptions = {
7676
} & ProtocolOptions;
7777

7878
export interface Store extends PointToPointProtocol {
79-
queryOrderedCallback: <T extends Message>(
79+
queryOrderedCallback: <T extends DecodedMessage>(
8080
decoders: Decoder<T>[],
8181
callback: (message: T) => Promise<void | boolean> | boolean | void,
8282
options?: StoreQueryOptions
8383
) => Promise<void>;
84-
queryCallbackOnPromise: <T extends Message>(
84+
queryCallbackOnPromise: <T extends DecodedMessage>(
8585
decoders: Decoder<T>[],
8686
callback: (
8787
message: Promise<T | undefined>
8888
) => Promise<void | boolean> | boolean | void,
8989
options?: StoreQueryOptions
9090
) => Promise<void>;
91-
queryGenerator: <T extends Message>(
91+
queryGenerator: <T extends DecodedMessage>(
9292
decoders: Decoder<T>[],
9393
options?: StoreQueryOptions
9494
) => AsyncGenerator<Promise<T | undefined>[]>;
9595
}
9696

9797
export interface Relay extends GossipSub {
98-
send: (encoder: Encoder, message: Partial<Message>) => Promise<SendResult>;
99-
addObserver: <T extends Message>(
98+
send: (encoder: Encoder, message: Message) => Promise<SendResult>;
99+
addObserver: <T extends DecodedMessage>(
100100
decoder: Decoder<T>,
101101
callback: Callback<T>
102102
) => () => void;
@@ -155,6 +155,10 @@ export interface RateLimitProof {
155155
rlnIdentifier: Uint8Array;
156156
}
157157

158+
/**
159+
* Interface matching the protobuf library.
160+
* Field types matches the protobuf type over the wire
161+
*/
158162
export interface ProtoMessage {
159163
payload: Uint8Array | undefined;
160164
contentTopic: string | undefined;
@@ -163,20 +167,29 @@ export interface ProtoMessage {
163167
rateLimitProof: RateLimitProof | undefined;
164168
}
165169

170+
/**
171+
* Interface for messages to encode and send.
172+
*/
166173
export interface Message {
167-
payload: Uint8Array | undefined;
168-
contentTopic: string | undefined;
169-
timestamp: Date | undefined;
170-
rateLimitProof: RateLimitProof | undefined;
174+
payload?: Uint8Array;
175+
timestamp?: Date;
176+
rateLimitProof?: RateLimitProof;
171177
}
172178

173179
export interface Encoder {
174180
contentTopic: string;
175-
toWire: (message: Partial<Message>) => Promise<Uint8Array | undefined>;
176-
toProtoObj: (message: Partial<Message>) => Promise<ProtoMessage | undefined>;
181+
toWire: (message: Message) => Promise<Uint8Array | undefined>;
182+
toProtoObj: (message: Message) => Promise<ProtoMessage | undefined>;
183+
}
184+
185+
export interface DecodedMessage {
186+
payload: Uint8Array | undefined;
187+
contentTopic: string | undefined;
188+
timestamp: Date | undefined;
189+
rateLimitProof: RateLimitProof | undefined;
177190
}
178191

179-
export interface Decoder<T extends Message> {
192+
export interface Decoder<T extends DecodedMessage> {
180193
contentTopic: string;
181194
fromWireToProtoObj: (bytes: Uint8Array) => Promise<ProtoMessage | undefined>;
182195
fromProtoObj: (proto: ProtoMessage) => Promise<T | undefined>;

packages/message-encryption/src/index.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ import {
55
MessageV0,
66
proto,
77
} from "@waku/core/lib/waku_message/version_0";
8-
import type { Decoder, Encoder, Message, ProtoMessage } from "@waku/interfaces";
8+
import type {
9+
DecodedMessage,
10+
Decoder,
11+
Encoder,
12+
Message,
13+
ProtoMessage,
14+
} from "@waku/interfaces";
915
import debug from "debug";
1016

1117
import { Symmetric } from "./constants.js";
@@ -38,7 +44,7 @@ export type Signature = {
3844
publicKey: Uint8Array | undefined;
3945
};
4046

41-
export class MessageV1 extends MessageV0 implements Message {
47+
export class MessageV1 extends MessageV0 implements DecodedMessage {
4248
private readonly _decodedPayload: Uint8Array;
4349

4450
constructor(

packages/tests/tests/filter.node.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { bytesToUtf8, utf8ToBytes } from "@waku/byte-utils";
22
import { waitForRemotePeer } from "@waku/core/lib/wait_for_remote_peer";
33
import { DecoderV0, EncoderV0 } from "@waku/core/lib/waku_message/version_0";
44
import { createFullNode } from "@waku/create";
5-
import type { Message, WakuFull } from "@waku/interfaces";
5+
import type { DecodedMessage, WakuFull } from "@waku/interfaces";
66
import { Protocols } from "@waku/interfaces";
77
import { expect } from "chai";
88
import debug from "debug";
@@ -47,7 +47,7 @@ describe("Waku Filter", () => {
4747
const messageText = "Filtering works!";
4848
const message = { payload: utf8ToBytes(messageText) };
4949

50-
const callback = (msg: Message): void => {
50+
const callback = (msg: DecodedMessage): void => {
5151
log("Got a message");
5252
messageCount++;
5353
expect(msg.contentTopic).to.eq(TestContentTopic);
@@ -71,7 +71,7 @@ describe("Waku Filter", () => {
7171
this.timeout(10000);
7272

7373
let messageCount = 0;
74-
const callback = (msg: Message): void => {
74+
const callback = (msg: DecodedMessage): void => {
7575
messageCount++;
7676
expect(msg.contentTopic).to.eq(TestContentTopic);
7777
};

packages/tests/tests/relay.node.spec.ts

+13-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
MessageV0,
99
} from "@waku/core/lib/waku_message/version_0";
1010
import { createPrivacyNode } from "@waku/create";
11-
import type { Message, WakuPrivacy } from "@waku/interfaces";
11+
import type { DecodedMessage, WakuPrivacy } from "@waku/interfaces";
1212
import { Protocols } from "@waku/interfaces";
1313
import {
1414
AsymDecoder,
@@ -118,9 +118,11 @@ describe("Waku Relay [node only]", () => {
118118
timestamp: messageTimestamp,
119119
};
120120

121-
const receivedMsgPromise: Promise<Message> = new Promise((resolve) => {
122-
waku2.relay.addObserver(TestDecoder, resolve);
123-
});
121+
const receivedMsgPromise: Promise<DecodedMessage> = new Promise(
122+
(resolve) => {
123+
waku2.relay.addObserver(TestDecoder, resolve);
124+
}
125+
);
124126

125127
await waku1.relay.send(TestEncoder, message);
126128

@@ -148,12 +150,12 @@ describe("Waku Relay [node only]", () => {
148150
const fooDecoder = new DecoderV0(fooContentTopic);
149151
const barDecoder = new DecoderV0(barContentTopic);
150152

151-
const fooMessages: Message[] = [];
153+
const fooMessages: DecodedMessage[] = [];
152154
waku2.relay.addObserver(fooDecoder, (msg) => {
153155
fooMessages.push(msg);
154156
});
155157

156-
const barMessages: Message[] = [];
158+
const barMessages: DecodedMessage[] = [];
157159
waku2.relay.addObserver(barDecoder, (msg) => {
158160
barMessages.push(msg);
159161
});
@@ -197,7 +199,7 @@ describe("Waku Relay [node only]", () => {
197199
const asymDecoder = new AsymDecoder(asymTopic, privateKey);
198200
const symDecoder = new SymDecoder(symTopic, symKey);
199201

200-
const msgs: Message[] = [];
202+
const msgs: DecodedMessage[] = [];
201203
waku2.relay.addObserver(asymDecoder, (wakuMsg) => {
202204
msgs.push(wakuMsg);
203205
});
@@ -228,7 +230,7 @@ describe("Waku Relay [node only]", () => {
228230
const contentTopic = "added-then-deleted-observer";
229231

230232
// The promise **fails** if we receive a message on this observer.
231-
const receivedMsgPromise: Promise<Message> = new Promise(
233+
const receivedMsgPromise: Promise<DecodedMessage> = new Promise(
232234
(resolve, reject) => {
233235
const deleteObserver = waku2.relay.addObserver(
234236
new DecoderV0(contentTopic),
@@ -304,15 +306,15 @@ describe("Waku Relay [node only]", () => {
304306

305307
const messageText = "Communicating using a custom pubsub topic";
306308

307-
const waku2ReceivedMsgPromise: Promise<Message> = new Promise(
309+
const waku2ReceivedMsgPromise: Promise<DecodedMessage> = new Promise(
308310
(resolve) => {
309311
waku2.relay.addObserver(TestDecoder, resolve);
310312
}
311313
);
312314

313315
// The promise **fails** if we receive a message on the default
314316
// pubsub topic.
315-
const waku3NoMsgPromise: Promise<Message> = new Promise(
317+
const waku3NoMsgPromise: Promise<DecodedMessage> = new Promise(
316318
(resolve, reject) => {
317319
waku3.relay.addObserver(TestDecoder, reject);
318320
setTimeout(resolve, 1000);
@@ -466,7 +468,7 @@ describe("Waku Relay [node only]", () => {
466468
const msgStr = "Hello there!";
467469
const message = { payload: utf8ToBytes(msgStr) };
468470

469-
const waku2ReceivedMsgPromise: Promise<Message> = new Promise(
471+
const waku2ReceivedMsgPromise: Promise<DecodedMessage> = new Promise(
470472
(resolve) => {
471473
waku2.relay.addObserver(TestDecoder, resolve);
472474
}

0 commit comments

Comments
 (0)