Skip to content

Commit fd3e191

Browse files
more work
1 parent ec197ed commit fd3e191

File tree

5 files changed

+88
-18
lines changed

5 files changed

+88
-18
lines changed

dash/src/sml/error.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use bincode::{Decode, Encode};
12
use crate::BlockHash;
23
use thiserror::Error;
34

4-
#[derive(Debug, Error, Clone, PartialEq, Eq)]
5+
#[derive(Debug, Error, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
6+
#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
57
pub enum SmlError {
68
/// Error indicating that the base block is not the genesis block.
79
#[error("Base block is not the genesis block: {0}")]

dash/src/sml/masternode_list/apply_diff.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,7 @@ impl MasternodeList {
5050
updated_quorums
5151
.entry(new_quorum.llmq_type)
5252
.or_default()
53-
.insert(new_quorum.quorum_hash, {
54-
let commitment_hash = new_quorum.calculate_commitment_hash();
55-
let entry_hash = new_quorum.calculate_entry_hash();
56-
QualifiedQuorumEntry {
57-
quorum_entry: new_quorum,
58-
verified: LLMQEntryVerificationStatus::Skipped(LLMQEntryVerificationSkipStatus::NotMarkedForVerification), // Default to unverified
59-
commitment_hash,
60-
entry_hash,
61-
}
62-
});
53+
.insert(new_quorum.quorum_hash, new_quorum.into());
6354
}
6455

6556
// Create and return the new MasternodeList

dash/src/sml/masternode_list_engine/mod.rs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ use bincode::{Decode, Encode};
1010
use serde::{Deserialize, Serialize};
1111
use crate::{BlockHash, Network, QuorumHash};
1212
use crate::bls_sig_utils::BLSSignature;
13-
use crate::network::message_qrinfo::QuorumSnapshot;
13+
use crate::network::message_qrinfo::{QRInfo, QuorumSnapshot};
1414
use crate::network::message_sml::MnListDiff;
1515
use crate::prelude::CoreBlockHeight;
1616
use crate::sml::error::SmlError;
1717
use crate::sml::error::SmlError::CorruptedCodeExecution;
1818
use crate::sml::llmq_type::LLMQType;
1919
use crate::sml::masternode_list::from_diff::TryIntoWithBlockHashLookup;
2020
use crate::sml::masternode_list::MasternodeList;
21+
use crate::sml::quorum_entry::qualified_quorum_entry::QualifiedQuorumEntry;
2122
use crate::sml::quorum_validation_error::QuorumValidationError;
23+
use crate::transaction::special_transaction::quorum_commitment::QuorumEntry;
2224

2325
#[derive(Clone, Eq, PartialEq)]
2426
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -30,6 +32,7 @@ pub struct MasternodeListEngine {
3032
pub masternode_lists : BTreeMap<CoreBlockHeight, MasternodeList>,
3133
pub known_chain_locks: BTreeMap<BlockHash, BLSSignature>,
3234
pub known_snapshots: BTreeMap<BlockHash, QuorumSnapshot>,
35+
pub last_commitment_entries: Vec<QualifiedQuorumEntry>,
3336
pub network: Network,
3437
}
3538

@@ -44,6 +47,7 @@ impl MasternodeListEngine {
4447
masternode_lists: [(block_height, masternode_list)].into(),
4548
known_chain_locks: Default::default(),
4649
known_snapshots: Default::default(),
50+
last_commitment_entries: vec![],
4751
network,
4852
})
4953
}
@@ -79,21 +83,66 @@ impl MasternodeListEngine {
7983
self.block_hashes.insert(height, block_hash);
8084
}
8185

86+
pub fn feed_qr_info(&mut self, qrinfo: QRInfo, verify_rotated_quorums: bool) -> Result<(), QuorumValidationError> {
87+
let QRInfo {
88+
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
89+
} = qrinfo;
90+
for (snapshot, diff) in quorum_snapshot_list.into_iter().zip(mn_list_diff_list.into_iter()) {
91+
self.known_snapshots.insert(diff.block_hash, snapshot);
92+
self.apply_diff(diff, None, false)?;
93+
}
94+
95+
self.last_commitment_entries.clear();
96+
97+
if let Some((quorum_snapshot_at_h_minus_4c, mn_list_diff_at_h_minus_4c)) = quorum_snapshot_and_mn_list_diff_at_h_minus_4c {
98+
self.known_snapshots.insert(mn_list_diff_at_h_minus_4c.block_hash, quorum_snapshot_at_h_minus_4c);
99+
self.apply_diff(mn_list_diff_at_h_minus_4c, None, false)?;
100+
}
101+
102+
self.known_snapshots.insert(mn_list_diff_at_h_minus_3c.block_hash, quorum_snapshot_at_h_minus_3c);
103+
self.apply_diff(mn_list_diff_at_h_minus_3c, None, false)?;
104+
self.known_snapshots.insert(mn_list_diff_at_h_minus_2c.block_hash, quorum_snapshot_at_h_minus_2c);
105+
self.apply_diff(mn_list_diff_at_h_minus_2c, None, false)?;
106+
self.known_snapshots.insert(mn_list_diff_at_h_minus_c.block_hash, quorum_snapshot_at_h_minus_c);
107+
self.apply_diff(mn_list_diff_at_h_minus_c, None, false)?;
108+
self.apply_diff(mn_list_diff_h, None, false)?;
109+
self.apply_diff(mn_list_diff_tip, None, false)?;
110+
111+
if verify_rotated_quorums {
112+
for rotated_quorum in last_commitment_per_index {
113+
let mut qualified = rotated_quorum.into();
114+
self.validate_and_update_quorum_status(&mut qualified);
115+
self.last_commitment_entries.push(qualified);
116+
}
117+
} else {
118+
for quorum in last_commitment_per_index {
119+
self.last_commitment_entries.push(quorum.into());
120+
}
121+
}
122+
Ok(())
123+
}
124+
82125
pub fn feed_chain_lock_sig(&mut self, block_hash: BlockHash, chain_lock_sig: BLSSignature) {
83126
self.known_chain_locks.insert(block_hash, chain_lock_sig);
84127
}
85128

