33
44use std:: str:: FromStr ;
55
6- use anyhow:: bail;
76use axum:: async_trait;
87use build_info:: chrono:: { DateTime , Utc } ;
98use indexer_dips:: {
@@ -19,54 +18,59 @@ pub struct PsqlAgreementStore {
1918 pub pool : PgPool ,
2019}
2120
22- // Utility to convert alloy::alloy_primitives::Uint<256, 4> into sqlx::BigDecimal
23- fn uint256_to_bigdecimal ( uint256 : & uint256 ) -> BigDecimal {
24- BigDecimal :: from_str ( & uint256. to_string ( ) ) . unwrap ( )
25- }
26-
27- fn uint32_to_i64 ( uint32 : u32 ) -> i64 {
28- uint32. into ( )
21+ fn uint256_to_bigdecimal ( value : & uint256 , field : & str ) -> Result < BigDecimal , DipsError > {
22+ BigDecimal :: from_str ( & value. to_string ( ) )
23+ . map_err ( |e| DipsError :: InvalidVoucher ( format ! ( "{}: {}" , field, e) ) )
2924}
3025
3126#[ async_trait]
3227impl AgreementStore for PsqlAgreementStore {
3328 async fn get_by_id (
3429 & self ,
3530 id : Uuid ,
36- ) -> anyhow :: Result < Option < ( SignedIndexingAgreementVoucher , bool ) > > {
31+ ) -> Result < Option < ( SignedIndexingAgreementVoucher , bool ) > , DipsError > {
3732 let item = sqlx:: query!( "SELECT * FROM indexing_agreements WHERE id=$1" , id, )
3833 . fetch_one ( & self . pool )
3934 . await ;
4035
4136 let item = match item {
4237 Ok ( item) => item,
4338 Err ( sqlx:: Error :: RowNotFound ) => return Ok ( None ) ,
44- Err ( err) => bail ! ( err) ,
39+ Err ( err) => return Err ( DipsError :: UnknownError ( err. into ( ) ) ) ,
4540 } ;
4641
47- let signed =
48- SignedIndexingAgreementVoucher :: abi_decode ( item . signed_payload . as_ref ( ) , true ) ?;
42+ let signed = SignedIndexingAgreementVoucher :: abi_decode ( item . signed_payload . as_ref ( ) , true )
43+ . map_err ( |e| DipsError :: AbiDecoding ( e . to_string ( ) ) ) ?;
4944 let cancelled = item. cancelled_at . is_some ( ) ;
5045 Ok ( Some ( ( signed, cancelled) ) )
5146 }
5247 async fn create_agreement (
5348 & self ,
5449 agreement : SignedIndexingAgreementVoucher ,
5550 metadata : SubgraphIndexingVoucherMetadata ,
56- ) -> anyhow :: Result < ( ) > {
51+ ) -> Result < ( ) , DipsError > {
5752 let id = Uuid :: from_bytes ( agreement. voucher . agreement_id . into ( ) ) ;
5853 let bs = agreement. encode_vec ( ) ;
5954 let now = Utc :: now ( ) ;
60- let deadline =
61- DateTime :: from_timestamp ( agreement. voucher . deadline . try_into ( ) . unwrap ( ) , 0 ) . unwrap ( ) ;
62- let base_price_per_epoch = uint256_to_bigdecimal ( & metadata. basePricePerEpoch ) ;
63- let price_per_entity = uint256_to_bigdecimal ( & metadata. pricePerEntity ) ;
64- let duration_epochs = uint32_to_i64 ( agreement. voucher . durationEpochs ) ;
65- let max_initial_amount = uint256_to_bigdecimal ( & agreement. voucher . maxInitialAmount ) ;
66- let max_ongoing_amount_per_epoch =
67- uint256_to_bigdecimal ( & agreement. voucher . maxOngoingAmountPerEpoch ) ;
68- let min_epochs_per_collection = uint32_to_i64 ( agreement. voucher . minEpochsPerCollection ) ;
69- let max_epochs_per_collection = uint32_to_i64 ( agreement. voucher . maxEpochsPerCollection ) ;
55+ let deadline_i64: i64 = agreement
56+ . voucher
57+ . deadline
58+ . try_into ( )
59+ . map_err ( |_| DipsError :: InvalidVoucher ( "deadline" . to_string ( ) ) ) ?;
60+ let deadline = DateTime :: from_timestamp ( deadline_i64, 0 )
61+ . ok_or ( DipsError :: InvalidVoucher ( "deadline" . to_string ( ) ) ) ?;
62+ let base_price_per_epoch =
63+ uint256_to_bigdecimal ( & metadata. basePricePerEpoch , "basePricePerEpoch" ) ?;
64+ let price_per_entity = uint256_to_bigdecimal ( & metadata. pricePerEntity , "pricePerEntity" ) ?;
65+ let duration_epochs: i64 = agreement. voucher . durationEpochs . into ( ) ;
66+ let max_initial_amount =
67+ uint256_to_bigdecimal ( & agreement. voucher . maxInitialAmount , "maxInitialAmount" ) ?;
68+ let max_ongoing_amount_per_epoch = uint256_to_bigdecimal (
69+ & agreement. voucher . maxOngoingAmountPerEpoch ,
70+ "maxOngoingAmountPerEpoch" ,
71+ ) ?;
72+ let min_epochs_per_collection: i64 = agreement. voucher . minEpochsPerCollection . into ( ) ;
73+ let max_epochs_per_collection: i64 = agreement. voucher . maxEpochsPerCollection . into ( ) ;
7074 sqlx:: query!(
7175 "INSERT INTO indexing_agreements VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,null,null,null)" ,
7276 id,
@@ -90,7 +94,8 @@ impl AgreementStore for PsqlAgreementStore {
9094 now
9195 )
9296 . execute ( & self . pool )
93- . await ?;
97+ . await
98+ . map_err ( |e| DipsError :: UnknownError ( e. into ( ) ) ) ?;
9499
95100 Ok ( ( ) )
96101 }
@@ -221,18 +226,17 @@ pub(crate) mod test {
221226 . unwrap ( ) ;
222227
223228 // Retrieve agreement
224- let retrieved = store. get_by_id ( id) . await . unwrap ( ) . unwrap ( ) ;
229+ let ( retrieved_signed_voucher , cancelled ) = store. get_by_id ( id) . await . unwrap ( ) . unwrap ( ) ;
225230
226- let retrieved_voucher = & retrieved. 0 . voucher ;
227- let cancelled = retrieved. 1 ;
231+ let retrieved_voucher = & retrieved_signed_voucher. voucher ;
228232 let retrieved_metadata =
229233 <indexer_dips:: SubgraphIndexingVoucherMetadata as SolType >:: abi_decode (
230234 retrieved_voucher. metadata . as_ref ( ) ,
231235 true ,
232236 )
233237 . unwrap ( ) ;
234238 // Verify retrieved agreement matches original
235- assert_eq ! ( retrieved . 0 . signature, agreement. signature) ;
239+ assert_eq ! ( retrieved_signed_voucher . signature, agreement. signature) ;
236240 assert_eq ! (
237241 retrieved_voucher. durationEpochs,
238242 agreement. voucher. durationEpochs
0 commit comments