fix(spv): match masternode owner/voting key hashes in compact filters#863
Conversation
During SPV historical sync, `dash-spv` chose which blocks to download by matching the wallet's watched scriptPubKeys against BIP157/158 compact filters. The matcher built its `FilterQuery` from scriptPubKeys only. Dash Core, however, also inserts a `ProRegTx`'s owner (`keyIDOwner`) and voting (`keyIDVoting`) key hashes into the block's compact filter as bare 20-byte `hash160` elements, not as P2PKH scripts (see `ExtractSpecialTxFilterElements`). A masternode owner who controls only the owner/voting keys, with no wallet-owned input or output in the `ProRegTx`, therefore never matched, the block was never downloaded, and the payload-aware wallet scan never ran on it. This adds each provider owner and voting key hash (bare 20-byte `hash160`) to the compact-filter query. `key-wallet` surfaces them via `WalletInfoInterface::monitored_filter_elements`, extracting the same bytes (same order) the BIP37 bloom path already inserts via `address_payload_bytes`. `key-wallet-manager` exposes `WalletInterface::monitored_filter_elements_for` and folds the extra elements into the shared `FilterQuery` (its `other` length bucket) in `check_compact_filters_for_elements` (renamed from `check_compact_filters_for_script_pubkeys`). `dash-spv`'s filter manager now passes each wallet's elements alongside its scripts in both the batch scan and the new-script rescan, including the per-wallet attribution queries. Step 1 of dashpay#861: owner/voting only. Collateral outpoint and `proTxHash` follow in stacked branches.
📝 WalkthroughWalkthroughWallet compact-filter matching now includes monitored bare provider owner and voting key hashes alongside scriptPubKeys. Wallet interfaces expose these elements, the matcher accepts them, and SPV scan/rescan attribution uses both query dimensions. ChangesCompact filter element matching
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant WalletInfo
participant WalletManager
participant FiltersManager
participant CompactFilterMatcher
WalletInfo->>WalletManager: provide monitored filter elements
WalletManager->>FiltersManager: return wallet scripts and elements
FiltersManager->>CompactFilterMatcher: match unioned scripts and elements
CompactFilterMatcher-->>FiltersManager: return matching filter keys
FiltersManager->>WalletManager: attribute matches per wallet
Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## dev #863 +/- ##
==========================================
- Coverage 73.62% 73.61% -0.01%
==========================================
Files 324 324
Lines 73195 73374 +179
==========================================
+ Hits 53888 54013 +125
- Misses 19307 19361 +54
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs (1)
358-379: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a unit test for
monitored_filter_elements.No test in this file exercises the new extraction logic directly (that a
ProviderOwnerKeys/ProviderVotingKeysaccount'shash160is returned and other account types are excluded). As per coding guidelines, "Write unit tests for new functionality" for**/*.rs, and this is non-trivial logic (not a plain getter), so it falls outside the "skip tests for trivial methods" learning.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs` around lines 358 - 379, Add a focused unit test for WalletInfo::monitored_filter_elements covering ProviderOwnerKeys and ProviderVotingKeys accounts with PubkeyHash/ScriptHash addresses, asserting their 20-byte hashes are returned, while addresses with unsupported payloads and non-provider account types are excluded. Reuse the file’s existing wallet/account test helpers and assert the complete returned vector.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs`:
- Around line 358-379: Add a focused unit test for
WalletInfo::monitored_filter_elements covering ProviderOwnerKeys and
ProviderVotingKeys accounts with PubkeyHash/ScriptHash addresses, asserting
their 20-byte hashes are returned, while addresses with unsupported payloads and
non-provider account types are excluded. Reuse the file’s existing
wallet/account test helpers and assert the complete returned vector.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0ae380c4-6642-4e66-9354-3d3302216180
📒 Files selected for processing (6)
dash-spv/src/sync/filters/manager.rskey-wallet-manager/src/lib.rskey-wallet-manager/src/matching.rskey-wallet-manager/src/process_block.rskey-wallet-manager/src/wallet_interface.rskey-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
During SPV historical sync,
dash-spvchose which blocks to download by matching the wallet's watched scriptPubKeys against BIP157/158 compact filters. The matcher built itsFilterQueryfrom scriptPubKeys only. Dash Core, however, also inserts aProRegTx's owner (keyIDOwner) and voting (keyIDVoting) key hashes into the block's compact filter as bare 20-bytehash160elements, not as P2PKH scripts (seeExtractSpecialTxFilterElements). A masternode owner who controls only the owner/voting keys, with no wallet-owned input or output in theProRegTx, therefore never matched, the block was never downloaded, and the payload-aware wallet scan never ran on it.This adds each provider owner and voting key hash (bare 20-byte
hash160) to the compact-filter query.key-walletsurfaces them viaWalletInfoInterface::monitored_filter_elements, extracting the same bytes (same order) the BIP37 bloom path already inserts viaaddress_payload_bytes.key-wallet-managerexposesWalletInterface::monitored_filter_elements_forand folds the extra elements into the sharedFilterQuery(itsotherlength bucket) incheck_compact_filters_for_elements(renamed fromcheck_compact_filters_for_script_pubkeys).dash-spv's filter manager now passes each wallet's elements alongside its scripts in both the batch scan and the new-script rescan, including the per-wallet attribution queries.Step 1 of #861: owner/voting only. Collateral outpoint and
proTxHashfollow in stacked branches.Summary by CodeRabbit
New Features
Bug Fixes