@@ -383,6 +383,32 @@ where
383383 Ok ( ( ) )
384384 }
385385
386+ pub async fn submit_merkle_and_fulfill (
387+ & self ,
388+ root : B256 ,
389+ seal : Bytes ,
390+ fulfillments : Vec < Fulfillment > ,
391+ assessor_seal : Bytes ,
392+ ) -> Result < ( ) , MarketError > {
393+ tracing:: debug!( "Calling submitRootAndFulfillBatch({root:?}, {seal:x}, {fulfillments:?}, {assessor_seal:x})" ) ;
394+ let call = self
395+ . instance
396+ . submitRootAndFulfillBatch ( root, seal, fulfillments, assessor_seal)
397+ . from ( self . caller ) ;
398+ tracing:: debug!( "Calldata: {}" , call. calldata( ) ) ;
399+ let pending_tx = call. send ( ) . await . map_err ( IProofMarketErrors :: decode_error) ?;
400+ tracing:: debug!( "Broadcasting tx {}" , pending_tx. tx_hash( ) ) ;
401+ let tx_hash = pending_tx
402+ . with_timeout ( Some ( self . timeout ) )
403+ . watch ( )
404+ . await
405+ . context ( "failed to confirm tx" ) ?;
406+
407+ tracing:: info!( "Submitted merkle root and proof for batch {}" , tx_hash) ;
408+
409+ Ok ( ( ) )
410+ }
411+
386412 /// Checks if a request is locked in.
387413 pub async fn is_locked_in ( & self , request_id : U256 ) -> Result < bool , MarketError > {
388414 tracing:: debug!( "Calling requestIsLocked({})" , request_id) ;
@@ -889,4 +915,59 @@ mod tests {
889915 assert_eq ! ( journal, fulfillment. journal) ;
890916 assert_eq ! ( seal, fulfillment. seal) ;
891917 }
918+
919+ #[ tokio:: test]
920+ #[ traced_test]
921+ async fn test_e2e_merged_submit_fulfill ( ) {
922+ // Setup anvil
923+ let anvil = Anvil :: new ( ) . spawn ( ) ;
924+
925+ let ctx = TestCtx :: new ( & anvil) . await . unwrap ( ) ;
926+
927+ let eip712_domain = eip712_domain ! {
928+ name: "IProofMarket" ,
929+ version: "1" ,
930+ chain_id: anvil. chain_id( ) ,
931+ verifying_contract: * ctx. customer_market. instance( ) . address( ) ,
932+ } ;
933+
934+ let request = new_request ( 1 , & ctx) . await ;
935+
936+ let request_id =
937+ ctx. customer_market . submit_request ( & request, & ctx. customer_signer ) . await . unwrap ( ) ;
938+
939+ // fetch logs to retrieve the customer signature from the event
940+ let logs = ctx. customer_market . instance ( ) . RequestSubmitted_filter ( ) . query ( ) . await . unwrap ( ) ;
941+
942+ let ( _, log) = logs. first ( ) . unwrap ( ) ;
943+ let log = log. log_decode :: < IProofMarket :: RequestSubmitted > ( ) . unwrap ( ) ;
944+ let request = log. inner . data . request ;
945+ let customer_sig = log. inner . data . clientSignature ;
946+
947+ // Deposit prover balances
948+ ctx. prover_market . deposit ( parse_ether ( "1" ) . unwrap ( ) ) . await . unwrap ( ) ;
949+
950+ // Lockin the request
951+ ctx. prover_market . lockin_request ( & request, & customer_sig, None ) . await . unwrap ( ) ;
952+ assert ! ( ctx. customer_market. is_locked_in( request_id) . await . unwrap( ) ) ;
953+ assert ! ( ctx. customer_market. get_status( request_id) . await . unwrap( ) == ProofStatus :: Locked ) ;
954+
955+ // mock the fulfillment
956+ let ( root, set_verifier_seal, fulfillment, market_seal) =
957+ mock_singleton ( request_id, eip712_domain) ;
958+
959+ let fulfillments = vec ! [ fulfillment] ;
960+ // publish the committed root + fulfillments
961+ ctx. prover_market
962+ . submit_merkle_and_fulfill ( root, set_verifier_seal, fulfillments. clone ( ) , market_seal)
963+ . await
964+ . unwrap ( ) ;
965+
966+ // retrieve journal and seal from the fulfilled request
967+ let ( journal, seal) =
968+ ctx. customer_market . get_request_fulfillment ( request_id) . await . unwrap ( ) ;
969+
970+ assert_eq ! ( journal, fulfillments[ 0 ] . journal) ;
971+ assert_eq ! ( seal, fulfillments[ 0 ] . seal) ;
972+ }
892973}
0 commit comments