feat(cashu): restore/monitor in-flight locked escrows — Track A TA-3#831
feat(cashu): restore/monitor in-flight locked escrows — Track A TA-3#831grunch wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d39115ca60
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| continue; | ||
| }; | ||
|
|
||
| match cashu_client.check_token_unspent(token).await { |
There was a problem hiding this comment.
Verify the stored mint before checking state
When an operator changes [cashu].mint_url while there are locked rows from the previous mint, this calls NUT-07 on the newly configured client without comparing the stored order.cashu_mint_url (or the token's mint URL) to cashu_client.mint_url(). Since checkstate only receives Y values and the existing verifier notes that unknown secrets can be reported Unspent, the restore log can mark an escrow from another mint as live even though this daemon is no longer connected to the mint that issued/redeems it; guard the mint URL before treating Ok(true) as live.
Useful? React with 👍 / 👎.
|
|
||
| // Re-hydrate in-flight locked escrows after a restart (TA-3), the | ||
| // Cashu analogue of the Lightning `find_held_invoices` resubscribe. | ||
| cashu_restore::restore_cashu_escrows(get_db_pool().as_ref(), &cashu_client).await; |
There was a problem hiding this comment.
Don't block boot on best-effort restore checks
This call is awaited before the Cashu branch builds the AppContext, starts the scheduler, or enters run_cashu; inside restore_cashu_escrows each order is checked serially and check_state can wait up to MINT_REQUEST_TIMEOUT (10s). With a slow mint and many locked escrows, a best-effort monitor can therefore stall all event processing for N×10s on every restart, so run the checks in the background or cap the whole restore pass instead of blocking boot.
Useful? React with 👍 / 👎.
|
|
||
| /// Re-hydrate and re-check every in-flight locked Cashu escrow at boot. | ||
| pub async fn restore_cashu_escrows(pool: &SqlitePool, cashu_client: &CashuClient) { | ||
| let locked = match find_locked_cashu_orders(pool).await { |
There was a problem hiding this comment.
Filter restore to in-flight Cashu statuses
find_locked_cashu_orders is explicitly designed and tested to return terminal locked rows because cashu_escrow_locked_at is never cleared; by feeding every returned row into the spent/pending warning, a normally released escrow whose proofs are spent, or a canceled terminal order, will be logged as needing attention on every later boot. The restore path is described as monitoring in-flight escrows, so filter out terminal statuses here (or ensure close paths clear the lock) before calling the mint.
Useful? React with 👍 / 👎.
On boot in Cashu mode, re-hydrate in-flight locked escrows from the DB (the Cashu analogue of the Lightning `find_held_invoices` resubscribe) so a restart never loses sight of a locked-but-not-released escrow (docs/cashu/02-track-a-lock.md §6/§10). - `CashuClient::check_token_unspent`: whether every proof of a stored escrow token is still unspent at the mint (NUT-07), fail-closed on a short state reply. Reuses the Y-derivation the lock path already uses; does not re-run the full acceptance check (the token is immutable and was validated at lock). - `cashu_restore::restore_cashu_escrows`: list `find_locked_cashu_orders`, and for each re-check the token against the mint, logging a warning for any escrow that is spent/pending (redeemed or double-spent while the daemon was down). Best-effort, log-only — it never mutates order state (that belongs to the release/cancel/dispute tracks) and never blocks boot. - Wired into the `main.rs` Cashu boot branch after the mint connects, before the scheduler starts. Test: restore over an empty pool finds nothing and never contacts the mint. The mint-backed spent/live detection is exercised by the CF-3 integration harness. Depends on CF-4 + CF-5. Base: feat/cashu-ta2-take-flow Refs: docs/cashu/02-track-a-lock.md (TA-3)
6652b70 to
a16c745
Compare
d39115c to
456c3f4
Compare
What & why
On boot in Cashu mode, re-hydrate in-flight locked escrows from the DB — the Cashu analogue of the Lightning path's
find_held_invoicesresubscribe — so a restart never loses sight of an escrow that is locked but not yet released (docs/cashu/02-track-a-lock.md§6/§10). This is the optional, recommended monitor PR of Track A.Changes
CashuClient::check_token_unspent: whether every proof of a stored escrow token is still unspent at the mint (NUT-07), fail-closed on a short state reply. Reuses the Y-derivation the lock path already uses; it does not re-run the fullverify_escrow_tokenacceptance check (the token is immutable and was validated at lock — this only answers "is it still live?").cashu_restore::restore_cashu_escrows: listfind_locked_cashu_orders, and for each re-check the token, logging a warning for any escrow that is spent/pending (redeemed or double-spent while the daemon was down). Best-effort, log-only — it never mutates order state (that belongs to the release/cancel/dispute tracks) and never blocks boot on a mint hiccup.main.rsCashu boot branch after the mint connects, before the scheduler starts.Tests
Checklist
cargo fmt --checkcargo clippy --all-targets --all-features -- -D warningscargo test— 1028 passedDepends on #830 (TA-2), #829 (TA-1), #828 (CF-5). Refs:
docs/cashu/02-track-a-lock.md(TA-3).🧪 Manual testing — step by step
Prereqs: the Cashu-mode
mostrodsetup from CF-5 (#828) — mint up (docker compose -f docker-compose.cashu.yml up -d),[cashu] enabled = true. This branch is stacked on TA-2 (contains CF-5 + TA-1 + TA-2 + TA-3). Run withRUST_LOG=mostro=info.1. Clean start — nothing locked
mostrodin Cashu mode.2. Re-hydrate a locked escrow across a restart
AddCashuEscrow), or seed a row directly:mostrod. Expected at boot:3. Unit test
cargo test --bin mostrod cashu_restoreExpected: the empty-pool restore path is a clean no-op that never contacts the mint. ✔️