11use {
22 crate :: {
3- api:: GetRandomValueResponse ,
4- chain:: ethereum:: SignablePythContract ,
3+ chain:: ethereum:: { RevealedWithCallbackFilter , SignablePythContract } ,
54 config:: { Config , GenerateOptions } ,
65 } ,
76 anyhow:: Result ,
87 base64:: { engine:: general_purpose:: STANDARD as base64_standard_engine, Engine as _} ,
8+ ethers:: providers:: Middleware ,
99 std:: sync:: Arc ,
10+ tokio:: time:: { self , Duration } ,
1011} ;
1112
1213/// Run the entire random number generation protocol to produce a random number.
@@ -22,42 +23,54 @@ pub async fn generate(opts: &GenerateOptions) -> Result<()> {
2223 let user_randomness = rand:: random :: < [ u8 ; 32 ] > ( ) ;
2324 let provider = opts. provider ;
2425
26+ let mut last_block_number = contract. provider ( ) . get_block_number ( ) . await ?;
27+ tracing:: info!( block_number = last_block_number. as_u64( ) , "block number" ) ;
28+
29+ tracing:: info!( "Requesting random number..." ) ;
30+
2531 // Request a random number on the contract
2632 let sequence_number = contract
27- . request_wrapper ( & provider, & user_randomness, opts . blockhash )
33+ . request_with_callback_wrapper ( & provider, & user_randomness)
2834 . await ?;
2935
30- tracing:: info!( sequence_number = sequence_number, "random number requested" , ) ;
36+ tracing:: info!( sequence_number = sequence_number, "Random number requested" , ) ;
3137
32- // Get the committed value from the provider
33- let resp = reqwest:: get ( opts. url . join ( & format ! (
34- "/v1/chains/{}/revelations/{}" ,
35- opts. chain_id, sequence_number
36- ) ) ?)
37- . await ?
38- . json :: < GetRandomValueResponse > ( )
39- . await ?;
38+ let mut num_retries = 0 ;
39+ let mut found_request = false ;
40+ while !found_request && num_retries < 10 {
41+ let current_block_number = contract. provider ( ) . get_block_number ( ) . await ?;
42+ tracing:: info!(
43+ start_block = last_block_number. as_u64( ) ,
44+ end_block = current_block_number. as_u64( ) ,
45+ "Checking events between blocks."
46+ ) ;
4047
41- tracing:: info!(
42- response = base64_standard_engine. encode( resp. value. data( ) ) ,
43- "Retrieved the provider's random value." ,
44- ) ;
45- let provider_randomness = resp. value . data ( ) ;
46-
47- // Submit the provider's and our values to the contract to reveal the random number.
48- let random_value = contract
49- . reveal_wrapper (
50- & provider,
51- sequence_number,
52- & user_randomness,
53- provider_randomness,
54- )
55- . await ?;
48+ let mut event = contract. revealed_with_callback_filter ( ) ;
49+ event. filter = event
50+ . filter
51+ . from_block ( last_block_number)
52+ . to_block ( current_block_number) ;
5653
57- tracing:: info!(
58- number = base64_standard_engine. encode( random_value) ,
59- "Random number generated."
60- ) ;
54+ let res: Vec < RevealedWithCallbackFilter > = event. query ( ) . await ?;
55+
56+ for r in res. iter ( ) {
57+ if r. request . sequence_number == sequence_number && r. request . provider == provider {
58+ tracing:: info!(
59+ number = base64_standard_engine. encode( r. random_number) ,
60+ "Random number generated."
61+ ) ;
62+ found_request = true ;
63+ }
64+ }
65+
66+ last_block_number = current_block_number;
67+ num_retries += 1 ;
68+ time:: sleep ( Duration :: from_secs ( 1 ) ) . await ;
69+ }
70+
71+ if !found_request {
72+ tracing:: info!( "Failed to receive a callback with the random number." ) ;
73+ }
6174
6275 Ok ( ( ) )
6376}
0 commit comments