31 lines
1.2 KiB
JavaScript
31 lines
1.2 KiB
JavaScript
// Solves the server's proof-of-work bot check (see BotCheckChallenge) in parallel web workers, so the page stays
|
|
// responsive. Resolves with the number, or -1 if none was found.
|
|
export function solve(salt, hash, maxNumber) {
|
|
const workerCount = Math.max(1, Math.min(navigator.hardwareConcurrency || 2, 8));
|
|
const sliceSize = Math.ceil((maxNumber + 1) / workerCount);
|
|
const workerUrl = new URL('./bot-check-worker.js', import.meta.url);
|
|
|
|
return new Promise(resolve => {
|
|
const workers = [];
|
|
let running = workerCount;
|
|
const finish = result => {
|
|
workers.forEach(worker => worker.terminate());
|
|
resolve(result);
|
|
};
|
|
const sliceDone = () => {
|
|
if (--running === 0) {
|
|
finish(-1);
|
|
}
|
|
};
|
|
|
|
for (let i = 0; i < workerCount; i++) {
|
|
const worker = new Worker(workerUrl);
|
|
workers.push(worker);
|
|
worker.onmessage = ({ data }) => data >= 0 ? finish(data) : sliceDone();
|
|
worker.onerror = sliceDone;
|
|
|
|
const start = i * sliceSize;
|
|
worker.postMessage({ salt, hash, start, end: Math.min(start + sliceSize - 1, maxNumber) });
|
|
}
|
|
});
|
|
}
|