Skip to content

chore: re-merge v0.42-dev (real merge commit)#699

Merged
QuantumExplorer merged 4 commits intofeat/per-wallet-filter-scanfrom
merge/v0.42-dev-into-per-wallet-filter-scan-v2
Apr 28, 2026
Merged

chore: re-merge v0.42-dev (real merge commit)#699
QuantumExplorer merged 4 commits intofeat/per-wallet-filter-scanfrom
merge/v0.42-dev-into-per-wallet-filter-scan-v2

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

Follow-up to #698. That PR was squash-merged, which flattened the two-parent merge commit into a single linear commit. As a result, feat/per-wallet-filter-scan's history no longer records v0.42-dev as an ancestor, and #694 re-computes the same conflicts even though the content is already integrated.

This PR creates a real merge commit so the parent link is recorded.

⚠️ MUST be merged with "Create a merge commit"

Do NOT use "Squash and merge" — squashing again would recreate the same problem and leave #694 in CONFLICTING state. Use the dropdown next to the merge button to pick "Create a merge commit".

What's in this merge

  • The 3 previously-conflicting files (key-wallet-manager/src/{lib,process_block,event_tests}.rs) get re-flagged by git's 3-way merge as conflicts because the squashed commit looks like an independent change to git, not a merge. Resolved with git merge -X ours since feat/per-wallet-filter-scan already has the correct merged content from #698.
  • Picks up #685 (mutable-pair accessors + insert_wallet) which landed on v0.42-dev after #698 was merged. That's the only net content change — key-wallet-manager/src/accessors.rs +68 lines.

Verified

  • cargo build --workspace
  • cargo test -p key-wallet-manager — 31 unit + integration tests pass
  • Merge commit has two parents: a8e381ad (current feat tip) + da28aca1 (current v0.42-dev tip), so #694's merge-base will be v0.42-dev's tip, eliminating the phantom conflicts.

Test plan

  • Merge with "Create a merge commit" (not squash)
  • After merge, #694 should flip to MERGEABLE

🤖 Generated with Claude Code

github-actions Bot and others added 4 commits April 28, 2026 11:36
Co-authored-by: QuantumExplorer <11468583+QuantumExplorer@users.noreply.github.com>
* feat: make wallet events atomic

Reshape `WalletEvent` so each variant carries the records or context needed to persist a wallet update atomically off a single event, alongside the post-change balance.

The variant set is now:

- `TransactionReceived { wallet_id, record, balance }`. Fires when the wallet first sees an off-chain transaction.
- `TransactionStatusChanged { wallet_id, txid, context, balance }`. Fires when a known off-chain transaction has its state change. Currently fires only for InstantSend locks.
- `BlockUpdate { wallet_id, height, inserted, updated, matured, balance }`. Carries records bucketed by what happened to them in the block, plus the post-block balance.
- `SyncHeightUpdate { wallet_id, height }`. Marks a filter-batch checkpoint.

`TransactionRecord` carries `account_type` directly, identifying the owning account. `WalletInfoInterface` gains a `matured_coinbase_records` method that enumerates coinbase records crossing the maturity threshold during a height advance, populating `BlockUpdate.matured`.

The FFI groups the flattened account-discriminator fields into an `FFIAccountType` struct and renames the prior discriminant enum to `FFIAccountKind`.

* fix: record balance before bumping `block_processed_wallet_count`

Tests wait on `block_processed_wallet_count` and then read `last_confirmed`/`last_unconfirmed`. Bumping the counter before storing the balance snapshot left those reads racey. Reorder so the balance is recorded first.

Addresses CodeRabbit review comment on PR #696
#696 (comment)

* fix: place `IdentityTopUp.registration_index` in `index_secondary`

The `FFIAccountType` doc states `index_secondary` carries `registration_index` for `IdentityTopUp` and `index = 0` for variants without a meaningful primary index, matching the parallel encoding in `FFIAccountKind::from_account_type`. The `From<&AccountType>` impl wrote `registration_index` into `index` instead, breaking the documented FFI contract.

Addresses CodeRabbit review comment on PR #696
#696 (comment)

* fix: route confirmation backfills to `new_records`

`is_new` is wallet-wide (set on the first matching account, then breaks), so the per-account `else` branch can run for an account that did not previously hold the record. `confirm_transaction` backfills via `record_transaction` in that case, but the post-call record was always pushed onto `updated_records`, breaking the atomic `inserted`/`updated` contract consumed by `WalletEvent::BlockUpdate`. Capture `existed_before` per account and route to `new_records` when the record was just created.

