@@ -4,6 +4,20 @@ use crate::sml::masternode_list::MasternodeList;
44use crate :: Transaction ;
55use crate :: transaction:: special_transaction:: TransactionPayload ;
66
7+ /// Computes the Merkle root from a list of hashes.
8+ ///
9+ /// This function constructs a Merkle tree from the provided vector of 32-byte hashes.
10+ /// If the vector is empty, it returns `None`. Otherwise, it iteratively hashes pairs
11+ /// of nodes until a single root hash is obtained.
12+ ///
13+ /// # Parameters
14+ ///
15+ /// - `hashes`: A vector of 32-byte hashes representing the leaves of the Merkle tree.
16+ ///
17+ /// # Returns
18+ ///
19+ /// - `Some([u8; 32])`: The computed Merkle root if at least one hash is provided.
20+ /// - `None`: If the input vector is empty.
721#[ inline]
822pub fn merkle_root_from_hashes ( hashes : Vec < [ u8 ; 32 ] > ) -> Option < [ u8 ; 32 ] > {
923 let length = hashes. len ( ) ;
@@ -28,6 +42,19 @@ pub fn merkle_root_from_hashes(hashes: Vec<[u8; 32]>) -> Option<[u8; 32]> {
2842}
2943
3044impl MasternodeList {
45+ /// Validates whether the stored masternode list Merkle root matches the one in the coinbase transaction.
46+ ///
47+ /// This function compares the calculated masternode Merkle root with the one provided
48+ /// in the coinbase transaction payload to verify the integrity of the masternode list.
49+ ///
50+ /// # Parameters
51+ ///
52+ /// - `coinbase_transaction`: The coinbase transaction containing the expected Merkle root.
53+ ///
54+ /// # Returns
55+ ///
56+ /// - `true` if the Merkle root matches.
57+ /// - `false` otherwise.
3158 pub fn has_valid_mn_list_root ( & self , coinbase_transaction : & Transaction ) -> bool {
3259 let Some ( TransactionPayload :: CoinbasePayloadType ( coinbase_payload) ) = & coinbase_transaction. special_transaction_payload else {
3360 return false ;
@@ -42,6 +69,19 @@ impl MasternodeList {
4269 }
4370 }
4471
72+ /// Validates whether the stored LLMQ list Merkle root matches the one in the coinbase transaction.
73+ ///
74+ /// This function compares the calculated quorum Merkle root with the one provided
75+ /// in the coinbase transaction payload to verify the integrity of the quorum list.
76+ ///
77+ /// # Parameters
78+ ///
79+ /// - `coinbase_transaction`: The coinbase transaction containing the expected Merkle root.
80+ ///
81+ /// # Returns
82+ ///
83+ /// - `true` if the Merkle root matches.
84+ /// - `false` otherwise.
4585 pub fn has_valid_llmq_list_root ( & self , coinbase_transaction : & Transaction ) -> bool {
4686 let Some ( TransactionPayload :: CoinbasePayloadType ( coinbase_payload) ) = & coinbase_transaction. special_transaction_payload else {
4787 return false ;
@@ -61,23 +101,50 @@ impl MasternodeList {
61101 has_valid_quorum_list_root
62102 }
63103
104+ /// Computes the Merkle root for the masternode list at a given block height.
105+ ///
106+ /// This function generates a Merkle root for the masternode list based on the
107+ /// masternode entries at the specified block height.
108+ ///
109+ /// # Parameters
110+ ///
111+ /// - `block_height`: The block height at which to compute the Merkle root.
112+ ///
113+ /// # Returns
114+ ///
115+ /// - `Some(MerkleRootMasternodeList)`: The calculated Merkle root.
116+ /// - `None`: If no hashes are available for the given block height.
64117 pub fn calculate_masternodes_merkle_root ( & self , block_height : u32 ) -> Option < MerkleRootMasternodeList > {
65118 self . hashes_for_merkle_root ( block_height)
66119 . and_then ( merkle_root_from_hashes) . map ( |hash| MerkleRootMasternodeList :: from_byte_array ( hash) )
67120 }
68- // pub fn calculate_masternodes_merkle_root_with_block_height_lookup<BL: Fn(*const std::os::raw::c_void, [u8; 32]) -> u32>(
69- // &self,
70- // context: *const std::os::raw::c_void,
71- // block_height_lookup: BL
72- // ) -> Option<[u8; 32]> {
73- // self.hashes_for_merkle_root_with_block_height_lookup(context, block_height_lookup)
74- // .and_then(merkle_root_from_hashes)
75- // }
76121
122+ /// Computes the Merkle root for the LLMQ (Long-Living Masternode Quorum) list.
123+ ///
124+ /// This function constructs a Merkle tree using the commitment hashes of all known LLMQs
125+ /// and returns the root hash.
126+ ///
127+ /// # Returns
128+ ///
129+ /// - `Some(MerkleRootQuorums)`: The calculated Merkle root.
130+ /// - `None`: If no quorum commitment hashes are available.
77131 pub fn calculate_llmq_merkle_root ( & self ) -> Option < MerkleRootQuorums > {
78132 merkle_root_from_hashes ( self . hashes_for_quorum_merkle_root ( ) ) . map ( |hash| MerkleRootQuorums :: from_byte_array ( hash) )
79133 }
80134
135+ /// Retrieves the list of hashes required to compute the masternode list Merkle root.
136+ ///
137+ /// This function sorts the masternode list by pro-reg transaction hash and extracts
138+ /// the entry hashes for the given block height.
139+ ///
140+ /// # Parameters
141+ ///
142+ /// - `block_height`: The block height for which to retrieve the hashes.
143+ ///
144+ /// # Returns
145+ ///
146+ /// - `Some(Vec<[u8; 32]>)`: A sorted list of masternode entry hashes.
147+ /// - `None`: If the block height is invalid (`u32::MAX`).
81148 pub fn hashes_for_merkle_root ( & self , block_height : u32 ) -> Option < Vec < [ u8 ; 32 ] > > {
82149 ( block_height != u32:: MAX ) . then_some ( {
83150 let mut pro_tx_hashes = self . reversed_pro_reg_tx_hashes ( ) ;
@@ -94,23 +161,14 @@ impl MasternodeList {
94161 } )
95162 }
96163
97- // pub fn hashes_for_merkle_root_with_block_height_lookup<BL: Fn(*const std::os::raw::c_void, [u8; 32]) -> u32>(
98- // &self,
99- // context: *const std::os::raw::c_void,
100- // block_height_lookup: BL
101- // ) -> Option<Vec<[u8; 32]>> {
102- // let pro_tx_hashes = self.provider_tx_ordered_hashes();
103- // let block_height = block_height_lookup(context, self.block_hash);
104- // if block_height == u32::MAX {
105- // println!("Block height lookup queried an unknown block {}", self.block_hash);
106- // return None; //this should never happen
107- // }
108- // Some(pro_tx_hashes
109- // .into_iter()
110- // .map(|hash| (&self.masternodes[&hash]).entry_hash_at(block_height))
111- // .collect::<Vec<_>>())
112- // }
113-
164+ /// Retrieves the list of hashes required to compute the quorum Merkle root.
165+ ///
166+ /// This function collects and sorts the entry hashes of all known quorums
167+ /// to construct a Merkle tree.
168+ ///
169+ /// # Returns
170+ ///
171+ /// - `Vec<[u8; 32]>`: A sorted list of quorum commitment hashes.
114172 pub fn hashes_for_quorum_merkle_root ( & self ) -> Vec < [ u8 ; 32 ] > {
115173 let mut llmq_commitment_hashes = self . quorums
116174 . values ( )
0 commit comments