Skip to content

feat: add TransactionStatusChanged event and emit wallet events#552

Open
xdustinface wants to merge 3 commits intov0.42-devfrom
feat/transaction-status-events
Open

feat: add TransactionStatusChanged event and emit wallet events#552
xdustinface wants to merge 3 commits intov0.42-devfrom
feat/transaction-status-events

Conversation

@xdustinface
Copy link
Collaborator

@xdustinface xdustinface commented Mar 16, 2026

  • Add TransactionStatusChanged variant to WalletEvent and a status field to TransactionReceived.
  • Wire up event emission in check_transaction_in_all_wallets, process_instant_send_lock, and update_synced_height.
  • Add FFI callback for status changes.

Based on:

Summary by CodeRabbit

  • New Features

    • Transaction events now include a status/context field and a new TransactionStatusChanged event is emitted.
    • InstantSend status updates are reported and trigger corresponding balance update notifications.
  • Tests

    • Expanded tests covering transaction lifecycle, status transitions, InstantSend paths, duplicate suppression, and related edge cases.
  • Bug Fixes

    • Events emitted only when wallet/transaction state changes, reducing duplicate or spurious notifications.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds transaction-status awareness end-to-end: TransactionReceived now includes a TransactionContext status, a new TransactionStatusChanged event and FFI callback were added, WalletManager emits TransactionReceived only for new transactions and TransactionStatusChanged when state changes, and tests + helpers validate lifecycle and InstantSend lock handling.

Changes

Cohort / File(s) Summary
FFI headers
dash-spv-ffi/include/dash_spv_ffi.h
Expanded OnTransactionReceivedCallback to include status; added OnTransactionStatusChangedCallback; extended FFIWalletEventCallbacks with on_transaction_status_changed.
FFI implementation & CLI
dash-spv-ffi/src/callbacks.rs, dash-spv-ffi/src/bin/ffi_cli.rs
Updated callback typedefs and dispatch to accept/pass FFITransactionContext status; added on_transaction_status_changed handler and registered it in callback initialization.
FFI tests
dash-spv-ffi/tests/dashd_sync/callbacks.rs, dash-spv-ffi/tests/dashd_sync/tests_callback.rs
Added extern on_transaction_status_changed callback and counter; updated on_transaction_received signature to accept _status; wired callbacks and assertions to track status-change invocations.
Event types
key-wallet-manager/src/events.rs
TransactionReceived variant now includes status: TransactionContext; added TransactionStatusChanged { wallet_id, txid, status } variant and updated descriptions.
Wallet interface & mock
key-wallet-manager/src/wallet_interface.rs, key-wallet-manager/src/test_utils/wallet.rs
Added process_instant_send_lock(&mut self, txid: Txid) to WalletInterface (no-op default); MockWallet stores status_changes and implements process_instant_send_lock.
WalletManager core & block processing
key-wallet-manager/src/wallet_manager/mod.rs, key-wallet-manager/src/wallet_manager/process_block.rs
Emit TransactionReceived only for new transactions; emit TransactionStatusChanged when state_modified is true; implemented process_instant_send_lock to mark InstantSend locks and emit status events; added test module hooks.
Transaction checking
key-wallet/src/transaction_checking/account_checker.rs, key-wallet/src/transaction_checking/wallet_checker.rs
Added state_modified: bool to TransactionCheckResult and set it when checks modify wallet state (new records, confirmations, InstantSend locks).
Managed wallet internals
key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
mark_instant_send_utxos now early-returns if txid already present in instant_send_locks to avoid duplicate processing.
Tests & helpers
key-wallet-manager/src/wallet_manager/event_tests.rs, key-wallet-manager/src/wallet_manager/test_helpers.rs
Added extensive async event lifecycle tests and helpers (setup, deterministic tx creation, assertions, lifecycle/suppression validators) for status flows and duplicate suppression.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant WM as WalletManager
    participant TxCheck as TransactionChecker
    participant EventEmit as EventEmitter
    participant Observer as EventObserver

    App->>WM: process_block(tx)
    WM->>TxCheck: check_transaction_in_all_wallets(tx)
    TxCheck->>TxCheck: evaluate context/status
    alt is_new == true
        TxCheck-->>WM: (is_new=true, state_modified=true, status)
        WM->>EventEmit: emit TransactionReceived(wallet_id, status, account_index, txid, amount, addresses)
    else state_modified == true
        TxCheck-->>WM: (is_new=false, state_modified=true, status)
        WM->>EventEmit: emit TransactionStatusChanged(wallet_id, txid, status)
    else state_modified == false
        TxCheck-->>WM: (state_modified=false)
        WM->>WM: no event emitted
    end
    EventEmit->>Observer: deliver event

    App->>WM: process_instant_send_lock(txid)
    WM->>WM: mark_instant_send_utxos(txid)
    WM->>EventEmit: emit TransactionStatusChanged(wallet_id, txid, InstantSend)
    EventEmit->>Observer: deliver status change
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

Suggested reviewers

  • ZocoLini

Poem

🐇
I hopped through queues with eager paws,
Statuses bloom in event-stream laws,
InstantSend glows, a quickening cheer,
Callbacks sing when states appear,
Tiny hops, big changes near 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 74.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a TransactionStatusChanged event and wiring wallet event emission throughout the codebase.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/transaction-status-events
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@xdustinface xdustinface force-pushed the feat/transaction-status-events branch from 4c13f8a to 6116068 Compare March 16, 2026 15:39
@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 77.97619% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.40%. Comparing base (be0f1fa) to head (7cf7b6c).

Files with missing lines Patch % Lines
dash-spv-ffi/src/callbacks.rs 11.76% 15 Missing ⚠️
dash-spv-ffi/src/bin/ffi_cli.rs 0.00% 12 Missing ⚠️
key-wallet/src/manager/events.rs 0.00% 6 Missing ⚠️
key-wallet/src/manager/test_helpers.rs 97.59% 2 Missing ⚠️
key-wallet/src/manager/mod.rs 96.00% 1 Missing ⚠️
key-wallet/src/manager/wallet_interface.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##           v0.42-dev     #552      +/-   ##
=============================================
+ Coverage      66.33%   66.40%   +0.06%     
=============================================
  Files            311      312       +1     
  Lines          64976    65128     +152     
