Skip to content

Commit 1905558

Browse files
authored
feat!: re-work messaging parts and sharding (#2399)
* remove message-hash package, move it to core * add js-doc to message hash * up * address type changes * fix lint
1 parent 16328a3 commit 1905558

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+255
-567
lines changed

.release-please-manifest.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"packages/utils": "0.0.23",
33
"packages/proto": "0.0.10",
44
"packages/interfaces": "0.0.30",
5-
"packages/message-hash": "0.1.19",
65
"packages/enr": "0.0.29",
76
"packages/core": "0.0.35",
87
"packages/message-encryption": "0.0.33",

.size-limit.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ module.exports = [
5959
},
6060
{
6161
name: "Deterministic Message Hashing",
62-
path: "packages/message-hash/bundle/index.js",
62+
path: ["packages/core/bundle/index.js"],
6363
import: "{ messageHash }",
6464
},
6565
];

package-lock.json

Lines changed: 3 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"packages/proto",
77
"packages/interfaces",
88
"packages/utils",
9-
"packages/message-hash",
109
"packages/enr",
1110
"packages/core",
1211
"packages/discovery",

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"@waku/proto": "0.0.10",
7575
"@waku/utils": "0.0.23",
7676
"debug": "^4.3.4",
77+
"@noble/hashes": "^1.3.2",
7778
"it-all": "^3.0.4",
7879
"it-length-prefixed": "^9.0.4",
7980
"it-pipe": "^3.0.1",

packages/core/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ export { ConnectionManager } from "./lib/connection_manager/index.js";
2020
export { StreamManager } from "./lib/stream_manager/index.js";
2121

