NUT-XX: Efficient wallet recovery #342

Open
Forte11Cuba wants to merge 7 commits from Forte11Cuba/nut-xx-efficient-wallet-recovery into main
Forte11Cuba commented 2026-02-18 10:04:00 +00:00 (Migrated from github.com)

Motivated by #301 . Replaces the NUT-13 linear scan with binary search + a depth invariant that bounds unspent proofs to the last d nonce indices.

Reduces BlindedMessages revealed to the mint from O(T) to ~182 (constant), and requests from O(T/b) to ~35. No mint changes required.

Builds on the binary search and d-invariant ideas from #301 . Credit to @a1denvalu3 for the original proposal and algorithm design, @robwoodgate for the halfway-house approach and the concerns around coin-selection that shaped the final invariant, @gandlafbtc for the local-search alternative that framed the trade-offs, and @davidcaseria for raising the practicality constraints that led to the relaxed invariant.

Open for discussion this is a draft NUT, not final. Feedback welcome especially on: the Depth Invariant definition, the gap-tolerance approach, and the default value of d.

Motivated by #301 . Replaces the NUT-13 linear scan with binary search + a depth invariant that bounds unspent proofs to the last `d` nonce indices. Reduces BlindedMessages revealed to the mint from O(T) to ~182 (constant), and requests from O(T/b) to ~35. No mint changes required. Builds on the binary search and d-invariant ideas from #301 . Credit to @a1denvalu3 for the original proposal and algorithm design, @robwoodgate for the halfway-house approach and the concerns around coin-selection that shaped the final invariant, @gandlafbtc for the local-search alternative that framed the trade-offs, and @davidcaseria for raising the practicality constraints that led to the relaxed invariant. Open for discussion this is a draft NUT, not final. Feedback welcome especially on: the Depth Invariant definition, the gap-tolerance approach, and the default value of `d`.
a1denvalu3 commented 2026-02-26 16:31:19 +00:00 (Migrated from github.com)

Just amazing.

Just amazing.
a1denvalu3 commented 2026-02-26 16:38:09 +00:00 (Migrated from github.com)

This NUT reduces leakage to O(log N + g + d) BlindedMessages

It also speeds up recovery, because you send log N requests.

> This NUT reduces leakage to O(log N + g + d) BlindedMessages It also speeds up recovery, because you send log N requests.
a1denvalu3 (Migrated from github.com) reviewed 2026-02-26 16:40:15 +00:00
a1denvalu3 (Migrated from github.com) commented 2026-02-26 16:40:15 +00:00

I would cut this and instead put in the PR description. This is more of a motivation.

I would cut this and instead put in the PR description. This is more of a motivation.
Forte11Cuba (Migrated from github.com) reviewed 2026-02-27 07:45:54 +00:00
Forte11Cuba (Migrated from github.com) commented 2026-02-27 07:45:54 +00:00

Good point trimmed it down to a two-line summary. The detailed motivation is already in the PR description.

Good point trimmed it down to a two-line summary. The detailed motivation is already in the PR description.
thesimplekid (Migrated from github.com) reviewed 2026-02-27 10:58:27 +00:00
thesimplekid (Migrated from github.com) commented 2026-02-27 10:58:27 +00:00

Not specific to this pr but we should also make sure we include context like this not just in the PR description but in the git log so we don't lose it the day github enviably doesn't work.

Not specific to this pr but we should also make sure we include context like this not just in the PR description but in the git log so we don't lose it the day github enviably doesn't work.
a1denvalu3 (Migrated from github.com) reviewed 2026-03-02 09:08:45 +00:00
@ -0,0 +39,4 @@
2. **On send (swap-to-send)**: A send operation involves a [NUT-03][03] swap that creates new outputs (send proofs + change proofs), which increases T. If this increase causes any remaining unspent proofs (those not involved in the swap) to have index `i ≤ T - d`, the wallet **MUST** consolidate them. Note: a pure melt (paying a Lightning invoice without swap) does not increase T and therefore cannot violate the invariant.
3. **Coin selection**: Wallets **MAY** use arbitrary coin selection. After any operation that increases T, the wallet **MUST** check whether any unspent proof now has index `i ≤ T - d` and consolidate if so. This preserves free coin selection while enforcing the invariant.
a1denvalu3 (Migrated from github.com) commented 2026-03-02 09:08:45 +00:00

There is also the case where a wallet already has d unspent proofs, and adding any more would violate the constraint no matter if you reissue the old ones. In that case, the operation should fail and compaction should be done to compress all of the existing unspent proofs into fewer ones.

