55 ethers:: {
66 core:: utils:: hex:: ToHex ,
77 prelude:: TxHash ,
8- types:: { Address , U256 } ,
8+ types:: { Address , Bytes , U256 } ,
99 utils:: keccak256,
1010 } ,
1111 serde:: Serialize ,
@@ -45,6 +45,17 @@ pub enum RequestEntryState {
4545 #[ schema( example = "a905ab56567d31a7fda38ed819d97bc257f3ebe385fc5c72ce226d3bb855f0fe" ) ]
4646 #[ serde_as( as = "serde_with::hex::Hex" ) ]
4747 combined_random_number : [ u8 ; 32 ] ,
48+ /// Whether the callback to the caller failed.
49+ callback_failed : bool ,
50+ /// Return value from the callback. If the callback failed, this field contains
51+ /// the error code and any additional returned data. Note that "" often indicates an out-of-gas error.
52+ /// If the callback returns more than 256 bytes, only the first 256 bytes of the callback return value are included.
53+ /// NOTE: This field is the raw bytes returned from the callback, not hex-decoded. The client should decode it as needed.
54+ callback_return_value : Bytes ,
55+ /// How much gas the callback used.
56+ #[ schema( example = "567890" , value_type = String ) ]
57+ #[ serde( with = "crate::serde::u32" ) ]
58+ callback_gas_used : u32 ,
4859 } ,
4960 Failed {
5061 reason : String ,
@@ -78,8 +89,7 @@ pub struct RequestStatus {
7889 /// Gas limit for the callback in the smallest unit of the chain.
7990 /// For example, if the native currency is ETH, this will be in wei.
8091 #[ schema( example = "500000" , value_type = String ) ]
81- #[ serde( with = "crate::serde::u256" ) ]
82- pub gas_limit : U256 ,
92+ pub gas_limit : u32 ,
8393 /// The user contribution to the random number.
8494 #[ schema( example = "a905ab56567d31a7fda38ed819d97bc257f3ebe385fc5c72ce226d3bb855f0fe" ) ]
8595 #[ serde_as( as = "serde_with::hex::Hex" ) ]
@@ -121,6 +131,9 @@ struct RequestRow {
121131 provider_random_number : Option < String > ,
122132 gas_used : Option < String > ,
123133 info : Option < String > ,
134+ callback_failed : Option < i64 > ,
135+ callback_return_value : Option < String > ,
136+ callback_gas_used : Option < String > ,
124137}
125138
126139impl TryFrom < RequestRow > for RequestStatus {
@@ -139,7 +152,9 @@ impl TryFrom<RequestRow> for RequestStatus {
139152 let user_random_number = hex:: FromHex :: from_hex ( row. user_random_number ) ?;
140153 let request_tx_hash = row. request_tx_hash . parse ( ) ?;
141154 let sender = row. sender . parse ( ) ?;
142- let gas_limit = U256 :: from_dec_str ( & row. gas_limit )
155+ let gas_limit = row
156+ . gas_limit
157+ . parse :: < u32 > ( )
143158 . map_err ( |_| anyhow:: anyhow!( "Failed to parse gas limit" ) ) ?;
144159
145160 let state = match row. state . as_str ( ) {
@@ -173,6 +188,18 @@ impl TryFrom<RequestRow> for RequestStatus {
173188 & user_random_number,
174189 & provider_random_number,
175190 ) ,
191+ // Sqlx::Any doesn't support boolean types, so we need to convert from integer
192+ // https://github.com/launchbadge/sqlx/issues/2778
193+ callback_failed : row. callback_failed . unwrap_or ( 0 ) == 1 ,
194+ callback_return_value : row
195+ . callback_return_value
196+ . map ( |s| s. parse :: < Bytes > ( ) . unwrap_or_default ( ) )
197+ . unwrap_or_default ( ) ,
198+ callback_gas_used : row
199+ . callback_gas_used
200+ . unwrap_or_default ( )
201+ . parse :: < u32 > ( )
202+ . map_err ( |_| anyhow:: anyhow!( "Failed to parse callback_gas_used" ) ) ?,
176203 }
177204 }
178205 "Failed" => RequestEntryState :: Failed {
@@ -312,18 +339,29 @@ impl History {
312339 provider_random_number,
313340 gas_used,
314341 combined_random_number : _,
342+ callback_failed,
343+ callback_return_value,
344+ callback_gas_used,
315345 } => {
316346 let reveal_block_number = reveal_block_number as i64 ;
317347 let reveal_tx_hash: String = reveal_tx_hash. encode_hex ( ) ;
318348 let provider_random_number: String = provider_random_number. encode_hex ( ) ;
319349 let gas_used: String = gas_used. to_string ( ) ;
320- let result = sqlx:: query ( "UPDATE request SET state = $1, last_updated_at = $2, reveal_block_number = $3, reveal_tx_hash = $4, provider_random_number = $5, gas_used = $6 WHERE network_id = $7 AND sequence = $8 AND provider = $9 AND request_tx_hash = $10" )
350+ // Sqlx::Any doesn't support boolean types, so we need to convert to integer
351+ // https://github.com/launchbadge/sqlx/issues/2778
352+ let callback_failed: i64 = if callback_failed { 1 } else { 0 } ;
353+ let callback_return_value: String = callback_return_value. encode_hex ( ) ;
354+ let callback_gas_used: String = callback_gas_used. to_string ( ) ;
355+ let result = sqlx:: query ( "UPDATE request SET state = $1, last_updated_at = $2, reveal_block_number = $3, reveal_tx_hash = $4, provider_random_number = $5, gas_used = $6, callback_failed = $7, callback_return_value = $8, callback_gas_used = $9 WHERE network_id = $10 AND sequence = $11 AND provider = $12 AND request_tx_hash = $13" )
321356 . bind ( "Completed" )
322357 . bind ( new_status. last_updated_at . timestamp ( ) )
323358 . bind ( reveal_block_number)
324359 . bind ( reveal_tx_hash)
325360 . bind ( provider_random_number)
326361 . bind ( gas_used)
362+ . bind ( callback_failed)
363+ . bind ( callback_return_value)
364+ . bind ( callback_gas_used)
327365 . bind ( network_id)
328366 . bind ( sequence)
329367 . bind ( provider. clone ( ) )
@@ -646,7 +684,7 @@ mod test {
646684 user_random_number : [ 20 ; 32 ] ,
647685 sender : Address :: random ( ) ,
648686 state : RequestEntryState :: Pending ,
649- gas_limit : U256 :: from ( 500_000 ) ,
687+ gas_limit : 500_000 ,
650688 }
651689 }
652690
@@ -665,6 +703,9 @@ mod test {
665703 & status. user_random_number ,
666704 & [ 40 ; 32 ] ,
667705 ) ,
706+ callback_failed : false ,
707+ callback_return_value : Default :: default ( ) ,
708+ callback_gas_used : 100_000 ,
668709 } ;
669710 History :: update_request_status ( & history. pool , status. clone ( ) ) . await ;
670711
@@ -876,6 +917,9 @@ mod test {
876917 & status. user_random_number ,
877918 & [ 40 ; 32 ] ,
878919 ) ,
920+ callback_failed : false ,
921+ callback_return_value : Default :: default ( ) ,
922+ callback_gas_used : 0 ,
879923 } ;
880924 History :: update_request_status ( & history. pool , status. clone ( ) ) . await ;
881925 let mut failed_status = status. clone ( ) ;
0 commit comments