NUT-XX pubkey quote discovery: sweeper reconcile + cdk pin cba8469b #21
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/nutxx-pubkey-lookup"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The translator's wallet now discovers its mint quotes by locking pubkey — a 15s reconcile loop asking the mint for all still-mintable quotes locked to its key — instead of depending on per-quote notifications that can be dropped. A dropped notification used to mean that quote's ehash was silently never minted; now it costs a few seconds. Nothing changes for the pool or the mint protocol surface. This is the base of the epoch milestone stack (vnprc/hashpool#13): merging it unblocks the epoch-mechanics and multi-unit-sweeper work. What proves it:
cargo check,cargo test(20/20) andclippyare green on the current pin, the four MSRV lock pins are intact, and a cold cross-family reviewer read the re-pin and found nothing. What is NOT re-proven: the original end-to-end live run, for the reason in the next paragraph. If this is wrong, revert the merge — master stays functional on7011eebc.The cdk pin changed after this PR was first validated, and that matters for how you read it. This branch was originally pinned to cdk
cba8469band live-run validated against it on 2026-08-10 (64 quotes / 662 ehash minted via pubkey reconcile, including 12 deliberately dropped notifications). That revision is now confirmed lost — it exists on no reachable remote and in no local object store (details in the comment below). The pin is nowe5a85f810a91bd1d8882a4a60ed93fd60bb691c1(vnprc/cdkbranchnutxx-wallet-v2), workspace 0.17.0, carrying the same four APIs this branch calls. Because the old revision is gone, the new pin cannot be diffed against the one the live run was performed on, so that live-run result stands as a record of what was observed then and is not re-established by this change. Re-running it is cheap once the stack is up and is the honest next step before relying on the dropped-notification path in anger.Refs vnprc/hashpool#7. Refs vnprc/hashpool#25.
What changed since the original review
bfc15a92re-pins cdk from the unreachablecba8469btoe5a85f8acrossprotocols/Cargo.toml,roles/Cargo.tomlanddevenv.nix.30b82da7merges master, which carries the devenv repair (e09a7381) without whichdevenv shellcannot enter on this branch at all, plus the dev-stack controls (735678e5).1d1b25d9movesroles/Cargo.lockonto the new revision by incremental resolution.Risk
R2. The cdk pin moves in all four places that must agree (
protocols/Cargo.toml,roles/Cargo.toml,devenv.nix,roles/Cargo.lock), verified consistent including the short-rev form.roles/Cargo.lockchanged 32 lines and every one of them is asource =line — no version, checksum or dependency list moved — so the MSRV-pinned transitive deps are untouched:time0.3.41,serde_with3.17.0,darling0.21.3,simple_asn10.6.3 against devenv's rustc 1.86.0. A fresh re-resolve would picktime0.3.55 (MSRV 1.88) and fail; see vnprc/hashpool#10. The old 0xC0 notification path is retained but its wallet-side fetch is disabled, so discovery is sweep-only.Residual risk that re-pinning cannot remove: the replacement revision is a different commit from the one the live run exercised. Its API surface is verified present and the unit tests pass, but behavioural equivalence on the reconcile path is not proven by a diff.
Validation
Run on the current pin, in the devenv shell (rustc 1.86.0, gcc 14.2.1):
cargo check -p translator_sv2— clean.cargo test -p translator_sv2— 20 passed, 0 failed. Re-run independently by the integrator, same result.cargo clippy -p translator_sv2 --all-targets— no errors; two pre-existing style warnings remain inwallet.rs:15andchannel_manager.rs:900, both recorded nits, neither introduced here.cba8469bremains anywhere in the tree; all 16 cdk entries inroles/Cargo.lockare ate5a85f8.roles/Cargo.lock, independently twice.Not run: the 2026-08-10 end-to-end live run, as explained above. Not run: anything in
protocols/, whose gitignored lock hits the known pre-existingtime0.3.55 MSRV failure of vnprc/hashpool#10 on any clean worktree — unrelated to this change.The MintQuoteNotification (0xC0) handler's fetch_mint_quote(quote_id, Custom("ehash")) call is now redundant: the quote sweeper's pubkey reconcile (Wallet::mint_quotes_by_pubkey) is the discovery source of record. Comment out the fetch, leaving the payload decode, the quote_id/amount extraction, and the info! logging in place so the notification is still observed and logged, just no longer acted on. The rest of the SV2 plumbing is untouched: the pool poller, the MintQuoteNotification/MintQuoteFailure message types, and the mint-side send all remain as-is. Retained but now-unused import and struct field are marked #[allow(...)] with a note rather than removed, so re-enabling the fetch later is a one-line uncomment.Adversarial review findings.
Merge verification (all clean):
49edec22has an empty combined diff (no evil-merge content); vs the validated branch tip it adds exactly master's three docs files; vs master only branch work + the declared pin supersession, with nothing from master lost (files the 0.17 bump touched that aren't in this diff are byte-identical to master). Single[patch.crates-io]per workspace, singlecdkCommit, all 16 lock entries atcba8469b, MSRV pins intact (time0.3.41 /serde_with3.17.0 /darling0.21.3 /simple_asn10.6.3), zero stale revs from all 12 superseded hashes, zero conflict markers; the quote.rs resolution (Custom(Arc<str>)form) is the only one that compiles at the kept pin.should-fix (body text) — "the mint gains the NUT-XX lookup endpoint from the cdk bump" is false: the
/mint/quote/pubkeyroute is identical at master's pin7011eebc. What the bump actually delivers is theonly_mintablefilter + pubkey-encoding fixes mint-side and the lookup API wallet-side. Corrected in the body so a future bisect/revert doesn't misjudge master's capabilities.Verdict: textbook merge, nothing lost; body corrected.
Owner request: re-pin cdk off the dead revision so this PR can build again.
The pinned revision
cba8469be5b37c067f0cf594b267801afe357960no longer exists anywhere reachable. Checked: all 45 branches ofgithub.com/vnprc/cdk, all 18 ofgithub.com/themhv/cdk,cashubtc/cdk, and the shared GitHub fork network by commit API (422 no such commit, against200for master's pin7011eebcas a control); all 33 repositories on the forge, which hosts no cdk fork at all; every git object store on the rust-dev VM; andnexus:~/work/cdk, which has no matching branch, one worktree, no reflog trace, and no second cdk checkout. The remaining possibility is a private GitHub repository.Replacement pin is
vnprc/cdke5a85f8(branchnutxx-wallet-v2), chosen because it is workspace0.17.0, matching this repo's crate version requirements, and carries all four cdk APIs this branch and vnprc/hashpool#23 call:batch_check_mint_quote_status,batch_mint,get_unissued_mint_quotes, andonly_mintable— the last being the entire delta over master's pin, which lacks it.only_mintableis present on both the mint side (crates/cdk/src/mint/issue,crates/cdk-axum/src/custom_handlers.rs,crates/cdk-sql-common/src/mint/quotes.rs) and the wallet side (crates/cdk/src/wallet/issue,crates/cdk/src/wallet/mint_connector/http_client.rs).Validation limit worth stating plainly: because
cba8469bis gone, the new pin cannot be diffed against the revision this PR's live-run validation was performed on, so equivalence of intent is not provable. The witness for the re-pin is compilation plus this repo's test suites, not a diff. The 2026-08-10 live-run result in the body stands as a record of what was observed on the old pin and is not re-established by this change.Commits follow on this branch; no force-push.
In plain English
The pool's wallet has to know which mining rewards it is owed before it can collect them. It used to find out by being told: the mint sent a message for each reward, one at a time. If a message went missing, the wallet never learned that reward existed, and the ecash for it was silently never collected. Nobody noticed, because nothing was obviously broken — the money just quietly did not arrive.
This changes the wallet to ask instead of wait. Every fifteen seconds it asks the mint "what do I still have outstanding?" and works from that answer. A lost message now costs a few seconds instead of the reward.
This is the base the other two epoch pull requests build on, so it merges first.
Status
Verified on a running dev stack: shares were mined, rewards were quoted and collected, and the balance grew as expected. The dependency this branch pins now lives on the forge rather than only on GitHub, so it cannot go missing again.
Superseded by a squashed branch with the same tree. Closing and reopening because the forge refuses force-push on an open pull request branch. Note this branch now also carries the multi-unit sweeper, which merged into it as vnprc/hashpool#31, so the replacement covers both and its title and body are rewritten to say so.
Pull request closed