Skip to content

Commit 291174b

Browse files
committed
fix(dash): classify missing infrastructure errors as Skipped
`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`.
1 parent 66e5614 commit 291174b

3 files changed

Lines changed: 42 additions & 22 deletions

File tree

dash/src/sml/llmq_entry_verification.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ pub enum LLMQEntryVerificationSkipStatus {
1414
NotMarkedForVerification,
1515
MissedList(CoreBlockHeight),
1616
UnknownBlock(BlockHash),
17+
/// The quorum entry came through without an attached
18+
/// `VerifyingChainLockSignaturesType::Rotating`. Typically happens when
19+
/// a QRInfo's historical diff covers a block range in which no rotating
20+
/// DKG successfully committed, so `apply_diff` extracts no
21+
/// `rotation_sig` and `feed_qr_info` can't populate the 4-sig tuple for
22+
/// the quorums in `lastCommitmentPerIndex`.
23+
MissingRotationChainLockSigs(BlockHash),
1724
OtherContext(String),
1825
}
1926

@@ -30,6 +37,9 @@ impl Display for LLMQEntryVerificationSkipStatus {
3037
LLMQEntryVerificationSkipStatus::UnknownBlock(block_hash) => {
3138
format!("UnknownBlock({})", block_hash)
3239
}
40+
LLMQEntryVerificationSkipStatus::MissingRotationChainLockSigs(quorum_hash) => {
41+
format!("MissingRotationChainLockSigs({})", quorum_hash)
42+
}
3343
LLMQEntryVerificationSkipStatus::OtherContext(message) => {
3444
format!("OtherContext({message})")
3545
}
@@ -49,6 +59,32 @@ pub enum LLMQEntryVerificationStatus {
4959
Skipped(LLMQEntryVerificationSkipStatus),
5060
Invalid(QuorumValidationError),
5161
}
62+
impl From<QuorumValidationError> for LLMQEntryVerificationStatus {
63+
/// Classify a validation error as either `Skipped` (missing infrastructure
64+
/// data that the caller should have provided) or `Invalid` (the quorum
65+
/// data itself is genuinely bad).
66+
fn from(error: QuorumValidationError) -> Self {
67+
match error {
68+
QuorumValidationError::RequiredBlockNotPresent(block_hash, _) => {
69+
Self::Skipped(LLMQEntryVerificationSkipStatus::UnknownBlock(block_hash))
70+
}
71+
QuorumValidationError::RequiredMasternodeListNotPresent(height)
72+
| QuorumValidationError::RequiredBlockHeightNotPresent(height) => {
73+
Self::Skipped(LLMQEntryVerificationSkipStatus::MissedList(height))
74+
}
75+
QuorumValidationError::RequiredSnapshotNotPresent(hash) => {
76+
Self::Skipped(LLMQEntryVerificationSkipStatus::UnknownBlock(hash))
77+
}
78+
QuorumValidationError::RequiredRotatedChainLockSigsNotPresent(quorum_hash) => {
79+
Self::Skipped(LLMQEntryVerificationSkipStatus::MissingRotationChainLockSigs(
80+
quorum_hash,
81+
))
82+
}
83+
other => Self::Invalid(other),
84+
}
85+
}
86+
}
87+
5288
impl Display for LLMQEntryVerificationStatus {
5389
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
5490
f.write_str(

dash/src/sml/masternode_list_engine/validation.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,9 @@ impl MasternodeListEngine {
109109
let masternodes_by_quorum_hash = match self.find_rotated_masternodes_for_quorums(quorums) {
110110
Ok(masternodes_by_quorum_hash) => masternodes_by_quorum_hash,
111111
Err(e) => {
112+
let status: LLMQEntryVerificationStatus = e.into();
112113
for quorum in quorums {
113-
return_statuses.insert(
114-
quorum.quorum_entry.quorum_hash,
115-
LLMQEntryVerificationStatus::Invalid(e.clone()),
116-
);
114+
return_statuses.insert(quorum.quorum_entry.quorum_hash, status.clone());
117115
}
118116
return return_statuses;
119117
}

dash/src/sml/quorum_entry/qualified_quorum_entry.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,9 @@ impl QualifiedQuorumEntry {
6666
///
6767
/// * `result` - A `Result` containing either success (`Ok`) or a `QuorumValidationError`.
6868
pub fn update_quorum_status(&mut self, result: Result<(), QuorumValidationError>) {
69-
match result {
70-
Err(QuorumValidationError::RequiredBlockNotPresent(block_hash, _)) => {
71-
self.verified = LLMQEntryVerificationStatus::Skipped(
72-
LLMQEntryVerificationSkipStatus::UnknownBlock(block_hash),
73-
);
74-
}
75-
Err(QuorumValidationError::RequiredMasternodeListNotPresent(block_height)) => {
76-
self.verified = LLMQEntryVerificationStatus::Skipped(
77-
LLMQEntryVerificationSkipStatus::MissedList(block_height),
78-
);
79-
}
80-
Err(e) => {
81-
self.verified = LLMQEntryVerificationStatus::Invalid(e);
82-
}
83-
Ok(_) => {
84-
self.verified = LLMQEntryVerificationStatus::Verified;
85-
}
86-
}
69+
self.verified = match result {
70+
Ok(_) => LLMQEntryVerificationStatus::Verified,
71+
Err(e) => e.into(),
72+
};
8773
}
8874
}

0 commit comments

Comments
 (0)