Skip to content

refactor(key-wallet): dedupe core account types via shared trait + composition#728

Open
QuantumExplorer wants to merge 3 commits intoclaude/adoring-booth-151626from
claude/managed-account-dedupe
Open

refactor(key-wallet): dedupe core account types via shared trait + composition#728
QuantumExplorer wants to merge 3 commits intoclaude/adoring-booth-151626from
claude/managed-account-dedupe

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

Summary

Follow-up to #711 that eliminates the near-total method duplication between ManagedCoreFundsAccount and ManagedCoreKeysAccount that the rename split introduced.

Three coordinated changes:

  1. Shared trait owns the duplicated logic. All 21 previously-duplicated methods (address-pool / key-derivation / index queries) move into ManagedAccountTrait as default impls, expressed in terms of 8 primitive accessors. The bodies now live exactly once.
  2. Funds account composes the keys account. ManagedCoreFundsAccount is now a thin wrapper: { core: ManagedCoreKeysAccount, balance, utxos, spent_outpoints }. It implements the trait by delegating the 8 primitives to core. Only funds-specific operations (transaction recording, UTXO updates, balance computation, Standard-account receive/change paths) remain inherent.
  3. Fields privatized on both structs. External access now goes through trait accessors or new inherent getters (balance(), balance_mut(), utxos(), utxos_mut(), etc.). Field accesses migrated to method calls across key-wallet, key-wallet-ffi, key-wallet-manager, and dash-spv test helpers.

The custom Deserialize impl is rewritten: it deserializes the inner core (which carries transactions) and rebuilds spent_outpoints from those inputs. Wire format changes (nested core object); serialization compatibility was explicitly out of scope per the discussion preceding this PR.

Numbers

  • managed_core_funds_account.rs: 1348 → 677 lines (-49%)
  • managed_core_keys_account.rs: 666 → 157 lines (-76%)
  • managed_account_trait.rs: 57 → 597 lines (the relocated shared logic)
  • Net: -621 lines across 24 files

Test plan

  • cargo check --workspace --all-targets — clean
  • cargo clippy --workspace --all-targets --all-features — clean (no warnings)
  • cargo test --workspace --lib — 1802 passed, 0 failed
  • cargo test -p key-wallet --lib — 461 passed, 0 failed
  • dashd integration tests in dash-spv (need setup-dashd.py; not run locally)
  • CI passes against the refactor(key-wallet): split ManagedCoreAccount into funds + keys variants #711 base

