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,12 @@ pub async fn validate_and_cancel_agreement(
370380#[ cfg( test) ]
371381mod test {
372382 use std:: {
383+ collections:: HashMap ,
373384 sync:: Arc ,
374385 time:: { Duration , SystemTime , UNIX_EPOCH } ,
375386 } ;
376387
388+ use indexer_monitor:: EscrowAccounts ;
377389 use rand:: { distr:: Alphanumeric , Rng } ;
378390 use thegraph_core:: alloy:: {
379391 primitives:: { Address , FixedBytes , U256 } ,
@@ -384,9 +396,9 @@ mod test {
384396
385397 pub use crate :: store:: { AgreementStore , InMemoryAgreementStore } ;
386398 use crate :: {
387- dips_agreement_eip712_domain, dips_cancellation_eip712_domain, ipfs :: TestIpfsClient ,
388- price :: PriceCalculator , CancellationRequest , DipsError , IndexingAgreementVoucher ,
389- SignedIndexingAgreementVoucher , SubgraphIndexingVoucherMetadata ,
399+ dips_agreement_eip712_domain, dips_cancellation_eip712_domain, server :: DipsServerContext ,
400+ CancellationRequest , DipsError , IndexingAgreementVoucher , SignedIndexingAgreementVoucher ,
401+ SubgraphIndexingVoucherMetadata ,
390402 } ;
391403
392404 #[ tokio:: test]
@@ -424,22 +436,19 @@ mod test {
424436 let abi_voucher = voucher. abi_encode ( ) ;
425437 let id = Uuid :: from_bytes ( voucher. voucher . agreement_id . into ( ) ) ;
426438
427- let store = Arc :: new ( InMemoryAgreementStore :: default ( ) ) ;
428-
439+ let ctx = DipsServerContext :: for_testing ( ) ;
429440 let actual_id = super :: validate_and_create_agreement (
430- store . clone ( ) ,
441+ ctx . clone ( ) ,
431442 & domain,
432443 & payee_addr,
433444 vec ! [ payer_addr] ,
434445 abi_voucher,
435- & PriceCalculator :: for_testing ( ) ,
436- Arc :: new ( TestIpfsClient :: mainnet ( ) ) ,
437446 )
438447 . await
439448 . unwrap ( ) ;
440449 assert_eq ! ( actual_id, id) ;
441450
442- let stored_agreement = store. get_by_id ( actual_id) . await . unwrap ( ) . unwrap ( ) ;
451+ let stored_agreement = ctx . store . get_by_id ( actual_id) . await . unwrap ( ) . unwrap ( ) ;
443452
444453 assert_eq ! ( voucher, stored_agreement. voucher) ;
445454 assert ! ( !stored_agreement. cancelled) ;
@@ -448,6 +457,7 @@ mod test {
448457
449458 #[ test]
450459 fn voucher_signature_verification ( ) {
460+ let ctx = DipsServerContext :: for_testing ( ) ;
451461 let deployment_id = "Qmbg1qF4YgHjiVfsVt6a13ddrVcRtWyJQfD4LA3CwHM29f" . to_string ( ) ;
452462 let payee = PrivateKeySigner :: random ( ) ;
453463 let payee_addr = payee. address ( ) ;
@@ -480,23 +490,34 @@ mod test {
480490 let signed = voucher. sign ( & domain, payer) . unwrap ( ) ;
481491 assert_eq ! (
482492 signed
483- . validate( & domain, & payee_addr, vec![ ] )
493+ . validate( & ctx . signer_validator , & domain, & payee_addr, vec![ ] )
484494 . unwrap_err( )
485495 . to_string( ) ,
486496 DipsError :: PayerNotAuthorised ( voucher. payer) . to_string( )
487497 ) ;
488498 assert ! ( signed
489- . validate( & domain, & payee_addr, vec![ payer_addr] )
499+ . validate(
500+ & ctx. signer_validator,
501+ & domain,
502+ & payee_addr,
503+ vec![ payer_addr]
504+ )
490505 . is_ok( ) ) ;
491506 }
492507
493- #[ test]
494- fn check_voucher_modified ( ) {
495- let deployment_id = "Qmbg1qF4YgHjiVfsVt6a13ddrVcRtWyJQfD4LA3CwHM29f" . to_string ( ) ;
508+ #[ tokio:: test]
509+ async fn check_voucher_modified ( ) {
496510 let payee = PrivateKeySigner :: random ( ) ;
497511 let payee_addr = payee. address ( ) ;
498512 let payer = PrivateKeySigner :: random ( ) ;
499513 let payer_addr = payer. address ( ) ;
514+ let ctx = DipsServerContext :: for_testing_mocked_accounts ( EscrowAccounts :: new (
515+ HashMap :: default ( ) ,
516+ HashMap :: from_iter ( vec ! [ ( payer_addr, vec![ payer_addr] ) ] ) ,
517+ ) )
518+ . await ;
519+
520+ let deployment_id = "Qmbg1qF4YgHjiVfsVt6a13ddrVcRtWyJQfD4LA3CwHM29f" . to_string ( ) ;
500521
501522 let metadata = SubgraphIndexingVoucherMetadata {
502523 basePricePerEpoch : U256 :: from ( 10000_u64 ) ,
@@ -526,9 +547,14 @@ mod test {
526547
527548 assert ! ( matches!(
528549 signed
529- . validate( & domain, & payee_addr, vec![ payer_addr] )
550+ . validate(
551+ & ctx. signer_validator,
552+ & domain,
553+ & payee_addr,
554+ vec![ payer_addr]
555+ )
530556 . unwrap_err( ) ,
531- DipsError :: PayerNotAuthorised ( _)
557+ DipsError :: SignerNotAuthorised ( _)
532558 ) ) ;
533559 }
534560
@@ -630,6 +656,7 @@ mod test {
630656
631657 #[ tokio:: test]
632658 async fn test_create_and_cancel_agreement ( ) -> anyhow:: Result < ( ) > {
659+ let ctx = DipsServerContext :: for_testing ( ) ;
633660 let voucher_ctx = VoucherContext :: random ( ) ;
634661 let store = Arc :: new ( InMemoryAgreementStore :: default ( ) ) ;
635662
@@ -645,13 +672,11 @@ mod test {
645672
646673 // Create agreement
647674 let agreement_id = super :: validate_and_create_agreement (
648- store . clone ( ) ,
675+ ctx . clone ( ) ,
649676 & voucher_ctx. domain ( ) ,
650677 & voucher_ctx. payee . address ( ) ,
651678 vec ! [ voucher_ctx. payer. address( ) ] ,
652679 signed_voucher. encode_vec ( ) ,
653- & PriceCalculator :: for_testing ( ) ,
654- Arc :: new ( TestIpfsClient :: mainnet ( ) ) ,
655680 )
656681 . await ?;
657682
@@ -672,7 +697,7 @@ mod test {
672697
673698 assert_eq ! ( agreement_id, cancelled_id) ;
674699
675- // Verify agreement is cancelled
700+ // Verify agreement is cancel
676701 let stored_agreement = store. get_by_id ( agreement_id) . await ?. unwrap ( ) ;
677702 assert ! ( stored_agreement. cancelled) ;
678703
@@ -681,8 +706,8 @@ mod test {
681706
682707 #[ tokio:: test]
683708 async fn test_create_validations_errors ( ) -> anyhow:: Result < ( ) > {
709+ let ctx = DipsServerContext :: for_testing ( ) ;
684710 let voucher_ctx = VoucherContext :: random ( ) ;
685- let store = Arc :: new ( InMemoryAgreementStore :: default ( ) ) ;
686711
687712 let metadata = SubgraphIndexingVoucherMetadata {
688713 basePricePerEpoch : U256 :: from ( 10000_u64 ) ,
@@ -734,13 +759,11 @@ mod test {
734759 let cases = vec ! [ wrong_network_voucher, low_price_voucher, valid_voucher] ;
735760 for ( voucher, result) in cases. into_iter ( ) . zip ( expected_result. into_iter ( ) ) {
736761 let out = super :: validate_and_create_agreement (
737- store . clone ( ) ,
762+ ctx . clone ( ) ,
738763 & voucher_ctx. domain ( ) ,
739764 & voucher_ctx. payee . address ( ) ,
740765 vec ! [ voucher_ctx. payer. address( ) ] ,
741766 voucher. encode_vec ( ) ,
742- & PriceCalculator :: for_testing ( ) ,
743- Arc :: new ( TestIpfsClient :: mainnet ( ) ) ,
744767 )
745768 . await ;
746769
0 commit comments