Skip to content

fix(dash-spv): match masternode collateral outpoints in compact filters#864

Merged
QuantumExplorer merged 1 commit into
devfrom
fix/spv-mn-collateral-filter
Jul 11, 2026
Merged

fix(dash-spv): match masternode collateral outpoints in compact filters#864
QuantumExplorer merged 1 commit into
devfrom
fix/spv-mn-collateral-filter

Conversation

@xdustinface

@xdustinface xdustinface commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

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.

Summary by CodeRabbit

  • Bug Fixes

    • Improved wallet monitoring for provider collateral by recognizing serialized collateral outpoints in compact filters.
    • Provider-capable wallets can now detect relevant collateral UTXOs even when associated provider keys are not held.
    • Funding-only wallets continue to avoid generating provider-specific filter elements.
  • Tests

    • Added coverage for collateral outpoint matching and provider-specific filter behavior.

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.
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Provider-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.

Changes

Provider collateral compact-filter coverage

Layer / File(s) Summary
Provider detection and test setup
key-wallet/src/managed_account/managed_account_collection.rs, key-wallet/src/test_utils/wallet.rs
Adds provider-account detection and forwards wallet account-creation options through randomized wallet construction.
Monitored collateral elements
key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs
Provider-capable wallets include consensus-serialized watched UTXO outpoints in monitored filter elements, with tests for provider and funding-only wallets.
Collateral matching validation
key-wallet-manager/src/matching.rs
Tests that serialized collateral outpoints match compact filters only when supplied through extra_elements.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: QuantumExplorer, llbartekll

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: matching masternode collateral outpoints in compact filters.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/spv-mn-collateral-filter

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 845ee9e and 7fa9851.

📒 Files selected for processing (4)
  • key-wallet-manager/src/matching.rs
  • key-wallet/src/managed_account/managed_account_collection.rs
  • key-wallet/src/test_utils/wallet.rs
  • key-wallet/src/wallet/managed_wallet_info/wallet_info_interface.rs

Comment on lines 98 to +109
/// 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()
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 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

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.69%. Comparing base (845ee9e) to head (7fa9851).

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     
Flag Coverage Δ
core 77.08% <ø> (ø)
ffi 46.08% <ø> (ø)
rpc 20.00% <ø> (ø)
spv 91.10% <ø> (+0.16%) ⬆️
wallet 73.25% <100.00%> (+0.13%) ⬆️
Files with missing lines Coverage Δ
key-wallet-manager/src/matching.rs 96.64% <100.00%> (+0.54%) ⬆️
.../src/managed_account/managed_account_collection.rs 56.39% <100.00%> (+0.41%) ⬆️
...allet/managed_wallet_info/wallet_info_interface.rs 77.30% <100.00%> (+7.61%) ⬆️

... and 6 files with indirect coverage changes

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