Skip to content

refactor: cleanup WalletTransactionChecker::check_core_transaction#402

Merged
xdustinface merged 1 commit intov0.42-devfrom
refactor/check-transaction
Feb 3, 2026
Merged

refactor: cleanup WalletTransactionChecker::check_core_transaction#402
xdustinface merged 1 commit intov0.42-devfrom
refactor/check-transaction

Conversation

@xdustinface
Copy link
Collaborator

@xdustinface xdustinface commented Feb 1, 2026

  • Moves parts of it out into separate functions/helpers
  • Combines the gap limit maintenance cases since the ManagedAccountType::Standard is also already handled in ManagedAccountType::address_pools_mut
  • Early return in case of an already known transaction, adding the record again and updating UTXOs is no-op if the transaction is known already.

Summary by CodeRabbit

  • New Features

    • Transaction recording with automatic wallet balance and UTXO updates for spendable accounts.
    • Mutable account access to enable direct in-place account updates and broader collection visibility.
  • Improvements

    • Streamlined per-account transaction processing with a single summary log per transaction (net change, received, sent).
    • Enhanced transaction context tracking and display (confirmation, block info, timestamps).
    • Address gap-limit maintenance and new address suggestions during processing.
  • Refactor

    • Unified account lookup logic for consistent behavior.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 1, 2026

📝 Walkthrough

Walkthrough

Introduces a macro-backed account lookup and a public mutable accessor; adds per-account transaction recording and UTXO update helpers; refactors wallet transaction checking to accept a TransactionContext, delegate per-account recording, add TransactionContext helpers/Display, and consolidate logging and gap-limit handling.

Changes

Cohort / File(s) Summary
Account Accessor Consolidation
key-wallet/src/managed_account/managed_account_collection.rs
Added macro get_by_account_type_match_impl to centralize CoreAccountTypeMatch lookup; refactored get_by_account_type_match to use it; made ManagedAccountCollection public; added pub fn get_by_account_type_match_mut(&mut self, ...) -> Option<&mut ManagedCoreAccount>.
Transaction Recording & UTXO Management
key-wallet/src/managed_account/mod.rs
Added private helper fn update_utxos(&mut self, tx: &Transaction, account_match: &AccountMatch, context: TransactionContext) and crate-visible pub(crate) fn record_transaction(&mut self, tx, account_match, context) to create TransactionRecord and update UTXOs; added imports (Transaction, Txid, BTreeSet).
Transaction Checking Refactor
key-wallet/src/transaction_checking/wallet_checker.rs
Renamed/changed trait method to check_core_transaction accepting context: TransactionContext and wallet: &mut Wallet; added Display impl and helper accessors on TransactionContext; replaced inline UTXO/ingest logic with per-account get_by_account_type_match_mut() + account.record_transaction(...); consolidated logging and gap-limit/address-pool handling; exported KeySource and CoreBlockHeight in scope.

Sequence Diagram

sequenceDiagram
    participant Checker as "WalletTransactionChecker" rect rgba(60,120,200,0.5)
    participant Wallet as "Wallet" rect rgba(120,180,240,0.5)
    participant Account as "ManagedAccount" rect rgba(80,200,120,0.5)
    participant UTXO as "UTXO Store" rect rgba(200,160,60,0.5)

    Checker->>Checker: check_core_transaction(tx, context, wallet, update_state)
    alt update_state && tx relevant
        Checker->>Wallet: identify affected_accounts (AccountMatch)
        loop per affected account
            Checker->>Wallet: get_by_account_type_match_mut(account_type_match)
            Wallet->>Account: record_transaction(tx, account_match, context)
            Account->>Account: create TransactionRecord
            Account->>UTXO: update_utxos(tx, account_match, context)
            Account->>Wallet: mark addresses used / suggest new addresses
        end
        Checker->>Checker: compute net_change & log final summary
        Checker->>Wallet: increment wallet.metadata.total_transactions
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibble code and stitch a macro seam,

I add a mutable hop to the account stream.
I count spent crumbs and stash the rest,
I mark each burrow where coins have nested.
The ledger hums — my work's well-dressed.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The PR title 'refactor: cleanup WalletTransactionChecker::check_core_transaction' accurately describes the primary change: refactoring and cleaning up the check_core_transaction method by extracting logic into helper functions and simplifying transaction handling.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/check-transaction

Important

Action Needed: IP Allowlist Update

If your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:

  • 136.113.208.247/32 (new)
  • 34.170.211.100/32
  • 35.222.179.152/32

