Skip to content

fix(dash): classify missing infrastructure errors as Skipped#721

Open
xdustinface wants to merge 1 commit intov0.42-devfrom
fix/llmq-verification-status-classifier
Open

fix(dash): classify missing infrastructure errors as Skipped#721
xdustinface wants to merge 1 commit intov0.42-devfrom
fix/llmq-verification-status-classifier

Conversation

@xdustinface
Copy link
Copy Markdown
Collaborator

@xdustinface xdustinface commented May 4, 2026

QuorumValidationError carries both "the quorum data is bad" cases and "the caller didn't supply the data we need to verify". update_quorum_status and the rotated-quorum lookup in validation.rs mapped several of the latter to LLMQEntryVerificationStatus::Invalid, misreporting unverifiable quorums as bad.

Add a From<QuorumValidationError> for LLMQEntryVerificationStatus impl that routes the infrastructure-data variants to Skipped, and let both call sites use .into():

  • RequiredBlockHeightNotPresent becomes Skipped(MissedList).
  • RequiredSnapshotNotPresent becomes Skipped(UnknownBlock).
  • RequiredRotatedChainLockSigsNotPresent becomes a new Skipped(MissingRotationChainLockSigs) variant for the QRInfo case where a historical diff covers a range with no successful rotating DKG, so feed_qr_info can't populate the 4-sig tuple.

All other variants still map to Invalid.

Summary by CodeRabbit

  • Refactor
    • Centralized and improved verification-status mapping so infrastructure-related issues are classified as skipped where appropriate and status updates are applied consistently.
  • Bug Fixes
    • When quorum infrastructure lookups fail, affected quorums now receive a consistent skipped status while preserving existing invalid marks.
  • Tests
    • Added unit tests covering status classification and display for the new skip cases.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

📝 Walkthrough

Walkthrough

Centralizes LLMQ validation error classification by extending skip-reasons in LLMQEntryVerificationSkipStatus, adding From<QuorumValidationError> for LLMQEntryVerificationStatus, and updating call sites to use the new conversion; tests added to assert mapping and Display formatting.

Changes

LLMQ error classification & call-site simplification

