Skip to content

refactor(key-wallet): move spendable_utxos from wallet to account#643

Merged
xdustinface merged 4 commits intov0.42-devfrom
sam/utxos-per-account
Apr 13, 2026
Merged

refactor(key-wallet): move spendable_utxos from wallet to account#643
xdustinface merged 4 commits intov0.42-devfrom
sam/utxos-per-account

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

@QuantumExplorer QuantumExplorer commented Apr 13, 2026

Summary

Two related cleanups to how key-wallet exposes spendable funds.

1. spendable_utxos moves from wallet to account

WalletInfoInterface::get_spendable_utxos aggregated a single "spendable UTXO set" across every account in a wallet, which is misleading — spendability rules and intent differ between standard, coinjoin, identity, and provider account types. The method is removed; ManagedCoreAccount::spendable_utxos(synced_height) replaces it, forcing callers to pick an account explicitly.

2. Balance: spendableconfirmed + unconfirmed

Mempool 0-conf outputs are genuinely spendable (you can chain on them in the mempool), but the old code hid them in a separate unconfirmed bucket and excluded them from is_spendable. Changes:

  • Utxo::is_spendable drops the is_confirmed || is_instantlocked check; a non-coinbase UTXO is spendable unless locked (coinbase still needs 100 confs).
  • WalletCoreBalance's spendable field is renamed to confirmed. Both confirmed and unconfirmed now count as spendable funds. spendable() becomes a helper returning confirmed + unconfirmed.
  • ManagedCoreAccount::update_balance splits mature, non-locked funds into confirmed (is_confirmed || is_instantlocked) vs unconfirmed (mempool only) so the UI can still surface the settled-vs-mempool distinction.
  • Renames propagate through WalletEvent::BalanceUpdated (key-wallet-manager), OnBalanceUpdatedCallback (dash-spv-ffi), and FFIBalance mappings (key-wallet-ffi). Several FFI sites were previously plumbing balance.spendable() into fields literally named confirmed — fixed to use balance.confirmed().

Breaking changes

  • WalletInfoInterface::get_spendable_utxos removed.
  • WalletCoreBalance: spendable field renamed to confirmed; spendable() is now confirmed + unconfirmed rather than just the old confirmed/mature amount.
  • WalletEvent::BalanceUpdated.spendable renamed to confirmed.
  • OnBalanceUpdatedCallback in dash-spv-ffi: second parameter renamed spendableconfirmed (same ABI, different name).
  • Utxo::is_spendable is now strictly more permissive: mempool 0-conf non-coinbase UTXOs return true where they previously returned false. Coin selection is unaffected because coin_selection.rs already checks is_confirmed || is_instantlocked explicitly via include_unconfirmed.

Test plan

  • cargo check --workspace --tests
  • cargo test -p key-wallet (446 unit + all integration groups pass)
  • cargo test -p key-wallet-manager (36 pass, event + process_block renames covered)
  • cargo test -p key-wallet-ffi --lib (200 pass)
  • cargo test -p dash-spv --lib (368 pass)

Spendability semantics are account-type specific (e.g. identity vs
standard vs coinjoin), so aggregating a single "wallet spendable UTXO
set" across every account hides meaningful distinctions. Drop
WalletInfoInterface::get_spendable_utxos and add
ManagedCoreAccount::spendable_utxos(synced_height), forcing callers to
ask per account. Updates the wallet_checker tests to query the
BIP44 account directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 13, 2026

📝 Walkthrough

Walkthrough

This pull request refactors spendable UTXO filtering by relocating the get_spendable_utxos() method from the wallet-level WalletInfoInterface trait to the account-level ManagedCoreAccount struct. Corresponding test cases are updated to invoke the new account-level method instead of the wallet-level variant.

Changes

Cohort / File(s) Summary
New Account-Level Method
key-wallet/src/managed_account/mod.rs
Added spendable_utxos(&self, synced_height: u32) method to ManagedCoreAccount that filters and returns UTXOs matching spendability criteria at a given height.
Test Updates
key-wallet/src/transaction_checking/wallet_checker.rs
Updated coinbase-maturity tests to call spendable_utxos() on the managed account instead of wallet-level get_spendable_utxos(), with assertions refactored accordingly.
Removed Wallet-Level Method
key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
Removed get_spendable_utxos() method declaration from WalletInfoInterface trait and its implementation in ManagedWalletInfo.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A hop, a skip, down the account we now go,
Where UTXOs dance in their spendable glow!
No wallet confusions, just cleanly refined—
Each coin in its place, perfectly aligned! 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main refactoring: moving the spendable_utxos method from the wallet level to the account level.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sam/utxos-per-account

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 13, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 2026

