@@ -82,6 +82,8 @@ pub struct IngressService<Q: MessageQueue, M: Mempool> {
8282 builder_tx : broadcast:: Sender < MeterBundleResponse > ,
8383 backrun_enabled : bool ,
8484 builder_backrun_tx : broadcast:: Sender < AcceptedBundle > ,
85+ max_backrun_txs : usize ,
86+ max_backrun_gas_limit : u64 ,
8587}
8688
8789impl < Q : MessageQueue , M : Mempool > IngressService < Q , M > {
@@ -127,18 +129,40 @@ impl<Q: MessageQueue, M: Mempool> IngressService<Q, M> {
127129 builder_tx,
128130 backrun_enabled : config. backrun_enabled ,
129131 builder_backrun_tx,
132+ max_backrun_txs : config. max_backrun_txs ,
133+ max_backrun_gas_limit : config. max_backrun_gas_limit ,
130134 }
131135 }
132136}
133137
138+ fn validate_backrun_bundle_limits (
139+ txs_count : usize ,
140+ total_gas_limit : u64 ,
141+ max_backrun_txs : usize ,
142+ max_backrun_gas_limit : u64 ,
143+ ) -> Result < ( ) , String > {
144+ if txs_count < 2 {
145+ return Err (
146+ "Backrun bundle must have at least 2 transactions (target + backrun)" . to_string ( ) ,
147+ ) ;
148+ }
149+ if txs_count > max_backrun_txs {
150+ return Err ( format ! (
151+ "Backrun bundle exceeds max transaction count: {txs_count} > {max_backrun_txs}" ,
152+ ) ) ;
153+ }
154+ if total_gas_limit > max_backrun_gas_limit {
155+ return Err ( format ! (
156+ "Backrun bundle exceeds max gas limit: {total_gas_limit} > {max_backrun_gas_limit}" ,
157+ ) ) ;
158+ }
159+ Ok ( ( ) )
160+ }
161+
134162#[ async_trait]
135163impl < Q : MessageQueue + ' static , M : Mempool + ' static > IngressApiServer for IngressService < Q , M > {
136164 async fn send_backrun_bundle ( & self , bundle : Bundle ) -> RpcResult < BundleHash > {
137165 if !self . backrun_enabled {
138- info ! (
139- message = "Backrun bundle submission is disabled" ,
140- backrun_enabled = self . backrun_enabled
141- ) ;
142166 return Err (
143167 EthApiError :: InvalidParams ( "Backrun bundle submission is disabled" . into ( ) )
144168 . into_rpc_err ( ) ,
@@ -149,15 +173,23 @@ impl<Q: MessageQueue + 'static, M: Mempool + 'static> IngressApiServer for Ingre
149173 let ( accepted_bundle, bundle_hash) =
150174 self . validate_parse_and_meter_bundle ( & bundle, false ) . await ?;
151175
176+ let total_gas_limit: u64 = accepted_bundle. txs . iter ( ) . map ( |tx| tx. gas_limit ( ) ) . sum ( ) ;
177+ validate_backrun_bundle_limits (
178+ accepted_bundle. txs . len ( ) ,
179+ total_gas_limit,
180+ self . max_backrun_txs ,
181+ self . max_backrun_gas_limit ,
182+ )
183+ . map_err ( |e| EthApiError :: InvalidParams ( e) . into_rpc_err ( ) ) ?;
184+
152185 self . metrics . backrun_bundles_received_total . increment ( 1 ) ;
153186
154- if let Err ( e) = self . builder_backrun_tx . send ( accepted_bundle. clone ( ) ) {
155- warn ! (
156- message = "Failed to send backrun bundle to builders" ,
157- bundle_hash = %bundle_hash,
158- error = %e
159- ) ;
160- }
187+ self . builder_backrun_tx
188+ . send ( accepted_bundle. clone ( ) )
189+ . map_err ( |e| {
190+ EthApiError :: InvalidParams ( format ! ( "Failed to send backrun bundle: {e}" ) )
191+ . into_rpc_err ( )
192+ } ) ?;
161193
162194 self . send_audit_event ( & accepted_bundle, bundle_hash) ;
163195
@@ -578,6 +610,8 @@ mod tests {
578610 raw_tx_forward_rpc : None ,
579611 chain_id : 11 ,
580612 user_operation_topic : String :: new ( ) ,
613+ max_backrun_txs : 5 ,
614+ max_backrun_gas_limit : 5000000 ,
581615 }
582616 }
583617
@@ -854,4 +888,26 @@ mod tests {
854888
855889 assert ! ( wrong_user_op_result. is_err( ) ) ;
856890 }
891+
892+ #[ test]
893+ fn test_validate_backrun_bundle_rejects_invalid ( ) {
894+ // Too few transactions (need at least 2: target + backrun)
895+ let result = validate_backrun_bundle_limits ( 1 , 21000 , 5 , 5000000 ) ;
896+ assert ! ( result. is_err( ) ) ;
897+ assert ! ( result. unwrap_err( ) . contains( "at least 2 transactions" ) ) ;
898+
899+ // Exceeds max tx count
900+ let result = validate_backrun_bundle_limits ( 6 , 21000 , 5 , 5000000 ) ;
901+ assert ! ( result. is_err( ) ) ;
902+ assert ! (
903+ result
904+ . unwrap_err( )
905+ . contains( "exceeds max transaction count" )
906+ ) ;
907+
908+ // Exceeds max gas limit
909+ let result = validate_backrun_bundle_limits ( 2 , 6000000 , 5 , 5000000 ) ;
910+ assert ! ( result. is_err( ) ) ;
911+ assert ! ( result. unwrap_err( ) . contains( "exceeds max gas limit" ) ) ;
912+ }
857913}
0 commit comments