@@ -10,15 +10,17 @@ use bincode::{Decode, Encode};
1010use serde:: { Deserialize , Serialize } ;
1111use crate :: { BlockHash , Network , QuorumHash } ;
1212use crate :: bls_sig_utils:: BLSSignature ;
13- use crate :: network:: message_qrinfo:: QuorumSnapshot ;
13+ use crate :: network:: message_qrinfo:: { QRInfo , QuorumSnapshot } ;
1414use crate :: network:: message_sml:: MnListDiff ;
1515use crate :: prelude:: CoreBlockHeight ;
1616use crate :: sml:: error:: SmlError ;
1717use crate :: sml:: error:: SmlError :: CorruptedCodeExecution ;
1818use crate :: sml:: llmq_type:: LLMQType ;
1919use crate :: sml:: masternode_list:: from_diff:: TryIntoWithBlockHashLookup ;
2020use crate :: sml:: masternode_list:: MasternodeList ;
21+ use crate :: sml:: quorum_entry:: qualified_quorum_entry:: QualifiedQuorumEntry ;
2122use 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 }
0 commit comments