2222
export { MetadataCodec, wakuMetadata } from "./lib/metadata/index.js";
23+
24+
export { messageHash, messageHashStr } from "./lib/message_hash/index.js";

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export { proto };
2222
export class DecodedMessage implements IDecodedMessage {
2323
public constructor(
2424
public pubsubTopic: string,
25-
protected proto: proto.WakuMessage
25+
private proto: proto.WakuMessage
2626
) {}
2727

2828
public get ephemeral(): boolean {
@@ -37,10 +37,6 @@ export class DecodedMessage implements IDecodedMessage {
3737
return this.proto.contentTopic;
3838
}
3939

40-
public get _rawTimestamp(): bigint | undefined {
41-
return this.proto.timestamp;
42-
}
43-
4440
public get timestamp(): Date | undefined {
4541
// In the case we receive a value that is bigger than JS's max number,
4642
// we catch the error and return undefined.
@@ -63,7 +59,7 @@ export class DecodedMessage implements IDecodedMessage {
6359
public get version(): number {
6460
// https://rfc.vac.dev/spec/14/
6561
// > If omitted, the value SHOULD be interpreted as version 0.
66-
return this.proto.version ?? 0;
62+
return this.proto.version ?? Version;
6763
}
6864

6965
public get rateLimitProof(): IRateLimitProof | undefined {
@@ -160,7 +156,7 @@ export class Decoder implements IDecoder<IDecodedMessage> {
160156
public async fromProtoObj(
161157
pubsubTopic: string,
162158
proto: IProtoMessage
163-
): Promise<DecodedMessage | undefined> {
159+
): Promise<IDecodedMessage | undefined> {
164160
// https://rfc.vac.dev/spec/14/
165161
// > If omitted, the value SHOULD be interpreted as version 0.
166162
if (proto.version ?? 0 !== Version) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { messageHash, messageHashStr } from "./message_hash.js";

packages/message-hash/src/index.spec.ts renamed to packages/core/src/lib/message_hash/message_hash.spec.ts

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import type { IDecodedMessage, IProtoMessage } from "@waku/interfaces";
22
import { bytesToHex, hexToBytes } from "@waku/utils/bytes";
33
import { expect } from "chai";
44

5-
import { messageHash } from "./index.js";
5+
import { messageHash, messageHashStr } from "./index.js";
66

77
// https://rfc.vac.dev/spec/14/#test-vectors
8-
describe("RFC Test Vectors", () => {
8+
describe("Message Hash: RFC Test Vectors", () => {
99
it("Waku message hash computation (meta size of 12 bytes)", () => {
1010
const expectedHash =
1111
"64cce733fed134e83da02b02c6f689814872b1a0ac97ea56b76095c3c72bfe05";
@@ -98,6 +98,7 @@ describe("RFC Test Vectors", () => {
9898
"3f11bc950dce0e3ffdcf205ae6414c01130bb5d9f20644869bff80407fa52c8f";
9999
const pubsubTopic = "/waku/2/default-waku/proto";
100100
const message: IDecodedMessage = {
101+
version: 0,
101102
payload: new Uint8Array(),
102103
pubsubTopic,
103104
contentTopic: "/waku/2/default-content/proto",
@@ -110,3 +111,71 @@ describe("RFC Test Vectors", () => {
110111
expect(bytesToHex(hash)).to.equal(expectedHash);
111112
});
112113
});
114+
115+
describe("messageHash and messageHashStr", () => {
116+
const pubsubTopic = "/waku/2/default-waku/proto";
117+
const testMessage: IProtoMessage = {
118+
payload: hexToBytes("0x010203045445535405060708"),
119+
contentTopic: "/waku/2/default-content/proto",
120+
meta: hexToBytes("0x73757065722d736563726574"),
121+
timestamp: BigInt("0x175789bfa23f8400"),
122+
ephemeral: undefined,
123+
rateLimitProof: undefined,
124+
version: undefined
125+
};
126+
127+
it("messageHash returns a Uint8Array", () => {
128+
const hash = messageHash(pubsubTopic, testMessage);
129+
expect(hash).to.be.instanceOf(Uint8Array);
130+
expect(hash.length).to.equal(32); // SHA-256 hash is 32 bytes
131+
});
132+
133+
it("messageHashStr returns a hex string", () => {
134+
const hashStr = messageHashStr(pubsubTopic, testMessage);
135+
expect(typeof hashStr).to.equal("string");
136+
expect(hashStr.length).to.equal(64); // SHA-256 hash is 32 bytes = 64 hex chars
137+
expect(hashStr).to.match(/^[0-9a-f]+$/); // Should be a valid hex string
138+
});
139+
140+
it("messageHashStr returns the same value as bytesToHex(messageHash)", () => {
141+
const hash = messageHash(pubsubTopic, testMessage);
142+
const hashStrFromBytes = bytesToHex(hash);
143+
const hashStr = messageHashStr(pubsubTopic, testMessage);
144+
expect(hashStr).to.equal(hashStrFromBytes);
145+
});
146+
147+
it("messageHashStr works with IDecodedMessage", () => {
148+
const decodedMessage: IDecodedMessage = {
149+
version: 0,
150+
payload: new Uint8Array([1, 2, 3, 4]),
151+
pubsubTopic,
152+
contentTopic: "/waku/2/default-content/proto",
153+
meta: new Uint8Array([5, 6, 7, 8]),
154+
timestamp: new Date("2024-04-30T10:54:14.978Z"),
155+
ephemeral: undefined,
156+
rateLimitProof: undefined
157+
};
158+
159+
const hashStr = messageHashStr(pubsubTopic, decodedMessage);
160+
expect(typeof hashStr).to.equal("string");
161+
expect(hashStr.length).to.equal(64);
162+
});
163+
164+
it("messageHashStr produces consistent results for the same input", () => {
165+
const hashStr1 = messageHashStr(pubsubTopic, testMessage);
166+
const hashStr2 = messageHashStr(pubsubTopic, testMessage);
167+
expect(hashStr1).to.equal(hashStr2);
168+
});
169+
170+
it("messageHashStr produces different results for different inputs", () => {
171+
const hashStr1 = messageHashStr(pubsubTopic, testMessage);
172+
173+
const differentMessage = {
174+
...testMessage,
175+
payload: hexToBytes("0x0102030454455354050607080A") // Different payload
176+
};
177+
178+
const hashStr2 = messageHashStr(pubsubTopic, differentMessage);
179+
expect(hashStr1).to.not.equal(hashStr2);
180+
});
181+
});

packages/message-hash/src/index.ts renamed to packages/core/src/lib/message_hash/message_hash.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@ import {
1111
/**
1212
* Deterministic Message Hashing as defined in
1313
* [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#deterministic-message-hashing)
14+
*
15+
* Computes a SHA-256 hash of the concatenation of pubsub topic, payload, content topic, meta, and timestamp.
16+
*
17+
* @param pubsubTopic - The pubsub topic string
18+
* @param message - The message to be hashed
19+
* @returns A Uint8Array containing the SHA-256 hash
20+
*
21+
* @example
22+
* ```typescript
23+
* import { messageHash } from "@waku/core";
24+
*
25+
* const pubsubTopic = "/waku/2/default-waku/proto";
26+
* const message = {
27+
* payload: new Uint8Array([1, 2, 3, 4]),
28+
* contentTopic: "/waku/2/default-content/proto",
29+
* meta: new Uint8Array([5, 6, 7, 8]),
30+
* timestamp: new Date()
31+
* };
32+
*
33+
* const hash = messageHash(pubsubTopic, message);
34+
* ```
1435
*/
1536
export function messageHash(
1637
pubsubTopic: string,
@@ -51,6 +72,30 @@ function tryConvertTimestampToBytes(
5172
return numberToBytes(bigIntTimestamp);
5273
}
5374

75+
/**
76+
* Computes a deterministic message hash and returns it as a hexadecimal string.
77+
* This is a convenience wrapper around messageHash that converts the result to a hex string.
78+
*
79+
* @param pubsubTopic - The pubsub topic string
80+
* @param message - The message to be hashed
81+
* @returns A string containing the hex representation of the SHA-256 hash
82+
*
83+
* @example
84+
* ```typescript
85+
* import { messageHashStr } from "@waku/core";
86+
*
87+
* const pubsubTopic = "/waku/2/default-waku/proto";
88+
* const message = {
89+
* payload: new Uint8Array([1, 2, 3, 4]),
90+
* contentTopic: "/waku/2/default-content/proto",
91+
* meta: new Uint8Array([5, 6, 7, 8]),
92+
* timestamp: new Date()
93+
* };
94+
*
95+
* const hashString = messageHashStr(pubsubTopic, message);
96+
* console.log(hashString); // e.g. "a1b2c3d4..."
97+
* ```
98+
*/
5499
export function messageHashStr(
55100
pubsubTopic: string,
56101
message: IProtoMessage | IDecodedMessage

0 commit comments

Comments
 (0)