@@ -560,3 +560,94 @@ async fn backrun_bundle_rejected_exceeds_da_limit(rbuilder: LocalInstance) -> ey
560560
561561 Ok ( ( ) )
562562}
563+
564+ /// Tests that backrun bundles with invalid tx errors (e.g. nonce too low) are skipped gracefully
565+ #[ rb_test( flashblocks) ]
566+ async fn backrun_bundle_invalid_tx_skipped ( rbuilder : LocalInstance ) -> eyre:: Result < ( ) > {
567+ let driver = rbuilder. driver ( ) . await ?;
568+ let accounts = driver. fund_accounts ( 3 , ONE_ETH ) . await ?;
569+
570+ let target_tx = driver
571+ . create_transaction ( )
572+ . with_signer ( accounts[ 0 ] )
573+ . with_max_priority_fee_per_gas ( 20 )
574+ . build ( )
575+ . await ;
576+ let target_tx_hash = target_tx. tx_hash ( ) . clone ( ) ;
577+
578+ let provider = rbuilder. provider ( ) . await ?;
579+ let _ = provider
580+ . send_raw_transaction ( target_tx. encoded_2718 ( ) . as_slice ( ) )
581+ . await ?;
582+
583+ let backrun_tx = driver
584+ . create_transaction ( )
585+ . with_signer ( accounts[ 1 ] )
586+ . with_max_priority_fee_per_gas ( 50 )
587+ . with_nonce ( 0 )
588+ . build ( )
589+ . await ;
590+ let backrun_tx_hash = backrun_tx. tx_hash ( ) . clone ( ) ;
591+
592+ // Send a conflicting tx with same nonce but higher fee - it will be included first
593+ let conflicting_tx = driver
594+ . create_transaction ( )
595+ . with_signer ( accounts[ 1 ] )
596+ . with_max_priority_fee_per_gas ( 100 )
597+ . with_nonce ( 0 )
598+ . send ( )
599+ . await ?;
600+ let conflicting_tx_hash = conflicting_tx. tx_hash ( ) . clone ( ) ;
601+
602+ let bundle = AcceptedBundle {
603+ uuid : Uuid :: new_v4 ( ) ,
604+ txs : vec ! [ target_tx, backrun_tx] ,
605+ block_number : driver. latest ( ) . await ?. header . number + 1 ,
606+ flashblock_number_min : None ,
607+ flashblock_number_max : None ,
608+ min_timestamp : None ,
609+ max_timestamp : None ,
610+ reverting_tx_hashes : vec ! [ ] ,
611+ replacement_uuid : None ,
612+ dropping_tx_hashes : vec ! [ ] ,
613+ meter_bundle_response : MeterBundleResponse {
614+ bundle_gas_price : U256 :: ZERO ,
615+ bundle_hash : TxHash :: ZERO ,
616+ coinbase_diff : U256 :: ZERO ,
617+ eth_sent_to_coinbase : U256 :: ZERO ,
618+ gas_fees : U256 :: ZERO ,
619+ results : vec ! [ ] ,
620+ state_block_number : 0 ,
621+ state_flashblock_index : None ,
622+ total_gas_used : 0 ,
623+ total_execution_time_us : 0 ,
624+ } ,
625+ } ;
626+
627+ rbuilder
628+ . tx_data_store ( )
629+ . insert_backrun_bundle ( bundle)
630+ . expect ( "Failed to insert backrun bundle" ) ;
631+
632+ driver. build_new_block ( ) . await ?;
633+
634+ let block = driver. latest_full ( ) . await ?;
635+ let tx_hashes: Vec < _ > = block. transactions . hashes ( ) . collect ( ) ;
636+
637+ assert ! (
638+ tx_hashes. contains( & target_tx_hash) ,
639+ "Target tx should be included in block"
640+ ) ;
641+
642+ assert ! (
643+ tx_hashes. contains( & conflicting_tx_hash) ,
644+ "Conflicting tx should be included in block"
645+ ) ;
646+
647+ assert ! (
648+ !tx_hashes. contains( & backrun_tx_hash) ,
649+ "Backrun tx should NOT be in block (nonce-too-low EVM error)"
650+ ) ;
651+
652+ Ok ( ( ) )
653+ }
0 commit comments