Skip to content

fix: stop slow ALTCHA solves from rejecting real submissions - #8

Merged
oxyc merged 2 commits into
mainfrom
fix/slow-solve-hard-failure
Oct 19, 2026
Merged

oxyc merged 2 commits into
mainfrom
fix/slow-solve-hard-failure

Conversation

@oxyc

@oxyc oxyc commented Oct 19, 2026

Copy link
Copy Markdown
Member

Problem

Snellman reported intermittent "Sorry, your submission could not be verified" on forms 43/45 (cost set to Very high, 1M), with ALTCHA [name=altcha] verification failed Error: Failed to find solution. in the console. The GF log shows every rejection as reason: missing, in bursts of retries seconds apart.

  • auto="onload" only starts the proof; submitting before it finishes posts an empty altcha field.
  • A rejected AJAX submit re-renders the form, so the proof restarts from zero and quick retries fail the same way.
  • A solve that hits the widget's 90s timeout leaves it in error and is never retried.
  • Browser WebCrypto PBKDF2 measured ~1M iterations/s per core (Chromium, M-series Mac), so 1M cost averages ~25s on a fast 10-core desktop and exceeds 90s on an ordinary laptop. The old labels (~20s) were off by an order of magnitude on slower hardware.

Changes

  • Hold GF submissions via the async gform/submission/pre_submission filter until the proof is solved or has failed for good. GF keeps its spinner up meanwhile.
  • On error, fetch a fresh challenge and retry, capped at 3 retries.
  • Corrected strength labels and README guidance.

Tested

Against snellmanrecipes locally (form 43, cost 1M), with this build swapped in:

  • Submit immediately after load → waited for the proof, entry accepted (82s).
  • Forced timeout on the first solve → retried with a fresh challenge, verified.
  • Every attempt forced to time out → retries stopped at the cap and the submit finished with the server's "reload" message (no hang).
  • composer test (67 tests) and composer lint pass.

🤖 Generated with Claude Code

oxyc and others added 2 commits October 19, 2026 12:34
A form submitted before the background proof finished posted an empty
altcha field (logged as reason=missing), and the AJAX re-render restarted
the proof from zero so quick retries failed the same way. A solve that hit
the widget's 90s timeout ("Failed to find solution.") was never retried.

- Hold Gravity Forms submissions in gform/submission/pre_submission until
  the proof is solved (or has failed for good).
- Retry a failed solve with a fresh challenge, up to 3 times.
- Correct the strength labels: browser PBKDF2 runs ~1M iterations/s per
  core, so Very high (1M) averages ~25s on a fast desktop and exceeds the
  90s timeout on ordinary laptops.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oxyc
oxyc merged commit a87867a into main Oct 19, 2026
5 checks passed
@oxyc
oxyc deleted the fix/slow-solve-hard-failure branch October 19, 2026 16:13
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