Layer / File(s) Summary
Data Shape / Variants
dash/src/sml/llmq_entry_verification.rs
Adds skip variants: MissingSnapshot(BlockHash), MissingChainLock(CoreBlockHeight, BlockHash), MissingRotationChainLockSigs(QuorumHash), MissingRotationChainLockSig(u8, BlockHash).
Display / Formatting
dash/src/sml/llmq_entry_verification.rs
Extends Display match arms to render the new Missing* variants.
Error → Status Conversion
dash/src/sml/llmq_entry_verification.rs
Implements From<QuorumValidationError> for LLMQEntryVerificationStatus, mapping specific QuorumValidationError cases to Skipped(...) (including rotation-chain-lock / rotation sig cases) and other errors to Invalid(...).
Call-site refactor (wiring)
dash/src/sml/masternode_list_engine/validation.rs, dash/src/sml/quorum_entry/qualified_quorum_entry.rs
Replaces ad-hoc pattern matches / explicit Invalid(...) wrapping with e.into() conversions; consolidates error-to-status handling and applies converted status consistently (including bulk insertion on lookup failures).
Tests
dash/src/sml/llmq_entry_verification.rs (#[cfg(test)]), dash/src/sml/masternode_list_engine/validation.rs (tests)
Adds unit tests verifying QuorumValidationError -> LLMQEntryVerificationStatus mapping across handled arms, Display output for new skip variants, and that infrastructure lookup failures produce Skipped(_) while preserving pre-existing Invalid(_).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰
In burrows where the quorums hop,
Errors now find a single stop,
Skips and invalids neatly shown,
One trait guides them all, well sown. 🥕

🚥 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 and specifically describes the main change: classifying missing infrastructure errors as Skipped rather than Invalid in the LLMQ verification status system.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

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

✨ 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/llmq-verification-status-classifier

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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 4, 2026

Codecov Report

❌ Patch coverage is 95.94595% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.99%. Comparing base (fcaf66e) to head (7300318).
⚠️ Report is 1 commits behind head on v0.42-dev.

Files with missing lines Patch % Lines
dash/src/sml/masternode_list_engine/validation.rs 88.00% 9 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##           v0.42-dev     #721      +/-   ##
=============================================
+ Coverage      70.57%   70.99%   +0.41%     
=============================================
  Files            319      319              
  Lines          68211    68398     +187     
=============================================
+ Hits           48142    48561     +419     
+ Misses         20069    19837     -232     
Flag Coverage Δ
core 76.18% <95.94%> (+0.36%) ⬆️
ffi 45.49% <ø> (+2.12%) ⬆️
rpc 20.00% <ø> (ø)
spv 87.21% <ø> (-0.01%) ⬇️
wallet 69.64% <ø> (ø)
Files with missing lines Coverage Δ
dash/src/sml/llmq_entry_verification.rs 87.05% <100.00%> (+87.05%) ⬆️
...ash/src/sml/quorum_entry/qualified_quorum_entry.rs 95.91% <100.00%> (+25.33%) ⬆️
dash/src/sml/masternode_list_engine/validation.rs 86.03% <88.00%> (+10.42%) ⬆️

... and 19 files with indirect coverage changes

@xdustinface
Copy link
Copy Markdown
Collaborator Author

xdustinface commented May 4, 2026

@CodeRabbit review!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Tip

For best results, initiate chat on the files or code changes.

@xdustinface Sure! I'll review the changes now.

[review]

@xdustinface
Copy link
Copy Markdown
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 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
Copy Markdown
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: 1

Caution

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

⚠️ Outside diff range comments (1)
dash/src/sml/llmq_entry_verification.rs (1)

13-25: ⚠️ Potential issue | 🔴 Critical

Inserting MissingRotationChainLockSigs before OtherContext shifts its bincode discriminant — critical serialization break for persisted data.

MasternodeListEngine (which includes LLMQEntryVerificationStatus in quorum_statuses) is serialized and persisted to disk as MasternodeState.engine_state. Enum variants are encoded with discriminants assigned in declaration order; with no explicit #[bincode(variant_index = N)] overrides, OtherContext moves from discriminant 3 to 4. Any previously persisted Skipped(OtherContext(...)) will be silently misread as Skipped(MissingRotationChainLockSigs(...)) or fail to decode after deserialization, causing silent data corruption.

The safe fix is to append the new variant at the end of the enum rather than inserting it before OtherContext:

🛡️ Proposed fix — append variant to preserve discriminants
 pub enum LLMQEntryVerificationSkipStatus {
     NotMarkedForVerification,
     MissedList(CoreBlockHeight),
     UnknownBlock(BlockHash),
-    /// The quorum entry came through without an attached
-    /// `VerifyingChainLockSignaturesType::Rotating`. Typically happens when
-    /// a QRInfo's historical diff covers a block range in which no rotating
-    /// DKG successfully committed, so `apply_diff` extracts no
-    /// `rotation_sig` and `feed_qr_info` can't populate the 4-sig tuple for
-    /// the quorums in `lastCommitmentPerIndex`.
-    MissingRotationChainLockSigs(BlockHash),
     OtherContext(String),
+    /// The quorum entry came through without an attached
+    /// `VerifyingChainLockSignaturesType::Rotating`. Typically happens when
+    /// a QRInfo's historical diff covers a block range in which no rotating
+    /// DKG successfully committed, so `apply_diff` extracts no
+    /// `rotation_sig` and `feed_qr_info` can't populate the 4-sig tuple for
+    /// the quorums in `lastCommitmentPerIndex`.
+    MissingRotationChainLockSigs(BlockHash),
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dash/src/sml/llmq_entry_verification.rs` around lines 13 - 25,
LLMQEntryVerificationSkipStatus was changed so inserting
MissingRotationChainLockSigs before OtherContext shifts bincode discriminants
and breaks persisted MasternodeState.engine_state; fix by moving the
MissingRotationChainLockSigs variant to the end of the
LLMQEntryVerificationSkipStatus enum (after OtherContext) so existing
discriminant ordering for LLMQEntryVerificationStatus/MasternodeListEngine
remains unchanged; ensure no other reordering occurs (or alternatively add
explicit bincode variant_index attributes if reordering is unavoidable).
🤖 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/src/sml/llmq_entry_verification.rs`:
- Around line 62-86: Add match arms in the From<QuorumValidationError> for the
three missing-infrastructure variants so they map to Skipped instead of falling
through to Invalid: handle
QuorumValidationError::RequiredRotatedChainLockSigNotPresent(index, block_hash)
->
Self::Skipped(LLMQEntryVerificationSkipStatus::MissingRotationChainLockSig(index,
block_hash)); QuorumValidationError::RequiredChainLockNotPresent(height,
block_hash) ->
Self::Skipped(LLMQEntryVerificationSkipStatus::UnknownBlock(block_hash)); and
QuorumValidationError::VerifyingMasternodeListNotPresent(height) ->
Self::Skipped(LLMQEntryVerificationSkipStatus::MissedList(height)); keep the
existing arms (e.g. RequiredRotatedChainLockSigsNotPresent,
RequiredBlockNotPresent, RequiredSnapshotNotPresent) unchanged.

---

Outside diff comments:
In `@dash/src/sml/llmq_entry_verification.rs`:
- Around line 13-25: LLMQEntryVerificationSkipStatus was changed so inserting
MissingRotationChainLockSigs before OtherContext shifts bincode discriminants
and breaks persisted MasternodeState.engine_state; fix by moving the
MissingRotationChainLockSigs variant to the end of the
LLMQEntryVerificationSkipStatus enum (after OtherContext) so existing
discriminant ordering for LLMQEntryVerificationStatus/MasternodeListEngine
remains unchanged; ensure no other reordering occurs (or alternatively add
explicit bincode variant_index attributes if reordering is unavoidable).
🪄 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: f9e48bcb-72b8-4a4f-9e90-edf9996ff24d

📥 Commits

Reviewing files that changed from the base of the PR and between fcaf66e and 218cdcd.

📒 Files selected for processing (3)
  • dash/src/sml/llmq_entry_verification.rs
  • dash/src/sml/masternode_list_engine/validation.rs
  • dash/src/sml/quorum_entry/qualified_quorum_entry.rs

Comment thread dash/src/sml/llmq_entry_verification.rs
Several `QuorumValidationError` variants represent missing caller-supplied infrastructure (unknown block, unloaded masternode list, missing snapshot, chain lock, rotation sig) rather than bad quorum data, but the call sites mapped them to `LLMQEntryVerificationStatus::Invalid`, pushing callers to reject quorums they should refetch.

Add a `From<QuorumValidationError> for LLMQEntryVerificationStatus` impl as the single canonical classifier, route every construction site through `.into()`, and add the missing `Skipped` sub-variants needed to preserve context. Also guard the bulk-overwrite path so structurally-broken quorums keep `Invalid` when an infrastructure error fires.
@xdustinface xdustinface force-pushed the fix/llmq-verification-status-classifier branch from 218cdcd to 7300318 Compare May 4, 2026 13:51
Copy link
Copy Markdown
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)
dash/src/sml/masternode_list_engine/validation.rs (1)

135-141: 💤 Low value

Consider using .into() for consistency.

This error path explicitly constructs Invalid(e.clone()) while other sites now use .into(). Both are correct since CorruptedCodeExecution falls through to Invalid anyway, but using .into() would maintain consistency with the rest of the function.

♻️ Optional consistency fix
                 Err(e) => {
-                    return_statuses.insert(
-                        quorum.quorum_entry.quorum_hash,
-                        LLMQEntryVerificationStatus::Invalid(e.clone()),
-                    );
+                    return_statuses.insert(quorum.quorum_entry.quorum_hash, e.into());
                     continue;
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dash/src/sml/masternode_list_engine/validation.rs` around lines 135 - 141,
Replace the explicit construction
LLMQEntryVerificationStatus::Invalid(e.clone()) with using .into() for
consistency with other paths: locate the insert into return_statuses keyed by
quorum.quorum_entry.quorum_hash and change the value expression to e.into() (or
e.clone().into() if a clone is still required) so the error type converts into
LLMQEntryVerificationStatus via Into instead of directly constructing the
Invalid variant.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@dash/src/sml/masternode_list_engine/validation.rs`:
- Around line 135-141: Replace the explicit construction
LLMQEntryVerificationStatus::Invalid(e.clone()) with using .into() for
consistency with other paths: locate the insert into return_statuses keyed by
quorum.quorum_entry.quorum_hash and change the value expression to e.into() (or
e.clone().into() if a clone is still required) so the error type converts into
LLMQEntryVerificationStatus via Into instead of directly constructing the
Invalid variant.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 931befd2-a67d-4d16-8dad-f3aa34b2d920

📥 Commits

Reviewing files that changed from the base of the PR and between 218cdcd and 7300318.

📒 Files selected for processing (3)
  • dash/src/sml/llmq_entry_verification.rs
  • dash/src/sml/masternode_list_engine/validation.rs
  • dash/src/sml/quorum_entry/qualified_quorum_entry.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • dash/src/sml/quorum_entry/qualified_quorum_entry.rs

@github-actions github-actions Bot added the ready-for-review CodeRabbit has approved this PR label May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review CodeRabbit has approved this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant