22 crate :: api:: ChainId ,
33 anyhow:: Result ,
44 chrono:: { DateTime , NaiveDateTime } ,
5- ethers:: { core:: utils:: hex:: ToHex , prelude:: TxHash , types:: { Address , U256 } } ,
5+ ethers:: {
6+ core:: utils:: hex:: ToHex ,
7+ prelude:: TxHash ,
8+ types:: { Address , U256 } ,
9+ utils:: keccak256,
10+ } ,
611 serde:: Serialize ,
712 serde_with:: serde_as,
813 sqlx:: { migrate, Pool , Sqlite , SqlitePool } ,
1722pub enum RequestEntryState {
1823 Pending ,
1924 Completed {
25+ /// The block number of the reveal transaction.
2026 reveal_block_number : u64 ,
2127 /// The transaction hash of the reveal transaction.
2228 #[ schema( example = "0xfe5f880ac10c0aae43f910b5a17f98a93cdd2eb2dce3a5ae34e5827a3a071a32" , value_type = String ) ]
@@ -28,7 +34,12 @@ pub enum RequestEntryState {
2834 /// The gas used for the reveal transaction in the smallest unit of the chain.
2935 /// For example, if the native currency is ETH, this will be in wei.
3036 #[ schema( example = "567890" , value_type = String ) ]
37+ #[ serde( with = "crate::serde::u256" ) ]
3138 gas_used : U256 ,
39+ /// The combined random number generated from the user and provider contributions.
40+ #[ schema( example = "a905ab56567d31a7fda38ed819d97bc257f3ebe385fc5c72ce226d3bb855f0fe" ) ]
41+ #[ serde_as( as = "serde_with::hex::Hex" ) ]
42+ combined_random_number : [ u8 ; 32 ] ,
3243 } ,
3344 Failed {
3445 reason : String ,
@@ -56,6 +67,11 @@ pub struct RequestStatus {
5667 /// The transaction hash of the request transaction.
5768 #[ schema( example = "0x5a3a984f41bb5443f5efa6070ed59ccb25edd8dbe6ce7f9294cf5caa64ed00ae" , value_type = String ) ]
5869 pub request_tx_hash : TxHash ,
70+ /// Gas limit for the callback in the smallest unit of the chain.
71+ /// For example, if the native currency is ETH, this will be in wei.
72+ #[ schema( example = "500000" , value_type = String ) ]
73+ #[ serde( with = "crate::serde::u256" ) ]
74+ pub gas_limit : U256 ,
5975 /// The user contribution to the random number.
6076 #[ schema( example = "a905ab56567d31a7fda38ed819d97bc257f3ebe385fc5c72ce226d3bb855f0fe" ) ]
6177 #[ serde_as( as = "serde_with::hex::Hex" ) ]
@@ -66,6 +82,18 @@ pub struct RequestStatus {
6682 pub state : RequestEntryState ,
6783}
6884
85+ impl RequestStatus {
86+ pub fn generate_combined_random_number (
87+ user_random_number : & [ u8 ; 32 ] ,
88+ provider_random_number : & [ u8 ; 32 ] ,
89+ ) -> [ u8 ; 32 ] {
90+ let mut concat: [ u8 ; 96 ] = [ 0 ; 96 ] ; // last 32 bytes are for the block hash which is not used here
91+ concat[ 0 ..32 ] . copy_from_slice ( user_random_number) ;
92+ concat[ 32 ..64 ] . copy_from_slice ( provider_random_number) ;
93+ keccak256 ( & concat)
94+ }
95+ }
96+
6997#[ derive( Clone , Debug , Serialize , ToSchema , PartialEq ) ]
7098struct RequestRow {
7199 chain_id : String ,
@@ -78,6 +106,7 @@ struct RequestRow {
78106 request_tx_hash : String ,
79107 user_random_number : String ,
80108 sender : String ,
109+ gas_limit : String ,
81110 reveal_block_number : Option < i64 > ,
82111 reveal_tx_hash : Option < String > ,
83112 provider_random_number : Option < String > ,
@@ -98,6 +127,8 @@ impl TryFrom<RequestRow> for RequestStatus {
98127 let user_random_number = hex:: FromHex :: from_hex ( row. user_random_number ) ?;
99128 let request_tx_hash = row. request_tx_hash . parse ( ) ?;
100129 let sender = row. sender . parse ( ) ?;
130+ let gas_limit = U256 :: from_dec_str ( & row. gas_limit )
131+ . map_err ( |_| anyhow:: anyhow!( "Failed to parse gas limit" ) ) ?;
101132
102133 let state = match row. state . as_str ( ) {
103134 "Pending" => RequestEntryState :: Pending ,
@@ -116,16 +147,20 @@ impl TryFrom<RequestRow> for RequestStatus {
116147 ) ) ?;
117148 let provider_random_number: [ u8 ; 32 ] =
118149 hex:: FromHex :: from_hex ( provider_random_number) ?;
119- let gas_used = row. gas_used . ok_or ( anyhow :: anyhow! (
120- "Gas used is missing for completed request"
121- ) ) ?;
150+ let gas_used = row
151+ . gas_used
152+ . ok_or ( anyhow :: anyhow! ( "Gas used is missing for completed request" ) ) ?;
122153 let gas_used = U256 :: from_dec_str ( & gas_used)
123154 . map_err ( |_| anyhow:: anyhow!( "Failed to parse gas used" ) ) ?;
124155 RequestEntryState :: Completed {
125156 reveal_block_number,
126157 reveal_tx_hash,
127158 provider_random_number,
128159 gas_used,
160+ combined_random_number : Self :: generate_combined_random_number (
161+ & user_random_number,
162+ & provider_random_number,
163+ ) ,
129164 }
130165 }
131166 "Failed" => RequestEntryState :: Failed {
@@ -150,6 +185,7 @@ impl TryFrom<RequestRow> for RequestStatus {
150185 request_tx_hash,
151186 user_random_number,
152187 sender,
188+ gas_limit,
153189 } )
154190 }
155191}
@@ -208,12 +244,13 @@ impl History {
208244 let chain_id = new_status. chain_id ;
209245 let request_tx_hash: String = new_status. request_tx_hash . encode_hex ( ) ;
210246 let provider: String = new_status. provider . encode_hex ( ) ;
247+ let gas_limit = new_status. gas_limit . to_string ( ) ;
211248 let result = match new_status. state {
212249 RequestEntryState :: Pending => {
213250 let block_number = new_status. request_block_number as i64 ;
214251 let sender: String = new_status. sender . encode_hex ( ) ;
215252 let user_random_number: String = new_status. user_random_number . encode_hex ( ) ;
216- sqlx:: query!( "INSERT INTO request(chain_id, provider, sequence, created_at, last_updated_at, state, request_block_number, request_tx_hash, user_random_number, sender) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ,
253+ sqlx:: query!( "INSERT INTO request(chain_id, provider, sequence, created_at, last_updated_at, state, request_block_number, request_tx_hash, user_random_number, sender, gas_limit ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ,
217254 chain_id,
218255 provider,
219256 sequence,
@@ -223,15 +260,18 @@ impl History {
223260 block_number,
224261 request_tx_hash,
225262 user_random_number,
226- sender)
263+ sender,
264+ gas_limit
265+ )
227266 . execute ( pool)
228267 . await
229268 }
230269 RequestEntryState :: Completed {
231270 reveal_block_number,
232271 reveal_tx_hash,
233272 provider_random_number,
234- gas_used
273+ gas_used,
274+ combined_random_number : _,
235275 } => {
236276 let reveal_block_number = reveal_block_number as i64 ;
237277 let reveal_tx_hash: String = reveal_tx_hash. encode_hex ( ) ;
@@ -429,6 +469,7 @@ mod test {
429469 user_random_number : [ 20 ; 32 ] ,
430470 sender : Address :: random ( ) ,
431471 state : RequestEntryState :: Pending ,
472+ gas_limit : U256 :: from ( 500_000 ) ,
432473 }
433474 }
434475
@@ -443,6 +484,10 @@ mod test {
443484 reveal_tx_hash,
444485 provider_random_number : [ 40 ; 32 ] ,
445486 gas_used : U256 :: from ( 567890 ) ,
487+ combined_random_number : RequestStatus :: generate_combined_random_number (
488+ & status. user_random_number ,
489+ & [ 40 ; 32 ] ,
490+ ) ,
446491 } ;
447492 History :: update_request_status ( & history. pool , status. clone ( ) ) . await ;
448493
@@ -494,6 +539,10 @@ mod test {
494539 reveal_tx_hash,
495540 provider_random_number : [ 40 ; 32 ] ,
496541 gas_used : U256 :: from ( 567890 ) ,
542+ combined_random_number : RequestStatus :: generate_combined_random_number (
543+ & status. user_random_number ,
544+ & [ 40 ; 32 ] ,
545+ ) ,
497546 } ;
498547 History :: update_request_status ( & history. pool , status. clone ( ) ) . await ;
499548 let mut failed_status = status. clone ( ) ;
@@ -527,6 +576,26 @@ mod test {
527576 assert_eq ! ( logs, vec![ status. clone( ) ] ) ;
528577 }
529578
579+ #[ tokio:: test]
580+ async fn test_generate_combined_random_number ( ) {
581+ let user_random_number = hex:: FromHex :: from_hex (
582+ "0000000000000000000000006c8ac03d388d5572f77aca84573628ee87a7a4da" ,
583+ )
584+ . unwrap ( ) ;
585+ let provider_random_number = hex:: FromHex :: from_hex (
586+ "deeb67cb894c33f7b20ae484228a9096b51e8db11461fcb0975c681cf0875d37" ,
587+ )
588+ . unwrap ( ) ;
589+ let combined_random_number = RequestStatus :: generate_combined_random_number (
590+ & user_random_number,
591+ & provider_random_number,
592+ ) ;
593+ let expected_combined_random_number: [ u8 ; 32 ] = hex:: FromHex :: from_hex (
594+ "1c26ffa1f8430dc91cb755a98bf37ce82ac0e2cfd961e10111935917694609d5" ,
595+ )
596+ . unwrap ( ) ;
597+ assert_eq ! ( combined_random_number, expected_combined_random_number, ) ;
598+ }
530599
531600 #[ tokio:: test]
532601 async fn test_history_filter_irrelevant_logs ( ) {
0 commit comments