Skip to content

Commit 5d0493d

Browse files
bincode serialization
1 parent a6f83a1 commit 5d0493d

File tree

12 files changed

+175
-52
lines changed

12 files changed

+175
-52
lines changed

dash/src/hash_types.rs

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -147,29 +147,30 @@ use hashes::{sha256, sha256d, hash160, hash_newtype, Hash, hash_newtype_no_ord};
147147
pub struct QuorumCommitmentHash(sha256d::Hash);
148148

149149
pub struct Sha256dHash(sha256d::Hash);
150-
}
151-
152-
hash_newtype_no_ord! {
153150
pub struct ScoreHash(sha256d::Hash);
154-
}
155-
156-
impl Ord for ScoreHash {
157-
fn cmp(&self, other: &Self) -> Ordering {
158-
let mut self_bytes = self.0.to_byte_array();
159-
let mut other_bytes = other.0.to_byte_array();
160-
161-
self_bytes.reverse();
162-
other_bytes.reverse();
163-
164-
self_bytes.cmp(&other_bytes)
165151
}
166-
}
167152

168-
impl PartialOrd for ScoreHash {
169-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
170-
Some(self.cmp(other))
171-
}
172-
}
153+
// hash_newtype_no_ord! {
154+
//
155+
// }
156+
157+
// impl Ord for ScoreHash {
158+
// fn cmp(&self, other: &Self) -> Ordering {
159+
// let mut self_bytes = self.0.to_byte_array();
160+
// let mut other_bytes = other.0.to_byte_array();
161+
//
162+
// self_bytes.reverse();
163+
// other_bytes.reverse();
164+
//
165+
// self_bytes.cmp(&other_bytes)
166+
// }
167+
// }
168+
//
169+
// impl PartialOrd for ScoreHash {
170+
// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
171+
// Some(self.cmp(other))
172+
// }
173+
// }
173174

174175

175176
/// A hash used to identify a quorum
@@ -229,13 +230,6 @@ impl PartialOrd for ScoreHash {
229230
pub fn to_hex(&self) -> String {
230231
self.0.to_string()
231232
}
232-
233-
/// Returns a new `ProTxHash` with the bytes reversed.
234-
pub fn reverse(&self) -> Self {
235-
let mut reversed_bytes = self.0.to_byte_array();
236-
reversed_bytes.reverse();
237-
Self::from_byte_array(reversed_bytes)
238-
}
239233
}
240234

241235
impl ScoreHash {
@@ -249,19 +243,12 @@ impl PartialOrd for ScoreHash {
249243
self.0.to_string()
250244
}
251245

252-
/// Returns a new `ProTxHash` with the bytes reversed.
253-
pub fn reverse(&self) -> Self {
254-
let mut reversed_bytes = self.0.to_byte_array();
255-
reversed_bytes.reverse();
256-
Self::from_byte_array(reversed_bytes)
257-
}
258-
259246
pub fn create_score(confirmed_hash_hashed_with_pro_reg_tx: Option<ConfirmedHashHashedWithProRegTx>, modifier: QuorumModifierHash) -> Self {
260247
let mut bytes = vec![];
261248
if let Some(confirmed_hash_hashed_with_pro_reg_tx) = confirmed_hash_hashed_with_pro_reg_tx{
262249
bytes.append(&mut confirmed_hash_hashed_with_pro_reg_tx.to_byte_array().to_vec());
263-
bytes.append(&mut modifier.to_byte_array().to_vec());
264250
}
251+
bytes.append(&mut modifier.to_byte_array().to_vec());
265252
Self::hash(bytes.as_slice())
266253
}
267254
}

dash/src/sml/masternode_list/scores_for_quorum.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::Network;
55
use crate::sml::masternode_list::MasternodeList;
66
use crate::sml::masternode_list_entry::MasternodeType;
77
use crate::sml::masternode_list_entry::qualified_masternode_list_entry::QualifiedMasternodeListEntry;
8+
use crate::sml::order_option::LLMQOrderOption;
89
use crate::sml::quorum_entry::qualified_quorum_entry::QualifiedQuorumEntry;
910
use crate::sml::quorum_entry::quorum_modifier_type::LLMQModifierType;
1011

