2022-04-11 19:10:42 +00:00
|
|
|
import {spawn, Pool, Worker, Thread} from "@chainsafe/threads";
|
2022-04-14 17:16:06 +00:00
|
|
|
import {Implementation, PointFormat, PublicKey, Signature} from "../../../../src/types.js";
|
2022-04-11 15:08:15 +00:00
|
|
|
import {WorkerApi} from "./worker.js";
|
2021-04-04 23:44:55 +00:00
|
|
|
|
|
|
|
type ThreadType = {
|
|
|
|
[K in keyof WorkerApi]: (...args: Parameters<WorkerApi[K]>) => Promise<ReturnType<WorkerApi[K]>>;
|
|
|
|
};
|
|
|
|
|
2022-04-11 19:10:42 +00:00
|
|
|
import path from "path";
|
|
|
|
import {fileURLToPath} from "url";
|
|
|
|
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
|
2021-04-04 23:44:55 +00:00
|
|
|
export class BlsMultiThreadNaive {
|
|
|
|
impl: Implementation;
|
|
|
|
pool: Pool<Thread & ThreadType>;
|
|
|
|
format: PointFormat;
|
|
|
|
|
|
|
|
constructor(impl: Implementation, workerCount?: number) {
|
|
|
|
this.impl = impl;
|
|
|
|
// Use compressed for herumi for now.
|
|
|
|
// THe worker is not able to deserialize from uncompressed
|
|
|
|
// `Error: err _wrapDeserialize`
|
|
|
|
this.format = impl === "blst-native" ? PointFormat.uncompressed : PointFormat.compressed;
|
2022-04-11 19:10:42 +00:00
|
|
|
this.pool = Pool(
|
|
|
|
() =>
|
|
|
|
(spawn(
|
|
|
|
// There is still an annoyance dealing with ESM imports here:
|
|
|
|
// threads.js attempts to require.resolve any files passed to Worker, and
|
|
|
|
// the esm module resolver requires the .js extension, even though the .js file does not actually exist.
|
|
|
|
// The solution for now:
|
|
|
|
// Pass in the script path as an absolute path and suppress threads.js default behavior when importing
|
|
|
|
new Worker(path.join(__dirname, "./worker.js"), {suppressResolveScript: true, suppressTranspileTS: true})
|
|
|
|
) as any) as Promise<Thread & ThreadType>,
|
|
|
|
workerCount
|
|
|
|
);
|
2021-04-04 23:44:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async destroy(): Promise<void> {
|
|
|
|
await this.pool.terminate(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
async verify(pk: PublicKey, msg: Uint8Array, sig: Signature): Promise<boolean> {
|
|
|
|
return this.pool.queue((worker) =>
|
|
|
|
worker.verify(this.impl, pk.toBytes(PointFormat.uncompressed), msg, sig.toBytes(PointFormat.uncompressed))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
async verifyMultipleAggregateSignatures(
|
|
|
|
sets: {publicKey: PublicKey; message: Uint8Array; signature: Signature}[]
|
|
|
|
): Promise<boolean> {
|
|
|
|
return this.pool.queue((worker) =>
|
|
|
|
worker.verifyMultipleAggregateSignatures(
|
|
|
|
this.impl,
|
|
|
|
sets.map((s) => ({
|
|
|
|
publicKey: s.publicKey.toBytes(PointFormat.uncompressed),
|
|
|
|
message: s.message,
|
|
|
|
signature: s.signature.toBytes(PointFormat.uncompressed),
|
|
|
|
}))
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|