86-
pub fn apply_diff(&mut self, masternode_list_diff: MnListDiff, diff_end_height: CoreBlockHeight, verify_quorums: bool) -> Result<(), SmlError> {
129+
pub fn apply_diff(&mut self, masternode_list_diff: MnListDiff, diff_end_height: Option<CoreBlockHeight>, verify_quorums: bool) -> Result<(), SmlError> {
87130
if let Some(known_genesis_block_hash) = self.network.known_genesis_block_hash().or_else(|| self.block_hashes.get(&0).cloned()) {
88131
if masternode_list_diff.base_block_hash == known_genesis_block_hash {
89132
// we are going from the start
90133
let block_hash = masternode_list_diff.block_hash;
91134

92-
let masternode_list = masternode_list_diff.try_into_with_block_hash_lookup(|block_hash| Some(diff_end_height), self.network)?;
135+
let masternode_list = masternode_list_diff.try_into_with_block_hash_lookup(|block_hash| diff_end_height, self.network)?;
93136

137+
let diff_end_height = match diff_end_height {
138+
None => self.block_heights.get(&block_hash).ok_or(SmlError::BlockHashLookupFailed(block_hash)).cloned()?,
139+
Some(diff_end_height) => {
140+
self.block_hashes.insert(diff_end_height, block_hash);
141+
self.block_heights.insert(block_hash, diff_end_height);
142+
diff_end_height
143+
},
144+
};
94145
self.masternode_lists.insert(diff_end_height, masternode_list);
95-
self.block_hashes.insert(diff_end_height, block_hash);
96-
self.block_heights.insert(block_hash, diff_end_height);
97146
return Ok(());
98147
}
99148
}
@@ -107,6 +156,11 @@ impl MasternodeListEngine {
107156

108157
let block_hash = masternode_list_diff.block_hash;
109158

159+
let diff_end_height = match diff_end_height {
160+
None => self.block_heights.get(&block_hash).ok_or(SmlError::BlockHashLookupFailed(block_hash)).cloned()?,
161+
Some(diff_end_height) => diff_end_height,
162+
};
163+
110164
let mut masternode_list = base_masternode_list.apply_diff(masternode_list_diff.clone(), diff_end_height)?;
111165

112166
#[cfg(feature = "quorum_validation")]
@@ -122,9 +176,9 @@ impl MasternodeListEngine {
122176
return Err(SmlError::FeatureNotTurnedOn("quorum validation feature is not turned on".to_string()));
123177
}
124178

125-
self.masternode_lists.insert(diff_end_height, masternode_list);
126179
self.block_hashes.insert(diff_end_height, block_hash);
127180
self.block_heights.insert(block_hash, diff_end_height);
181+
self.masternode_lists.insert(diff_end_height, masternode_list);
128182

129183
Ok(())
130184
}

dash/src/sml/quorum_entry/qualified_quorum_entry.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@ pub struct QualifiedQuorumEntry {
1717
pub entry_hash: QuorumEntryHash,
1818
}
1919

20+
impl From<QuorumEntry> for QualifiedQuorumEntry {
21+
fn from(value: QuorumEntry) -> Self {
22+
let commitment_hash = value.calculate_commitment_hash();
23+
let entry_hash = value.calculate_entry_hash();
24+
QualifiedQuorumEntry {
25+
quorum_entry: value,
26+
verified: LLMQEntryVerificationStatus::Skipped(LLMQEntryVerificationSkipStatus::NotMarkedForVerification), // Default to unverified
27+
commitment_hash,
28+
entry_hash,
29+
}
30+
}
31+
}
32+
2033
impl QualifiedQuorumEntry {
2134
pub fn update_quorum_status(&mut self, result: Result<(), QuorumValidationError>) {
2235
match result {

dash/src/sml/quorum_validation_error.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use bincode::{Decode, Encode};
33
use thiserror::Error;
44
use crate::BlockHash;
55
use crate::prelude::CoreBlockHeight;
6+
use crate::sml::error::SmlError;
67

78
#[derive(Debug, Error, Clone, Ord, PartialOrd, PartialEq, Hash, Eq)]
89
#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
@@ -56,5 +57,14 @@ pub enum QuorumValidationError {
5657
CommitmentHashNotPresent,
5758

5859
#[error("Required snapshot not present {0}")]
59-
RequiredSnapshotNotPresent(BlockHash)
60+
RequiredSnapshotNotPresent(BlockHash),
61+
62+
#[error("Simplified masternode list error {0}")]
63+
SMLError(SmlError),
64+
}
65+
66+
impl From<SmlError> for QuorumValidationError {
67+
fn from(value: SmlError) -> Self {
68+
QuorumValidationError::SMLError(value)
69+
}
6070
}

0 commit comments

Comments
 (0)