Ver código fonte

examples/multithreaded_mining: use optimized vm hashing api and an atomic nonce to ensure sequential nonce mining

skoupidi 9 meses atrás
pai
commit
0e31d5a239
1 arquivos alterados com 19 adições e 11 exclusões
  1. 19 11
      examples/multithreaded_mining.rs

+ 19 - 11
examples/multithreaded_mining.rs

@@ -89,18 +89,20 @@ fn single_thread_mine(header: &mut Header, target: &BigUint, input: &[u8; 32]) {
     println!("Initialized RandomX VM in {:?}", vm_start.elapsed());
 
     println!("Mining started!");
+    header.nonce = 0;
     let mining_start = Instant::now();
+    vm.calculate_hash_first(header.hash().as_bytes()).unwrap();
     loop {
-        let out_hash = vm.calculate_hash(header.hash().as_bytes()).unwrap();
+        header.nonce += 1;
+        let out_hash = vm.calculate_hash_next(header.hash().as_bytes()).unwrap();
         let out_hash = BigUint::from_bytes_le(&out_hash);
         if &out_hash <= target {
+            header.nonce -= 1; // Since out hash refers to previous nonce
             println!("Found block header using nonce {}", header.nonce);
             println!("Block header hash {}", header.hash());
             println!("RandomX output: 0x{out_hash:064x}");
             break;
         }
-
-        header.nonce += 1;
     }
     println!("Completed mining in {:?}", mining_start.elapsed());
     println!("Mined header: {header:?}");
@@ -115,6 +117,7 @@ fn multi_thread_mine(threads: usize, header: &mut Header, target: &BigUint, inpu
 
     println!("Initializing mining threads...");
     let mut handles = Vec::with_capacity(threads);
+    let atomic_nonce = Arc::new(AtomicU64::new(0));
     let found_header = Arc::new(AtomicBool::new(false));
     let found_nonce = Arc::new(AtomicU64::new(0));
     let threads_u64 = threads as u64;
@@ -127,9 +130,9 @@ fn multi_thread_mine(threads: usize, header: &mut Header, target: &BigUint, inpu
 
         let target = target.clone();
         let mut thread_header = header.clone();
-        thread_header.nonce = t;
-        let found_header = Arc::clone(&found_header);
-        let found_nonce = Arc::clone(&found_nonce);
+        let atomic_nonce = atomic_nonce.clone();
+        let found_header = found_header.clone();
+        let found_nonce = found_nonce.clone();
         let dataset = dataset.clone();
 
         handles.push(thread::spawn(move || {
@@ -137,16 +140,24 @@ fn multi_thread_mine(threads: usize, header: &mut Header, target: &BigUint, inpu
             let vm_start = Instant::now();
             let vm = RandomXVM::new(flags, None, Some(dataset)).unwrap();
             println!("Initialized RandomX VM #{t} in {:?}", vm_start.elapsed());
+            let mut last_nonce = atomic_nonce.fetch_add(1, Ordering::SeqCst);
+            thread_header.nonce = last_nonce;
+            vm.calculate_hash_first(thread_header.hash().as_bytes())
+                .unwrap();
             loop {
                 if found_header.load(Ordering::SeqCst) {
                     println!("Block header found, thread #{t} exiting");
                     break;
                 }
 
-                let out_hash = vm.calculate_hash(thread_header.hash().as_bytes()).unwrap();
+                thread_header.nonce = atomic_nonce.fetch_add(1, Ordering::SeqCst);
+                let out_hash = vm
+                    .calculate_hash_next(thread_header.hash().as_bytes())
+                    .unwrap();
                 let out_hash = BigUint::from_bytes_le(&out_hash);
                 if out_hash <= target {
                     found_header.store(true, Ordering::SeqCst);
+                    thread_header.nonce = last_nonce; // Since out hash refers to previous run nonce
                     found_nonce.store(thread_header.nonce, Ordering::SeqCst);
                     println!(
                         "Thread #{t} found block header using nonce {}",
@@ -156,10 +167,7 @@ fn multi_thread_mine(threads: usize, header: &mut Header, target: &BigUint, inpu
                     println!("RandomX output: 0x{out_hash:064x}");
                     break;
                 }
-
-                // This means thread 0 will use nonces, 0, 4, 8, ...
-                // and thread 1 will use nonces, 1, 5, 9, ...
-                thread_header.nonce += threads_u64;
+                last_nonce = thread_header.nonce;
             }
         }));
     }