use anyhow::Result;
use uhash_core::{meets_difficulty, UniversalHash};
use crate::solver::{ProofResult, Solver};
pub struct CpuSolver {
hasher: UniversalHash,
}
impl CpuSolver {
pub fn new() -> Self {
Self {
hasher: UniversalHash::new(),
}
}
}
impl Default for CpuSolver {
fn default() -> Self {
Self::new()
}
}
impl Solver for CpuSolver {
fn backend_name(&self) -> &'static str {
"cpu"
}
fn recommended_lanes(&mut self, requested: usize) -> usize {
if requested == 0 {
1024
} else {
requested
}
}
fn find_proof_batch(
&mut self,
header_without_nonce: &[u8],
start_nonce: u64,
lanes: usize,
difficulty: u32,
) -> Result<ProofResult> {
let mut input = Vec::with_capacity(header_without_nonce.len() + 8);
for i in 0..lanes {
let nonce = start_nonce.saturating_add(i as u64);
input.clear();
input.extend_from_slice(header_without_nonce);
input.extend_from_slice(&nonce.to_le_bytes());
let hash = self.hasher.hash(&input);
if meets_difficulty(&hash, difficulty) {
return Ok(Some((nonce, hash)));
}
}
Ok(None)
}
fn benchmark_hashes(
&mut self,
header_without_nonce: &[u8],
start_nonce: u64,
lanes: usize,
) -> Result<usize> {
let mut input = Vec::with_capacity(header_without_nonce.len() + 8);
for i in 0..lanes {
let nonce = start_nonce.saturating_add(i as u64);
input.clear();
input.extend_from_slice(header_without_nonce);
input.extend_from_slice(&nonce.to_le_bytes());
let _ = self.hasher.hash(&input);
}
Ok(lanes)
}
}