summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGab Virebent <gabriel1@virebent.art>2026-07-01 17:48:59 +0200
committerGab Virebent <gabriel1@virebent.art>2026-07-01 17:48:59 +0200
commit4da18fe598f243c777d330ba9d50f1ecd4382b05 (patch)
tree2c85d6e987b6a1c4226f2aff81e89972939ff166
parent78d57b1090a5a23abce2a732f091a4ef007d60cc (diff)
downloadnymdrop-4da18fe598f243c777d330ba9d50f1ecd4382b05.tar.gz
nymdrop-4da18fe598f243c777d330ba9d50f1ecd4382b05.tar.xz
nymdrop-4da18fe598f243c777d330ba9d50f1ecd4382b05.zip
Fix PoW status message never rendering in the browser
A tight loop of only-awaited crypto.subtle.digest calls never yields to the browser's rendering pipeline (they resolve as microtasks), so the "computing proof of work" status update was silently skipped from the user's perspective even though the computation ran correctly. Insert an explicit macrotask yield before and periodically during the search so the message actually paints and the tab stays responsive.
-rw-r--r--static/crypto.js10
1 files changed, 10 insertions, 0 deletions
diff --git a/static/crypto.js b/static/crypto.js
index 0455958..04a1400 100644
--- a/static/crypto.js
+++ b/static/crypto.js
@@ -25,6 +25,14 @@ function leadingZeroBits(bytes) {
return count;
}
+// A loop of only-awaited microtasks (like crypto.subtle.digest) never gives
+// the browser a chance to paint — the event loop keeps draining microtasks
+// before it's willing to render a frame. A macrotask yield (setTimeout) is
+// what actually lets a pending DOM update (e.g. a status message) show up.
+function yieldToBrowser() {
+ return new Promise((resolve) => setTimeout(resolve, 0));
+}
+
// Self-contained hashcash-style proof of work: no challenge round-trip with
// the server. Finds a nonce such that SHA-256("<unix-ts>:<nonce>") has at
// least `difficultyBits` leading zero bits. The server only verifies this,
@@ -32,12 +40,14 @@ function leadingZeroBits(bytes) {
async function computeProofOfWork(difficultyBits) {
const encoder = new TextEncoder();
const ts = Math.floor(Date.now() / 1000);
+ await yieldToBrowser(); // let the "computing proof of work" message paint first
for (let nonce = 0; ; nonce++) {
const stamp = ts + ":" + nonce;
const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(stamp)));
if (leadingZeroBits(hash) >= difficultyBits) {
return stamp;
}
+ if (nonce % 2000 === 0) await yieldToBrowser(); // keep the tab responsive
}
}