diff --git a/crates/prover/src/core/backend/cpu/grind.rs b/crates/prover/src/core/backend/cpu/grind.rs index 9ca424861..2eef4bbc9 100644 --- a/crates/prover/src/core/backend/cpu/grind.rs +++ b/crates/prover/src/core/backend/cpu/grind.rs @@ -1,18 +1,35 @@ +#[cfg(feature = "parallel")] +use rayon::prelude::*; + use super::CpuBackend; use crate::core::channel::Channel; use crate::core::proof_of_work::GrindOps; -impl GrindOps for CpuBackend { +impl GrindOps for CpuBackend +where + C: Channel + std::marker::Sync, +{ fn grind(channel: &C, pow_bits: u32) -> u64 { // TODO(spapini): This is a naive implementation. Optimize it. - let mut nonce = 0; - loop { + + let check_nonce = |nonce: &u64| { let mut channel = channel.clone(); - channel.mix_u64(nonce); - if channel.trailing_zeros() >= pow_bits { - return nonce; + channel.mix_u64(*nonce); + channel.trailing_zeros() >= pow_bits + }; + + { + let range = 0..u64::MAX; + #[cfg(not(feature = "parallel"))] + { + range.into_iter().find(check_nonce) + } + + #[cfg(feature = "parallel")] + { + range.into_par_iter().find_any(check_nonce) } - nonce += 1; } + .expect("Grind failed to find a solution.") } }