Skip to content

Split vote proving from persistence - #203

Merged
p0mvn merged 9 commits into
mainfrom
feat/split-vote-proving
Aug 22, 2026
Merged

Split vote proving from persistence#203
p0mvn merged 9 commits into
mainfrom
feat/split-vote-proving

Conversation

@p0mvn

@p0mvn p0mvn commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Motivation / Why

Holding SQLite while generating vote proofs blocks concurrent wallet work. Separating preparation from persistence keeps proving outside the transaction while optimistic state validation prevents stale results from being committed.

Notes

  • Rebased onto main after Update crypto and PIR dependencies #202 merged; base retargeted from chore/update-crypto-pir-dependencies to main.
  • Now prepares 3.1.0-rc.7, not rc.6 — rc.6 was published from Update crypto and PIR dependencies #202 with the crypto/PIR dependency update.
  • No dependency changes: the only manifest edit versus main is the crate version bump. The Zakura wallet pins are inherited from the published rc.6 release.

Tests

  • cargo test --workspace --locked
  • cargo test -p zcash_voting --features test-fixtures --locked
  • cargo test -p zcash_voting -p zcash-voting-wallet-example --all-targets --no-default-features --features zakura --locked
  • 1674 tests passed, 0 failed
  • git diff --check

@p0mvn p0mvn mentioned this pull request Aug 22, 2026
6 tasks
p0mvn and others added 7 commits August 21, 2026 22:20
Prepare ZKP2 commitments outside SQLite and atomically reject stale bundle state before persisting concurrent vote work.
Document the split proving API and finalize the primary crate prerelease on top
of the supporting dependency releases.

rc.6 was published from #202 with the crypto and PIR dependency update, so the
split-proving API lands in rc.7 instead.
Group round, drafts, witness, and stage reporter into one input so the
prepare path stays (db, signer, batch).
Keep the dependency label intact after the VoteCommitBatch note edit.
Reject prepared and recovered vote handoffs when their wallet or proof inputs become stale before persistence.
Opening a voting database left SQLite's busy timeout at its default of zero, so
any write that raced another connection's transaction failed immediately with
SQLITE_BUSY rather than waiting for it to finish. A wallet that keeps a second
connection open -- or runs vote proving alongside persistence -- could see a
write fail on a lock that would have cleared in milliseconds.

Set a 5 second busy timeout when the connection is opened, and cover it with a
test that holds BEGIN IMMEDIATE on a second connection and asserts the write
waits for the rollback instead of returning an error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UULDTCWGE87MXSECGPyT61
Capturing the full preparation state first meant a mismatched signer network
surfaced as "failed to load ZKP2 inputs ... Query returned no rows" from the
state lookup, because the ZKP2 query runs before anything compares networks. A
caller passing Mainnet against a Testnet round got a missing-row error naming
the round and bundle instead of the mismatch that actually caused it.

Load the round network and validate it before capturing state, which is the
order the pre-refactor path used and the order
test_prepare_vote_commitment_rejects_network_mismatch_before_zkp2_inputs
expects.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UULDTCWGE87MXSECGPyT61
@p0mvn
p0mvn force-pushed the feat/split-vote-proving branch from 014786f to 57205b6 Compare August 22, 2026 04:31
@p0mvn
p0mvn changed the base branch from chore/update-crypto-pir-dependencies to main August 22, 2026 04:31
@p0mvn
p0mvn marked this pull request as ready for review August 22, 2026 04:41
Comment on lines +90 to +93
conn.busy_timeout(SQLITE_BUSY_TIMEOUT)
.map_err(|e| VotingError::Internal {
message: format!("failed to configure database busy timeout: {}", e),
})?;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this is a drive-by from code reviews, stems from adding concurrency

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit worried about this change because it applies globally. But in manual tests, did not observe any issues.

Mentioning for reviewer visibility

@p0mvn

p0mvn commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread zcash_voting/src/vote.rs Outdated
A deferred read-validate-write can pass the optimistic check on a stale
snapshot and then fail with SQLITE_BUSY instead of rejecting stale state.
@p0mvn

p0mvn commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit b30b821. Configure here.

@p0mvn
p0mvn merged commit 679c982 into main Aug 22, 2026
17 checks passed
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.

2 participants