Skip to content

Solve the report endpoint's proof-of-work#116

Merged
Shpigford merged 1 commit into
mainfrom
abuse-layers
Jul 13, 2026
Merged

Solve the report endpoint's proof-of-work#116
Shpigford merged 1 commit into
mainfrom
abuse-layers

Conversation

@Shpigford

Copy link
Copy Markdown
Owner

Pairs with knockoff-backend#4 (already deployed — PoW is enforced in prod now). Fetches the signed challenge from /merchants/challenge and grinds nonces via WebCrypto (sub-second at 14 bits, capped at 15s/8x expected work), payload-bound so solutions can't be replayed across reports. Degrades cleanly: any failure sends the report unproofed, the server declines the vote, local UX unaffected. Difficulty is server-tunable via the challenge response. Verified live on a real seller page: challenge fetched, nonce ground, proof independently re-validated, pioneer toast intact. 219/219 tests, Safari synced. Note: until this ships in a release, v0.7.x installs' votes are declined (~auto-update window).

/merchants/report now requires a proof-of-work bound to the exact report
(part of the backend's abuse layers, with the corroboration gate, subnet
consensus, breaker, and bans). Before reporting, fetch the signed
challenge and grind nonces with WebCrypto until the digest clears the
server's difficulty — sub-second at the current 14 bits, bounded at ~8x
the expected work or 15s. On any failure (old worker, offline, budget
exceeded) the report goes out unproofed and the server declines the
vote; the local experience — toast, passport, counts — is untouched.
The difficulty check lives in the detector for tests; the server can
retune bits via the challenge without an extension release.
@Shpigford Shpigford merged commit 5c5fe68 into main Jul 13, 2026
@Shpigford Shpigford deleted the abuse-layers branch July 13, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant