Skip to content

Commit 41301ea

Browse files
committed
feat: add v3 protocol support tests and exports
- Export LightPushCodecV3 and LightPushCodecs from core package - Add v3 protocol support tests with status code validation - Add mock functions for v3 responses and RLN errors - Test mixed v2/v3 peer scenarios - Validate protocol error mapping and status code handling - Fix linting errors by adding explicit return types
1 parent 539c92f commit 41301ea

11 files changed

Lines changed: 413 additions & 163 deletions

File tree

packages/core/src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ export * as waku_filter from "./lib/filter/index.js";
1010
export { FilterCore, FilterCodecs } from "./lib/filter/index.js";
1111

1212
export * as waku_light_push from "./lib/light_push/index.js";
13-
export { LightPushCodec, LightPushCore } from "./lib/light_push/index.js";
13+
export {
14+
LightPushCodec,
15+
LightPushCodecV3,
16+
LightPushCodecs,
17+
LightPushCore
18+
} from "./lib/light_push/index.js";
1419

1520
export * as waku_store from "./lib/store/index.js";
1621
export { StoreCore, StoreCodec } from "./lib/store/index.js";

packages/core/src/lib/filter/filter.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import type { PeerId, Stream } from "@libp2p/interface";
22
import type { IncomingStreamData } from "@libp2p/interface-internal";
33
import {
44
type ContentTopic,
5-
type CoreProtocolResult,
5+
type FilterCoreResult,
6+
FilterError,
67
type Libp2p,
7-
ProtocolError,
88
type PubsubTopic
99
} from "@waku/interfaces";
1010
import { WakuMessage } from "@waku/proto";
@@ -62,7 +62,7 @@ export class FilterCore {
6262
pubsubTopic: PubsubTopic,
6363
peerId: PeerId,
6464
contentTopics: ContentTopic[]
65-
): Promise<CoreProtocolResult> {
65+
): Promise<FilterCoreResult> {
6666
const stream = await this.streamManager.getStream(peerId);
6767

6868
const request = FilterSubscribeRpc.createSubscribeRequest(
@@ -88,7 +88,7 @@ export class FilterCore {
8888
return {
8989
success: null,
9090
failure: {
91-
error: ProtocolError.GENERIC_FAIL,
91+
error: FilterError.SUBSCRIPTION_FAILED,
9292
peerId: peerId
9393
}
9494
};
@@ -103,8 +103,11 @@ export class FilterCore {
103103
);
104104
return {
105105
failure: {
106-
error: ProtocolError.REMOTE_PEER_REJECTED,
107-
peerId: peerId
106+
error: FilterError.REMOTE_PEER_REJECTED,
107+
peerId: peerId,
108+
statusCode: statusCode,
109+
statusDesc: statusDesc,
110+
requestId: requestId
108111
},
109112
success: null
110113
};
@@ -120,7 +123,7 @@ export class FilterCore {
120123
pubsubTopic: PubsubTopic,
121124
peerId: PeerId,
122125
contentTopics: ContentTopic[]
123-
): Promise<CoreProtocolResult> {
126+
): Promise<FilterCoreResult> {
124127
let stream: Stream | undefined;
125128
try {
126129
stream = await this.streamManager.getStream(peerId);
@@ -132,7 +135,7 @@ export class FilterCore {
132135
return {
133136
success: null,
134137
failure: {
135-
error: ProtocolError.NO_STREAM_AVAILABLE,
138+
error: FilterError.NO_STREAM_AVAILABLE,
136139
peerId: peerId
137140
}
138141
};
@@ -150,7 +153,7 @@ export class FilterCore {
150153
return {
151154
success: null,
152155
failure: {
153-
error: ProtocolError.GENERIC_FAIL,
156+
error: FilterError.GENERIC_FAIL,
154157
peerId: peerId
155158
}
156159
};
@@ -165,7 +168,7 @@ export class FilterCore {
165168
public async unsubscribeAll(
166169
pubsubTopic: PubsubTopic,
167170
peerId: PeerId
168-
): Promise<CoreProtocolResult> {
171+
): Promise<FilterCoreResult> {
169172
const stream = await this.streamManager.getStream(peerId);
170173

171174
const request = FilterSubscribeRpc.createUnsubscribeAllRequest(pubsubTopic);
@@ -181,7 +184,7 @@ export class FilterCore {
181184
if (!res || !res.length) {
182185
return {
183186
failure: {
184-
error: ProtocolError.NO_RESPONSE,
187+
error: FilterError.NO_RESPONSE,
185188
peerId: peerId
186189
},
187190
success: null
@@ -197,7 +200,7 @@ export class FilterCore {
197200
);
198201
return {
199202
failure: {
200-
error: ProtocolError.REMOTE_PEER_REJECTED,
203+
error: FilterError.REMOTE_PEER_REJECTED,
201204
peerId: peerId
202205
},
203206
success: null
@@ -210,7 +213,7 @@ export class FilterCore {
210213
};
211214
}
212215

213-
public async ping(peerId: PeerId): Promise<CoreProtocolResult> {
216+
public async ping(peerId: PeerId): Promise<FilterCoreResult> {
214217
let stream: Stream | undefined;
215218
try {
216219
stream = await this.streamManager.getStream(peerId);
@@ -222,7 +225,7 @@ export class FilterCore {
222225
return {
223226
success: null,
224227
failure: {
225-
error: ProtocolError.NO_STREAM_AVAILABLE,
228+
error: FilterError.NO_STREAM_AVAILABLE,
226229
peerId: peerId
227230
}
228231
};
@@ -244,7 +247,7 @@ export class FilterCore {
244247
return {
245248
success: null,
246249
failure: {
247-
error: ProtocolError.GENERIC_FAIL,
250+
error: FilterError.GENERIC_FAIL,
248251
peerId: peerId
249252
}
250253
};
@@ -254,7 +257,7 @@ export class FilterCore {
254257
return {
255258
success: null,
256259
failure: {
257-
error: ProtocolError.NO_RESPONSE,
260+
error: FilterError.NO_RESPONSE,
258261
peerId: peerId
259262
}
260263
};
@@ -270,7 +273,7 @@ export class FilterCore {
270273
return {
271274
success: null,
272275
failure: {
273-
error: ProtocolError.REMOTE_PEER_REJECTED,
276+
error: FilterError.REMOTE_PEER_REJECTED,
274277
peerId: peerId
275278
}
276279
};
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
export { LightPushCore, LightPushCodec, PushResponse } from "./light_push.js";
1+
export {
2+
LightPushCore,
3+
LightPushCodec,
4+
LightPushCodecV3,
5+
LightPushCodecs,
6+
PushResponse
7+
} from "./light_push.js";

packages/core/src/lib/light_push/light_push.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import type { PeerId, Stream } from "@libp2p/interface";
22
import {
3-
type CoreProtocolResult,
43
type IEncoder,
54
type IMessage,
65
isSuccess as isV3Success,
76
type Libp2p,
8-
ProtocolError,
7+
type LightPushCoreResult,
8+
LightPushError,
99
type ThisOrThat,
10-
toProtocolError
10+
toLightPushError
1111
} from "@waku/interfaces";
1212
import { PushResponse } from "@waku/proto";
1313
import { isMessageSizeUnderCap } from "@waku/utils";
@@ -30,7 +30,12 @@ export const LightPushCodecV3 = "/vac/waku/lightpush/3.0.0";
3030
export const LightPushCodecs = [LightPushCodecV3, LightPushCodec];
3131
export { PushResponse };
3232

33-
type PreparePushMessageResult = ThisOrThat<"query", PushRpc>;
33+
type PreparePushMessageResult = ThisOrThat<
34+
"query",
35+
PushRpc,
36+
"error",
37+
LightPushError
38+
>;
3439

3540
/**
3641
* Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
@@ -89,20 +94,20 @@ export class LightPushCore {
8994
try {
9095
if (!message.payload || message.payload.length === 0) {
9196
log.error("Failed to send waku light push: payload is empty");
92-
return { query: null, error: ProtocolError.EMPTY_PAYLOAD };
97+
return { query: null, error: LightPushError.EMPTY_PAYLOAD };
9398
}
9499

95100
if (!(await isMessageSizeUnderCap(encoder, message))) {
96101
log.error("Failed to send waku light push: message is bigger than 1MB");
97-
return { query: null, error: ProtocolError.SIZE_TOO_BIG };
102+
return { query: null, error: LightPushError.SIZE_TOO_BIG };
98103
}
99104

100105
const protoMessage = await encoder.toProtoObj(message);
101106
if (!protoMessage) {
102107
log.error("Failed to encode to protoMessage, aborting push");
103108
return {
104109
query: null,
105-
error: ProtocolError.ENCODE_FAILED
110+
error: LightPushError.ENCODE_FAILED
106111
};
107112
}
108113

@@ -113,7 +118,7 @@ export class LightPushCore {
113118

114119
return {
115120
query: null,
116-
error: ProtocolError.GENERIC_FAIL
121+
error: LightPushError.GENERIC_FAIL
117122
};
118123
}
119124
}
@@ -122,7 +127,7 @@ export class LightPushCore {
122127
encoder: IEncoder,
123128
message: IMessage,
124129
peerId: PeerId
125-
): Promise<CoreProtocolResult> {
130+
): Promise<LightPushCoreResult> {
126131
const { query, error: preparationError } = await this.preparePushMessage(
127132
encoder,
128133
message
@@ -154,7 +159,7 @@ export class LightPushCore {
154159
return {
155160
success: null,
156161
failure: {
157-
error: ProtocolError.NO_STREAM_AVAILABLE,
162+
error: LightPushError.NO_STREAM_AVAILABLE,
158163
peerId: peerId
159164
}
160165
};
@@ -176,7 +181,7 @@ export class LightPushCore {
176181
return {
177182
success: null,
178183
failure: {
179-
error: ProtocolError.STREAM_ABORTED,
184+
error: LightPushError.STREAM_ABORTED,
180185
peerId: peerId
181186
}
182187
};
@@ -195,7 +200,7 @@ export class LightPushCore {
195200
return {
196201
success: null,
197202
failure: {
198-
error: ProtocolError.DECODE_FAILED,
203+
error: LightPushError.DECODE_FAILED,
199204
peerId: peerId
200205
}
201206
};
@@ -206,23 +211,25 @@ export class LightPushCore {
206211
return {
207212
success: null,
208213
failure: {
209-
error: ProtocolError.NO_RESPONSE,
214+
error: LightPushError.NO_RESPONSE,
210215
peerId: peerId
211216
}
212217
};
213218
}
214219

215220
if (protocol === LightPushCodecV3 && response.statusCode !== undefined) {
216221
if (!isV3Success(response.statusCode)) {
217-
const error = toProtocolError(response.statusCode);
222+
const error = toLightPushError(response.statusCode);
218223
log.error(
219224
`Remote peer rejected with v3 status code ${response.statusCode}: ${response.statusDesc || response.info}`
220225
);
221226
return {
222227
success: null,
223228
failure: {
224229
error,
225-
peerId: peerId
230+
peerId: peerId,
231+
statusCode: response.statusCode,
232+
statusDesc: response.statusDesc || response.info
226233
}
227234
};
228235
}
@@ -239,7 +246,7 @@ export class LightPushCore {
239246
return {
240247
success: null,
241248
failure: {
242-
error: ProtocolError.RLN_PROOF_GENERATION,
249+
error: LightPushError.RLN_PROOF_GENERATION,
243250
peerId: peerId
244251
}
245252
};
@@ -250,8 +257,9 @@ export class LightPushCore {
250257
return {
251258
success: null,
252259
failure: {
253-
error: ProtocolError.REMOTE_PEER_REJECTED,
254-
peerId: peerId
260+
error: LightPushError.REMOTE_PEER_REJECTED,
261+
peerId: peerId,
262+
statusDesc: response.info
255263
}
256264
};
257265
}

packages/interfaces/src/light_push.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ProtocolError } from "./protocols.js";
2-
import type { ISender, ISendOptions } from "./sender.js";
1+
import { LightPushError } from "./protocols.js";
2+
import type { ILightPushSender, ISendOptions } from "./sender.js";
33

44
export type LightPushProtocolOptions = ISendOptions & {
55
/**
@@ -16,7 +16,7 @@ export type LightPushProtocolOptions = ISendOptions & {
1616
numPeersToUse?: number;
1717
};
1818

19-
export type ILightPush = ISender & {
19+
export type ILightPush = ILightPushSender & {
2020
readonly multicodec: string;
2121
start: () => void;
2222
stop: () => void;
@@ -53,35 +53,48 @@ export function isSuccess(statusCode: number | undefined): boolean {
5353
return statusCode === LightPushStatusCode.SUCCESS;
5454
}
5555

56-
export function toProtocolError(
56+
export function toLightPushError(
5757
statusCode: LightPushStatusCode | number | undefined
58-
): ProtocolError {
58+
): LightPushError {
5959
if (!statusCode) {
60-
return ProtocolError.GENERIC_FAIL;
60+
return LightPushError.GENERIC_FAIL;
6161
}
6262

6363
switch (statusCode) {
6464
case LightPushStatusCode.SUCCESS:
65-
return ProtocolError.GENERIC_FAIL;
65+
return LightPushError.GENERIC_FAIL;
6666
case LightPushStatusCode.BAD_REQUEST:
67+
return LightPushError.BAD_REQUEST;
6768
case LightPushStatusCode.INVALID_MESSAGE:
69+
return LightPushError.INVALID_MESSAGE;
6870
case LightPushStatusCode.TOO_MANY_REQUESTS:
69-
return ProtocolError.REMOTE_PEER_REJECTED;
71+
return LightPushError.TOO_MANY_REQUESTS;
7072
case LightPushStatusCode.PAYLOAD_TOO_LARGE:
71-
return ProtocolError.SIZE_TOO_BIG;
73+
return LightPushError.PAYLOAD_TOO_LARGE;
7274
case LightPushStatusCode.UNSUPPORTED_TOPIC:
73-
return ProtocolError.TOPIC_NOT_CONFIGURED;
75+
return LightPushError.UNSUPPORTED_TOPIC;
7476
case LightPushStatusCode.UNAVAILABLE:
77+
return LightPushError.UNAVAILABLE;
7578
case LightPushStatusCode.NO_PEERS:
76-
return ProtocolError.NO_PEER_AVAILABLE;
79+
return LightPushError.NO_PEERS;
7780
case LightPushStatusCode.NO_RLN_PROOF:
78-
return ProtocolError.RLN_PROOF_GENERATION;
81+
return LightPushError.NO_RLN_PROOF;
7982
case LightPushStatusCode.INTERNAL_ERROR:
8083
default:
81-
return ProtocolError.GENERIC_FAIL;
84+
return LightPushError.INTERNAL_ERROR;
8285
}
8386
}
8487

88+
// Legacy function for backward compatibility
89+
/**
90+
* @deprecated Use toLightPushError instead
91+
*/
92+
export function toProtocolError(
93+
statusCode: LightPushStatusCode | number | undefined
94+
): LightPushError {
95+
return toLightPushError(statusCode);
96+
}
97+
8598
export function getStatusDescription(
8699
statusCode: number | undefined,
87100
customDesc?: string

0 commit comments

Comments
 (0)