From 748f14cec94a06408c54972e7b2d47a88886d261 Mon Sep 17 00:00:00 2001 From: "fryorcraken.eth" Date: Fri, 30 Sep 2022 14:25:44 +1000 Subject: [PATCH] fix: ensure proof is attached when decoding --- package-lock.json | 14 +++++------ package.json | 2 +- src/codec.spec.ts | 61 ++++++++++++++++++++++++++++++++++++++++++----- src/codec.ts | 40 ++++++++++++++++++------------- src/message.ts | 2 +- 5 files changed, 88 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index d464eaa..4d50970 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "husky": "^7.0.4", "ignore-loader": "^0.1.2", "isomorphic-fetch": "^3.0.0", - "js-waku": "^0.29.0-7714812", + "js-waku": "^0.29.0-29436ea", "jsdom": "^19.0.0", "jsdom-global": "^3.0.2", "karma": "^6.3.12", @@ -6648,9 +6648,9 @@ "license": "MIT" }, "node_modules/js-waku": { - "version": "0.29.0-7714812", - "resolved": "https://registry.npmjs.org/js-waku/-/js-waku-0.29.0-7714812.tgz", - "integrity": "sha512-pHX7cvrLC8Yw0KxTa8KJlFcE9S5WLkBWqd0pWqBWGCG5mU1Q6LWBZv+rOYuhn9wkCCpjF5jWJvmTohzkGt91XA==", + "version": "0.29.0-29436ea", + "resolved": "https://registry.npmjs.org/js-waku/-/js-waku-0.29.0-29436ea.tgz", + "integrity": "sha512-I2rbC4X0Ho5jnLQp+5V7jqVBk0OY11+mR8zh2HFbPo3m3ifqYaASeMmdE7fFQ/LY0uUFx1qphJq/0X+agD91wA==", "dev": true, "dependencies": { "@chainsafe/libp2p-gossipsub": "^4.1.1", @@ -15734,9 +15734,9 @@ "dev": true }, "js-waku": { - "version": "0.29.0-7714812", - "resolved": "https://registry.npmjs.org/js-waku/-/js-waku-0.29.0-7714812.tgz", - "integrity": "sha512-pHX7cvrLC8Yw0KxTa8KJlFcE9S5WLkBWqd0pWqBWGCG5mU1Q6LWBZv+rOYuhn9wkCCpjF5jWJvmTohzkGt91XA==", + "version": "0.29.0-29436ea", + "resolved": "https://registry.npmjs.org/js-waku/-/js-waku-0.29.0-29436ea.tgz", + "integrity": "sha512-I2rbC4X0Ho5jnLQp+5V7jqVBk0OY11+mR8zh2HFbPo3m3ifqYaASeMmdE7fFQ/LY0uUFx1qphJq/0X+agD91wA==", "dev": true, "requires": { "@chainsafe/libp2p-gossipsub": "^4.1.1", diff --git a/package.json b/package.json index e2b93ba..a51bfa5 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "husky": "^7.0.4", "ignore-loader": "^0.1.2", "isomorphic-fetch": "^3.0.0", - "js-waku": "^0.29.0-7714812", + "js-waku": "^0.29.0-29436ea", "jsdom": "^19.0.0", "jsdom-global": "^3.0.2", "karma": "^6.3.12", diff --git a/src/codec.spec.ts b/src/codec.spec.ts index 2e8305c..a7e2bc3 100644 --- a/src/codec.spec.ts +++ b/src/codec.spec.ts @@ -1,14 +1,19 @@ import { expect } from "chai"; -import { DecoderV0, EncoderV0 } from "js-waku/lib/waku_message/version_0"; +import { + DecoderV0, + EncoderV0, + MessageV0, +} from "js-waku/lib/waku_message/version_0"; import { RLNDecoder, RLNEncoder } from "./codec.js"; +import { RlnMessage } from "./message.js"; import * as rln from "./index.js"; const TestContentTopic = "/test/1/waku-message/utf8"; describe("js-rln: encoder", () => { - it("should attach a proof to a waku message", async function () { + it("should attach a proof to a waku message when using toWire", async function () { const rlnInstance = await rln.create(); const memKeys = rlnInstance.generateMembershipKey(); const index = 0; @@ -27,13 +32,57 @@ describe("js-rln: encoder", () => { new DecoderV0(TestContentTopic) ); - const bytes = await rlnEncoder.encode({ payload }); - const protoResult = await rlnDecoder.decodeProto(bytes!); + const bytes = await rlnEncoder.toWire({ payload }); - const msg = (await rlnDecoder.decode(protoResult!))!; + expect(bytes).to.not.be.undefined; + const protoResult = await rlnDecoder.fromWireToProtoObj(bytes!); - // Validate proof + expect(protoResult).to.not.be.undefined; + const msg = (await rlnDecoder.fromProtoObj(protoResult!))!; + + expect(msg.rateLimitProof).to.not.be.undefined; expect(msg.verify()).to.be.true; + expect(msg.epoch).to.not.be.undefined; + expect(msg.epoch).to.be.gt(0); + + expect(msg.contentTopic).to.eq(TestContentTopic); + expect(msg.msg.version).to.eq(0); + expect(msg.payload).to.deep.eq(payload); + expect(msg.timestamp).to.not.be.undefined; + }); + + it("should attach a proof to a waku message when using toProtoObj", async function () { + const rlnInstance = await rln.create(); + const memKeys = rlnInstance.generateMembershipKey(); + const index = 0; + const payload = new Uint8Array([1, 2, 3, 4, 5]); + + rlnInstance.insertMember(memKeys.IDCommitment); + + const rlnEncoder = new RLNEncoder( + new EncoderV0(TestContentTopic), + rlnInstance, + index, + memKeys + ); + const rlnDecoder = new RLNDecoder( + rlnInstance, + new DecoderV0(TestContentTopic) + ); + + const proto = await rlnEncoder.toProtoObj({ payload }); + + expect(proto).to.not.be.undefined; + const msg = (await rlnDecoder.fromProtoObj( + proto! + )) as RlnMessage; + + expect(msg).to.not.be.undefined; + expect(msg.rateLimitProof).to.not.be.undefined; + + expect(msg.verify()).to.be.true; + expect(msg.epoch).to.not.be.undefined; + expect(msg.epoch).to.be.gt(0); expect(msg.contentTopic).to.eq(TestContentTopic); expect(msg.msg.version).to.eq(0); diff --git a/src/codec.ts b/src/codec.ts index 265f149..c4d789c 100644 --- a/src/codec.ts +++ b/src/codec.ts @@ -1,10 +1,11 @@ import debug from "debug"; -import { proto_message, utils } from "js-waku"; +import { utils } from "js-waku"; import { Decoder, Encoder, Message, ProtoMessage, + RateLimitProof, } from "js-waku/lib/interfaces"; import { RlnMessage } from "./message.js"; @@ -27,16 +28,26 @@ export class RLNEncoder implements Encoder { this.contentTopic = encoder.contentTopic; } - async encode(message: Message): Promise { - const protoMessage = await this.encodeProto(message); - if (!protoMessage) return; - return proto_message.WakuMessage.encode(protoMessage); + async toWire(message: Partial): Promise { + message.rateLimitProof = await this.generateProof(message); + + return this.encoder.toWire(message); } - async encodeProto(message: Message): Promise { - const protoMessage = await this.encoder.encodeProto(message); + async toProtoObj( + message: Partial + ): Promise { + const protoMessage = await this.encoder.toProtoObj(message); if (!protoMessage) return; + protoMessage.rateLimitProof = await this.generateProof(message); + + return protoMessage; + } + + private async generateProof( + message: Partial + ): Promise { const signal = toRLNSignal(message); console.time("proof_gen_timer"); @@ -47,10 +58,7 @@ export class RLNEncoder implements Encoder { this.idKey ); console.timeEnd("proof_gen_timer"); - - protoMessage.rateLimitProof = proof; - - return protoMessage; + return proof; } } @@ -61,20 +69,20 @@ export class RLNDecoder implements Decoder> { return this.decoder.contentTopic; } - decodeProto(bytes: Uint8Array): Promise { - const protoMessage = proto_message.WakuMessage.decode(bytes); + fromWireToProtoObj(bytes: Uint8Array): Promise { + const protoMessage = this.decoder.fromWireToProtoObj(bytes); log("Message decoded", protoMessage); return Promise.resolve(protoMessage); } - async decode(proto: ProtoMessage): Promise | undefined> { - const msg: T | undefined = await this.decoder.decode(proto); + async fromProtoObj(proto: ProtoMessage): Promise | undefined> { + const msg: T | undefined = await this.decoder.fromProtoObj(proto); if (!msg) return; return new RlnMessage(this.rlnInstance, msg, proto.rateLimitProof); } } -function toRLNSignal(msg: Message): Uint8Array { +function toRLNSignal(msg: Partial): Uint8Array { const contentTopicBytes = utils.utf8ToBytes(msg.contentTopic ?? ""); return new Uint8Array([...(msg.payload ?? []), ...contentTopicBytes]); } diff --git a/src/message.ts b/src/message.ts index ab6d45a..a0df079 100644 --- a/src/message.ts +++ b/src/message.ts @@ -7,7 +7,7 @@ export class RlnMessage implements Message { constructor( public rlnInstance: RLNInstance, public msg: T, - public rateLimitProof?: RateLimitProof + public rateLimitProof: RateLimitProof | undefined ) {} public verify(): boolean | undefined {