|
|
@@ -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;
|
|
|
}
|
|
|
}));
|
|
|
}
|