Skip to content

feat: update light push to match v3 spec #2404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ packages/discovery/mock_local_storage
.giga
.cursor
.DS_Store
CLAUDE.md
CLAUDE.md
packages/discovery/scratch/

5 changes: 5 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export { FilterCore, FilterCodecs } from "./lib/filter/index.js";

export * as waku_light_push from "./lib/light_push/index.js";
export { LightPushCodec, LightPushCore } from "./lib/light_push/index.js";
export {
LightPushCoreV2,
LightPushCodecV2,
LightPushCoreV3
} from "./lib/light_push/index.js";

export * as waku_store from "./lib/store/index.js";
export { StoreCore, StoreCodec } from "./lib/store/index.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
private options: ConnectionManagerOptions;
private libp2p: Libp2p;
private dialAttemptsForPeer: Map<string, number> = new Map();
private dialErrorsForPeer: Map<string, any> = new Map();

Check warning on line 60 in packages/core/src/lib/connection_manager/connection_manager.ts

View workflow job for this annotation

GitHub Actions / proto

Unexpected any. Specify a different type

Check warning on line 60 in packages/core/src/lib/connection_manager/connection_manager.ts

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type

private currentActiveParallelDialCount = 0;
private pendingPeerDialQueue: Array<PeerId> = [];
Expand Down Expand Up @@ -267,7 +267,7 @@
* // Dial using multiaddr with specific protocols
* await connectionManager.dialPeer(multiaddr, [
* "/vac/waku/relay/2.0.0",
* "/vac/waku/lightpush/2.0.0-beta1"
* "/vac/waku/lightpush/3.0.0"
* ]);
* ```
*
Expand Down Expand Up @@ -315,7 +315,7 @@
} else {
// Handle generic error
log.error(
`Error dialing peer ${peerIdStr} - ${(error as any).message}`

Check warning on line 318 in packages/core/src/lib/connection_manager/connection_manager.ts

View workflow job for this annotation

GitHub Actions / proto

Unexpected any. Specify a different type

Check warning on line 318 in packages/core/src/lib/connection_manager/connection_manager.ts

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type
);
}
this.dialErrorsForPeer.set(peerIdStr, error);
Expand Down
23 changes: 22 additions & 1 deletion packages/core/src/lib/light_push/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
export { LightPushCore, LightPushCodec, PushResponse } from "./light_push.js";
export {
LightPushCore,
LightPushCodec,
LightPushCoreV2,
LightPushCodecV2,
Copy link
Collaborator

@weboko weboko Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not add aliases

PushResponse
} from "./light_push.js";

export { LightPushCoreV3 } from "./light_push_v3.js";
export { PushRpcV3 } from "./push_rpc_v3.js";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the point of importing LightPushCodecV3 from @waku/interfaces -> light_push_v3.ts-> @waku/core?

export {
lightPushStatusCodeToProtocolErrorV3,
lightPushStatusDescriptionsV3,
getLightPushStatusDescriptionV3
} from "./status_codes_v3.js";
export {
LightPushStatusCode,
lightPushStatusCodeToProtocolError,
lightPushStatusDescriptions,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this needs to be exported?

I assume this mapping is internal for LigthPushCore and LigthPushSDK just accepts response

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same other methods

let's not pollute our export space with not needed stuff

getLightPushStatusDescription,
isSuccessStatusCode
} from "./status_codes.js";
72 changes: 38 additions & 34 deletions packages/core/src/lib/light_push/light_push.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { PeerId, Stream } from "@libp2p/interface";
import {
type CoreProtocolResult,
type CoreProtocolResultWithMeta,
type IEncoder,
type IMessage,
type Libp2p,
ProtocolError,
PubsubTopic,
type ThisOrThat
} from "@waku/interfaces";
import { PushResponse } from "@waku/proto";
import { proto_lightpush_v2, PushResponse } from "@waku/proto";
import { isMessageSizeUnderCap } from "@waku/utils";
import { Logger } from "@waku/utils";
import all from "it-all";
Expand All @@ -18,19 +18,17 @@ import { Uint8ArrayList } from "uint8arraylist";

import { StreamManager } from "../stream_manager/index.js";

import { PushRpc } from "./push_rpc.js";
import { isRLNResponseError } from "./utils.js";
import { PushRpcV2 } from "./push_rpc_v2.js";
import { mapInfoToProtocolError } from "./utils.js";

const log = new Logger("light-push");

export const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
export { PushResponse };

type PreparePushMessageResult = ThisOrThat<"query", PushRpc>;
export const LightPushCodecV2 = LightPushCodec;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: LightPushCodec is already exported, we can keep only one


type PreparePushMessageResult = ThisOrThat<"query", PushRpcV2>;
Copy link
Collaborator

@weboko weboko Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesn't seem to be used at all

Suggested change
type PreparePushMessageResult = ThisOrThat<"query", PushRpcV2>;


/**
* Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
*/
export class LightPushCore {
private readonly streamManager: StreamManager;

Expand Down Expand Up @@ -67,7 +65,7 @@ export class LightPushCore {
};
}

const query = PushRpc.createRequest(protoMessage, encoder.pubsubTopic);
const query = PushRpcV2.createRequest(protoMessage, encoder.pubsubTopic);
return { query, error: null };
} catch (error) {
log.error("Failed to prepare push message", error);
Expand All @@ -83,7 +81,7 @@ export class LightPushCore {
encoder: IEncoder,
message: IMessage,
peerId: PeerId
): Promise<CoreProtocolResult> {
): Promise<CoreProtocolResultWithMeta> {
const { query, error: preparationError } = await this.preparePushMessage(
encoder,
message
Expand All @@ -95,7 +93,8 @@ export class LightPushCore {
failure: {
error: preparationError,
peerId
}
},
protocolUsed: LightPushCodec
};
}

Expand All @@ -109,7 +108,8 @@ export class LightPushCore {
failure: {
error: ProtocolError.NO_STREAM_AVAILABLE,
peerId: peerId
}
},
protocolUsed: LightPushCodec
};
}

Expand All @@ -123,14 +123,14 @@ export class LightPushCore {
async (source) => await all(source)
);
} catch (err) {
// can fail only because of `stream` abortion
log.error("Failed to send waku light push request", err);
return {
success: null,
failure: {
error: ProtocolError.STREAM_ABORTED,
peerId: peerId
}
},
protocolUsed: LightPushCodec
};
}

Expand All @@ -139,17 +139,18 @@ export class LightPushCore {
bytes.append(chunk);
});

let response: PushResponse | undefined;
let response: proto_lightpush_v2.PushResponse | undefined;
try {
response = PushRpc.decode(bytes).response;
response = PushRpcV2.decode(bytes).response;
} catch (err) {
log.error("Failed to decode push reply", err);
return {
success: null,
failure: {
error: ProtocolError.DECODE_FAILED,
peerId: peerId
}
},
protocolUsed: LightPushCodec
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it added?
it doesn't seem to be used or useful

let's remove it as sdk layer is aware of which protocol was actually used at the very minum

};
}

Expand All @@ -160,32 +161,35 @@ export class LightPushCore {
failure: {
error: ProtocolError.NO_RESPONSE,
peerId: peerId
}
};
}

if (isRLNResponseError(response.info)) {
log.error("Remote peer fault: RLN generation");
return {
success: null,
failure: {
error: ProtocolError.RLN_PROOF_GENERATION,
peerId: peerId
}
},
protocolUsed: LightPushCodec
};
}

if (!response.isSuccess) {
log.error("Remote peer rejected the message: ", response.info);
const errorMessage = response.info || "Message rejected";
log.error("Remote peer rejected the message: ", errorMessage);

// Use pattern matching to determine the appropriate error type
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Use pattern matching to determine the appropriate error type

const error = mapInfoToProtocolError(response.info);

return {
success: null,
failure: {
error: ProtocolError.REMOTE_PEER_REJECTED,
error: error,
peerId: peerId
}
},
protocolUsed: LightPushCodec
};
}

return { success: peerId, failure: null };
return {
success: peerId,
failure: null,
protocolUsed: LightPushCodec
};
}
}

export const LightPushCoreV2 = LightPushCore;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also not really needed to introduce another alias export

export { PushResponse };
Loading
Loading