=============================================
+ Hits           43103    43246     +143     
- Misses         21873    21882       +9     
Flag Coverage Δ
core 75.13% <ø> (ø)
ffi 36.73% <6.89%> (-0.07%) ⬇️
rpc 28.28% <ø> (ø)
spv 81.08% <ø> (-0.05%) ⬇️
wallet 66.62% <92.80%> (+0.35%) ⬆️
Files with missing lines Coverage Δ
key-wallet/src/manager/process_block.rs 63.76% <100.00%> (+14.78%) ⬆️
...wallet/src/transaction_checking/account_checker.rs 64.01% <100.00%> (+0.05%) ⬆️
...-wallet/src/transaction_checking/wallet_checker.rs 95.42% <ø> (+0.31%) ⬆️
...allet/managed_wallet_info/wallet_info_interface.rs 79.48% <100.00%> (+10.18%) ⬆️
key-wallet/src/manager/mod.rs 52.20% <96.00%> (+3.28%) ⬆️
key-wallet/src/manager/wallet_interface.rs 0.00% <0.00%> (ø)
key-wallet/src/manager/test_helpers.rs 97.59% <97.59%> (ø)
key-wallet/src/manager/events.rs 0.00% <0.00%> (ø)
dash-spv-ffi/src/bin/ffi_cli.rs 0.00% <0.00%> (ø)
dash-spv-ffi/src/callbacks.rs 59.91% <11.76%> (-3.56%) ⬇️

... and 6 files with indirect coverage changes

@xdustinface xdustinface force-pushed the feat/wallet-confirmation-lifecycle branch from 11405bc to 41d957f Compare March 17, 2026 02:57
@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Mar 17, 2026
@github-actions
Copy link

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

@QuantumExplorer
Copy link
Member

Review from Claude

Issue 1: Duplicate TransactionStatusChanged events via dual IS-lock entry points

Severity: Medium

process_instant_send_lock and check_core_transaction with TransactionContext::InstantSend are independent code paths that both emit TransactionStatusChanged for IS locks, but use different dedup mechanisms:

  • check_core_transaction deduplicates via instant_send_locks: HashSet<Txid>
  • process_instant_send_lock only checks whether UTXOs were newly marked, and never touches instant_send_locks

If process_instant_send_lock(txid) runs first, it marks UTXOs but doesn't update the HashSet. When check_core_transaction(tx, InstantSend) runs later, instant_send_locks.insert(txid) succeeds (not in set), state_modified is set to true unconditionally, and a duplicate TransactionStatusChanged fires.

Additionally, state_modified = true is set unconditionally after the UTXO marking loop regardless of whether any UTXO actually changed — even a fully redundant IS lock triggers an event.

Suggested fix: Either (a) have process_instant_send_lock also insert into instant_send_locks, or (b) gate state_modified = true on whether mark_utxos_instant_send actually changed anything.

Issue 2: FFI Breaking Change — OnTransactionReceivedCallback signature changed

Severity: High

The new status parameter is inserted as the second argument in OnTransactionReceivedCallback, shifting all subsequent parameters. Any existing C/Swift consumer compiled against the old header will have mismatched argument alignment — account_index receives the status value, txid points to garbage, amount is corrupt. This is undefined behavior.

