1
1
use {
2
2
crate :: {
3
- api:: GetRandomValueResponse ,
4
- chain:: ethereum:: SignablePythContract ,
3
+ chain:: ethereum:: { RevealedWithCallbackFilter , SignablePythContract } ,
5
4
config:: { Config , GenerateOptions } ,
6
5
} ,
7
6
anyhow:: Result ,
8
7
base64:: { engine:: general_purpose:: STANDARD as base64_standard_engine, Engine as _} ,
8
+ ethers:: providers:: Middleware ,
9
9
std:: sync:: Arc ,
10
+ tokio:: time:: { self , Duration } ,
10
11
} ;
11
12
12
13
/// Run the entire random number generation protocol to produce a random number.
@@ -22,42 +23,54 @@ pub async fn generate(opts: &GenerateOptions) -> Result<()> {
22
23
let user_randomness = rand:: random :: < [ u8 ; 32 ] > ( ) ;
23
24
let provider = opts. provider ;
24
25
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
+
25
31
// Request a random number on the contract
26
32
let sequence_number = contract
27
- . request_wrapper ( & provider, & user_randomness, opts . blockhash )
33
+ . request_with_callback_wrapper ( & provider, & user_randomness)
28
34
. await ?;
29
35
30
- tracing:: info!( sequence_number = sequence_number, "random number requested" , ) ;
36
+ tracing:: info!( sequence_number = sequence_number, "Random number requested" , ) ;
31
37
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
+ ) ;
40
47
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) ;
56
53
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
+ }
61
74
62
75
Ok ( ( ) )
63
76
}
0 commit comments