Skip to content

Commit e184069

Browse files
committed
feat: update light push to match v3 spec
1 parent 49f26d8 commit e184069

22 files changed

+2497
-231
lines changed

packages/core/src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ export { FilterCore, FilterCodecs } from "./lib/filter/index.js";
1111

1212
export * as waku_light_push from "./lib/light_push/index.js";
1313
export { LightPushCodec, LightPushCore } from "./lib/light_push/index.js";
14+
export {
15+
LightPushCoreV2,
16+
LightPushCodecV2,
17+
LightPushCoreV3,
18+
LightPushCodecV3,
19+
LightPushStatusCodeV3,
20+
lightPushStatusCodeToProtocolErrorV3,
21+
isSuccessStatusCodeV3
22+
} from "./lib/light_push/index.js";
1423

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

packages/core/src/lib/connection_manager/connection_manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ export class ConnectionManager
267267
* // Dial using multiaddr with specific protocols
268268
* await connectionManager.dialPeer(multiaddr, [
269269
* "/vac/waku/relay/2.0.0",
270-
* "/vac/waku/lightpush/2.0.0-beta1"
270+
* "/vac/waku/lightpush/3.0.0"
271271
* ]);
272272
* ```
273273
*
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,22 @@
1+
// V2 exports
2+
export { LightPushCoreV2, LightPushCodecV2 } from "./light_push_v2.js";
3+
4+
// V3 exports
5+
export { LightPushCoreV3, LightPushCodecV3 } from "./light_push_v3.js";
6+
export {
7+
LightPushStatusCodeV3,
8+
lightPushStatusCodeToProtocolErrorV3,
9+
lightPushStatusDescriptionsV3,
10+
getLightPushStatusDescriptionV3,
11+
isSuccessStatusCodeV3
12+
} from "./status_codes_v3.js";
13+
14+
// Legacy exports for backward compatibility (currently using v3)
115
export { LightPushCore, LightPushCodec, PushResponse } from "./light_push.js";
16+
export {
17+
LightPushStatusCode,
18+
lightPushStatusCodeToProtocolError,
19+
lightPushStatusDescriptions,
20+
getLightPushStatusDescription,
21+
isSuccessStatusCode
22+
} from "./status_codes.js";
Lines changed: 6 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,6 @@
1-
import type { PeerId, Stream } from "@libp2p/interface";
2-
import {
3-
type CoreProtocolResult,
4-
type IBaseProtocolCore,
5-
type IEncoder,
6-
type IMessage,
7-
type Libp2p,
8-
ProtocolError,
9-
PubsubTopic,
10-
type ThisOrThat
11-
} from "@waku/interfaces";
12-
import { PushResponse } from "@waku/proto";
13-
import { isMessageSizeUnderCap } from "@waku/utils";
14-
import { Logger } from "@waku/utils";
15-
import all from "it-all";
16-
import * as lp from "it-length-prefixed";
17-
import { pipe } from "it-pipe";
18-
import { Uint8ArrayList } from "uint8arraylist";
19-
20-
import { BaseProtocol } from "../base_protocol.js";
21-
22-
import { PushRpc } from "./push_rpc.js";
23-
import { isRLNResponseError } from "./utils.js";
24-
25-
const log = new Logger("light-push");
26-
27-
export const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
28-
export { PushResponse };
29-
30-
type PreparePushMessageResult = ThisOrThat<"query", PushRpc>;
31-
32-
/**
33-
* Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
34-
*/
35-
export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
36-
public constructor(
37-
public readonly pubsubTopics: PubsubTopic[],
38-
libp2p: Libp2p
39-
) {
40-
super(LightPushCodec, libp2p.components, pubsubTopics);
41-
}
42-
43-
private async preparePushMessage(
44-
encoder: IEncoder,
45-
message: IMessage
46-
): Promise<PreparePushMessageResult> {
47-
try {
48-
if (!message.payload || message.payload.length === 0) {
49-
log.error("Failed to send waku light push: payload is empty");
50-
return { query: null, error: ProtocolError.EMPTY_PAYLOAD };
51-
}
52-
53-
if (!(await isMessageSizeUnderCap(encoder, message))) {
54-
log.error("Failed to send waku light push: message is bigger than 1MB");
55-
return { query: null, error: ProtocolError.SIZE_TOO_BIG };
56-
}
57-
58-
const protoMessage = await encoder.toProtoObj(message);
59-
if (!protoMessage) {
60-
log.error("Failed to encode to protoMessage, aborting push");
61-
return {
62-
query: null,
63-
error: ProtocolError.ENCODE_FAILED
64-
};
65-
}
66-
67-
const query = PushRpc.createRequest(protoMessage, encoder.pubsubTopic);
68-
return { query, error: null };
69-
} catch (error) {
70-
log.error("Failed to prepare push message", error);
71-
72-
return {
73-
query: null,
74-
error: ProtocolError.GENERIC_FAIL
75-
};
76-
}
77-
}
78-
79-
public async send(
80-
encoder: IEncoder,
81-
message: IMessage,
82-
peerId: PeerId
83-
): Promise<CoreProtocolResult> {
84-
const { query, error: preparationError } = await this.preparePushMessage(
85-
encoder,
86-
message
87-
);
88-
89-
if (preparationError || !query) {
90-
return {
91-
success: null,
92-
failure: {
93-
error: preparationError,
94-
peerId
95-
}
96-
};
97-
}
98-
99-
let stream: Stream;
100-
try {
101-
stream = await this.getStream(peerId);
102-
} catch (error) {
103-
log.error("Failed to get stream", error);
104-
return {
105-
success: null,
106-
failure: {
107-
error: ProtocolError.NO_STREAM_AVAILABLE,
108-
peerId: peerId
109-
}
110-
};
111-
}
112-
113-
let res: Uint8ArrayList[] | undefined;
114-
try {
115-
res = await pipe(
116-
[query.encode()],
117-
lp.encode,
118-
stream,
119-
lp.decode,
120-
async (source) => await all(source)
121-
);
122-
} catch (err) {
123-
// can fail only because of `stream` abortion
124-
log.error("Failed to send waku light push request", err);
125-
return {
126-
success: null,
127-
failure: {
128-
error: ProtocolError.STREAM_ABORTED,
129-
peerId: peerId
130-
}
131-
};
132-
}
133-
134-
const bytes = new Uint8ArrayList();
135-
res.forEach((chunk) => {
136-
bytes.append(chunk);
137-
});
138-
139-
let response: PushResponse | undefined;
140-
try {
141-
response = PushRpc.decode(bytes).response;
142-
} catch (err) {
143-
log.error("Failed to decode push reply", err);
144-
return {
145-
success: null,
146-
failure: {
147-
error: ProtocolError.DECODE_FAILED,
148-
peerId: peerId
149-
}
150-
};
151-
}
152-
153-
if (!response) {
154-
log.error("Remote peer fault: No response in PushRPC");
155-
return {
156-
success: null,
157-
failure: {
158-
error: ProtocolError.NO_RESPONSE,
159-
peerId: peerId
160-
}
161-
};
162-
}
163-
164-
if (isRLNResponseError(response.info)) {
165-
log.error("Remote peer fault: RLN generation");
166-
return {
167-
success: null,
168-
failure: {
169-
error: ProtocolError.RLN_PROOF_GENERATION,
170-
peerId: peerId
171-
}
172-
};
173-
}
174-
175-
if (!response.isSuccess) {
176-
log.error("Remote peer rejected the message: ", response.info);
177-
return {
178-
success: null,
179-
failure: {
180-
error: ProtocolError.REMOTE_PEER_REJECTED,
181-
peerId: peerId
182-
}
183-
};
184-
}
185-
186-
return { success: peerId, failure: null };
187-
}
188-
}
1+
// Re-export v3 as the default implementation for backward compatibility
2+
export {
3+
LightPushCoreV3 as LightPushCore,
4+
LightPushCodecV3 as LightPushCodec
5+
} from "./light_push_v3.js";
6+
export { PushResponse } from "@waku/proto";

0 commit comments

Comments
 (0)