Răsfoiți Sursa

validator/utils: use the correct randomx hash based on block pow type in block_rank()

skoupidi 4 luni în urmă
părinte
comite
1b0a1a01a4
4 a modificat fișierele cu 57 adăugiri și 66 ștergeri
  1. 4 8
      src/validator/consensus.rs
  2. 6 12
      src/validator/mod.rs
  3. 30 31
      src/validator/pow.rs
  4. 17 15
      src/validator/utils.rs

+ 4 - 8
src/validator/consensus.rs

@@ -235,11 +235,9 @@ impl Consensus {
             // Apply block diffs
             fork.overlay.lock().unwrap().overlay.lock().unwrap().add_diff(&fork.diffs[index])?;
 
-            // Grab next mine target and difficulty
-            let (next_target, next_difficulty) = fork.module.next_mine_target_and_difficulty()?;
-
             // Calculate block rank
-            let (target_distance_sq, hash_distance_sq) = block_rank(block, &next_target)?;
+            let (next_difficulty, target_distance_sq, hash_distance_sq) =
+                block_rank(&mut fork.module, block)?;
 
             // Update PoW module
             fork.module.append(&block.header, &next_difficulty)?;
@@ -730,11 +728,9 @@ impl Fork {
     /// Auxiliary function to append a proposal and update current fork
     /// rank.
     pub async fn append_proposal(&mut self, proposal: &Proposal) -> Result<()> {
-        // Grab next mine target and difficulty
-        let (next_target, next_difficulty) = self.module.next_mine_target_and_difficulty()?;
-
         // Calculate block rank
-        let (target_distance_sq, hash_distance_sq) = block_rank(&proposal.block, &next_target)?;
+        let (next_difficulty, target_distance_sq, hash_distance_sq) =
+            block_rank(&mut self.module, &proposal.block)?;
 
         // Update fork ranks
         self.targets_rank += target_distance_sq.clone();

+ 6 - 12
src/validator/mod.rs

@@ -446,11 +446,9 @@ impl Validator {
                 }
             };
 
-            // Grab next mine target and difficulty
-            let (next_target, next_difficulty) = module.next_mine_target_and_difficulty()?;
-
             // Calculate block rank
-            let (target_distance_sq, hash_distance_sq) = block_rank(block, &next_target)?;
+            let (next_difficulty, target_distance_sq, hash_distance_sq) =
+                block_rank(&mut module, block)?;
 
             // Update current ranks
             current_targets_rank += target_distance_sq.clone();
@@ -561,11 +559,9 @@ impl Validator {
                 }
             };
 
-            // Grab next mine target and difficulty
-            let (next_target, next_difficulty) = module.next_mine_target_and_difficulty()?;
-
             // Calculate block rank
-            let (target_distance_sq, hash_distance_sq) = block_rank(block, &next_target)?;
+            let (next_difficulty, target_distance_sq, hash_distance_sq) =
+                block_rank(&mut module, block)?;
 
             // Update current ranks
             current_targets_rank += target_distance_sq.clone();
@@ -886,11 +882,9 @@ impl Validator {
             // Grab block
             let block = self.blockchain.get_blocks_by_heights(&[index])?[0].clone();
 
-            // Grab next mine target and difficulty
-            let (next_target, next_difficulty) = module.next_mine_target_and_difficulty()?;
-
             // Calculate block rank
-            let (target_distance_sq, hash_distance_sq) = block_rank(&block, &next_target)?;
+            let (next_difficulty, target_distance_sq, hash_distance_sq) =
+                block_rank(&mut module, &block)?;
 
             // Update chain ranks
             targets_rank += target_distance_sq.clone();

+ 30 - 31
src/validator/pow.rs

@@ -301,12 +301,11 @@ impl PoWModule {
         self.verify_block_hash(header)
     }
 
-    /// Verify provided block hash is less than provided mine target.
-    pub fn verify_block_target(&mut self, header: &Header, target: &BigUint) -> Result<BigUint> {
-        let verifier_setup = Instant::now();
-
-        // Grab verifier output hash based on block PoW data
-        let (out_hash, verification_time) = match &header.pow_data {
+    /// Compute provided block header hash based on its PoW data.
+    pub fn calculate_hash(&mut self, header: &Header) -> Result<BigUint> {
+        // Grab corresponding VM based on block PoW data
+        let vm_setup = Instant::now();
+        let (pow_type, vm, blob) = match &header.pow_data {
             DarkFi => {
                 // Check which VM key should be used.
                 // We only use the next key when the next block is the
@@ -322,33 +321,33 @@ impl PoWModule {
                     &self.darkfi_rx_keys.0
                 };
 
-                let vm = self.darkfi_rx_factory.create(&randomx_key.inner()[..])?;
-
-                debug!(
-                    target: "validator::pow::verify_block_target",
-                    "[VERIFIER] DarkFi PoW setup time: {:?}",
-                    verifier_setup.elapsed(),
-                );
-
-                let verification_time = Instant::now();
-                let out_hash = vm.calculate_hash(&header.to_block_hashing_blob())?;
-                (BigUint::from_bytes_le(&out_hash), verification_time)
-            }
-            Monero(powdata) => {
-                let vm = self.monero_rx_factory.create(powdata.randomx_key())?;
-
-                debug!(
-                    target: "validator::pow::verify_block_target",
-                    "[VERIFIER] Monero PoW setup time: {:?}",
-                    verifier_setup.elapsed(),
-                );
-
-                let verification_time = Instant::now();
-                let out_hash = vm.calculate_hash(&powdata.to_block_hashing_blob())?;
-                (BigUint::from_bytes_le(&out_hash), verification_time)
+                (
+                    "DarkFi",
+                    self.darkfi_rx_factory.create(&randomx_key.inner()[..])?,
+                    header.to_block_hashing_blob(),
+                )
             }
+            Monero(powdata) => (
+                "Monero",
+                self.monero_rx_factory.create(powdata.randomx_key())?,
+                powdata.to_block_hashing_blob(),
+            ),
         };
-        debug!(target: "validator::pow::verify_block_target", "[VERIFIER] Verification time: {:?}", verification_time.elapsed());
+        debug!(target: "validator::pow::calculate_hash", "[VERIFIER] {pow_type} PoW setup time: {:?}", vm_setup.elapsed());
+
+        // Compute the hash and convert it to `BigUint`
+        let compute_time = Instant::now();
+        let out_hash = vm.calculate_hash(&blob)?;
+        let out_hash = BigUint::from_bytes_le(&out_hash);
+        debug!(target: "validator::pow::calculate_hash", "[VERIFIER] Hash compute time: {:?}", compute_time.elapsed());
+
+        Ok(out_hash)
+    }
+
+    /// Verify provided block hash is less than provided mine target.
+    pub fn verify_block_target(&mut self, header: &Header, target: &BigUint) -> Result<BigUint> {
+        // Grab verifier output hash based on block PoW data
+        let out_hash = self.calculate_hash(header)?;
 
         // Verify hash is less than the provided mine target
         if out_hash > *target {

+ 17 - 15
src/validator/utils.rs

@@ -23,7 +23,6 @@ use darkfi_sdk::{
     tx::TransactionHash,
 };
 use num_bigint::BigUint;
-use randomx::{RandomXCache, RandomXFlags, RandomXVM};
 use tracing::info;
 
 use crate::{
@@ -142,41 +141,44 @@ pub fn header_rank(module: &mut PoWModule, header: &Header) -> Result<(BigUint,
     let target_distance = &*MAX_32_BYTES - target;
     let target_distance_sq = &target_distance * &target_distance;
 
-    // Compute the output hash distance
+    // Compute the squared output hash distance
     let hash_distance = &*MAX_32_BYTES - out_hash;
     let hash_distance_sq = &hash_distance * &hash_distance;
 
     Ok((difficulty, target_distance_sq, hash_distance_sq))
 }
 
-/// Compute a block's rank, assuming that its valid, based on provided
-/// mining target.
+/// Compute a block's rank, assuming that its valid, for provided PoW
+/// module.
+/// Returns next mine difficulty, along with the computed rank.
 ///
 /// Block's rank is the tuple of its squared mining target distance
 /// from max 32 bytes int, along with its squared RandomX hash number
 /// distance from max 32 bytes int. Genesis block has rank (0, 0).
-pub fn block_rank(block: &BlockInfo, target: &BigUint) -> Result<(BigUint, BigUint)> {
+pub fn block_rank(
+    module: &mut PoWModule,
+    block: &BlockInfo,
+) -> Result<(BigUint, BigUint, BigUint)> {
+    // Grab next mine target and difficulty
+    let (target, difficulty) = module.next_mine_target_and_difficulty()?;
+
     // Genesis block has rank 0
     if block.header.height == 0 {
-        return Ok((0u64.into(), 0u64.into()))
+        return Ok((difficulty, 0u64.into(), 0u64.into()))
     }
 
+    // Compute the block header hash based on its PoW data
+    let out_hash = module.calculate_hash(&block.header)?;
+
     // Compute the squared mining target distance
     let target_distance = &*MAX_32_BYTES - target;
     let target_distance_sq = &target_distance * &target_distance;
 
-    // Setup RandomX verifier
-    let flags = RandomXFlags::get_recommended_flags();
-    let cache = RandomXCache::new(flags, block.header.previous.inner())?;
-    let vm = RandomXVM::new(flags, Some(cache), None)?;
-
-    // Compute the output hash distance
-    let out_hash = vm.calculate_hash(block.hash().inner())?;
-    let out_hash = BigUint::from_bytes_le(&out_hash);
+    // Compute the squared output hash distance
     let hash_distance = &*MAX_32_BYTES - out_hash;
     let hash_distance_sq = &hash_distance * &hash_distance;
 
-    Ok((target_distance_sq, hash_distance_sq))
+    Ok((difficulty, target_distance_sq, hash_distance_sq))
 }
 
 /// Auxiliary function to calculate the middle value between provided