Skip to content

Commit d43e7e1

Browse files
working
1 parent 2b56fa2 commit d43e7e1

File tree

2 files changed

+104
-23
lines changed

2 files changed

+104
-23
lines changed

dash/src/sml/masternode_list_engine/mod.rs

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use crate::sml::llmq_type::LLMQType;
1919
use crate::sml::masternode_list::from_diff::TryIntoWithBlockHashLookup;
2020
use crate::sml::masternode_list::MasternodeList;
2121
use crate::sml::quorum_entry::qualified_quorum_entry::QualifiedQuorumEntry;
22-
use crate::sml::quorum_validation_error::QuorumValidationError;
22+
use crate::sml::quorum_validation_error::{ClientDataRetrievalError, QuorumValidationError};
23+
use crate::transaction::special_transaction::quorum_commitment::QuorumEntry;
2324

2425
#[derive(Clone, Eq, PartialEq)]
2526
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -82,10 +83,93 @@ impl MasternodeListEngine {
8283
self.block_hashes.insert(height, block_hash);
8384
}
8485

85-
pub fn feed_qr_info<FH, FS>(&mut self, qr_info: QRInfo, verify_rotated_quorums: bool, fetch_block_heights: Option<FH>,
86+
fn request_qr_info_block_heights<FH>(&mut self, qr_info: &QRInfo, fetch_block_height: &FH) -> Result<(), ClientDataRetrievalError>
87+
where
88+
FH: Fn(&BlockHash) -> Result<u32, ClientDataRetrievalError> {
89+
let mn_list_diffs = [
90+
&qr_info.mn_list_diff_tip,
91+
&qr_info.mn_list_diff_h,
92+
&qr_info.mn_list_diff_at_h_minus_c,
93+
&qr_info.mn_list_diff_at_h_minus_2c,
94+
&qr_info.mn_list_diff_at_h_minus_3c,
95+
];
96+
97+
// If h-4c exists, add it to the list
98+
if let Some((_, mn_list_diff_h_minus_4c)) = &qr_info.quorum_snapshot_and_mn_list_diff_at_h_minus_4c {
99+
mn_list_diffs.iter().try_for_each(|&mn_list_diff| {
100+
self.request_mn_list_diff_heights(mn_list_diff, fetch_block_height)
101+
})?;
102+
103+
// Feed h-4c separately
104+
self.request_mn_list_diff_heights(mn_list_diff_h_minus_4c, fetch_block_height)?;
105+
} else {
106+
mn_list_diffs.iter().try_for_each(|&mn_list_diff| {
107+
self.request_mn_list_diff_heights(mn_list_diff, fetch_block_height)
108+
})?;
109+
}
110+
111+
// Process `last_commitment_per_index` quorum hashes
112+
qr_info.last_commitment_per_index.iter().try_for_each(|quorum_entry| {
113+
self.request_quorum_entry_height(quorum_entry, fetch_block_height)
114+
})?;
115+
116+
// Process `mn_list_diff_list` (extra diffs)
117+
qr_info.mn_list_diff_list.iter().try_for_each(|mn_list_diff| {
118+
self.request_mn_list_diff_heights(mn_list_diff, fetch_block_height)
119+
})
120+
}
121+
122+
/// **Helper function:** Feeds the quorum hash height of a `QuorumEntry`
123+
fn request_quorum_entry_height<FH>(&mut self, quorum_entry: &QuorumEntry, fetch_block_height: &FH) -> Result<(), ClientDataRetrievalError>
124+
where
125+
FH: Fn(&BlockHash) -> Result<u32, ClientDataRetrievalError> {
126+
let height = fetch_block_height(&quorum_entry.quorum_hash)?;
127+
self.feed_block_height(height, quorum_entry.quorum_hash);
128+
Ok(())
129+
}
130+
131+
/// **Helper function:** Requests the base and block hash heights of an `MnListDiff`
132+
fn request_mn_list_diff_heights<FH>(&mut self, mn_list_diff: &MnListDiff, fetch_block_height: &FH) -> Result<(), ClientDataRetrievalError>
133+
where
134+
FH: Fn(&BlockHash) -> Result<u32, ClientDataRetrievalError> {
135+
// Feed base block hash height
136+
let base_height = fetch_block_height(&mn_list_diff.base_block_hash)?;
137+
self.feed_block_height(base_height, mn_list_diff.base_block_hash);
138+
139+
// Feed block hash height
140+
let block_height = fetch_block_height(&mn_list_diff.block_hash)?;
141+
self.feed_block_height(block_height, mn_list_diff.block_hash);
142+
Ok(())
143+
}
144+
145+
fn request_qr_info_cl_sigs<FS>(&mut self, qr_info: &QRInfo, fetch_chain_lock_sigs: &FS) -> Result<(), QuorumValidationError>
146+
where FS: Fn(&BlockHash) -> Result<Option<BLSSignature>, ClientDataRetrievalError> {
147+
let heights = self.required_cl_sig_heights(qr_info)?;
148+
for height in heights {
149+
let block_hash = self.block_hashes.get(&height).ok_or(QuorumValidationError::RequiredBlockHeightNotPresent(height))?;
150+
let maybe_chain_lock_sig = fetch_chain_lock_sigs(block_hash)?;
151+
if let Some(maybe_chain_lock_sig) = maybe_chain_lock_sig {
152+
self.feed_chain_lock_sig(*block_hash, maybe_chain_lock_sig);
153+
}
154+
}
155+
Ok(())
156+
}
157+
158+
pub fn feed_qr_info<FH, FS>(&mut self, qr_info: QRInfo, verify_rotated_quorums: bool, fetch_block_height: Option<FH>,
86159
fetch_chain_lock_sigs: Option<FS>) -> Result<(), QuorumValidationError> where
87-
FH: Fn(&QRInfo) -> Result<BTreeSet<u32>, QuorumValidationError>,
88-
FS: Fn(u32) -> Result<(BlockHash, Option<BLSSignature>), QuorumValidationError> {
160+
FH: Fn(&BlockHash) -> Result<u32, ClientDataRetrievalError>,
161+
FS: Fn(&BlockHash) -> Result<Option<BLSSignature>, ClientDataRetrievalError> {
162+
163+
// Fetch and process block heights using the provided callback
164+
if let Some(fetch_height) = fetch_block_height {
165+
self.request_qr_info_block_heights(&qr_info, &fetch_height)?;
166+
}
167+
168+
// Fetch and process block heights using the provided callback
169+
if let Some(fetch_chain_lock_sigs) = fetch_chain_lock_sigs {
170+
self.request_qr_info_cl_sigs(&qr_info, &fetch_chain_lock_sigs)?;
171+
}
172+
89173
let QRInfo {
90174
quorum_snapshot_at_h_minus_c, quorum_snapshot_at_h_minus_2c, quorum_snapshot_at_h_minus_3c, mn_list_diff_tip, mn_list_diff_h, mn_list_diff_at_h_minus_c, mn_list_diff_at_h_minus_2c, mn_list_diff_at_h_minus_3c, quorum_snapshot_and_mn_list_diff_at_h_minus_4c, last_commitment_per_index, quorum_snapshot_list, mn_list_diff_list
91175
} = qr_info;
@@ -110,25 +194,6 @@ impl MasternodeListEngine {
110194
self.apply_diff(mn_list_diff_h, None, false)?;
111195
self.apply_diff(mn_list_diff_tip, None, false)?;
112196

113-
// // Fetch and process block heights using the provided callback
114-
// if let Some(fetch_heights) = fetch_block_heights {
115-
// let heights = fetch_heights(&qr_info)?;
116-
// for height in heights {
117-
// if let Some(fetch_sigs) = fetch_chain_lock_sigs {
118-
// match fetch_sigs(height) {
119-
// Ok((block_hash, Some(chain_lock_sig))) => {
120-
// self.feed_chain_lock_sig(block_hash, chain_lock_sig);
121-
// }
122-
// Ok((_, None)) => continue, // No chain lock sig available
123-
// Err(e) => {
124-
// self.error = Some(e.to_string());
125-
// return Err(e);
126-
// }
127-
// }
128-
// }
129-
// }
130-
// }
131-
132197
let qualified_last_commitment_per_index : Vec<_> = last_commitment_per_index.into_iter().map(|quorum_entry| quorum_entry.into()).collect();
133198
if verify_rotated_quorums {
134199
let validation_statuses = self.validate_rotation_cycle_quorums_validation_statuses(qualified_last_commitment_per_index.as_slice());

dash/src/sml/quorum_validation_error.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ use crate::prelude::CoreBlockHeight;
66
use crate::sml::error::SmlError;
77
use crate::sml::llmq_type::LLMQType;
88

9+
#[derive(Debug, Error, Clone, Ord, PartialOrd, PartialEq, Hash, Eq)]
10+
#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
11+
pub enum ClientDataRetrievalError {
12+
#[error("Required block not present: {0}")]
13+
RequiredBlockNotPresent(BlockHash),
14+
}
15+
916
#[derive(Debug, Error, Clone, Ord, PartialOrd, PartialEq, Hash, Eq)]
1017
#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
1118
pub enum QuorumValidationError {
@@ -70,10 +77,19 @@ pub enum QuorumValidationError {
7077
CorruptedCodeExecution(String),
7178
#[error("Expected only rotated quorums, but got quorum {0} of type {1}")]
7279
ExpectedOnlyRotatedQuorums(QuorumHash, LLMQType),
80+
81+
#[error(transparent)]
82+
ClientDataRetrievalError(ClientDataRetrievalError)
7383
}
7484

7585
impl From<SmlError> for QuorumValidationError {
7686
fn from(value: SmlError) -> Self {
7787
QuorumValidationError::SMLError(value)
7888
}
89+
}
90+
91+
impl From<ClientDataRetrievalError> for QuorumValidationError {
92+
fn from(value: ClientDataRetrievalError) -> Self {
93+
QuorumValidationError::ClientDataRetrievalError(value)
94+
}
7995
}

0 commit comments

Comments
 (0)