@@ -436,7 +436,7 @@ mod tests {
436436 use alloy_provider:: RootProvider ;
437437 use async_trait:: async_trait;
438438 use std:: net:: { IpAddr , SocketAddr } ;
439- use std:: sync :: Arc ;
439+ use std:: str :: FromStr ;
440440 use tips_core:: test_utils:: create_test_meter_bundle_response;
441441 use tokio:: sync:: { broadcast, mpsc} ;
442442 use url:: Url ;
@@ -478,6 +478,7 @@ mod tests {
478478 max_buffered_backrun_bundles : 100 ,
479479 health_check_addr : SocketAddr :: from ( ( [ 127 , 0 , 0 , 1 ] , 8081 ) ) ,
480480 backrun_enabled : false ,
481+ raw_tx_forward_rpc : None ,
481482 }
482483 }
483484
@@ -548,20 +549,19 @@ mod tests {
548549
549550 let provider: RootProvider < Optimism > =
550551 RootProvider :: new_http ( mock_server. uri ( ) . parse ( ) . unwrap ( ) ) ;
551- let simulation_provider = Arc :: new ( provider. clone ( ) ) ;
552+
553+ let providers = Providers {
554+ mempool : provider. clone ( ) ,
555+ simulation : provider. clone ( ) ,
556+ raw_tx_forward : None ,
557+ } ;
552558
553559 let ( audit_tx, _audit_rx) = mpsc:: unbounded_channel ( ) ;
554560 let ( builder_tx, _builder_rx) = broadcast:: channel ( 1 ) ;
555561 let ( backrun_tx, _backrun_rx) = broadcast:: channel ( 1 ) ;
556562
557563 let service = IngressService :: new (
558- provider,
559- simulation_provider. as_ref ( ) . clone ( ) ,
560- MockQueue ,
561- audit_tx,
562- builder_tx,
563- backrun_tx,
564- config,
564+ providers, MockQueue , audit_tx, builder_tx, backrun_tx, config,
565565 ) ;
566566
567567 let bundle = Bundle :: default ( ) ;
@@ -574,4 +574,64 @@ mod tests {
574574 let response = result. unwrap_or_else ( |_| MeterBundleResponse :: default ( ) ) ;
575575 assert_eq ! ( response, MeterBundleResponse :: default ( ) ) ;
576576 }
577+
578+ #[ tokio:: test]
579+ async fn test_raw_tx_forward ( ) {
580+ let simulation_server = MockServer :: start ( ) . await ;
581+ let forward_server = MockServer :: start ( ) . await ;
582+
583+ // Mock error response from base_meterBundle
584+ Mock :: given ( method ( "POST" ) )
585+ . respond_with ( ResponseTemplate :: new ( 500 ) . set_body_json ( serde_json:: json!( {
586+ "jsonrpc" : "2.0" ,
587+ "id" : 1 ,
588+ "error" : {
589+ "code" : -32000 ,
590+ "message" : "Simulation failed"
591+ }
592+ } ) ) )
593+ . mount ( & simulation_server)
594+ . await ;
595+
596+ // Mock forward endpoint - expect exactly 1 call
597+ Mock :: given ( method ( "POST" ) )
598+ . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
599+ "jsonrpc" : "2.0" ,
600+ "id" : 1 ,
601+ "result" : "0x0000000000000000000000000000000000000000000000000000000000000000"
602+ } ) ) )
603+ . expect ( 1 )
604+ . mount ( & forward_server)
605+ . await ;
606+
607+ let mut config = create_test_config ( & simulation_server) ;
608+ config. tx_submission_method = TxSubmissionMethod :: Kafka ; // Skip mempool send
609+
610+ let providers = Providers {
611+ mempool : RootProvider :: new_http ( simulation_server. uri ( ) . parse ( ) . unwrap ( ) ) ,
612+ simulation : RootProvider :: new_http ( simulation_server. uri ( ) . parse ( ) . unwrap ( ) ) ,
613+ raw_tx_forward : Some ( RootProvider :: new_http (
614+ forward_server. uri ( ) . parse ( ) . unwrap ( ) ,
615+ ) ) ,
616+ } ;
617+
618+ let ( audit_tx, _audit_rx) = mpsc:: unbounded_channel ( ) ;
619+ let ( builder_tx, _builder_rx) = broadcast:: channel ( 1 ) ;
620+ let ( backrun_tx, _backrun_rx) = broadcast:: channel ( 1 ) ;
621+
622+ let service = IngressService :: new (
623+ providers, MockQueue , audit_tx, builder_tx, backrun_tx, config,
624+ ) ;
625+
626+ // Valid signed transaction bytes
627+ let tx_bytes = Bytes :: from_str ( "0x02f86c0d010183072335825208940000000000000000000000000000000000000000872386f26fc1000080c001a0cdb9e4f2f1ba53f9429077e7055e078cf599786e29059cd80c5e0e923bb2c114a01c90e29201e031baf1da66296c3a5c15c200bcb5e6c34da2f05f7d1778f8be07" ) . unwrap ( ) ;
628+
629+ let result = service. send_raw_transaction ( tx_bytes) . await ;
630+ assert ! ( result. is_ok( ) ) ;
631+
632+ // Wait for spawned forward task to complete
633+ tokio:: time:: sleep ( Duration :: from_millis ( 100 ) ) . await ;
634+
635+ // wiremock automatically verifies expect(1) when forward_server is dropped
636+ }
577637}
0 commit comments