Skip to content

Commit

Permalink
test(starknet_mempool): validate fee escalation attempt not replaced (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ayeletstarkware authored Dec 19, 2024
1 parent d20ffa5 commit 8c02df5
Showing 1 changed file with 75 additions and 11 deletions.
86 changes: 75 additions & 11 deletions crates/starknet_mempool/src/mempool_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,21 +148,26 @@ fn add_tx_and_verify_replacement(
in_priority_queue: bool,
in_pending_queue: bool,
) {
// Ensure that the transaction is not in both queues.
assert!(!(in_priority_queue && in_pending_queue));
assert!(
!(in_priority_queue && in_pending_queue),
"A transaction can be in at most one queue at a time."
);

add_tx(&mut mempool, &valid_replacement_input);

// Verify transaction was replaced.
let mut builder = MempoolContentBuilder::new();

if in_priority_queue {
builder =
builder.with_priority_queue([TransactionReference::new(&valid_replacement_input.tx)]);
}

if in_pending_queue {
builder =
builder.with_pending_queue([TransactionReference::new(&valid_replacement_input.tx)]);
}

let expected_mempool_content = builder.with_pool([valid_replacement_input.tx]).build();
expected_mempool_content.assert_eq(&mempool);
}
Expand All @@ -187,7 +192,14 @@ fn add_txs_and_verify_no_replacement(
mut mempool: Mempool,
existing_tx: AccountTransaction,
invalid_replacement_inputs: impl IntoIterator<Item = AddTransactionArgs>,
in_priority_queue: bool,
in_pending_queue: bool,
) {
assert!(
!(in_priority_queue && in_pending_queue),
"A transaction can be in at most one queue at a time."
);

for input in invalid_replacement_inputs {
add_tx_expect_error(
&mut mempool,
Expand All @@ -200,10 +212,37 @@ fn add_txs_and_verify_no_replacement(
}

// Verify transaction was not replaced.
let expected_mempool_content = MempoolContentBuilder::new().with_pool([existing_tx]).build();
let mut builder = MempoolContentBuilder::new();

if in_priority_queue {
builder = builder.with_priority_queue([TransactionReference::new(&existing_tx)]);
}

if in_pending_queue {
builder = builder.with_pending_queue([TransactionReference::new(&existing_tx)]);
}

let expected_mempool_content = builder.with_pool([existing_tx]).build();
expected_mempool_content.assert_eq(&mempool);
}

#[track_caller]
fn add_txs_and_verify_no_replacement_in_pool(
mempool: Mempool,
existing_tx: AccountTransaction,
invalid_replacement_inputs: impl IntoIterator<Item = AddTransactionArgs>,
) {
let in_priority_queue = false;
let in_pending_queue = false;
add_txs_and_verify_no_replacement(
mempool,
existing_tx,
invalid_replacement_inputs,
in_priority_queue,
in_pending_queue,
);
}

// Fixtures.

#[fixture]
Expand Down Expand Up @@ -596,13 +635,28 @@ fn test_fee_escalation_valid_replacement(
}

#[rstest]
fn test_fee_escalation_invalid_replacement() {
#[case::pool(false, false)]
#[case::pool_and_priority_queue(true, false)]
#[case::pool_and_pending_queue(false, true)]
fn test_fee_escalation_invalid_replacement(
#[case] in_priority_queue: bool,
#[case] in_pending_queue: bool,
) {
// Setup.
let existing_tx = tx!(tx_hash: 1, tip: 100, max_l2_gas_price: 100);
let mempool = MempoolContentBuilder::new()
.with_pool([existing_tx.clone()])
.with_fee_escalation_percentage(10)
.build_into_mempool();
let mut builder = MempoolContentBuilder::new().with_fee_escalation_percentage(10);

if in_priority_queue {
builder = builder.with_priority_queue([TransactionReference::new(&existing_tx)]);
}

if in_pending_queue {
builder = builder
.with_pending_queue([TransactionReference::new(&existing_tx)])
.with_gas_price_threshold(1000);
}

let mempool = builder.with_pool([existing_tx.clone()]).build_into_mempool();

let input_not_enough_tip = add_tx_input!(tx_hash: 3, tip: 109, max_l2_gas_price: 110);
let input_not_enough_gas_price = add_tx_input!(tx_hash: 4, tip: 110, max_l2_gas_price: 109);
Expand All @@ -611,7 +665,13 @@ fn test_fee_escalation_invalid_replacement() {
// Test and assert.
let invalid_replacement_inputs =
[input_not_enough_tip, input_not_enough_gas_price, input_not_enough_both];
add_txs_and_verify_no_replacement(mempool, existing_tx, invalid_replacement_inputs);
add_txs_and_verify_no_replacement(
mempool,
existing_tx,
invalid_replacement_inputs,
in_priority_queue,
in_pending_queue,
);
}

#[rstest]
Expand Down Expand Up @@ -667,7 +727,11 @@ fn test_fee_escalation_invalid_replacement_overflow_gracefully_handled() {

// Test and assert: overflow gracefully handled.
let invalid_replacement_input = add_tx_input!(tip: u64::MAX, max_l2_gas_price: u128::MAX);
add_txs_and_verify_no_replacement(mempool, existing_tx, [invalid_replacement_input]);
add_txs_and_verify_no_replacement_in_pool(
mempool,
existing_tx,
[invalid_replacement_input],
);
}

// Large percentage.
Expand All @@ -681,7 +745,7 @@ fn test_fee_escalation_invalid_replacement_overflow_gracefully_handled() {

// Test and assert: overflow gracefully handled.
let invalid_replacement_input = add_tx_input!(tip: u64::MAX, max_l2_gas_price: u128::MAX);
add_txs_and_verify_no_replacement(mempool, existing_tx, [invalid_replacement_input]);
add_txs_and_verify_no_replacement_in_pool(mempool, existing_tx, [invalid_replacement_input]);
}

// `update_gas_price_threshold` tests.
Expand Down

0 comments on commit 8c02df5

Please sign in to comment.