Przeglądaj źródła

validator: Adapt code to new RandomX crate API

parazyd 1 rok temu
rodzic
commit
09a78273d0
5 zmienionych plików z 40 dodań i 24 usunięć
  1. 10 0
      src/error.rs
  2. 2 2
      src/validator/consensus.rs
  3. 2 2
      src/validator/mod.rs
  4. 18 12
      src/validator/pow.rs
  5. 8 8
      src/validator/utils.rs

+ 10 - 0
src/error.rs

@@ -349,6 +349,10 @@ pub enum Error {
     #[error("MergeMineError: {0}")]
     MoneroMergeMineError(String),
 
+    #[cfg(feature = "randomx")]
+    #[error("RandomX Error: {0}")]
+    RandomXError(String),
+
     // ===============
     // Database errors
     // ===============
@@ -824,5 +828,11 @@ impl From<darkfi_sdk::error::DarkTreeError> for Error {
 impl From<tracing_subscriber::util::TryInitError> for Error {
     fn from(err: tracing_subscriber::util::TryInitError) -> Self {
         Self::LogInitError(err.to_string())
+}
+
+#[cfg(feature = "randomx")]
+impl From<randomx::RandomXError> for Error {
+    fn from(err: randomx::RandomXError) -> Self {
+        Self::RandomXError(err.to_string())
     }
 }

+ 2 - 2
src/validator/consensus.rs

@@ -214,7 +214,7 @@ impl Consensus {
             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 (target_distance_sq, hash_distance_sq) = block_rank(block, &next_target)?;
 
             // Update PoW module
             fork.module.append(block.header.timestamp, &next_difficulty);
@@ -744,7 +744,7 @@ impl Fork {
         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 (target_distance_sq, hash_distance_sq) = block_rank(&proposal.block, &next_target)?;
 
         // Update fork ranks
         self.targets_rank += target_distance_sq.clone();

+ 2 - 2
src/validator/mod.rs

@@ -477,7 +477,7 @@ impl Validator {
             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 (target_distance_sq, hash_distance_sq) = block_rank(block, &next_target)?;
 
             // Update current ranks
             current_targets_rank += target_distance_sq.clone();
@@ -591,7 +591,7 @@ impl Validator {
             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 (target_distance_sq, hash_distance_sq) = block_rank(block, &next_target)?;
 
             // Update current ranks
             current_targets_rank += target_distance_sq.clone();

+ 18 - 12
src/validator/pow.rs

@@ -274,14 +274,14 @@ impl PoWModule {
         let target = self.next_mine_target()?;
 
         // Setup verifier
-        let flags = RandomXFlags::default();
-        let cache = RandomXCache::new(flags, block.header.previous.inner()).unwrap();
-        let vm = RandomXVM::new(flags, &cache).unwrap();
+        let flags = RandomXFlags::get_recommended_flags();
+        let cache = RandomXCache::new(flags, block.header.previous.inner())?;
+        let vm = RandomXVM::new(flags, Some(cache), None)?;
         debug!(target: "validator::pow::verify_block", "[VERIFIER] Setup time: {:?}", verifier_setup.elapsed());
 
         // Compute the output hash
         let verification_time = Instant::now();
-        let out_hash = vm.hash(block.header.hash().inner());
+        let out_hash = vm.calculate_hash(block.header.hash().inner())?;
         let out_hash = BigUint::from_bytes_be(&out_hash);
 
         // Verify hash is less than the expected mine target
@@ -344,13 +344,16 @@ pub fn mine_block(
 ) -> Result<()> {
     let miner_setup = Instant::now();
 
-    debug!(target: "validator::pow::mine_block", "[MINER] Mine target: 0x{target:064x}");
+    // Calculate page offsets for each thread
+    let dataset_pages = RandomXDataset::count()?;
+
+    debug!(target: "validator::pow::mine_block", "[MINER] Mine target: 0x{:064x}", target);
     // Get the PoW input. The key changes with every mined block.
     let input = miner_block.header.previous;
-    debug!(target: "validator::pow::mine_block", "[MINER] PoW input: {input}");
-    let flags = RandomXFlags::default() | RandomXFlags::FULLMEM;
-    debug!(target: "validator::pow::mine_block", "[MINER] Initializing RandomX dataset...");
-    let dataset = Arc::new(RandomXDataset::new(flags, input.inner(), threads).unwrap());
+    debug!(target: "validator::pow::mine_block", "[MINER] PoW input: {}", input);
+    let flags = RandomXFlags::get_recommended_flags() | RandomXFlags::FULLMEM;
+    debug!(target: "validator::pow::mine_block", "[MINER] Initializing RandomX cache...");
+    let cache = RandomXCache::new(flags, input.inner())?;
     debug!(target: "validator::pow::mine_block", "[MINER] Setup time: {:?}", miner_setup.elapsed());
 
     // Multithreaded mining setup
@@ -364,13 +367,16 @@ pub fn mine_block(
         let mut block = miner_block.clone();
         let found_block = Arc::clone(&found_block);
         let found_nonce = Arc::clone(&found_nonce);
-        let dataset = Arc::clone(&dataset);
+
+        let page_offset = (dataset_pages / threads as u32) * (t as u32);
+        let dataset = RandomXDataset::new(flags, cache.clone(), page_offset)?;
+
         let stop_signal = stop_signal.clone();
 
         handles.push(thread::spawn(move || {
             debug!(target: "validator::pow::mine_block", "[MINER] Initializing RandomX VM #{t}...");
             let mut miner_nonce = t;
-            let vm = RandomXVM::new_fast(flags, &dataset).unwrap();
+            let vm = RandomXVM::new(flags, None, Some(dataset)).unwrap();
             loop {
                 // Check if stop signal was received
                 if stop_signal.is_full() {
@@ -384,7 +390,7 @@ pub fn mine_block(
                     break
                 }
 
-                let out_hash = vm.hash(block.hash().inner());
+                let out_hash = vm.calculate_hash(block.hash().inner()).unwrap();
                 let out_hash = BigUint::from_bytes_be(&out_hash);
                 if out_hash <= target {
                     found_block.store(true, Ordering::SeqCst);

+ 8 - 8
src/validator/utils.rs

@@ -122,10 +122,10 @@ pub fn header_rank(header: &Header, target: &BigUint) -> Result<(BigUint, BigUin
     // Setup RandomX verifier
     let flags = RandomXFlags::default();
     let cache = RandomXCache::new(flags, header.previous.inner()).unwrap();
-    let vm = RandomXVM::new(flags, &cache).unwrap();
+    let vm = RandomXVM::new(flags, Some(cache), None).unwrap();
 
     // Compute the output hash
-    let out_hash = vm.hash(header.hash().inner());
+    let out_hash = vm.calculate_hash(header.hash().inner())?;
     let out_hash = BigUint::from_bytes_be(&out_hash);
 
     // Verify hash is less than the expected mine target
@@ -152,10 +152,10 @@ pub fn header_rank(header: &Header, target: &BigUint) -> Result<(BigUint, BigUin
 /// 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) -> (BigUint, BigUint) {
+pub fn block_rank(block: &BlockInfo, target: &BigUint) -> Result<(BigUint, BigUint)> {
     // Genesis block has rank 0
     if block.header.height == 0 {
-        return (0u64.into(), 0u64.into())
+        return Ok((0u64.into(), 0u64.into()))
     }
 
     // Grab the max 32 bytes int
@@ -167,16 +167,16 @@ pub fn block_rank(block: &BlockInfo, target: &BigUint) -> (BigUint, BigUint) {
 
     // Setup RandomX verifier
     let flags = RandomXFlags::default();
-    let cache = RandomXCache::new(flags, block.header.previous.inner()).unwrap();
-    let vm = RandomXVM::new(flags, &cache).unwrap();
+    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.hash(block.hash().inner());
+    let out_hash = vm.calculate_hash(block.hash().inner())?;
     let out_hash = BigUint::from_bytes_be(&out_hash);
     let hash_distance = max - out_hash;
     let hash_distance_sq = &hash_distance * &hash_distance;
 
-    (target_distance_sq, hash_distance_sq)
+    Ok((target_distance_sq, hash_distance_sq))
 }
 
 /// Auxiliary function to calculate the middle value between provided u64 numbers