feat: POW miner
This commit is contained in:
56
packages/system/src/pow.ts
Normal file
56
packages/system/src/pow.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { NostrEvent } from "./nostr";
|
||||
import { PowWorkerMessage } from "./pow-worker";
|
||||
|
||||
export interface PowMiner {
|
||||
minePow(ev: NostrEvent, target: number): Promise<NostrEvent>;
|
||||
}
|
||||
|
||||
interface PowQueue {
|
||||
resolve: (ev: NostrEvent) => void;
|
||||
reject: () => void;
|
||||
timeout: ReturnType<typeof setTimeout>;
|
||||
}
|
||||
|
||||
export class PowWorker implements PowMiner {
|
||||
#worker: Worker;
|
||||
#queue: Map<string, PowQueue> = new Map();
|
||||
|
||||
constructor(script: string) {
|
||||
this.#worker = new Worker(script, {
|
||||
name: "POW",
|
||||
});
|
||||
this.#worker.onerror = ev => {
|
||||
console.error(ev);
|
||||
};
|
||||
this.#worker.onmessage = ev => {
|
||||
const data = ev.data as PowWorkerMessage;
|
||||
const job = this.#queue.get(data.id);
|
||||
if (job) {
|
||||
clearTimeout(job.timeout);
|
||||
this.#queue.delete(data.id);
|
||||
job.resolve(data.event);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
minePow(ev: NostrEvent, target: number) {
|
||||
return new Promise<NostrEvent>((resolve, reject) => {
|
||||
const req = {
|
||||
id: uuid(),
|
||||
cmd: "req",
|
||||
event: ev,
|
||||
target,
|
||||
} as PowWorkerMessage;
|
||||
this.#queue.set(req.id, {
|
||||
resolve: ex => resolve(ex),
|
||||
reject,
|
||||
timeout: setTimeout(() => {
|
||||
this.#queue.delete(req.id);
|
||||
reject();
|
||||
}, 600_000),
|
||||
});
|
||||
this.#worker.postMessage(req);
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user