From c661bc37d133976a005fb0b1060e3e0a34f69003 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Tue, 26 Aug 2025 15:05:03 -0300 Subject: [PATCH] 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 * chore: spelling Signed-off-by: Xe Iaso * fix(algorithms/fast): truncate decimal place on number of threads Signed-off-by: Xe Iaso --------- Signed-off-by: Xe Iaso --- .github/actions/spelling/expect.txt | 1 + docs/docs/CHANGELOG.md | 2 ++ web/js/algorithms/fast.mjs | 2 +- web/js/worker/sha256-purejs.mjs | 12 ++++++++++++ web/js/worker/sha256-webcrypto.mjs | 12 ++++++++++++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index e1d77b3..2ef91ce 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -304,6 +304,7 @@ Tik Timpibot TLog traefik +trunc uberspace Unbreak unbreakdocker diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md index e6a659f..bd5e1ae 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] + - Added a missing link to the Caddy installation environment in the installation documentation. - Downstream consumers can change the default [log/slog#Logger](https://pkg.go.dev/log/slog#Logger) instance that Anubis uses by setting `opts.Logger` to your slog instance of choice ([#864](https://github.com/TecharoHQ/anubis/issues/864)). - The [Thoth client](https://anubis.techaro.lol/docs/admin/thoth) is now public in the repo instead of being an internal package. @@ -30,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The hard dependency on WebCrypto has been removed, allowing a proof of work challenge to work over plain (unencrypted) HTTP. - Firefox for Android support has been fixed by embedding the challenge ID into the pass-challenge route. This also fixes some inconsistent issues with other mobile browsers. - The Anubis version number is put in the footer of every page. +- Prevent the proof of work nonce from being a decimal value by using Math.trunc to coerce it back to an integer if it happens ([#1043](https://github.com/TecharoHQ/anubis/issues/1043)). - The legacy JSON based policy file example has been removed and all documentation for how to write a policy file in JSON has been deleted. JSON based policy files will still work, but YAML is the superior option for Anubis configuration. - A standard library HTTP server log message about HTTP pipelining not working has been filtered out of Anubis' logs. There is no action that can be taken about it. - The default `favicon` pattern in `data/common/keep-internet-working.yaml` has been updated to permit requests for png/gif/jpg/svg files as well as ico. diff --git a/web/js/algorithms/fast.mjs b/web/js/algorithms/fast.mjs index 4175e35..ee08a19 100644 --- a/web/js/algorithms/fast.mjs +++ b/web/js/algorithms/fast.mjs @@ -4,7 +4,7 @@ export default function process( difficulty = 5, signal = null, progressCallback = null, - threads = Math.max(navigator.hardwareConcurrency / 2, 1), + threads = Math.trunc(Math.max(navigator.hardwareConcurrency / 2, 1)), ) { console.debug("fast algo"); diff --git a/web/js/worker/sha256-purejs.mjs b/web/js/worker/sha256-purejs.mjs index 96a6014..3211b44 100644 --- a/web/js/worker/sha256-purejs.mjs +++ b/web/js/worker/sha256-purejs.mjs @@ -53,6 +53,18 @@ addEventListener('message', async ({ data: eventData }) => { 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); diff --git a/web/js/worker/sha256-webcrypto.mjs b/web/js/worker/sha256-webcrypto.mjs index 97466fb..c2b071a 100644 --- a/web/js/worker/sha256-webcrypto.mjs +++ b/web/js/worker/sha256-webcrypto.mjs @@ -49,6 +49,18 @@ addEventListener("message", async ({ data: eventData }) => { 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);