Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions crates/rbuilder/src/building/testing/bundle_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,42 @@ fn test_bundle_consistency_check() -> eyre::Result<()> {
Ok(())
}

/// Tests allow_tx_skip behavior with two bundles sharing a reverting tx.
/// Bundle 1: reverting_tx_1 + backrun_1 β€” both execute successfully.
/// Bundle 2: reverting_tx_1 (stale nonce, skipped) + reverting_tx_2 + backrun_2 β€” only last two execute.
#[test]
fn test_bundle_allow_tx_skip() -> eyre::Result<()> {
let target_block = BlockArgs::MIN_BLOCK_NUMBER;
let mut test_setup = TestSetup::gen_test_setup(BlockArgs::default().with_number(target_block))?;

let reverting_tx_1 = test_setup.create_dummy_tx(NamedAddr::User(0), NamedAddr::Dummy, 0)?;
// Bundle 1: reverting_tx_1 (User(0), reverting) + backrun_1 (User(1))
test_setup.begin_bundle_order(target_block);
test_setup.add_external_tx(reverting_tx_1.clone(), TxRevertBehavior::AllowedIncluded)?;
test_setup.add_null_tx(NamedAddr::User(1), TxRevertBehavior::NotAllowed)?;
let result = test_setup.commit_order_ok();
assert_eq!(result.tx_infos.len(), 2);
assert!(result.tx_infos[0].receipt.success);
assert!(result.tx_infos[1].receipt.success);

// Bundle 2: SAME reverting_tx_1 as in bundle 1.
// + reverting_tx_2 (User(2), reverting)
// + backrun_2 (User(3))
test_setup.begin_bundle_order(target_block);
// reverting_tx_1 with stale nonce β€” will fail with NonceTooHigh and be skipped
// because allow_tx_skip=true and it's in reverting_tx_hashes
test_setup.add_external_tx(reverting_tx_1, TxRevertBehavior::AllowedIncluded)?;
test_setup.add_null_tx(NamedAddr::User(2), TxRevertBehavior::AllowedIncluded)?;
test_setup.add_null_tx(NamedAddr::User(3), TxRevertBehavior::NotAllowed)?;
let result = test_setup.commit_order_ok();
// reverting_tx_1 was skipped, only reverting_tx_2 + backrun_2 landed
assert_eq!(result.tx_infos.len(), 2);
assert!(result.tx_infos[0].receipt.success);
assert!(result.tx_infos[1].receipt.success);

Ok(())
}

#[test]
///Checks TxRevertBehavior::AllowedInclude/AllowedExcluded by checking the consumed gas.
fn bundle_revert_modes_tests() -> eyre::Result<()> {
Expand Down
36 changes: 27 additions & 9 deletions crates/rbuilder/src/building/testing/bundle_tests/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,24 +106,32 @@ impl TestSetup {
)
}

/// Send value from ->to , uses currentfrom nonce
pub fn add_dummy_tx(
/// Send value from ->to , uses current from nonce
pub fn create_dummy_tx(
&mut self,
from: NamedAddr,
to: NamedAddr,
value: u64,
revert_behavior: TxRevertBehavior,
) -> eyre::Result<TxHash> {
) -> eyre::Result<TransactionSignedEcRecoveredWithBlobs> {
let args = TxArgs::new(from, self.current_nonce(from)?)
.to(to)
.value(value);
let tx = self.test_chain.sign_tx(args)?;
Ok(TransactionSignedEcRecoveredWithBlobs::new_no_blobs(tx).unwrap())
}

/// create_dummy_tx +
pub fn add_dummy_tx(
&mut self,
from: NamedAddr,
to: NamedAddr,
value: u64,
revert_behavior: TxRevertBehavior,
) -> eyre::Result<TxHash> {
let tx = self.create_dummy_tx(from, to, value)?;
let tx_hash = *tx.hash();
self.order_builder.add_tx(
TransactionSignedEcRecoveredWithBlobs::new_no_blobs(tx).unwrap(),
revert_behavior,
);
Ok(tx_hash)
self.order_builder.add_tx(tx, revert_behavior);
Ok(tx_hash.into())
}

fn add_tx(&mut self, args: TxArgs, revert_behavior: TxRevertBehavior) -> eyre::Result<TxHash> {
Expand All @@ -136,6 +144,16 @@ impl TestSetup {
Ok(tx_hash)
}

/// Allows to add a tx manually built or via create_dummy_tx
pub fn add_external_tx(
&mut self,
tx: TransactionSignedEcRecoveredWithBlobs,
revert_behavior: TxRevertBehavior,
) -> eyre::Result<()> {
self.order_builder.add_tx(tx, revert_behavior);
Ok(())
}

pub fn add_send_to_coinbase_tx(&mut self, from: NamedAddr, value: u64) -> eyre::Result<TxHash> {
self.add_tx(
TxArgs::new_send_to_coinbase(from, self.current_nonce(from)?, value),
Expand Down
Loading