33
44use std:: { str:: FromStr , sync:: Arc } ;
55
6- use ipfs:: IpfsFetcher ;
7- use price:: PriceCalculator ;
6+ use server:: DipsServerContext ;
87use thegraph_core:: alloy:: {
98 core:: primitives:: Address ,
109 primitives:: { b256, ChainId , PrimitiveSignature as Signature , Uint , B256 } ,
@@ -18,6 +17,7 @@ pub mod ipfs;
1817pub mod price;
1918pub mod proto;
2019pub mod server;
20+ pub mod signers;
2121pub mod store;
2222
2323use store:: AgreementStore ;
@@ -190,14 +190,16 @@ impl SignedIndexingAgreementVoucher {
190190 // TODO: Validate all values
191191 pub fn validate (
192192 & self ,
193+ signer_validator : & Arc < dyn signers:: SignerValidator > ,
193194 domain : & Eip712Domain ,
194195 expected_payee : & Address ,
195196 allowed_payers : impl AsRef < [ Address ] > ,
196197 ) -> Result < ( ) , DipsError > {
197198 let sig = Signature :: from_str ( & self . signature . to_string ( ) )
198199 . map_err ( |err| DipsError :: InvalidSignature ( err. to_string ( ) ) ) ?;
199200
200- let payer = sig
201+ let payer = self . voucher . payer ;
202+ let signer = sig
201203 . recover_address_from_prehash ( & self . voucher . eip712_signing_hash ( domain) )
202204 . map_err ( |err| DipsError :: InvalidSignature ( err. to_string ( ) ) ) ?;
203205
@@ -207,6 +209,10 @@ impl SignedIndexingAgreementVoucher {
207209 return Err ( DipsError :: PayerNotAuthorised ( payer) ) ;
208210 }
209211
212+ signer_validator
213+ . validate ( & payer, & signer)
214+ . map_err ( |_| DipsError :: SignerNotAuthorised ( signer) ) ?;
215+
210216 if !self . voucher . recipient . eq ( expected_payee) {
211217 return Err ( DipsError :: UnexpectedPayee {
212218 expected : * expected_payee,
@@ -284,14 +290,18 @@ impl CollectionRequest {
284290}
285291
286292pub async fn validate_and_create_agreement (
287- store : Arc < dyn AgreementStore > ,
293+ ctx : Arc < DipsServerContext > ,
288294 domain : & Eip712Domain ,
289295 expected_payee : & Address ,
290296 allowed_payers : impl AsRef < [ Address ] > ,
291297 voucher : Vec < u8 > ,
292- price_calculator : & PriceCalculator ,
293- ipfs_client : Arc < dyn IpfsFetcher > ,
294298) -> Result < Uuid , DipsError > {
299+ let DipsServerContext {
300+ store,
301+ ipfs_fetcher,
302+ price_calculator,
303+ signer_validator,
304+ } = ctx. as_ref ( ) ;
295305 let decoded_voucher = SignedIndexingAgreementVoucher :: abi_decode ( voucher. as_ref ( ) , true )
296306 . map_err ( |e| DipsError :: AbiDecoding ( e. to_string ( ) ) ) ?;
297307 let metadata = SubgraphIndexingVoucherMetadata :: abi_decode (
@@ -300,9 +310,9 @@ pub async fn validate_and_create_agreement(
300310 )
301311 . map_err ( |e| DipsError :: AbiDecoding ( e. to_string ( ) ) ) ?;
302312
303- decoded_voucher. validate ( domain, expected_payee, allowed_payers) ?;
313+ decoded_voucher. validate ( signer_validator , domain, expected_payee, allowed_payers) ?;
304314
305- let manifest = ipfs_client . fetch ( & metadata. subgraphDeploymentId ) . await ?;
315+ let manifest = ipfs_fetcher . fetch ( & metadata. subgraphDeploymentId ) . await ?;
306316 match manifest. network ( ) {
307317 Some ( chain_id) if chain_id == metadata. chainId => { }
308318 Some ( chain_id) => {
@@ -370,10 +380,11 @@ pub async fn validate_and_cancel_agreement(
370380#[ cfg( test) ]
371381mod test {
372382 use std:: {
373- sync :: Arc ,
383+ collections :: HashMap ,
374384 time:: { Duration , SystemTime , UNIX_EPOCH } ,
375385 } ;
376386
387+ use indexer_monitor:: EscrowAccounts ;
377388 use rand:: { distr:: Alphanumeric , Rng } ;
378389 use thegraph_core:: alloy:: {
379390 primitives:: { Address , FixedBytes , U256 } ,
@@ -384,9 +395,9 @@ mod test {
384395
385396 pub use crate :: store:: { AgreementStore , InMemoryAgreementStore } ;
386397 use crate :: {
387- dips_agreement_eip712_domain, dips_cancellation_eip712_domain, ipfs :: TestIpfsClient ,
388- price :: PriceCalculator , CancellationRequest , DipsError , IndexingAgreementVoucher ,
389- SignedIndexingAgreementVoucher , SubgraphIndexingVoucherMetadata ,
398+ dips_agreement_eip712_domain, dips_cancellation_eip712_domain, server :: DipsServerContext ,
399+ CancellationRequest , DipsError , IndexingAgreementVoucher , SignedIndexingAgreementVoucher ,
400+ SubgraphIndexingVoucherMetadata ,
390401 } ;
391402
392403 #[ tokio:: test]
@@ -424,22 +435,19 @@ mod test {
424435 let abi_voucher = voucher. abi_encode ( ) ;
425436 let id = Uuid :: from_bytes ( voucher. voucher . agreement_id . into ( ) ) ;
426437
427- let store = Arc :: new ( InMemoryAgreementStore :: default ( ) ) ;
428-
438+ let ctx = DipsServerContext :: for_testing ( ) ;
429439 let actual_id = super :: validate_and_create_agreement (
430- store . clone ( ) ,
440+ ctx . clone ( ) ,
431441 & domain,
432442 & payee_addr,
433443 vec ! [ payer_addr] ,
434444 abi_voucher,
435- & PriceCalculator :: for_testing ( ) ,
436- Arc :: new ( TestIpfsClient :: mainnet ( ) ) ,
437445 )
438446 . await
439447 . unwrap ( ) ;
440448 assert_eq ! ( actual_id, id) ;
441449
442- let stored_agreement = store. get_by_id ( actual_id) . await . unwrap ( ) . unwrap ( ) ;
450+ let stored_agreement = ctx . store . get_by_id ( actual_id) . await . unwrap ( ) . unwrap ( ) ;
443451
444452 assert_eq ! ( voucher, stored_agreement. voucher) ;
445453 assert ! ( !stored_agreement. cancelled) ;
@@ -448,6 +456,7 @@ mod test {
448456
449457 #[ test]
450458 fn voucher_signature_verification ( ) {
459+ let ctx = DipsServerContext :: for_testing ( ) ;
451460 let deployment_id = "Qmbg1qF4YgHjiVfsVt6a13ddrVcRtWyJQfD4LA3CwHM29f" . to_string ( ) ;
452461 let payee = PrivateKeySigner :: random ( ) ;
453462 let payee_addr = payee. address ( ) ;
@@ -480,23 +489,34 @@ mod test {
480489 let signed = voucher. sign ( & domain, payer) . unwrap ( ) ;
481490 assert_eq ! (
482491 signed
483- . validate( & domain, & payee_addr, vec![ ] )
492+ . validate( & ctx . signer_validator , & domain, & payee_addr, vec![ ] )
484493 . unwrap_err( )
485494 . to_string( ) ,
486495 DipsError :: PayerNotAuthorised ( voucher. payer) . to_string( )
487496 ) ;
488497 assert ! ( signed
489- . validate( & domain, & payee_addr, vec![ payer_addr] )
498+ . validate(
499+ & ctx. signer_validator,
500+ & domain,
501+ & payee_addr,
502+ vec![ payer_addr]
503+ )
490504 . is_ok( ) ) ;
491505 }
492506
493- #[ test]
494- fn check_voucher_modified ( ) {
495- let deployment_id = "Qmbg1qF4YgHjiVfsVt6a13ddrVcRtWyJQfD4LA3CwHM29f" . to_string ( ) ;
507+ #[ tokio:: test]
508+ async fn check_voucher_modified ( ) {
496509 let payee = PrivateKeySigner :: random ( ) ;
497510 let payee_addr = payee. address ( ) ;
498511 let payer = PrivateKeySigner :: random ( ) ;
499512 let payer_addr = payer. address ( ) ;
513+ let ctx = DipsServerContext :: for_testing_mocked_accounts ( EscrowAccounts :: new (
514+ HashMap :: default ( ) ,
515+ HashMap :: from_iter ( vec ! [ ( payer_addr, vec![ payer_addr] ) ] ) ,
516+ ) )
517+ . await ;
518+
519+ let deployment_id = "Qmbg1qF4YgHjiVfsVt6a13ddrVcRtWyJQfD4LA3CwHM29f" . to_string ( ) ;
500520
501521 let metadata = SubgraphIndexingVoucherMetadata {
502522 basePricePerEpoch : U256 :: from ( 10000_u64 ) ,
@@ -526,9 +546,14 @@ mod test {
526546
527547 assert ! ( matches!(
528548 signed
529- . validate( & domain, & payee_addr, vec![ payer_addr] )
549+ . validate(
550+ & ctx. signer_validator,
551+ & domain,
552+ & payee_addr,
553+ vec![ payer_addr]
554+ )
530555 . unwrap_err( ) ,
531- DipsError :: PayerNotAuthorised ( _)
556+ DipsError :: SignerNotAuthorised ( _)
532557 ) ) ;
533558 }
534559
@@ -630,8 +655,8 @@ mod test {
630655
631656 #[ tokio:: test]
632657 async fn test_create_and_cancel_agreement ( ) -> anyhow:: Result < ( ) > {
658+ let ctx = DipsServerContext :: for_testing ( ) ;
633659 let voucher_ctx = VoucherContext :: random ( ) ;
634- let store = Arc :: new ( InMemoryAgreementStore :: default ( ) ) ;
635660
636661 // Create metadata and voucher
637662 let metadata = SubgraphIndexingVoucherMetadata {
@@ -645,13 +670,11 @@ mod test {
645670
646671 // Create agreement
647672 let agreement_id = super :: validate_and_create_agreement (
648- store . clone ( ) ,
673+ ctx . clone ( ) ,
649674 & voucher_ctx. domain ( ) ,
650675 & voucher_ctx. payee . address ( ) ,
651676 vec ! [ voucher_ctx. payer. address( ) ] ,
652677 signed_voucher. encode_vec ( ) ,
653- & PriceCalculator :: for_testing ( ) ,
654- Arc :: new ( TestIpfsClient :: mainnet ( ) ) ,
655678 )
656679 . await ?;
657680
@@ -664,7 +687,7 @@ mod test {
664687
665688 // Cancel agreement
666689 let cancelled_id = super :: validate_and_cancel_agreement (
667- store. clone ( ) ,
690+ ctx . store . clone ( ) ,
668691 & cancel_domain,
669692 signed_cancel. encode_vec ( ) ,
670693 )
@@ -673,16 +696,16 @@ mod test {
673696 assert_eq ! ( agreement_id, cancelled_id) ;
674697
675698 // Verify agreement is cancelled
676- let stored_agreement = store. get_by_id ( agreement_id) . await ?. unwrap ( ) ;
699+ let stored_agreement = ctx . store . get_by_id ( agreement_id) . await ?. unwrap ( ) ;
677700 assert ! ( stored_agreement. cancelled) ;
678701
679702 Ok ( ( ) )
680703 }
681704
682705 #[ tokio:: test]
683706 async fn test_create_validations_errors ( ) -> anyhow:: Result < ( ) > {
707+ let ctx = DipsServerContext :: for_testing ( ) ;
684708 let voucher_ctx = VoucherContext :: random ( ) ;
685- let store = Arc :: new ( InMemoryAgreementStore :: default ( ) ) ;
686709
687710 let metadata = SubgraphIndexingVoucherMetadata {
688711 basePricePerEpoch : U256 :: from ( 10000_u64 ) ,
@@ -734,13 +757,11 @@ mod test {
734757 let cases = vec ! [ wrong_network_voucher, low_price_voucher, valid_voucher] ;
735758 for ( voucher, result) in cases. into_iter ( ) . zip ( expected_result. into_iter ( ) ) {
736759 let out = super :: validate_and_create_agreement (
737- store . clone ( ) ,
760+ ctx . clone ( ) ,
738761 & voucher_ctx. domain ( ) ,
739762 & voucher_ctx. payee . address ( ) ,
740763 vec ! [ voucher_ctx. payer. address( ) ] ,
741764 voucher. encode_vec ( ) ,
742- & PriceCalculator :: for_testing ( ) ,
743- Arc :: new ( TestIpfsClient :: mainnet ( ) ) ,
744765 )
745766 . await ;
746767
0 commit comments