Notes

  • Targets claude/adoring-booth-151626 (PR refactor(key-wallet): split ManagedCoreAccount into funds + keys variants #711's branch) so it stacks cleanly on the structural rename.
  • Wire-format change in the serde representation of ManagedCoreFundsAccount is intentional — transactions and account-type fields now sit under a core object. Persisted state from prior versions will not deserialize unmigrated; serialization compat was deemed not required.

🤖 Generated with Claude Code

…mposition

Eliminates the near-total method duplication between `ManagedCoreFundsAccount`
and `ManagedCoreKeysAccount` introduced by the rename split:

- Move all 21 shared methods (address-pool / key-derivation / index queries)
  into `ManagedAccountTrait` as default impls, expressed in terms of 8
  primitive accessors. The bodies now live exactly once.
- Restructure `ManagedCoreFundsAccount` as composition: it now wraps a
  `ManagedCoreKeysAccount` (`core` field) and adds the funds-only state
  (`balance`, `utxos`, `spent_outpoints`). It implements the trait by
  delegating the 8 primitives to `core`; only funds-specific operations
  remain as inherent methods (transaction recording, UTXO updates, balance
  computation, Standard-account receive/change paths).
- Privatize all fields on both structs. External access goes through
  the trait accessors or new inherent getters/setters (`balance()`,
  `balance_mut()`, `utxos()`, `utxos_mut()`, etc.). Field accesses across
  `key-wallet`, `key-wallet-ffi`, `key-wallet-manager`, and `dash-spv`
  test helpers migrated to method calls.
- Replace the manual `Deserialize` impl: it now deserializes the inner
  `core` (which carries `transactions`) and rebuilds `spent_outpoints`
  from those transaction inputs. Wire format changes (nested `core`
  object); serialization compatibility was explicitly out of scope.

Net diff: -621 lines across 24 files. `managed_core_funds_account.rs`
shrinks 1348 -> 677 lines; `managed_core_keys_account.rs` shrinks 666 -> 157.

Verified:
- cargo check --workspace --all-targets: clean
- cargo clippy --workspace --all-targets --all-features: clean
- cargo test --workspace --lib: 1802 passed, 0 failed
- cargo test -p key-wallet --lib: 461 passed, 0 failed
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 5, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: be35bc3b-eb3d-4d32-8d94-91d9e57e76ad

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/managed-account-dedupe

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

❌ Patch coverage is 52.91139% with 186 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.94%. Comparing base (425bc19) to head (3335954).

Files with missing lines Patch % Lines
...allet/src/managed_account/managed_account_trait.rs 38.17% 149 Missing ⚠️
.../src/managed_account/managed_core_funds_account.rs 76.59% 11 Missing ⚠️
key-wallet-ffi/src/address_pool.rs 0.00% 9 Missing ⚠️
key-wallet-ffi/src/managed_account.rs 30.76% 9 Missing ⚠️
.../src/managed_account/managed_account_collection.rs 33.33% 2 Missing ⚠️
...t/src/managed_account/managed_core_keys_account.rs 86.66% 2 Missing ⚠️
...wallet/src/transaction_checking/account_checker.rs 81.81% 2 Missing ⚠️
key-wallet-ffi/src/managed_wallet.rs 50.00% 1 Missing ⚠️
key-wallet-ffi/src/transaction.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                       Coverage Diff                       @@
##           claude/adoring-booth-151626     #728      +/-   ##
===============================================================
+ Coverage                        70.28%   70.94%   +0.65%     
===============================================================
  Files                              320      320              
  Lines                            68527    68247     -280     
===============================================================
+ Hits                             48167    48417     +250     
+ Misses                           20360    19830     -530     
Flag Coverage Δ
core 75.81% <ø> (ø)
ffi 45.75% <20.00%> (+2.37%) ⬆️
rpc 20.00% <ø> (ø)
spv 87.24% <ø> (-0.08%) ⬇️
wallet 69.80% <55.13%> (+1.23%) ⬆️
Files with missing lines Coverage Δ
key-wallet-manager/src/lib.rs 62.83% <ø> (ø)
...-wallet/src/transaction_checking/wallet_checker.rs 99.39% <100.00%> (ø)
...c/wallet/managed_wallet_info/asset_lock_builder.rs 79.61% <100.00%> (ø)
...src/wallet/managed_wallet_info/managed_accounts.rs 19.85% <ø> (ø)
...allet/managed_wallet_info/wallet_info_interface.rs 81.98% <100.00%> (ø)
key-wallet-ffi/src/managed_wallet.rs 81.34% <50.00%> (+2.16%) ⬆️
key-wallet-ffi/src/transaction.rs 0.00% <0.00%> (ø)
.../src/managed_account/managed_account_collection.rs 55.66% <33.33%> (ø)
...t/src/managed_account/managed_core_keys_account.rs 55.12% <86.66%> (+55.12%) ⬆️
...wallet/src/transaction_checking/account_checker.rs 67.02% <81.81%> (ø)
... and 4 more

... and 16 files with indirect coverage changes

…fields

Per review feedback:

- Rename `ManagedCoreFundsAccount::core` -> `keys`. Method accessors
  rename `core()` / `core_mut()` -> `keys()` / `keys_mut()`. The serde
  helper struct field also renames `core` -> `keys` (changes the wire
  format again, still fine since serialization compat is out of scope).
- Make `balance` and `utxos` `pub` again on `ManagedCoreFundsAccount`.
  Drop the now-redundant `balance()` / `balance_mut()` / `utxos()` /
  `utxos_mut()` inherent methods. Call sites that had been migrated to
  method calls revert to direct field access (`account.balance`,
  `account.utxos`). `spent_outpoints` stays private — it carries an
  invariant tied to `keys.transactions()`.

Verified: cargo check + clippy clean across the workspace; all
1802 lib tests pass; key-wallet 461/461.
Copy link
Copy Markdown
Member Author

@QuantumExplorer QuantumExplorer left a comment

Choose a reason for hiding this comment

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

Self Reviewed

- Drop the `[`Self::record_transaction`]` link from the
  `ManagedCoreFundsAccount` doc comment; `record_transaction` is
  `pub(crate)` and rustdoc with `-D warnings` rejects intra-doc links
  from a public item to a private one.
- `cargo fmt --all` to fix import ordering (placement of the new
  `ManagedAccountTrait` use lines) and a long-line wrap in
  `account_checker.rs`.

Tests + clippy still clean locally.
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.

1 participant