nuke/web/js/worker/sha256-purejs.mjs
Xe Iaso c661bc37d1
fix(worker): constrain nonce value to be a whole integer (#1045)
* fix(worker): constrain nonce value to be a whole integer

Closes #1043

Sometimes the worker could get into a strange state where it has a
decimal nonce, but the server assumes that the nonce can only be a whole
number. This patch constrains the nonce to be a whole number on the
worker end by detecting if the nonce is a decimal number and then
truncating away the decimal portion.

Signed-off-by: Xe Iaso <me@xeiaso.net>

* chore: spelling

Signed-off-by: Xe Iaso <me@xeiaso.net>

* fix(algorithms/fast): truncate decimal place on number of threads

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-08-26 14:05:03 -04:00

73 lines
No EOL
1.7 KiB
JavaScript

import { Sha256 } from '@aws-crypto/sha256-js';
const calculateSHA256 = (text) => {
const hash = new Sha256();
hash.update(text);
return hash.digest();
};
function toHexString(arr) {
return Array.from(arr)
.map((c) => c.toString(16).padStart(2, "0"))
.join("");
}
addEventListener('message', async ({ data: eventData }) => {
const { data, difficulty, threads } = eventData;
let nonce = eventData.nonce;
const isMainThread = nonce === 0;
let iterations = 0;
const requiredZeroBytes = Math.floor(difficulty / 2);
const isDifficultyOdd = difficulty % 2 !== 0;
for (; ;) {
const hashBuffer = await calculateSHA256(data + nonce);
const hashArray = new Uint8Array(hashBuffer);
let isValid = true;
for (let i = 0; i < requiredZeroBytes; i++) {
if (hashArray[i] !== 0) {
isValid = false;
break;
}
}
if (isValid && isDifficultyOdd) {
if ((hashArray[requiredZeroBytes] >> 4) !== 0) {
isValid = false;
}
}
if (isValid) {
const finalHash = toHexString(hashArray);
postMessage({
hash: finalHash,
data,
difficulty,
nonce,
});
return; // Exit worker
}
nonce += threads;
iterations++;
/* Truncate the decimal portion of the nonce. This is a bit of an evil bit
* hack, but it works reliably enough. The core of why this works is:
*
* > 13.4 % 1 !== 0
* true
* > 13 % 1 !== 0
* false
*/
if (nonce % 1 !== 0) {
nonce = Math.trunc(nonce);
}
// Send a progress update from the main thread every 1024 iterations.
if (isMainThread && (iterations & 1023) === 0) {
postMessage(nonce);
}
}
});