@@ -14,22 +15,46 @@ impl MasternodeList {
1415
quorum: &QualifiedQuorumEntry,
1516
quorum_modifier: LLMQModifierType,
1617
network: Network,
18+
order_option: &LLMQOrderOption,
1719
) -> T
1820
where T: FromIterator<QualifiedMasternodeListEntry> {
1921
let llmq_type = quorum.quorum_entry.llmq_type;
2022
let hpmn_only = llmq_type == network.platform_type();
2123
let quorum_modifier = quorum_modifier.build_llmq_hash();
2224
let score_dictionary = self.scores_for_quorum(quorum_modifier, hpmn_only);
23-
if quorum.quorum_entry.quorum_hash.to_string() == "00000000000000048529d958e7cfa32f51f0ac0584f7037ac34d8448f8a2a684".to_string() {
24-
println!("00000000000000048529d958e7cfa32f51f0ac0584f7037ac34d8448f8a2a684 info");
25-
println!("quorum modifier {}", quorum_modifier);
26-
for (score, list_entry) in score_dictionary.iter() {
27-
println!("score_hash {} -> {}", score, list_entry.masternode_list_entry.pro_reg_tx_hash);
25+
// if quorum.quorum_entry.quorum_hash.to_string() == "0000000000000010d1f1ab756f1f3223485fdc7bce1cbb0e7437383bf7600b06".to_string() {
26+
27+
// } else {
28+
// println!("trying {}", quorum.quorum_entry.quorum_hash)
29+
// }
30+
println!("quorum modifier {}", quorum_modifier.reverse());
31+
if order_option.reverse_sort_scores {
32+
let mut score_dictionary: Vec<_> = score_dictionary.into_iter().collect();
33+
score_dictionary.sort_by(|(s1, _), (s2, _)| {
34+
35+
if order_option.reverse_sort_order {
36+
s2.reverse().cmp(&s1.reverse())
37+
} else {
38+
s1.reverse().cmp(&s2.reverse())
39+
}
40+
});
41+
for (score, list_entry) in score_dictionary.iter().take(5) {
42+
println!("score_hash {} {} -> {}", if order_option.reverse_sort_order { 1 } else { 2}, score, list_entry.masternode_list_entry.pro_reg_tx_hash);
2843
}
44+
score_dictionary.into_iter().take(llmq_type.size() as usize).map(|(a, b)| b).collect()
2945
} else {
30-
println!("trying {}", quorum.quorum_entry.quorum_hash)
46+
if order_option.reverse_sort_order {
47+
for (score, list_entry) in score_dictionary.iter().rev().take(5) {
48+
println!("3 score_hash {} -> {}", score, list_entry.masternode_list_entry.pro_reg_tx_hash);
49+
}
50+
score_dictionary.into_values().rev().take(llmq_type.size() as usize).collect()
51+
} else {
52+
for (score, list_entry) in score_dictionary.iter().take(5) {
53+
println!("4 score_hash {} -> {}", score, list_entry.masternode_list_entry.pro_reg_tx_hash);
54+
}
55+
score_dictionary.into_values().take(llmq_type.size() as usize).collect()
56+
}
3157
}
32-
score_dictionary.into_values().take(llmq_type.size() as usize).collect()
3358
}
3459

3560
pub fn scores_for_quorum(

dash/src/sml/masternode_list_engine/mod.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::sml::error::SmlError::CorruptedCodeExecution;
1515
use crate::sml::llmq_type::LLMQType;
1616
use crate::sml::masternode_list::from_diff::TryIntoWithBlockHashLookup;
1717
use crate::sml::masternode_list::MasternodeList;
18+
use crate::sml::order_option::LLMQOrderOption;
1819
use crate::sml::quorum_validation_error::QuorumValidationError;
1920

2021
#[derive(Clone, Eq, PartialEq)]
@@ -144,7 +145,7 @@ impl MasternodeListEngine {
144145
let mut inner = BTreeMap::new();
145146

146147
for (quorum_hash, quorum_entry) in hash_to_quorum_entries.iter() {
147-
inner.insert(*quorum_hash, self.validate_quorum(quorum_entry));
148+
inner.insert(*quorum_hash, self.validate_quorum(quorum_entry, &LLMQOrderOption::default()));
148149
}
149150
results.insert(*quorum_type, inner);
150151
}
@@ -160,4 +161,58 @@ impl MasternodeListEngine {
160161
}
161162
Ok(())
162163
}
164+
}
165+
166+
#[cfg(test)]
167+
mod tests {
168+
use crate::QuorumHash;
169+
use crate::sml::llmq_entry_verification::LLMQEntryVerificationStatus;
170+
use crate::sml::llmq_type::LLMQType::{Llmqtype100_67, Llmqtype400_60, Llmqtype400_85, Llmqtype50_60};
171+
use crate::sml::masternode_list_engine::MasternodeListEngine;
172+
use std::str::FromStr;
173+
use crate::sml::order_option::LLMQOrderOption;
174+
175+
#[test]
176+
fn deserialize_mn_list_engine_and_validate_quorums() {
177+
let block_hex = include_str!("../../../tests/data/test_DML_diffs/masternode_list_engine.hex");
178+
let data = hex::decode(block_hex).expect("decode hex");
179+
let mut mn_list_engine: MasternodeListEngine = bincode::decode_from_slice(&data, bincode::config::standard()).expect("expected to decode").0;
180+
181+
assert_eq!(mn_list_engine.masternode_lists.len(), 27);
182+
183+
let last_masternode_list_height = *mn_list_engine.masternode_lists.last_key_value().unwrap().0;
184+
185+
mn_list_engine.verify_masternode_list_quorums(last_masternode_list_height, &[Llmqtype50_60, Llmqtype400_85]).expect("expected to verify quorums");
186+
187+
let last_masternode_list = mn_list_engine.masternode_lists.last_key_value().unwrap().1;
188+
189+
for (quorum_type, quorum_entries) in last_masternode_list.quorums.iter() {
190+
if *quorum_type == Llmqtype400_85 || *quorum_type == Llmqtype50_60 || *quorum_type == Llmqtype400_60 {
191+
continue;
192+
}
193+
for (quorum_hash, quorum) in quorum_entries.iter() {
194+
let (_, known_block_height) = mn_list_engine.masternode_list_and_height_for_block_hash_8_blocks_ago(&quorum.quorum_entry.quorum_hash).expect("expected to find validating masternode");
195+
assert_eq!(quorum.verified, LLMQEntryVerificationStatus::Verified, "could not verify quorum {} of type {} with masternode list {}", quorum_hash, quorum.quorum_entry.llmq_type, known_block_height);
196+
}
197+
}
198+
}
199+
200+
#[test]
201+
fn deserialize_mn_list_engine_and_validate_single_quorum() {
202+
let block_hex = include_str!("../../../tests/data/test_DML_diffs/masternode_list_engine2.hex");
203+
let data = hex::decode(block_hex).expect("decode hex");
204+
let mn_list_engine: MasternodeListEngine = bincode::decode_from_slice(&data, bincode::config::standard()).expect("expected to decode").0;
205+
206+
assert_eq!(mn_list_engine.masternode_lists.len(), 27);
207+
208+
let last_masternode_list_height = *mn_list_engine.masternode_lists.last_key_value().unwrap().0;
209+
210+
let last_masternode_list = mn_list_engine.masternode_lists.last_key_value().unwrap().1;
211+
212+
let quorum = last_masternode_list.quorum_entry_of_type_for_quorum_hash(Llmqtype100_67, QuorumHash::from_str("000000000000001d4ebc43dbf9b25d2af6421641a84a1e04dd58f65d07b7ecf7").expect("expected to get quorum hash")).expect("expected to find quorum");
213+
214+
for option in LLMQOrderOption::all_combinations() {
215+
println!("using {:?} {:?}", option, mn_list_engine.validate_quorum(quorum, &option))
216+
}
217+
}
163218
}

dash/src/sml/masternode_list_engine/validation.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::sml::llmq_entry_verification::{LLMQEntryVerificationSkipStatus, LLMQE
66
use crate::sml::masternode_list_engine::MasternodeListEngine;
77
use crate::sml::masternode_list_entry::MasternodeListEntry;
88
use crate::sml::masternode_list_entry::qualified_masternode_list_entry::QualifiedMasternodeListEntry;
9+
use crate::sml::order_option::LLMQOrderOption;
910
use crate::sml::quorum_entry::qualified_quorum_entry::QualifiedQuorumEntry;
1011
use crate::sml::quorum_entry::quorum_modifier_type::LLMQModifierType;
1112
use crate::sml::quorum_validation_error::QuorumValidationError;
@@ -52,17 +53,18 @@ impl MasternodeListEngine {
5253
// }
5354
// }
5455
pub fn validate_and_update_quorum_status(&self, quorum: &mut QualifiedQuorumEntry) {
55-
quorum.update_quorum_status(self.validate_quorum(quorum));
56+
quorum.update_quorum_status(self.validate_quorum(quorum, &LLMQOrderOption::default()));
5657
}
5758

58-
pub fn validate_quorum(&self, quorum: &QualifiedQuorumEntry) -> Result<(), QuorumValidationError> {
59+
pub fn validate_quorum(&self, quorum: &QualifiedQuorumEntry, order_option: &LLMQOrderOption) -> Result<(), QuorumValidationError> {
5960
// first let's do basic structure validation
6061
quorum.quorum_entry.validate_structure()?;
6162

6263
let llmq_block_hash = quorum.quorum_entry.quorum_hash;
6364
let (masternode_list, known_block_height) = self.masternode_list_and_height_for_block_hash_8_blocks_ago(&llmq_block_hash)?;
6465
let quorum_modifier_type = LLMQModifierType::new_quorum_modifier_type(quorum.quorum_entry.llmq_type, masternode_list.block_hash, known_block_height, &self.known_chain_locks, self.network)?;
65-
let masternodes : Vec<_> = masternode_list.valid_masternodes_for_quorum(quorum, quorum_modifier_type, self.network);
66+
// println!("quorum modifier is {} giving {}", quorum_modifier_type, quorum_modifier_type.build_llmq_hash(order_option));
67+
let masternodes : Vec<_> = masternode_list.valid_masternodes_for_quorum(quorum, quorum_modifier_type, self.network, order_option);
6668
quorum.validate(masternodes.iter().map(|qualified_masternode_list_entry| &qualified_masternode_list_entry.masternode_list_entry))
6769
}
6870
}

dash/src/sml/masternode_list_entry/score.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@ use crate::sml::masternode_list_entry::qualified_masternode_list_entry::Qualifie
44
impl QualifiedMasternodeListEntry {
55
pub fn score(&self, modifier: QuorumModifierHash) -> Option<ScoreHash> {
66
if !self.masternode_list_entry.is_valid ||
7-
self.masternode_list_entry.confirmed_hash.is_none() {
7+
self.confirmed_hash_hashed_with_pro_reg_tx.is_none() {
88
return None;
99
}
10-
Some(ScoreHash::create_score(self.confirmed_hash_hashed_with_pro_reg_tx, modifier))
10+
println!("creating score for {}({})\nconfirmed_hash_hashed_with_pro_reg_tx: {}({})\nmodifier {}({})", self.masternode_list_entry.pro_reg_tx_hash, self.masternode_list_entry.pro_reg_tx_hash.reverse(), if let Some(confirmed_hash_hashed_with_pro_reg_tx) = self.confirmed_hash_hashed_with_pro_reg_tx { confirmed_hash_hashed_with_pro_reg_tx.to_string() } else {
11+
"None".to_string()
12+
}, if let Some(confirmed_hash_hashed_with_pro_reg_tx) = self.confirmed_hash_hashed_with_pro_reg_tx { confirmed_hash_hashed_with_pro_reg_tx.reverse().to_string() } else {
13+
"None".to_string()
14+
}, modifier, modifier.reverse());
15+
let score = ScoreHash::create_score(self.confirmed_hash_hashed_with_pro_reg_tx, modifier);
16+
println!("score is {}",score);
17+
Some(score)
1118
}
1219
}

dash/src/sml/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ pub mod llmq_entry_verification;
77
pub mod error;
88
pub mod quorum_validation_error;
99
pub mod quorum_entry;
10+
mod order_option;

dash/src/sml/order_option.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#[derive(Debug, PartialEq, Eq, Clone, Default)]
2+
pub struct LLMQOrderOption {
3+
pub reverse_sort_scores: bool,
4+
pub reverse_sort_order: bool,
5+
}
6+
7+
impl LLMQOrderOption {
8+
pub fn all_combinations() -> Vec<LLMQOrderOption> {
9+
let mut combinations = Vec::with_capacity(8);
10+
11+
for reverse_sort_scores in [false, true] {
12+
for reverse_sort_order in [false, true] {
13+
combinations.push(LLMQOrderOption {
14+
reverse_sort_scores,
15+
reverse_sort_order,
16+
});
17+
}
18+
}
19+
20+
combinations
21+
}
22+
}

dash/src/sml/quorum_entry/quorum_modifier_type.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::collections::BTreeMap;
2+
use std::fmt;
23
use std::io::Write;
34
use hashes::Hash;
45
use crate::consensus::Encodable;
@@ -8,13 +9,27 @@ use crate::{BlockHash, Network};
89
use crate::bls_sig_utils::BLSSignature;
910
use crate::prelude::CoreBlockHeight;
1011
use crate::sml::llmq_type::LLMQType;
12+
use crate::sml::order_option::LLMQOrderOption;
1113
use crate::sml::quorum_validation_error::QuorumValidationError;
1214

1315
pub enum LLMQModifierType {
1416
PreCoreV20(LLMQType, BlockHash),
1517
CoreV20(LLMQType, CoreBlockHeight, BLSSignature),
1618
}
1719

20+
impl fmt::Display for LLMQModifierType {
21+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22+
match self {
23+
LLMQModifierType::PreCoreV20(llmq_type, block_hash) => {
24+
write!(f, "PreCoreV20: Type: {}, BlockHash: {}", llmq_type, block_hash)
25+
}
26+
LLMQModifierType::CoreV20(llmq_type, height, signature) => {
27+
write!(f, "CoreV20: Type: {}, Height: {}, Signature: {}", llmq_type, height, signature)
28+
}
29+
}
30+
}
31+
}
32+
1833
impl LLMQModifierType {
1934
pub fn build_llmq_hash(&self) -> QuorumModifierHash {
2035
let mut writer = vec![];
@@ -35,7 +50,6 @@ impl LLMQModifierType {
3550
writer.write_all(cl_signature.as_bytes()).unwrap();
3651
}
3752
}
38-
3953
QuorumModifierHash::hash(&writer)
4054
}
4155

dash/src/sml/quorum_entry/validation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ impl QualifiedQuorumEntry {
1212
{
1313
let mut message = self.commitment_hash.to_byte_array();
1414
message.reverse();
15-
println!("quorum {}", self.quorum_entry.quorum_hash);
16-
println!("using message {}", hex::encode(message));
15+
// println!("quorum {}", self.quorum_entry.quorum_hash);
16+
// println!("using message {}", hex::encode(message));
1717
let message = message.as_slice();
1818
let public_keys : Vec<(blsful::PublicKey<Bls12381G2Impl>)> = operator_keys
1919
.into_iter().enumerate()
2020
.map(|(i, key)| {
21-
println!("using operator key {}. {}", i, key);
21+
// println!("using operator key {}. {}", i, key);
2222
key.try_into()
2323
})
2424
.collect::<Result<Vec<(blsful::PublicKey<Bls12381G2Impl>)>, QuorumValidationError>>()?;

dash/tests/data/test_DML_diffs/masternode_list_engine.hex

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)