There is also the case where a wallet already has `d` unspent proofs, and adding any more would violate the constraint no matter if you reissue the old ones. In that case, the operation should fail and compaction should be done to compress all of the existing unspent proofs into fewer ones.
a1denvalu3 (Migrated from github.com) reviewed 2026-03-02 09:09:47 +00:00
a1denvalu3 (Migrated from github.com) commented 2026-03-02 09:09:47 +00:00
Since recovery can be triggered at any time by data loss, the invariant **MUST** hold at all times — not just "before recovery". Wallets **MUST** consolidate violating proofs immediately before any operation that increases T.
```suggestion Since recovery can be triggered at any time by data loss, the invariant **MUST** hold at all times — not just "before recovery". Wallets **MUST** consolidate violating proofs immediately before any operation that increases T. ```
a1denvalu3 (Migrated from github.com) reviewed 2026-03-02 09:15:15 +00:00
a1denvalu3 (Migrated from github.com) commented 2026-03-02 09:15:15 +00:00

really good, although one doesn't know T until found.

really good, although one doesn't know T until found.
a1denvalu3 (Migrated from github.com) reviewed 2026-03-02 09:15:58 +00:00
a1denvalu3 (Migrated from github.com) commented 2026-03-02 09:15:58 +00:00

I think this information is not necessary to implementors and can be documented elsewhere.

I think this information is not necessary to implementors and can be documented elsewhere.
a1denvalu3 (Migrated from github.com) reviewed 2026-03-15 13:06:30 +00:00
a1denvalu3 (Migrated from github.com) commented 2026-03-15 13:06:30 +00:00

[...] reduces the number of BlindedMessages revealed to the mint from O(T) to a constant (~182)

Why costant 182?

> [...] reduces the number of `BlindedMessages` revealed to the mint from O(T) to a constant (~182) Why costant 182?
thesimplekid commented 2026-03-18 15:54:09 +00:00 (Migrated from github.com)

On the cdk call we discussed that a wallet birthday would be useful so a wallet knows if it need to use the old linear scan or can use the new method. We could use NUT27 to store a birthday in addition to the mint list. Currently there is a timestamp in the body of the backup but I think that's the time stamp of the backup, adding a optional wallet birthday to that json structure would be a simple backwards compatible change and helpful here.

On the cdk call we discussed that a wallet birthday would be useful so a wallet knows if it need to use the old linear scan or can use the new method. We could use [NUT27](https://github.com/cashubtc/nuts/blob/main/27.md) to store a birthday in addition to the mint list. Currently there is a timestamp in the body of the backup but I think that's the time stamp of the backup, adding a optional wallet birthday to that json structure would be a simple backwards compatible change and helpful here.
a1denvalu3 commented 2026-03-19 13:45:27 +00:00 (Migrated from github.com)

@thesimplekid Thinking more about it, the birthday doesn't really tells us if we can use the fast recovery. Maybe storing an explicit hint that the wallet respects the properties defined in nut-xx would be a more helpful tip.

@thesimplekid Thinking more about it, the birthday doesn't really tells us if we can use the fast recovery. Maybe storing an explicit hint that the wallet respects the properties defined in `nut-xx` would be a more helpful tip.
thesimplekid commented 2026-03-19 13:59:43 +00:00 (Migrated from github.com)

Good point. I think that would be reasonable to add to the event as well. Since the event body is just json we could specify that it can be extended by other nuts with optional json fields this way nut-27 does not define it or need to change for possible future nuts and each nut can define that.

Good point. I think that would be reasonable to add to the event as well. Since the event body is just json we could specify that it can be extended by other nuts with optional json fields this way nut-27 does not define it or need to change for possible future nuts and each nut can define that.
a1denvalu3 commented 2026-03-24 17:44:31 +00:00 (Migrated from github.com)

@Forte11Cuba made a PR to your PR, addressing what we talked about.

@Forte11Cuba made a PR to your PR, addressing what we talked about.
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin Forte11Cuba/nut-xx-efficient-wallet-recovery:Forte11Cuba/nut-xx-efficient-wallet-recovery
git switch Forte11Cuba/nut-xx-efficient-wallet-recovery

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff Forte11Cuba/nut-xx-efficient-wallet-recovery
git switch Forte11Cuba/nut-xx-efficient-wallet-recovery
git rebase main
git switch main
git merge --ff-only Forte11Cuba/nut-xx-efficient-wallet-recovery
git switch Forte11Cuba/nut-xx-efficient-wallet-recovery
git rebase main
git switch main
git merge --no-ff Forte11Cuba/nut-xx-efficient-wallet-recovery
git switch main
git merge --squash Forte11Cuba/nut-xx-efficient-wallet-recovery
git switch main
git merge --ff-only Forte11Cuba/nut-xx-efficient-wallet-recovery
git switch main
git merge Forte11Cuba/nut-xx-efficient-wallet-recovery
git push origin main
Sign in to join this conversation.
No description provided.