Просмотр исходного кода

blockchain/monero: Add method for validating XMR PowData

x 8 месяцев назад
Родитель
Сommit
69f560df9e
2 измененных файлов с 39 добавлено и 5 удалено
  1. 31 1
      src/blockchain/header_store.rs
  2. 8 4
      src/blockchain/monero/mod.rs

+ 31 - 1
src/blockchain/header_store.rs

@@ -33,7 +33,7 @@ use sled_overlay::{
 
 use crate::{util::time::Timestamp, Error, Result};
 
-use super::{monero::MoneroPowData, SledDbOverlayPtr};
+use super::{monero::{extract_aux_merkle_root, MoneroPowData}, SledDbOverlayPtr};
 
 /// Struct representing the Proof of Work used in a block.
 #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
@@ -152,6 +152,36 @@ impl Header {
 
         HeaderHash(hasher.finalize().into())
     }
+
+    /// Validate PowData from the header.
+    pub fn validate_powdata(&self) -> bool {
+		match &self.pow_data {
+			// For native DarkFi PoW, this is handled so we just return `true`.
+			PowData::DarkFi => true,
+			// For Monero PoW, we have to check a few things.
+			PowData::Monero(powdata) => {
+				if !powdata.is_coinbase_valid_merkle_root() {
+					return false
+				}
+
+				// Verify that MoneroPowData correctly corresponds to this header.
+				let aux_hash = monero::Hash::from(self.template_hash().inner());
+				let Ok(merkle_root) = extract_aux_merkle_root(&powdata.coinbase_tx_extra) else {
+					return false
+				};
+
+				let Some(merkle_root) = merkle_root else {
+					return false
+				};
+
+				if powdata.aux_chain_merkle_proof.calculate_root(&aux_hash) != merkle_root {
+					return false
+				}
+
+				true
+			}
+		}
+    }
 }
 
 impl Default for Header {

+ 8 - 4
src/blockchain/monero/mod.rs

@@ -433,13 +433,17 @@ fn parse_extra_field_truncate_on_error(raw_extra_field: &RawExtraField) -> Extra
     }
 }
 
+
 /// Extract the Monero block hash from the coinbase transaction's extra field
 pub fn extract_aux_merkle_root_from_block(monero: &monero::Block) -> Result<Option<monero::Hash>> {
-    // When we extract the merge mining hash, we do not care if the extra
-    // field can be parsed without error.
-    let extra_field = parse_extra_field_truncate_on_error(&monero.miner_tx.prefix.extra);
+    extract_aux_merkle_root(&monero.miner_tx.prefix.extra)
+}
 
-    // Only one merge mining tag is allowed
+
+/// Extract the Monero block hash from the coinbase transaction's extra field
+pub fn extract_aux_merkle_root(extra_field: &RawExtraField) -> Result<Option<monero::Hash>> {
+    let extra_field = parse_extra_field_truncate_on_error(extra_field);
+	// Only one merge mining tag is allowed
     let merge_mining_hashes: Vec<monero::Hash> = extra_field
         .0
         .iter()