Additionally, the FFITransactionContext enum values shifted (same issue as PR #540).

Suggested fix: If backward compatibility matters, consider appending status as the last parameter before user_data, or introduce on_transaction_received_v2 alongside the old callback.

Issue 3: TransactionStatusChanged missing wallet_id for multi-wallet consumers

Severity: Medium

TransactionReceived and BalanceUpdated both include wallet_id, but TransactionStatusChanged does not. The FFI callback also lacks it:

typedef void (*OnTransactionStatusChangedCallback)(const uint8_t (*txid)[32],
                                                   FFITransactionContext status,
                                                   void *user_data);

In a multi-wallet setup, consumers cannot determine which wallet's transaction changed state. The wallet_id is available at the emission site but is not included in the event.

Suggested fix: Add wallet_id to the TransactionStatusChanged event variant and FFI callback, and emit per-wallet events.

@xdustinface xdustinface force-pushed the feat/wallet-confirmation-lifecycle branch from 41d957f to 698d75a Compare March 17, 2026 14:07
@xdustinface xdustinface force-pushed the feat/transaction-status-events branch from 6116068 to 95f96fc Compare March 18, 2026 06:15
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Mar 18, 2026
Base automatically changed from feat/wallet-confirmation-lifecycle to v0.42-dev March 18, 2026 16:42
@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Mar 18, 2026
@github-actions
Copy link

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 feat/transaction-status-events branch from 95f96fc to c8fd4b2 Compare March 18, 2026 17:11
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Mar 18, 2026
@xdustinface xdustinface marked this pull request as ready for review March 18, 2026 17:11
@xdustinface
Copy link
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
key-wallet/src/transaction_checking/wallet_checker.rs (1)

191-203: ⚠️ Potential issue | 🟠 Major

Guard state_modified on actual IS-lock changes.

state_modified is set unconditionally in the existing-tx InstantSend path, even when no UTXO changed. That can trigger redundant TransactionStatusChanged emissions downstream.

Proposed fix
-                // Mark UTXOs as IS-locked in affected accounts
+                // Mark UTXOs as IS-locked in affected accounts
+                let mut any_changed = false;
                 for account_match in &result.affected_accounts {
                     if let Some(account) = self
                         .accounts
                         .get_by_account_type_match_mut(&account_match.account_type_match)
                     {
-                        account.mark_utxos_instant_send(&txid);
+                        if account.mark_utxos_instant_send(&txid) {
+                            any_changed = true;
+                        }
                     }
                 }
-                if update_balance {
+                if any_changed && update_balance {
                     self.update_balance();
                 }
-                result.state_modified = true;
+                result.state_modified = any_changed;
                 return result;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@key-wallet/src/transaction_checking/wallet_checker.rs` around lines 191 -
203, The code currently sets result.state_modified = true unconditionally after
calling account.mark_utxos_instant_send in the for loop; change this so
state_modified is only set when at least one account actually changed a UTXO.
Introduce a local boolean (e.g., let mut any_changed = false), call
account.mark_utxos_instant_send(&txid) inside the loop and have that method
return a bool indicating whether it modified any UTXO (or detect the change via
account state), then set any_changed |= returned_bool. After the loop, only call
self.update_balance() and set result.state_modified = true if any_changed is
true; otherwise return result unchanged. Ensure you update the
signature/behavior of mark_utxos_instant_send (or read account change flags)
accordingly.
dash-spv-ffi/src/callbacks.rs (1)

523-533: ⚠️ Potential issue | 🔴 Critical

Version the wallet callback ABI instead of changing v1 in place.

Line 526 inserts status ahead of existing callback arguments, and line 575 adds on_transaction_status_changed to the #[repr(C)] FFIWalletEventCallbacks struct. Both changes break the C/Swift FFI contract: any external consumer built against the previous header will have misaligned callback signatures and struct layouts, causing runtime failures or silent memory corruption. No versioned callback surface exists in the codebase. Preserve the current v1 types/layout intact and introduce FFIWalletEventCallbacksV2 / OnTransactionReceivedCallbackV2 alongside a new registration function dash_spv_ffi_client_set_wallet_event_callbacks_v2() to maintain forward compatibility.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dash-spv-ffi/src/callbacks.rs` around lines 523 - 533, The change mutates the
v1 ABI by inserting a new parameter into OnTransactionReceivedCallback and
adding on_transaction_status_changed to FFIWalletEventCallbacks, breaking
existing C/Swift consumers; instead keep the original
OnTransactionReceivedCallback and FFIWalletEventCallbacks unchanged, and add new
types FFIWalletEventCallbacksV2 and OnTransactionReceivedCallbackV2 (with the
extra status param) plus a new registration function
dash_spv_ffi_client_set_wallet_event_callbacks_v2() that accepts the V2 struct;
update any internal wiring to support both registrations while preserving the
original v1 symbols and layout so existing bindings remain valid.
🧹 Nitpick comments (1)
key-wallet-manager/src/wallet_interface.rs (1)

98-100: Clarify that the default implementation is intentionally a no-op.

The doc comment currently states side effects (“marks UTXOs”, “emits events”), but the default method does nothing. Please explicitly note this behavior to avoid accidental reliance by implementations that don’t override it.

Suggested doc tweak
-    /// Process an InstantSend lock for a transaction already in the wallet.
-    /// Marks UTXOs as IS-locked, emits status change and balance update events.
+    /// Process an InstantSend lock for a transaction already in the wallet.
+    /// Default implementation is a no-op; wallet implementations should override
+    /// this to mark UTXOs as IS-locked and emit status/balance events.
     fn process_instant_send_lock(&mut self, _txid: Txid) {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@key-wallet-manager/src/wallet_interface.rs` around lines 98 - 100, The doc
comment for process_instant_send_lock currently describes side effects but the
default implementation is a no-op; update the documentation for the method in
wallet_interface.rs (fn process_instant_send_lock) to explicitly state that the
provided default implementation does nothing and that implementations must
override the method to perform actions such as marking UTXOs as IS-locked,
emitting status-change events, and updating balances; keep the existing
behavioral description but add a clear sentence like “The default implementation
is a no-op — override to perform these actions.”
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dash-spv-ffi/include/dash_spv_ffi.h`:
- Around line 377-383: The change inserted FFITransactionContext into the
OnTransactionReceivedCallback signature and added
OnTransactionStatusChangedCallback into the FFIWalletEventCallbacks layout,
breaking ABI; restore backward compatibility by keeping the original typedef and
struct intact and add new versions instead: define a new typedef
OnTransactionReceivedCallbackV2 (with the extra FFITransactionContext status
parameter) and a new struct FFIWalletEventCallbacksV2 that includes the new
OnTransactionStatusChangedCallback in the new layout, leaving the existing
OnTransactionReceivedCallback and FFIWalletEventCallbacks unchanged, and update
any registration APIs to accept either the original callbacks or the V2 variants
(or add an explicit registration function that requires the caller to opt into
V2) so precompiled clients keep the original memory layout while new clients can
opt into the new signatures.

In `@dash-spv-ffi/tests/dashd_sync/tests_callback.rs`:
- Around line 110-126: Add a positive end-to-end test that drives a real Mempool
-> InstantSend/InBlock transition and asserts the new status-bearing callback
arguments: update CallbackTracker to store the last wallet_id, txid, and status
(in addition to the existing counters) and expose accessors; in
tests_callback.rs create a scenario that submits a tx to the mempool, triggers
the confirmation/InstantSend transition, then assert that
on_transaction_received and on_transaction_status_changed were called with the
expected status value by reading the CallbackTracker's
last_wallet_id/last_txid/last_status and comparing them to the expected wallet
and txid and to the new status enum; reference the existing functions
on_transaction_received and on_transaction_status_changed and the
CallbackTracker struct so changes are colocated with the existing asserts.

In `@key-wallet-manager/src/test_utils/wallet.rs`:
- Around line 102-105: process_instant_send_lock currently uses try_lock on
status_changes which can silently drop events under contention; change it to
acquire the lock deterministically (e.g. call lock() / unwrap() or otherwise
block until acquired) and then push (txid, TransactionContext::InstantSend) so
status_changes never loses records under contention; update the function
process_instant_send_lock to use the blocking lock mechanism (or a retry loop
that logs/errs on failure) instead of try_lock to ensure deterministic test
behavior.

In `@key-wallet-manager/src/wallet_manager/event_tests.rs`:
- Around line 197-228: The test currently only calls
process_instant_send_lock(tx.txid()) and asserts presence of events; update it
to cover the mixed entry points by invoking both paths
(process_instant_send_lock and check_transaction_in_all_wallets(...,
TransactionContext::InstantSend, ...)) in both orders and collecting events via
subscribe_events/drain_events; then assert that across both calls there is
exactly one WalletEvent::TransactionStatusChanged with status
TransactionContext::InstantSend for the expected wallet_id (and still assert
BalanceUpdated once), to catch duplicate-emission bugs. Ensure you reference the
existing helpers (setup_manager_with_wallet, create_tx_paying_to, drain_events)
and keep the wallet_id equality checks as in the original assertions.

In `@key-wallet-manager/src/wallet_manager/test_helpers.rs`:
- Around line 14-22: Change setup_manager_with_wallet to accept a Network
parameter instead of hardcoding Network::Testnet: update the signature of
setup_manager_with_wallet to fn setup_manager_with_wallet(network: Network) ->
(WalletManager<ManagedWalletInfo>, WalletId, Address) and construct the manager
with WalletManager::new(network) (references: setup_manager_with_wallet,
WalletManager::new, Network); update all test call sites to call it with
Network::Testnet or Network::Mainnet as appropriate, and optionally add a small
no-arg wrapper (e.g., setup_manager_with_wallet_testnet) that forwards
Network::Testnet for backward compatibility so new tests can run both
configurations.
- Around line 46-52: The drain_events helper currently treats all try_recv
errors the same and can silently drop events; update the body of pub(crate) fn
drain_events(rx: &mut broadcast::Receiver<WalletEvent>) to use an explicit match
on rx.try_recv(): push the event on Ok(e), break the loop on
Err(broadcast::error::TryRecvError::Empty), and panic (or assert/unwrap with a
clear message) on Err(broadcast::error::TryRecvError::Lagged(n)) so tests fail
if the receiver lagged and events were lost; reference drain_events,
broadcast::Receiver, WalletEvent and try_recv when making the change.

---

Outside diff comments:
In `@dash-spv-ffi/src/callbacks.rs`:
- Around line 523-533: The change mutates the v1 ABI by inserting a new
parameter into OnTransactionReceivedCallback and adding
on_transaction_status_changed to FFIWalletEventCallbacks, breaking existing
C/Swift consumers; instead keep the original OnTransactionReceivedCallback and
FFIWalletEventCallbacks unchanged, and add new types FFIWalletEventCallbacksV2
and OnTransactionReceivedCallbackV2 (with the extra status param) plus a new
registration function dash_spv_ffi_client_set_wallet_event_callbacks_v2() that
accepts the V2 struct; update any internal wiring to support both registrations
while preserving the original v1 symbols and layout so existing bindings remain
valid.

In `@key-wallet/src/transaction_checking/wallet_checker.rs`:
- Around line 191-203: The code currently sets result.state_modified = true
unconditionally after calling account.mark_utxos_instant_send in the for loop;
change this so state_modified is only set when at least one account actually
changed a UTXO. Introduce a local boolean (e.g., let mut any_changed = false),
call account.mark_utxos_instant_send(&txid) inside the loop and have that method
return a bool indicating whether it modified any UTXO (or detect the change via
account state), then set any_changed |= returned_bool. After the loop, only call
self.update_balance() and set result.state_modified = true if any_changed is
true; otherwise return result unchanged. Ensure you update the
signature/behavior of mark_utxos_instant_send (or read account change flags)
accordingly.

---

Nitpick comments:
In `@key-wallet-manager/src/wallet_interface.rs`:
- Around line 98-100: The doc comment for process_instant_send_lock currently
describes side effects but the default implementation is a no-op; update the
documentation for the method in wallet_interface.rs (fn
process_instant_send_lock) to explicitly state that the provided default
implementation does nothing and that implementations must override the method to
perform actions such as marking UTXOs as IS-locked, emitting status-change
events, and updating balances; keep the existing behavioral description but add
a clear sentence like “The default implementation is a no-op — override to
perform these actions.”

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 53118de6-43ae-4900-8074-e21a55d76d96

📥 Commits

Reviewing files that changed from the base of the PR and between 213a9b4 and c8fd4b2.

📒 Files selected for processing (14)
  • dash-spv-ffi/include/dash_spv_ffi.h
  • dash-spv-ffi/src/bin/ffi_cli.rs
  • dash-spv-ffi/src/callbacks.rs
  • dash-spv-ffi/tests/dashd_sync/callbacks.rs
  • dash-spv-ffi/tests/dashd_sync/tests_callback.rs
  • key-wallet-manager/src/events.rs
  • key-wallet-manager/src/test_utils/wallet.rs
  • key-wallet-manager/src/wallet_interface.rs
  • key-wallet-manager/src/wallet_manager/event_tests.rs
  • key-wallet-manager/src/wallet_manager/mod.rs
  • key-wallet-manager/src/wallet_manager/process_block.rs
  • key-wallet-manager/src/wallet_manager/test_helpers.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • key-wallet/src/transaction_checking/wallet_checker.rs

xdustinface added a commit that referenced this pull request Mar 18, 2026
…send_lock`

Addresses CodeRabbit review comment on PR #552
File: key-wallet-manager/src/test_utils/wallet.rs
xdustinface added a commit that referenced this pull request Mar 18, 2026
`process_instant_send_lock` did not record txids in `instant_send_locks`,
so a subsequent `check_transaction_in_all_wallets(..., InstantSend)` for
the same txid would emit a duplicate `TransactionStatusChanged` event.

Record the txid in `instant_send_locks` inside `mark_instant_send_utxos`
so both paths share the same deduplication set. Add tests covering both
orderings of the mixed entry points.

Addresses CodeRabbit review comment on PR #552
Files: key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs,
       key-wallet-manager/src/wallet_manager/event_tests.rs
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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@key-wallet-manager/src/wallet_manager/event_tests.rs`:
- Around line 11-433: Update the event-flow tests to run against both mainnet
and testnet by parameterizing the core helpers and flows: modify
setup_manager_with_wallet, assert_lifecycle_flow, and assert_context_suppressed
to accept a Network/Chain parameter (or add an explicit wrapper that creates a
manager for both networks) and then change each top-level #[tokio::test] to
iterate or call the helper twice (once for mainnet and once for testnet); ensure
process_block, process_instant_send_lock and check_transaction_in_all_wallets
are invoked on the manager instance tied to the specified network so the same
assertions run for both configurations.

In `@key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs`:
- Around line 237-239: The early return after checking
self.instant_send_locks.insert(*txid) prevents mark_utxos_instant_send from
running for duplicate txids and can miss later InstantSend transitions; change
the logic in the method containing the insert so that you always call
mark_utxos_instant_send(txid) (or the equivalent method) regardless of whether
insert returned false, and only suppress duplicate-specific actions (like
emitting duplicate-only events) based on the insert result—i.e., use the boolean
from self.instant_send_locks.insert(*txid) to conditionally skip duplicate-side
effects but do not return early before calling mark_utxos_instant_send.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f17e26ed-5fd7-490a-af79-d6fe2bab356c

📥 Commits

Reviewing files that changed from the base of the PR and between c8fd4b2 and 52b07ae.

📒 Files selected for processing (3)
  • key-wallet-manager/src/test_utils/wallet.rs
  • key-wallet-manager/src/wallet_manager/event_tests.rs
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 18, 2026
xdustinface added a commit that referenced this pull request Mar 19, 2026
…send_lock`

Addresses CodeRabbit review comment on PR #552
File: key-wallet-manager/src/test_utils/wallet.rs
xdustinface added a commit that referenced this pull request Mar 19, 2026
`process_instant_send_lock` did not record txids in `instant_send_locks`,
so a subsequent `check_transaction_in_all_wallets(..., InstantSend)` for
the same txid would emit a duplicate `TransactionStatusChanged` event.

Record the txid in `instant_send_locks` inside `mark_instant_send_utxos`
so both paths share the same deduplication set. Add tests covering both
orderings of the mixed entry points.

Addresses CodeRabbit review comment on PR #552
Files: key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs,
       key-wallet-manager/src/wallet_manager/event_tests.rs
@xdustinface xdustinface force-pushed the feat/transaction-status-events branch from 52b07ae to 837c8b7 Compare March 19, 2026 02:40
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
dash-spv-ffi/src/callbacks.rs (2)

523-533: ⚠️ Potential issue | 🟠 Major

ABI breaking change: status parameter inserted mid-signature.

The callback signature now has status as the second parameter, but existing C/Swift consumers compiled against the previous signature expect account_index in that position. This causes argument misalignment and undefined behavior for pre-compiled binaries.

To preserve backward compatibility:

  • Option A: Append status as the last parameter before user_data
  • Option B: Introduce OnTransactionReceivedCallbackV2 with the new signature while keeping the original intact
🛡️ Option A: Append status before user_data
 pub type OnTransactionReceivedCallback = Option<
     extern "C" fn(
         wallet_id: *const c_char,
-        status: FFITransactionContext,
         account_index: u32,
         txid: *const [u8; 32],
         amount: i64,
         addresses: *const c_char,
+        status: FFITransactionContext,
         user_data: *mut c_void,
     ),
 >;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dash-spv-ffi/src/callbacks.rs` around lines 523 - 533, The callback signature
was changed in-place causing an ABI break: restore backward compatibility by
keeping the original OnTransactionReceivedCallback (with wallet_id,
account_index, txid, amount, addresses, user_data) and implement one of two
fixes—either append the new status parameter just before user_data (so original
parameter order remains for existing consumers) or introduce a new typedef
OnTransactionReceivedCallbackV2 that includes the new status parameter in its
signature while leaving the existing OnTransactionReceivedCallback untouched;
update internal call sites to use the V2 symbol where appropriate and ensure any
registration/dispatch paths accept both callback types.

571-578: ⚠️ Potential issue | 🟠 Major

Struct layout break: new field shifts on_balance_updated and user_data offsets.

Inserting on_transaction_status_changed before on_balance_updated changes the memory layout. Pre-compiled C/Swift code accessing on_balance_updated or user_data will read incorrect memory locations.

Append the new field just before user_data to maintain backward-compatible offsets for existing fields:

🛡️ Proposed layout fix
 pub struct FFIWalletEventCallbacks {
     pub on_transaction_received: OnTransactionReceivedCallback,
-    pub on_transaction_status_changed: OnTransactionStatusChangedCallback,
     pub on_balance_updated: OnBalanceUpdatedCallback,
+    pub on_transaction_status_changed: OnTransactionStatusChangedCallback,
     pub user_data: *mut c_void,
 }

Update the Default impl accordingly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dash-spv-ffi/src/callbacks.rs` around lines 571 - 578, The new field
on_transaction_status_changed was inserted before on_balance_updated, altering
the struct memory layout of FFIWalletEventCallbacks; move
on_transaction_status_changed so it appears immediately before user_data (i.e.,
after on_balance_updated) to preserve existing offsets, and update the Default
implementation for FFIWalletEventCallbacks to initialize the fields in the new
order (including a sensible default for on_transaction_status_changed) so the
struct layout and defaults remain backward-compatible for C/Swift callers.
♻️ Duplicate comments (2)
key-wallet-manager/src/wallet_manager/test_helpers.rs (2)

14-22: ⚠️ Potential issue | 🟡 Minor

Parameterize test setup by network instead of hardcoding Testnet.

Line 15 hardcodes Network::Testnet, so all callers are locked to one network path and can’t easily run the same lifecycle assertions on mainnet.

Suggested fix
-pub(crate) fn setup_manager_with_wallet() -> (WalletManager<ManagedWalletInfo>, WalletId, Address) {
-    let mut manager = WalletManager::new(Network::Testnet);
+pub(crate) fn setup_manager_with_wallet(
+    network: Network,
+) -> (WalletManager<ManagedWalletInfo>, WalletId, Address) {
+    let mut manager = WalletManager::new(network);
     let wallet_id = manager
         .create_wallet_from_mnemonic(TEST_MNEMONIC, "", 0, WalletAccountCreationOptions::Default)
         .unwrap();
@@
     let addr = addresses[0].clone();
     (manager, wallet_id, addr)
 }
+
+pub(crate) fn setup_manager_with_wallet_testnet() -> (WalletManager<ManagedWalletInfo>, WalletId, Address) {
+    setup_manager_with_wallet(Network::Testnet)
+}

As per coding guidelines, "Test both mainnet and testnet configurations".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@key-wallet-manager/src/wallet_manager/test_helpers.rs` around lines 14 - 22,
The helper setup_manager_with_wallet hardcodes Network::Testnet when
constructing WalletManager (WalletManager::new(Network::Testnet)); change the
function to accept a Network parameter (e.g., setup_manager_with_wallet(network:
Network) -> (...)) and pass that into WalletManager::new so callers can invoke
it for Mainnet or Testnet; update any callers/tests to pass Network::Testnet or
Network::Mainnet accordingly and keep the same wallet creation flow
(create_wallet_from_mnemonic, monitored_addresses) and return types
(WalletManager<ManagedWalletInfo>, WalletId, Address).

46-50: ⚠️ Potential issue | 🟡 Minor

Handle TryRecvError::Lagged(_) explicitly in drain_events.

Current logic stops on any error, so Lagged(_) is treated like “no more events,” which can hide dropped events and make assertions falsely pass.

Suggested fix
 pub(crate) fn drain_events(rx: &mut broadcast::Receiver<WalletEvent>) -> Vec<WalletEvent> {
     let mut events = Vec::new();
-    while let Ok(e) = rx.try_recv() {
-        events.push(e);
-    }
+    loop {
+        match rx.try_recv() {
+            Ok(event) => events.push(event),
+            Err(broadcast::error::TryRecvError::Empty) => break,
+            Err(broadcast::error::TryRecvError::Closed) => break,
+            Err(broadcast::error::TryRecvError::Lagged(skipped)) => {
+                panic!("event receiver lagged and skipped {skipped} wallet events");
+            }
+        }
+    }
     events
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@key-wallet-manager/src/wallet_manager/test_helpers.rs` around lines 46 - 50,
The current drain_events function treats any try_recv error as "no more events"
and hides dropped messages; change the loop to match on rx.try_recv(): on Ok(e)
push to events; on Err(broadcast::error::TryRecvError::Empty) break the loop; on
Err(broadcast::error::TryRecvError::Lagged(skipped)) explicitly fail (panic or
assert) with a message including skipped so tests surface dropped events instead
of silently passing; reference the drain_events function, broadcast::Receiver,
TryRecvError::Lagged and WalletEvent when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@dash-spv-ffi/src/callbacks.rs`:
- Around line 523-533: The callback signature was changed in-place causing an
ABI break: restore backward compatibility by keeping the original
OnTransactionReceivedCallback (with wallet_id, account_index, txid, amount,
addresses, user_data) and implement one of two fixes—either append the new
status parameter just before user_data (so original parameter order remains for
existing consumers) or introduce a new typedef OnTransactionReceivedCallbackV2
that includes the new status parameter in its signature while leaving the
existing OnTransactionReceivedCallback untouched; update internal call sites to
use the V2 symbol where appropriate and ensure any registration/dispatch paths
accept both callback types.
- Around line 571-578: The new field on_transaction_status_changed was inserted
before on_balance_updated, altering the struct memory layout of
FFIWalletEventCallbacks; move on_transaction_status_changed so it appears
immediately before user_data (i.e., after on_balance_updated) to preserve
existing offsets, and update the Default implementation for
FFIWalletEventCallbacks to initialize the fields in the new order (including a
sensible default for on_transaction_status_changed) so the struct layout and
defaults remain backward-compatible for C/Swift callers.

---

Duplicate comments:
In `@key-wallet-manager/src/wallet_manager/test_helpers.rs`:
- Around line 14-22: The helper setup_manager_with_wallet hardcodes
Network::Testnet when constructing WalletManager
(WalletManager::new(Network::Testnet)); change the function to accept a Network
parameter (e.g., setup_manager_with_wallet(network: Network) -> (...)) and pass
that into WalletManager::new so callers can invoke it for Mainnet or Testnet;
update any callers/tests to pass Network::Testnet or Network::Mainnet
accordingly and keep the same wallet creation flow (create_wallet_from_mnemonic,
monitored_addresses) and return types (WalletManager<ManagedWalletInfo>,
WalletId, Address).
- Around line 46-50: The current drain_events function treats any try_recv error
as "no more events" and hides dropped messages; change the loop to match on
rx.try_recv(): on Ok(e) push to events; on
Err(broadcast::error::TryRecvError::Empty) break the loop; on
Err(broadcast::error::TryRecvError::Lagged(skipped)) explicitly fail (panic or
assert) with a message including skipped so tests surface dropped events instead
of silently passing; reference the drain_events function, broadcast::Receiver,
TryRecvError::Lagged and WalletEvent when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: df333cc6-e462-4344-a2a2-3369928af9f4

📥 Commits

Reviewing files that changed from the base of the PR and between 52b07ae and 837c8b7.

📒 Files selected for processing (15)
  • dash-spv-ffi/include/dash_spv_ffi.h
  • dash-spv-ffi/src/bin/ffi_cli.rs
  • dash-spv-ffi/src/callbacks.rs
  • dash-spv-ffi/tests/dashd_sync/callbacks.rs
  • dash-spv-ffi/tests/dashd_sync/tests_callback.rs
  • key-wallet-manager/src/events.rs
  • key-wallet-manager/src/test_utils/wallet.rs
  • key-wallet-manager/src/wallet_interface.rs
  • key-wallet-manager/src/wallet_manager/event_tests.rs
  • key-wallet-manager/src/wallet_manager/mod.rs
  • key-wallet-manager/src/wallet_manager/process_block.rs
  • key-wallet-manager/src/wallet_manager/test_helpers.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
✅ Files skipped from review due to trivial changes (2)
  • dash-spv-ffi/tests/dashd_sync/tests_callback.rs
  • dash-spv-ffi/tests/dashd_sync/callbacks.rs
🚧 Files skipped from review as they are similar to previous changes (10)
  • key-wallet-manager/src/wallet_interface.rs
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
  • dash-spv-ffi/src/bin/ffi_cli.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet-manager/src/test_utils/wallet.rs
  • key-wallet-manager/src/wallet_manager/process_block.rs
  • key-wallet-manager/src/events.rs
  • key-wallet-manager/src/wallet_manager/mod.rs
  • key-wallet-manager/src/wallet_manager/event_tests.rs

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 19, 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.

🧹 Nitpick comments (1)
key-wallet-manager/src/wallet_manager/event_tests.rs (1)

266-268: Remove redundant import.

dashcore::hashes::Hash is already imported at the module level (line 4). The local import is unnecessary.

♻️ Suggested fix
 async fn test_process_block_emits_events() {
     use dashcore::blockdata::block::{Block, Header, Version};
-    use dashcore::hashes::Hash;
     use dashcore::{BlockHash, CompactTarget, TxMerkleNode};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@key-wallet-manager/src/wallet_manager/event_tests.rs` around lines 266 - 268,
Remove the redundant local import of dashcore::hashes::Hash in the import block
that contains Block, Header, Version and BlockHash/CompactTarget/TxMerkleNode;
the symbol is already imported at module scope so simply delete the `use
dashcore::hashes::Hash;` line (leave the other imports and identifiers such as
Block, Header, Version, BlockHash, CompactTarget, and TxMerkleNode unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@key-wallet-manager/src/wallet_manager/event_tests.rs`:
- Around line 266-268: Remove the redundant local import of
dashcore::hashes::Hash in the import block that contains Block, Header, Version
and BlockHash/CompactTarget/TxMerkleNode; the symbol is already imported at
module scope so simply delete the `use dashcore::hashes::Hash;` line (leave the
other imports and identifiers such as Block, Header, Version, BlockHash,
CompactTarget, and TxMerkleNode unchanged).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 048166df-8544-4a75-93ac-5bb2485d64c7

📥 Commits

Reviewing files that changed from the base of the PR and between 837c8b7 and baff83f.

📒 Files selected for processing (2)
  • key-wallet-manager/src/wallet_manager/event_tests.rs
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
✅ Files skipped from review due to trivial changes (1)
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 19, 2026
xdustinface added a commit that referenced this pull request Mar 19, 2026
…send_lock`

Addresses CodeRabbit review comment on PR #552
File: key-wallet-manager/src/test_utils/wallet.rs
xdustinface added a commit that referenced this pull request Mar 19, 2026
`process_instant_send_lock` did not record txids in `instant_send_locks`,
so a subsequent `check_transaction_in_all_wallets(..., InstantSend)` for
the same txid would emit a duplicate `TransactionStatusChanged` event.

Record the txid in `instant_send_locks` inside `mark_instant_send_utxos`
so both paths share the same deduplication set. Add tests covering both
orderings of the mixed entry points.

Addresses CodeRabbit review comment on PR #552
Files: key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs,
       key-wallet-manager/src/wallet_manager/event_tests.rs
@xdustinface xdustinface force-pushed the feat/transaction-status-events branch from baff83f to 92cf7db Compare March 19, 2026 03:33
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
dash-spv-ffi/src/callbacks.rs (1)

523-533: ⚠️ Potential issue | 🟠 Major

Note: This is the source of the ABI break flagged in the header file.

The status parameter insertion at position 2 (after wallet_id) causes the ABI compatibility issue. To preserve backward compatibility, consider moving status to be the last parameter before user_data, or introduce a versioned callback type.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dash-spv-ffi/src/callbacks.rs` around lines 523 - 533, The callback type
OnTransactionReceivedCallback currently inserts the new status parameter as the
second argument, breaking the ABI; update the signature so FFITransactionContext
status is moved to be the last parameter before user_data (i.e., after addresses
and amount) or alternatively introduce a new versioned type (e.g.,
OnTransactionReceivedCallbackV2) preserving the original
OnTransactionReceivedCallback layout; ensure all references to
OnTransactionReceivedCallback and any registrations/extern "C" callers are
updated to the chosen approach to maintain backward compatibility.
♻️ Duplicate comments (1)
dash-spv-ffi/include/dash_spv_ffi.h (1)

377-394: ⚠️ Potential issue | 🟠 Major

ABI-breaking changes in callback signatures and struct layout.

The OnTransactionReceivedCallback signature was modified by inserting FFITransactionContext status as the second parameter, and FFIWalletEventCallbacks layout changed by inserting on_transaction_status_changed mid-struct. Pre-compiled C/Swift clients will experience undefined behavior when these callbacks are invoked with misaligned arguments.

As noted in the PR objectives, preserve backward compatibility by either:

  1. Appending status as the last parameter before user_data
  2. Introducing versioned callbacks (OnTransactionReceivedCallbackV2, FFIWalletEventCallbacksV2)

Since this header is auto-generated by cbindgen, the fix must be applied to the Rust source in dash-spv-ffi/src/callbacks.rs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dash-spv-ffi/include/dash_spv_ffi.h` around lines 377 - 394, The header
changed the ABI by inserting FFITransactionContext into the middle of
OnTransactionReceivedCallback and by inserting on_transaction_status_changed
into FFIWalletEventCallbacks; update the Rust source
(dash-spv-ffi/src/callbacks.rs) to preserve ABI compatibility by either adding a
new versioned type (e.g., define OnTransactionReceivedCallbackV2 and
FFIWalletEventCallbacksV2) or by moving the new FFITransactionContext parameter
to the end of the existing OnTransactionReceivedCallback before user_data so the
original function pointer layout is unchanged; ensure the generated cbindgen
output keeps the original OnTransactionReceivedCallback and
FFIWalletEventCallbacks definitions intact (and emits V2 variants if you choose
versioning), then re-run cbindgen to regenerate dash_spv_ffi.h.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@dash-spv-ffi/src/callbacks.rs`:
- Around line 523-533: The callback type OnTransactionReceivedCallback currently
inserts the new status parameter as the second argument, breaking the ABI;
update the signature so FFITransactionContext status is moved to be the last
parameter before user_data (i.e., after addresses and amount) or alternatively
introduce a new versioned type (e.g., OnTransactionReceivedCallbackV2)
preserving the original OnTransactionReceivedCallback layout; ensure all
references to OnTransactionReceivedCallback and any registrations/extern "C"
callers are updated to the chosen approach to maintain backward compatibility.

---

Duplicate comments:
In `@dash-spv-ffi/include/dash_spv_ffi.h`:
- Around line 377-394: The header changed the ABI by inserting
FFITransactionContext into the middle of OnTransactionReceivedCallback and by
inserting on_transaction_status_changed into FFIWalletEventCallbacks; update the
Rust source (dash-spv-ffi/src/callbacks.rs) to preserve ABI compatibility by
either adding a new versioned type (e.g., define OnTransactionReceivedCallbackV2
and FFIWalletEventCallbacksV2) or by moving the new FFITransactionContext
parameter to the end of the existing OnTransactionReceivedCallback before
user_data so the original function pointer layout is unchanged; ensure the
generated cbindgen output keeps the original OnTransactionReceivedCallback and
FFIWalletEventCallbacks definitions intact (and emits V2 variants if you choose
versioning), then re-run cbindgen to regenerate dash_spv_ffi.h.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f4edde5a-128e-4b81-8839-1a8dbc76d8db

📥 Commits

Reviewing files that changed from the base of the PR and between baff83f and 92cf7db.

📒 Files selected for processing (15)
  • dash-spv-ffi/include/dash_spv_ffi.h
  • dash-spv-ffi/src/bin/ffi_cli.rs
  • dash-spv-ffi/src/callbacks.rs
  • dash-spv-ffi/tests/dashd_sync/callbacks.rs
  • dash-spv-ffi/tests/dashd_sync/tests_callback.rs
  • key-wallet-manager/src/events.rs
  • key-wallet-manager/src/test_utils/wallet.rs
  • key-wallet-manager/src/wallet_interface.rs
  • key-wallet-manager/src/wallet_manager/event_tests.rs
  • key-wallet-manager/src/wallet_manager/mod.rs
  • key-wallet-manager/src/wallet_manager/process_block.rs
  • key-wallet-manager/src/wallet_manager/test_helpers.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
✅ Files skipped from review due to trivial changes (3)
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
  • key-wallet-manager/src/events.rs
  • key-wallet-manager/src/wallet_manager/event_tests.rs
🚧 Files skipped from review as they are similar to previous changes (6)
  • key-wallet-manager/src/wallet_interface.rs
  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • key-wallet-manager/src/test_utils/wallet.rs
  • dash-spv-ffi/tests/dashd_sync/tests_callback.rs
  • dash-spv-ffi/src/bin/ffi_cli.rs

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 19, 2026
@xdustinface xdustinface requested a review from ZocoLini March 19, 2026 03:51
xdustinface added a commit that referenced this pull request Mar 19, 2026
…send_lock`

Addresses CodeRabbit review comment on PR #552
File: key-wallet-manager/src/test_utils/wallet.rs
xdustinface added a commit that referenced this pull request Mar 19, 2026
`process_instant_send_lock` did not record txids in `instant_send_locks`,
so a subsequent `check_transaction_in_all_wallets(..., InstantSend)` for
the same txid would emit a duplicate `TransactionStatusChanged` event.

Record the txid in `instant_send_locks` inside `mark_instant_send_utxos`
so both paths share the same deduplication set. Add tests covering both
orderings of the mixed entry points.

Addresses CodeRabbit review comment on PR #552
Files: key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs,
       key-wallet-manager/src/wallet_manager/event_tests.rs
@xdustinface xdustinface force-pushed the feat/transaction-status-events branch from 92cf7db to 39d06fb Compare March 19, 2026 07:58
@github-actions github-actions bot added ready-for-review CodeRabbit has approved this PR merge-conflict The PR conflicts with the target branch. labels Mar 19, 2026
@github-actions
Copy link

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

xdustinface added a commit that referenced this pull request Mar 20, 2026
…send_lock`

Addresses CodeRabbit review comment on PR #552
File: key-wallet-manager/src/test_utils/wallet.rs
xdustinface added a commit that referenced this pull request Mar 20, 2026
`process_instant_send_lock` did not record txids in `instant_send_locks`,
so a subsequent `check_transaction_in_all_wallets(..., InstantSend)` for
the same txid would emit a duplicate `TransactionStatusChanged` event.

Record the txid in `instant_send_locks` inside `mark_instant_send_utxos`
so both paths share the same deduplication set. Add tests covering both
orderings of the mixed entry points.

Addresses CodeRabbit review comment on PR #552
Files: key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs,
       key-wallet-manager/src/wallet_manager/event_tests.rs
@xdustinface xdustinface force-pushed the feat/transaction-status-events branch from 39d06fb to 3063b15 Compare March 20, 2026 06:14
@github-actions github-actions bot added merge-conflict The PR conflicts with the target branch. and removed merge-conflict The PR conflicts with the target branch. ready-for-review CodeRabbit has approved this PR labels Mar 20, 2026
@github-actions
Copy link

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

xdustinface added a commit that referenced this pull request Mar 20, 2026
…send_lock`

Addresses CodeRabbit review comment on PR #552
File: key-wallet-manager/src/test_utils/wallet.rs
xdustinface added a commit that referenced this pull request Mar 20, 2026
`process_instant_send_lock` did not record txids in `instant_send_locks`,
so a subsequent `check_transaction_in_all_wallets(..., InstantSend)` for
the same txid would emit a duplicate `TransactionStatusChanged` event.

Record the txid in `instant_send_locks` inside `mark_instant_send_utxos`
so both paths share the same deduplication set. Add tests covering both
orderings of the mixed entry points.

Addresses CodeRabbit review comment on PR #552
Files: key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs,
       key-wallet-manager/src/wallet_manager/event_tests.rs
- Add `TransactionStatusChanged` variant to `WalletEvent` and a `status` field to `TransactionReceived`.
- Wire up event emission in `check_transaction_in_all_wallets`, `process_instant_send_lock`, and `update_synced_height`.
- Add FFI callback for status changes.
…send_lock`

Addresses CodeRabbit review comment on PR #552
File: key-wallet-manager/src/test_utils/wallet.rs
`process_instant_send_lock` did not record txids in `instant_send_locks`,
so a subsequent `check_transaction_in_all_wallets(..., InstantSend)` for
the same txid would emit a duplicate `TransactionStatusChanged` event.

Record the txid in `instant_send_locks` inside `mark_instant_send_utxos`
so both paths share the same deduplication set. Add tests covering both
orderings of the mixed entry points.

Addresses CodeRabbit review comment on PR #552
Files: key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs,
       key-wallet-manager/src/wallet_manager/event_tests.rs
@xdustinface xdustinface force-pushed the feat/transaction-status-events branch from 3063b15 to 7cf7b6c Compare March 20, 2026 09:39
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Mar 20, 2026
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