Skip to content
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

fix: measure total message size #1643

Merged
merged 2 commits into from
Oct 26, 2023
Merged
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
7 changes: 5 additions & 2 deletions packages/core/src/lib/light_push/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import {
SendResult
} from "@waku/interfaces";
import { PushResponse } from "@waku/proto";
import { ensurePubsubTopicIsConfigured, isSizeUnderCap } from "@waku/utils";
import {
ensurePubsubTopicIsConfigured,
isMessageSizeUnderCap
} from "@waku/utils";
import { Logger } from "@waku/utils";
import all from "it-all";
import * as lp from "it-length-prefixed";
Expand Down Expand Up @@ -61,7 +64,7 @@ class LightPush extends BaseProtocol implements ILightPush {
return { query: null, error: SendError.EMPTY_PAYLOAD };
}

if (!isSizeUnderCap(message.payload)) {
if (!(await isMessageSizeUnderCap(encoder, message))) {
log.error("Failed to send waku light push: message is bigger than 1MB");
return { query: null, error: SendError.SIZE_TOO_BIG };
}
Expand Down
16 changes: 8 additions & 8 deletions packages/relay/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
SendError,
SendResult
} from "@waku/interfaces";
import { isSizeUnderCap, toAsyncIterator } from "@waku/utils";
import { isWireSizeUnderCap, toAsyncIterator } from "@waku/utils";
import { pushOrInitMapSet } from "@waku/utils";
import { Logger } from "@waku/utils";

Expand Down Expand Up @@ -112,20 +112,20 @@ class Relay implements IRelay {
};
}

if (!isSizeUnderCap(message.payload)) {
log.error("Failed to send waku relay: message is bigger that 1MB");
const msg = await encoder.toWire(message);
if (!msg) {
log.error("Failed to encode message, aborting publish");
return {
recipients,
errors: [SendError.SIZE_TOO_BIG]
errors: [SendError.ENCODE_FAILED]
};
}

const msg = await encoder.toWire(message);
if (!msg) {
log.error("Failed to encode message, aborting publish");
if (!isWireSizeUnderCap(msg)) {
log.error("Failed to send waku relay: message is bigger that 1MB");
return {
recipients,
errors: [SendError.ENCODE_FAILED]
errors: [SendError.SIZE_TOO_BIG]
};
}

Expand Down
8 changes: 1 addition & 7 deletions packages/tests/tests/light-push/index.node.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,8 @@ describe("Waku Light Push", function () {
});

it("Push message equal or less that 1MB", async function () {
const oneMbPayload = generateRandomUint8Array(1024 ** 2);
let pushResponse = await waku.lightPush.send(TestEncoder, {
payload: oneMbPayload
});
expect(pushResponse.recipients.length).to.greaterThan(0);

const bigPayload = generateRandomUint8Array(65536);
pushResponse = await waku.lightPush.send(TestEncoder, {
const pushResponse = await waku.lightPush.send(TestEncoder, {
payload: bigPayload
});
expect(pushResponse.recipients.length).to.greaterThan(0);
Expand Down
11 changes: 0 additions & 11 deletions packages/tests/tests/relay/publish.node.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,6 @@ describe("Waku Relay, Publish", function () {
expect(await messageCollector.waitForMessages(1)).to.eq(false);
});

it("Publish message with size of 1 MB", async function () {
const pushResponse = await waku1.relay.send(TestEncoder, {
payload: generateRandomUint8Array(1024 ** 2)
});
expect(pushResponse.recipients.length).to.eq(1);
expect(pushResponse.recipients[0].toString()).to.eq(
waku2.libp2p.peerId.toString()
);
expect(await messageCollector.waitForMessages(1)).to.eq(true);
});

[1024 ** 2 + 65536, 2 * 1024 ** 2].forEach((testItem) => {
it("Fails to publish message with size larger than 1 MB", async function () {
const pushResponse = await waku1.relay.send(TestEncoder, {
Expand Down
27 changes: 20 additions & 7 deletions packages/utils/src/common/is_size_valid.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import type { IEncoder, IMessage } from "@waku/interfaces";

const MB = 1024 ** 2;
const SIZE_CAP = 1; // 1 MB
const SIZE_CAP_IN_MB = 1;

export const isSizeUnderCap = (payload: Uint8Array): boolean => {
if (payload.length / MB > SIZE_CAP) {
return false;
}
/**
* Return whether the size of the message is under the upper limit for the network.
* This performs a protobuf encoding! If you have access to the fully encoded message,
* use {@link isSizeUnderCapBuf} instead.
* @param message
* @param encoder
*/
export async function isMessageSizeUnderCap(
encoder: IEncoder,
message: IMessage
): Promise<boolean> {
const buf = await encoder.toWire(message);
if (!buf) return false;
return isWireSizeUnderCap(buf);
}

return true;
};
export const isWireSizeUnderCap = (buf: Uint8Array): boolean =>
buf.length / MB <= SIZE_CAP_IN_MB;