|
1 | 1 | use crypto::hash::platform_keccak::PlatformKeccak256 as Keccak256; |
2 | 2 | use digest::Digest; |
3 | | -#[cfg(feature = "parallel")] |
| 3 | +#[cfg(all(feature = "parallel", not(test)))] |
4 | 4 | use rayon::prelude::{IntoParallelIterator, ParallelIterator}; |
5 | 5 |
|
6 | 6 | const PREFIX: [u8; 8] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xed]; |
@@ -55,10 +55,26 @@ pub fn generate_nonce(seed: &[u8; 32], grinding_factor: u8) -> Option<u64> { |
55 | 55 | is_valid_nonce_for_inner_hash(&inner_hash, candidate_nonce, limit) |
56 | 56 | }); |
57 | 57 |
|
58 | | - #[cfg(feature = "parallel")] |
| 58 | + #[cfg(all(feature = "parallel", not(test)))] |
59 | 59 | return (0..u64::MAX).into_par_iter().find_any(|&candidate_nonce| { |
60 | 60 | is_valid_nonce_for_inner_hash(&inner_hash, candidate_nonce, limit) |
61 | 61 | }); |
| 62 | + |
| 63 | + // Tests that compare two proofs byte for byte — `retire_lde_proof_is_byte_identical` |
| 64 | + // is the one — are comparing two grindings as much as two provers, and |
| 65 | + // `find_any` returns an arbitrary valid nonce of the many that exist. The |
| 66 | + // nonce reaches the transcript, so a different one moves every challenge and |
| 67 | + // query index after it: the proofs differ with nothing wrong. The serial |
| 68 | + // search returns the smallest, which is stable across runs. |
| 69 | + // |
| 70 | + // Deliberately not `find_first` in production: which nonce comes back is not |
| 71 | + // a contract (see `generate_nonce_maybe_gpu`), and this search is the |
| 72 | + // prover's dominant CPU cost — ordering it would be paying for a property |
| 73 | + // only the tests want. |
| 74 | + #[cfg(all(feature = "parallel", test))] |
| 75 | + return (0..u64::MAX).find(|&candidate_nonce| { |
| 76 | + is_valid_nonce_for_inner_hash(&inner_hash, candidate_nonce, limit) |
| 77 | + }); |
62 | 78 | } |
63 | 79 |
|
64 | 80 | /// Checks if the leftmost 8 bytes of `Hash(inner_hash || candidate_nonce)` are less than `limit` |
|
0 commit comments