1
1
mod blake3;
2
+ mod keccak;
2
3
3
4
use crate :: {
4
5
Arthur , ByteChallenges , ByteIOPattern , ByteReader , ByteWriter , IOPattern , Merlin , ProofError ,
60
61
}
61
62
}
62
63
63
- pub trait PowStrategy {
64
+ pub trait PowStrategy : Clone + Sync {
64
65
/// Creates a new proof-of-work challenge.
65
66
/// The `challenge` is a 32-byte array that represents the challenge.
66
67
/// The `bits` is the binary logarithm of the expected amount of work.
@@ -71,5 +72,41 @@ pub trait PowStrategy {
71
72
fn check ( & mut self , nonce : u64 ) -> bool ;
72
73
73
74
/// Finds the minimal `nonce` that satisfies the challenge.
74
- fn solve ( & mut self ) -> Option < u64 > ;
75
+ #[ cfg( not( feature = "parallel" ) ) ]
76
+ fn solve ( & mut self ) -> Option < u64 > {
77
+ // TODO: Parallel default impl
78
+ ( 0u64 ..) . find_map ( |nonce| if self . check ( nonce) { Some ( nonce) } else { None } )
79
+ }
80
+
81
+ #[ cfg( feature = "parallel" ) ]
82
+ fn solve ( & mut self ) -> Option < u64 > {
83
+ // Split the work across all available threads.
84
+ // Use atomics to find the unique deterministic lowest satisfying nonce.
85
+
86
+ use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
87
+
88
+ use rayon:: broadcast;
89
+ let global_min = AtomicU64 :: new ( u64:: MAX ) ;
90
+ let _ = broadcast ( |ctx| {
91
+ let mut worker = self . clone ( ) ;
92
+ let nonces = ( ctx. index ( ) as u64 ..) . step_by ( ctx. num_threads ( ) ) ;
93
+ for nonce in nonces {
94
+ // Use relaxed ordering to eventually get notified of another thread's solution.
95
+ // (Propagation delay should be in the order of tens of nanoseconds.)
96
+ if nonce >= global_min. load ( Ordering :: Relaxed ) {
97
+ break ;
98
+ }
99
+ if worker. check ( nonce) {
100
+ // We found a solution, store it in the global_min.
101
+ // Use fetch_min to solve race condition with simultaneous solutions.
102
+ global_min. fetch_min ( nonce, Ordering :: SeqCst ) ;
103
+ break ;
104
+ }
105
+ }
106
+ } ) ;
107
+ match global_min. load ( Ordering :: SeqCst ) {
108
+ u64:: MAX => self . check ( u64:: MAX ) . then_some ( u64:: MAX ) ,
109
+ nonce => Some ( nonce) ,
110
+ }
111
+ }
75
112
}
0 commit comments