Codecov Report

❌ Patch coverage is 89.83051% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.87%. Comparing base (383b306) to head (f3dd99f).
⚠️ Report is 1 commits behind head on v0.42-dev.

Files with missing lines Patch % Lines
key-wallet-manager/src/events.rs 0.00% 3 Missing ⚠️
key-wallet-ffi/src/managed_account.rs 0.00% 1 Missing ⚠️
key-wallet-ffi/src/managed_wallet.rs 0.00% 1 Missing ⚠️
key-wallet-ffi/src/types.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##           v0.42-dev     #643      +/-   ##
=============================================
+ Coverage      67.48%   67.87%   +0.39%     
=============================================
  Files            246      318      +72     
  Lines          49280    67804   +18524     
=============================================
+ Hits           33256    46025   +12769     
- Misses         16024    21779    +5755     
Flag Coverage Δ
core 75.21% <ø> (ø)
ffi 38.62% <50.00%> (+2.24%) ⬆️
rpc 20.00% <ø> (ø)
spv 85.44% <ø> (+0.05%) ⬆️
wallet 67.62% <94.33%> (?)
Files with missing lines Coverage Δ
dash-spv-ffi/src/callbacks.rs 79.21% <100.00%> (ø)
key-wallet-ffi/src/wallet_manager.rs 64.88% <100.00%> (+11.70%) ⬆️
key-wallet-manager/src/accessors.rs 61.87% <100.00%> (ø)
key-wallet-manager/src/process_block.rs 86.01% <100.00%> (ø)
key-wallet/src/managed_account/mod.rs 54.01% <100.00%> (ø)
...-wallet/src/transaction_checking/wallet_checker.rs 97.89% <100.00%> (ø)
key-wallet/src/utxo.rs 91.66% <100.00%> (ø)
key-wallet/src/wallet/balance.rs 100.00% <100.00%> (ø)
...allet/managed_wallet_info/wallet_info_interface.rs 78.04% <ø> (ø)
key-wallet-ffi/src/managed_account.rs 56.87% <0.00%> (+7.05%) ⬆️
... and 3 more

... and 82 files with indirect coverage changes

@github-actions github-actions Bot added the ready-for-review CodeRabbit has approved this PR label Apr 13, 2026
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot removed the ready-for-review CodeRabbit has approved this PR label Apr 13, 2026
QuantumExplorer and others added 2 commits April 14, 2026 02:17
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mempool 0-conf outputs are spendable (you can chain on them in the
mempool), so Utxo::is_spendable no longer requires is_confirmed ||
is_instantlocked — a non-coinbase UTXO is spendable unless locked.

WalletCoreBalance's "spendable" field is renamed to "confirmed" and
both confirmed and unconfirmed buckets now count as spendable.
spendable() becomes a helper returning their sum. Renames propagate
through WalletEvent::BalanceUpdated (key-wallet-manager),
OnBalanceUpdatedCallback (dash-spv-ffi), and FFIBalance mappings
(key-wallet-ffi), all of which were previously plumbing
balance.spendable() into fields named "confirmed".

update_balance now fills the two buckets based on is_confirmed ||
is_instantlocked so the UI distinction between settled and mempool
funds is preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@ZocoLini ZocoLini left a comment

Choose a reason for hiding this comment

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

Quick question, are we using the spendable_utxos method or we are only testing it??

@QuantumExplorer
Copy link
Copy Markdown
Member Author

we are using spendable_utxos in places to decide what inputs to use, imo though transaction builder could help there, but... it doesn't matter all that much.

@ZocoLini
Copy link
Copy Markdown
Collaborator

the thing is, I don't see any usage of it in the PR other than in tests, and I don't know how we are querying the utxos in the transaction building function we expose but definitely not using his refactored logic, I have to take a look into it, maybe worth to update it

Copy link
Copy Markdown
Collaborator

@ZocoLini ZocoLini left a comment

Choose a reason for hiding this comment

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

lgtm, I think Kevin would like to different PRs tbh, lets wait for his review

@xdustinface xdustinface merged commit 1fc0b6c into v0.42-dev Apr 13, 2026
41 checks passed
@xdustinface xdustinface deleted the sam/utxos-per-account branch April 13, 2026 23:52
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.

3 participants