diff --git a/package-lock.json b/package-lock.json index 2ea0e1d..d464eaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "eslint-plugin-functional": "^4.0.2", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", - "fast-check": "^2.14.0", + "fast-check": "^2.25.0", "gh-pages": "^3.2.3", "husky": "^7.0.4", "ignore-loader": "^0.1.2", @@ -5052,8 +5052,9 @@ }, "node_modules/fast-check": { "version": "2.25.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", + "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", "dev": true, - "license": "MIT", "dependencies": { "pure-rand": "^5.0.1" }, @@ -14684,6 +14685,8 @@ }, "fast-check": { "version": "2.25.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.25.0.tgz", + "integrity": "sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg==", "dev": true, "requires": { "pure-rand": "^5.0.1" diff --git a/package.json b/package.json index 5f2cd3c..e2b93ba 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "eslint-plugin-functional": "^4.0.2", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", - "fast-check": "^2.14.0", + "fast-check": "^2.25.0", "gh-pages": "^3.2.3", "husky": "^7.0.4", "ignore-loader": "^0.1.2", diff --git a/src/epoch.spec.ts b/src/epoch.spec.ts new file mode 100644 index 0000000..ac06245 --- /dev/null +++ b/src/epoch.spec.ts @@ -0,0 +1,17 @@ +import { expect } from "chai"; +import fc from "fast-check"; + +import { epochBytesToInt, epochIntToBytes } from "./epoch.js"; + +describe("epoch serialization", () => { + it("Round trip", async function () { + await fc.assert( + fc.asyncProperty(fc.integer({ min: 0 }), async (date) => { + const bytes = epochIntToBytes(date); + const _date = epochBytesToInt(bytes); + + expect(_date.valueOf()).to.eq(date.valueOf()); + }) + ); + }); +}); diff --git a/src/epoch.ts b/src/epoch.ts index 3a14bd2..b87c975 100644 --- a/src/epoch.ts +++ b/src/epoch.ts @@ -5,7 +5,16 @@ const DefaultEpochUnitSeconds = 10; // the rln-relay epoch length in seconds export function dateToEpoch( timestamp: Date, epochUnitSeconds: number = DefaultEpochUnitSeconds -): Uint8Array { - const unix = Math.floor(timestamp.getTime() / 1000 / epochUnitSeconds); - return writeUIntLE(new Uint8Array(32), unix, 0, 8); +): number { + const time = timestamp.getTime(); + return Math.floor(time / 1000 / epochUnitSeconds); +} + +export function epochIntToBytes(epoch: number): Uint8Array { + return writeUIntLE(new Uint8Array(32), epoch, 0, 8); +} + +export function epochBytesToInt(bytes: Uint8Array): number { + const dv = new DataView(bytes.buffer); + return dv.getUint32(0, true); } diff --git a/src/rln.ts b/src/rln.ts index d82931d..62b04b5 100644 --- a/src/rln.ts +++ b/src/rln.ts @@ -2,7 +2,7 @@ import init, * as zerokitRLN from "@waku/zerokit-rln-wasm"; import { RateLimitProof } from "js-waku/lib/interfaces"; import { writeUIntLE } from "./byte_utils.js"; -import { dateToEpoch } from "./epoch.js"; +import { dateToEpoch, epochIntToBytes } from "./epoch.js"; import verificationKey from "./resources/verification_key.js"; import * as wc from "./witness_calculator.js"; import { WitnessCalculator } from "./witness_calculator.js"; @@ -152,9 +152,9 @@ export class RLNInstance { idKey: Uint8Array ): Promise { if (epoch == undefined) { - epoch = dateToEpoch(new Date()); + epoch = epochIntToBytes(dateToEpoch(new Date())); } else if (epoch instanceof Date) { - epoch = dateToEpoch(epoch); + epoch = epochIntToBytes(dateToEpoch(epoch)); } if (epoch.length != 32) throw "invalid epoch";