Skip to content

Commit

Permalink
perf(net): move hash comparing into worker
Browse files Browse the repository at this point in the history
- Allow host process to specify expected hash and get it compared in the worker.
  • Loading branch information
skjsjhb committed Jan 9, 2025
1 parent 2a8699a commit 9f37c7b
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 15 deletions.
3 changes: 1 addition & 2 deletions src/main/net/dlchk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ async function validate(init: { path: string, sha1?: string, size?: number }): P
const st = await fs.stat(init.path);

if (init.sha1) {
const h = await hash.forFile(init.path, "sha1");
return h.toLowerCase() === init.sha1.toLowerCase() ? "checked" : "failed";
return (await hash.checkFile(init.path, "sha1", init.sha1)) ? "checked" : "failed";
} else if (init.size && init.size > 0) {
return st.size === init.size ? "checked" : "failed";
}
Expand Down
20 changes: 17 additions & 3 deletions src/main/security/hash-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,31 @@ import fs from "node:fs";
export interface HashWorkerData {
path: string;
algorithm: string;
expect?: string;
}

function main() {
const { path, algorithm } = workerData as HashWorkerData;
const { path, algorithm, expect } = workerData as HashWorkerData;

const hash = createHash(algorithm);
const rs = fs.createReadStream(path);

rs.on("data", (chunk) => hash.update(chunk));
rs.on("end", () => parentPort?.postMessage(hash.digest("hex")));
rs.on("error", () => parentPort?.postMessage(""));
rs.once("end", () => {
const h = hash.digest("hex").toLowerCase().trim();
if (expect) {
parentPort?.postMessage(h === expect.toLowerCase().trim());
} else {
parentPort?.postMessage(h);
}
});
rs.once("error", () => {
if (expect) {
parentPort?.postMessage(false);
} else {
parentPort?.postMessage("");
}
});
}

void main();
14 changes: 11 additions & 3 deletions src/main/security/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import type { HashWorkerData } from "@/main/security/hash-worker";
import { Worker } from "node:worker_threads";
import { paths } from "@/main/fs/paths";

async function checkFile(pt: string, algorithm: string, expectHash: string): Promise<boolean> {
return await check(pt, algorithm, expectHash) as boolean;
}

async function forFile(pt: string, algorithm: string): Promise<string> {
const dat: HashWorkerData = { path: pt, algorithm };
return await check(pt, algorithm) as string;
}

async function check(pt: string, algorithm: string, expectHash?: string): Promise<string | boolean> {
const dat: HashWorkerData = { path: pt, algorithm, expect: expectHash };

const w = new Worker(paths.app.to("hash-worker.js"), { workerData: dat });
return new Promise<string>((res, rej) => {
return new Promise<string | boolean>((res, rej) => {
function err() {
rej(`Failed to hash file: ${pt}`);
}
Expand All @@ -20,5 +28,5 @@ async function forFile(pt: string, algorithm: string): Promise<string> {
}

export const hash = {
forFile
forFile, checkFile
};
13 changes: 8 additions & 5 deletions test/instrumented/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ export async function checkHash() {
await iTest.run("Hash File", async () => {
await fs.writeFile("hash-test.txt", "ciallo, world");

const sha1 = await hash.forFile("hash-test.txt", "sha1");
const sha256 = await hash.forFile("hash-test.txt", "sha256");

assert(sha1 === "f7525f9a515602c82385c51b5bb2678d70f111f2", "SHA-1 should match");
assert(sha256 === "7ddfd602ea34e005f781b50de561cd0ac7bb6cb22e5be47dd1f9ad01a5bd64a9", "SHA-256 should match");
assert(
await hash.checkFile("hash-test.txt", "sha1", "f7525f9a515602c82385c51b5bb2678d70f111f2"),
"SHA-1 should match"
);
assert(
await hash.checkFile("hash-test.txt", "sha256", "7ddfd602ea34e005f781b50de561cd0ac7bb6cb22e5be47dd1f9ad01a5bd64a9"),
"SHA-256 should match"
);
});
}
4 changes: 2 additions & 2 deletions test/instrumented/net.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export async function checkFileDownload() {
});

assert(completed === 2, "Task count should match");
assert(await hash.forFile("assetIndex.json", "sha1") === "f3c4aa96e12951cd2781b3e1c0e8ab82bf719cf2", "Hash 1 should match");
assert(await hash.forFile("log.xml", "sha1") === "bd65e7d2e3c237be76cfbef4c2405033d7f91521", "Hash 2 should match");
assert(await hash.checkFile("assetIndex.json", "sha1", "f3c4aa96e12951cd2781b3e1c0e8ab82bf719cf2"), "Hash 1 should match");
assert(await hash.checkFile("log.xml", "sha1", "bd65e7d2e3c237be76cfbef4c2405033d7f91521"), "Hash 2 should match");
});

await iTest.run("NFAT File Reuse", async () => {
Expand Down

0 comments on commit 9f37c7b

Please sign in to comment.