diff options
| author | Gab Virebent <gabriel1@virebent.art> | 2026-07-01 17:48:59 +0200 |
|---|---|---|
| committer | Gab Virebent <gabriel1@virebent.art> | 2026-07-01 17:48:59 +0200 |
| commit | 4da18fe598f243c777d330ba9d50f1ecd4382b05 (patch) | |
| tree | 2c85d6e987b6a1c4226f2aff81e89972939ff166 | |
| parent | 78d57b1090a5a23abce2a732f091a4ef007d60cc (diff) | |
| download | nymdrop-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.js | 10 |
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 } } |