Failure to add the new IP will result in interrupted reviews.


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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@key-wallet/src/managed_account/managed_account_collection.rs`:
- Around line 23-105: The PlatformPayment branch in the
get_by_account_type_match_impl! macro currently returns None and must instead
build a PlatformPaymentAccountKey from AccountTypeMatch::PlatformPayment's
account_index and key_class and use the same accessor to look it up; update the
AccountTypeMatch::PlatformPayment arm to construct PlatformPaymentAccountKey {
account: *account_index, key_class: *key_class } and call
$self.platform_payment_accounts.$get(&key) (mirroring the Dashpay arms) so
platform_payment_accounts are properly returned by
get_by_account_type_match_impl!.
🧹 Nitpick comments (2)
key-wallet/src/transaction_checking/wallet_checker.rs (2)

162-197: Per-account processing looks correct, but silently skipping gap limit maintenance warrants logging.

The flow properly:

  1. Records the transaction and updates UTXOs via account.record_transaction
  2. Marks involved addresses as used
  3. Maintains gap limits for address pools

However, when extended_public_key_for_account_type returns None (lines 176-181), the code silently continues without maintaining gap limits. This could leave address pools in an inconsistent state for watch-only wallets or accounts without xpub access.

Consider logging when gap limit maintenance is skipped
             let Some(xpub) = wallet.extended_public_key_for_account_type(
                 &account_match.account_type_match.to_account_type_to_check(),
                 account_match.account_type_match.account_index(),
             ) else {
+                tracing::debug!(
+                    account_index = ?account_match.account_type_match.account_index(),
+                    "Skipping gap limit maintenance: no xpub available for account"
+                );
                 continue;
             };

163-163: Clone of affected_accounts is necessary but could be documented.

The .clone() is required because result.new_addresses is mutated during iteration (line 186). This is correct but not immediately obvious.

Optional: Add a brief comment explaining the clone
-        for account_match in result.affected_accounts.clone() {
+        // Clone required: we modify result.new_addresses while iterating
+        for account_match in result.affected_accounts.clone() {

@xdustinface xdustinface force-pushed the refactor/check-transaction branch from 1b3de48 to a36ee4e Compare February 1, 2026 12:29
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@key-wallet/src/transaction_checking/wallet_checker.rs`:
- Around line 74-75: Update the doc comment for the wallet_checker::block_hash
method: it currently reads "Get the block height if confirmed" but the function
returns an Option<BlockHash>, so change the comment to accurately describe that
it returns the block hash if the transaction is confirmed (e.g., "Get the block
hash if confirmed" or similar). Ensure the corrected doc refers to the block
hash and the Option return semantics for the block_hash method.
🧹 Nitpick comments (2)
key-wallet/src/transaction_checking/wallet_checker.rs (2)

162-197: Consider documenting partial-update behavior for multi-account transactions.

The per-account processing loop can partially succeed: if maintain_gap_limit fails for one account, other accounts have already been updated via record_transaction. This isn't necessarily wrong, but the non-atomic behavior across multiple affected accounts should be documented or considered.

The error logging on lines 188-193 is appropriate for observability, but callers may not be aware that a transaction could be recorded in some accounts but not have proper gap-limit maintenance in others.

💡 Optional: Add a comment documenting the behavior
         // Process each affected account
+        // Note: Processing is best-effort per account. If gap-limit maintenance fails
+        // for one account, other accounts will still have been updated.
         for account_match in result.affected_accounts.clone() {

176-181: Silent skip when extended public key is unavailable.

When extended_public_key_for_account_type returns None, the loop continues without logging. This could mask configuration issues for accounts that should have an xpub. Consider adding a debug/trace log for observability.

📋 Optional: Add trace logging
             let Some(xpub) = wallet.extended_public_key_for_account_type(
                 &account_match.account_type_match.to_account_type_to_check(),
                 account_match.account_type_match.account_index(),
             ) else {
+                tracing::trace!(
+                    account_type = ?account_match.account_type_match,
+                    "Skipping gap limit maintenance - no extended public key available"
+                );
                 continue;
             };

@xdustinface xdustinface force-pushed the refactor/check-transaction branch from a36ee4e to 330a8ea Compare February 1, 2026 12:36
@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Feb 2, 2026
@github-actions
Copy link

github-actions bot commented Feb 2, 2026

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@xdustinface xdustinface force-pushed the refactor/check-transaction branch from 330a8ea to b1ca36d Compare February 3, 2026 00:10
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Feb 3, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@key-wallet/src/transaction_checking/wallet_checker.rs`:
- Around line 149-210: The early return when an existing tx is found (checking
txid via tx.txid() and self.accounts.get_by_account_type_match) causes skips of
account-level processing; instead, remove the return: set
result.is_new_transaction = false when a matching account.transaction exists but
continue to iterate and process all entries in result.affected_accounts (use the
same account.record_transaction and address pool maintenance logic), and guard
the wallet-level updates/logging (self.metadata.total_transactions increment and
tracing::info) so they only run when result.is_new_transaction is true to avoid
double-counting; keep other error handling (e.g., pool.maintain_gap_limit)
unchanged.

@xdustinface xdustinface force-pushed the refactor/check-transaction branch from b1ca36d to 0ba654c Compare February 3, 2026 00:27
- Moves parts of it out into separate functions/helpers
- Combines the gap limit maintenance cases since the `ManagedAccountType::Standard` is also already handled in `ManagedAccountType::address_pools_mut`
- Early return in case of an already known transaction, adding the record again and updating UTXOs is no-op if the transaction is known already.
@xdustinface xdustinface force-pushed the refactor/check-transaction branch from 0ba654c to c790ee6 Compare February 3, 2026 05:01
@xdustinface xdustinface changed the title refactor: cleanup WalletTransactionChecker::check_transaction refactor: cleanup WalletTransactionChecker::check_core_transaction Feb 3, 2026
@xdustinface xdustinface merged commit 5b0ef0d into v0.42-dev Feb 3, 2026
53 checks passed
@xdustinface xdustinface deleted the refactor/check-transaction branch February 3, 2026 15:19
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.

2 participants