fix(dash-spv): match masternode collateral outpoints in compact filters#864
Conversation
Dash Core inserts a `ProRegTx`'s `collateralOutpoint` into the block's BIP158 compact filter serialized the consensus way — 32-byte txid followed by the 4-byte little-endian vout, 36 bytes total (see `ExtractSpecialTxFilterElements`). A wallet that owns the 1000-DASH collateral output but holds none of the masternode's owner/voting keys — for example a third party registered the masternode against the wallet's collateral — never matches that `ProRegTx` on the scriptPubKey path, so the block is skipped during compact-filter sync. This extends `ManagedWalletInfo::monitored_filter_elements` to append each watched UTXO's consensus-serialized outpoint after the existing owner/voting hashes. The matcher and manager already fold `monitored_filter_elements` into the shared `FilterQuery`, so no change is needed there. The outpoint elements are gated on the wallet holding provider accounts (`ManagedAccountCollection::has_provider_accounts`). The collateral element only helps a masternode owner — it discovers a `ProRegTx` that references one of the wallet's UTXOs as collateral — and the common paths are already covered without it (an owner-created `ProRegTx` is matched by its fee input's script, a key-holding owner by the owner/voting hashes). A funding-only wallet can never hit that case, so it skips these elements rather than pay the per-UTXO false-positive cost on every compact-filter query. Within a provider wallet every UTXO is watched, to avoid hardcoding network-specific collateral amounts. Step 2 of #861: collateral outpoint. `proTxHash` follows in the next stacked branch.
📝 WalkthroughWalkthroughProvider-capable wallets now add consensus-serialized UTXO outpoints to monitored compact-filter elements. Provider detection and wallet test options were updated, with tests covering provider filtering and extra-element matching. ChangesProvider collateral compact-filter coverage
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@key-wallet/src/managed_account/managed_account_collection.rs`:
- Around line 98-109: Move the stale “Check if a managed account type exists in
the collection” rustdoc block so it directly precedes
contains_managed_account_type, and ensure has_provider_accounts retains only
documentation describing provider account detection.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: db961ade-789f-4a72-b927-cfa75c84a791
📒 Files selected for processing (4)
key-wallet-manager/src/matching.rskey-wallet/src/managed_account/managed_account_collection.rskey-wallet/src/test_utils/wallet.rskey-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
| /// Check if a managed account type exists in the collection | ||
| /// Whether the wallet holds any masternode provider account (owner, | ||
| /// voting, operator, or platform keys). | ||
| /// | ||
| /// A wallet with none of these can never own or operate a masternode, so it | ||
| /// has no reason to watch for masternode special transactions. | ||
| pub(crate) fn has_provider_accounts(&self) -> bool { | ||
| self.provider_owner_keys.is_some() | ||
| || self.provider_voting_keys.is_some() | ||
| || self.provider_operator_keys.is_some() | ||
| || self.provider_platform_keys.is_some() | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Stale doc comment on line 98 now attaches to has_provider_accounts.
Line 98 (/// Check if a managed account type exists in the collection) was the doc comment for contains_managed_account_type, but the new method was inserted between them. In Rust, consecutive /// lines form one doc block, so has_provider_accounts now carries an incorrect first line in its rustdoc.
📝 Proposed fix: move the stale comment to `contains_managed_account_type`
/// Check if a managed account type exists in the collection
+ pub fn contains_managed_account_type(&self, managed_type: &ManagedAccountType) -> bool {
+
+ /// Whether the wallet holds any masternode provider account (owner,
+ /// voting, operator, or platform keys).
+ ///
+ /// A wallet with none of these can never own or operate a masternode, so it
+ /// has no reason to watch for masternode special transactions.
+ pub(crate) fn has_provider_accounts(&self) -> bool {Reordering so contains_managed_account_type's doc stays with it:
+ /// Whether the wallet holds any masternode provider account (owner,
+ /// voting, operator, or platform keys).
+ ///
+ /// A wallet with none of these can never own or operate a masternode, so it
+ /// has no reason to watch for masternode special transactions.
+ pub(crate) fn has_provider_accounts(&self) -> bool {
+ self.provider_owner_keys.is_some()
+ || self.provider_voting_keys.is_some()
+ || self.provider_operator_keys.is_some()
+ || self.provider_platform_keys.is_some()
+ }
+
/// Check if a managed account type exists in the collection
pub fn contains_managed_account_type(&self, managed_type: &ManagedAccountType) -> bool {🤖 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/managed_account/managed_account_collection.rs` around lines 98
- 109, Move the stale “Check if a managed account type exists in the collection”
rustdoc block so it directly precedes contains_managed_account_type, and ensure
has_provider_accounts retains only documentation describing provider account
detection.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #864 +/- ##
==========================================
+ Coverage 73.62% 73.69% +0.07%
==========================================
Files 324 324
Lines 73374 73434 +60
==========================================
+ Hits 54018 54117 +99
+ Misses 19356 19317 -39
|
Dash Core inserts a
ProRegTx'scollateralOutpointinto the block's BIP158 compact filter serialized the consensus way — 32-byte txid followed by the 4-byte little-endian vout, 36 bytes total (seeExtractSpecialTxFilterElements). A wallet that owns the 1000-DASH collateral output but holds none of the masternode's owner/voting keys — for example a third party registered the masternode against the wallet's collateral — never matches thatProRegTxon the scriptPubKey path, so the block is skipped during compact-filter sync.This extends
ManagedWalletInfo::monitored_filter_elementsto append each watched UTXO's consensus-serialized outpoint after the existing owner/voting hashes. The matcher and manager already foldmonitored_filter_elementsinto the sharedFilterQuery, so no change is needed there.The outpoint elements are gated on the wallet holding provider accounts (
ManagedAccountCollection::has_provider_accounts). The collateral element only helps a masternode owner — it discovers aProRegTxthat references one of the wallet's UTXOs as collateral — and the common paths are already covered without it (an owner-createdProRegTxis matched by its fee input's script, a key-holding owner by the owner/voting hashes). A funding-only wallet can never hit that case, so it skips these elements rather than pay the per-UTXO false-positive cost on every compact-filter query. Within a provider wallet every UTXO is watched, to avoid hardcoding network-specific collateral amounts.Step 2 of #861: collateral outpoint.
proTxHashfollows in the next stacked branch.Summary by CodeRabbit
Bug Fixes
Tests