Addresses CodeRabbit review comment on PR #696
#696 (comment)

* refactor(key-wallet-manager): extract `finalize_block_advance` helper

`process_block` and `update_last_processed_height` duplicated the entire balance-snapshot, prior-heights collection, matured-coinbase window, height advance, and per-wallet `BlockUpdate` emission. Extract the shared tail into a private `WalletManager::finalize_block_advance` helper that takes the inserted/updated maps. `update_last_processed_height` becomes a one-line call with empty maps; `process_block` keeps only its txdata loop before delegating.

* refactor: rename wallet events for clearer semantics

Rename `WalletEvent` variants and the matching FFI callbacks to past-participle names that say what happened, replacing vague "Update" suffixes:

- `TransactionReceived` -> `TransactionDetected`. "Received" implied incoming funds, but the event fires for any first-time off-chain sighting (incoming or outgoing).
- `TransactionStatusChanged` -> `TransactionInstantLocked`. The event only ever fires for an InstantSend lock applied to a known mempool tx, so name it for what it actually is. Drop the `status: TransactionContext` field and carry the `InstantLock` directly.
- `BlockUpdate` -> `BlockProcessed`. Mirrors `process_block` and matches the past-participle pattern.
- `SyncHeightUpdate` -> `SyncHeightAdvanced`. Conveys monotonic forward motion.

FFI rename mirrors the Rust side: the IS callback now takes `islock_data: *const u8` + `islock_len: usize` instead of an `FFITransactionContext`, removing a discriminant that was always `InstantSend`. The wallet-side `OnBlockProcessedCallback` becomes `OnWalletBlockProcessedCallback` to disambiguate from the existing sync-event type with the same name.

* fix: record balance before bumping IS-locked counter in test callback

Addresses CodeRabbit review comment on PR #696
#696 (review)

The instant_locked callback bumped `transaction_instant_send_locked_count` before calling `record_balance`. Tests that wait on the counter and then read `last_confirmed`/`last_unconfirmed` could observe the previous balance snapshot. Match the ordering used by the other callbacks: store the balance first, then bump the counter.

* fix: backfill missing transaction record in InstantSend path

Addresses CodeRabbit review comment on PR #696
#696 (review)

The IS-lock branch in `WalletTransactionChecker::check_core_transaction` only updated accounts that already held a `TransactionRecord` for the txid. When wallet-level `is_new` was `false` (because at least one account had the record) but another matched account did not, the latter was silently skipped: no record was created and `mark_utxos_instant_send` ran against an empty UTXO set on that account.

Mirror the confirmation path: when the affected account lacks the record, call `record_transaction` to register the record and its UTXOs, then mark them IS-locked. This ordering ensures the freshly registered UTXOs receive the IS-lock flag too. The backfilled record is pushed into `new_records` to match the existing convention from commit 659a6d5.

Add `test_instantsend_backfills_missing_record_in_other_account` covering the multi-account scenario.
…685)

* feat(key-wallet-manager): add mutable-pair accessors + insert_wallet

Adds three accessors on WalletManager that exploit the split borrow
between the independent `wallets` and `wallet_infos` maps:

- `get_wallet_and_info_mut` — `(&Wallet, &mut T)` for mutations that
  read wallet config while writing info (UTXOs, balance, tx history).
- `get_wallet_mut_and_info_mut` — `(&mut Wallet, &mut T)` for cases
  that need to mutate the wallet itself (e.g. idempotent re-derivation
  of HD accounts during changeset replay).
- `insert_wallet` — register a pre-built `(Wallet, T)` pair, returns
  `WalletExists` on duplicate and bumps `structural_revision` on
  success. Enables restore paths that reconstruct wallets from
  persistence without going through the mnemonic-based builder.

Unit tests cover dedup error, split-borrow mutation across both maps,
and the monitor-revision bump on insert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(key-wallet-manager): drop redundant accessor tests

Per ZocoLini's review on #685: the type system already proves the
mutable-borrow accessors return the right shape, and monitor_revision is
covered elsewhere. Keep insert_wallet_rejects_duplicate since it
exercises actual error-path logic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 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: cc26442a-1cc9-4dbd-aee1-afdd3a471914

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 merge/v0.42-dev-into-per-wallet-filter-scan-v2

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.

@QuantumExplorer QuantumExplorer merged commit 8f112f1 into feat/per-wallet-filter-scan Apr 28, 2026
32 of 33 checks passed
@QuantumExplorer QuantumExplorer deleted the merge/v0.42-dev-into-per-wallet-filter-scan-v2 branch April 28, 2026 05:29
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