mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
fix(txpool): use ceiling division for replacement tx price bump check (#23012)
Signed-off-by: Delweng <delweng@gmail.com>
This commit is contained in:
@@ -3104,6 +3104,35 @@ mod tests {
|
||||
assert_eq!(pool.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_replace_underpriced_rounds_up_minimum_bump() {
|
||||
let on_chain_balance = U256::ZERO;
|
||||
let on_chain_nonce = 0;
|
||||
let mut f = MockTransactionFactory::default();
|
||||
let mut pool = AllTransactions { minimal_protocol_basefee: 0, ..Default::default() };
|
||||
let mut tx = MockTransaction::eip1559().inc_price().inc_limit();
|
||||
tx.set_priority_fee(1);
|
||||
tx.set_max_fee(1);
|
||||
|
||||
let first = f.validated(tx.clone());
|
||||
let _ = pool.insert_tx(first.clone(), on_chain_balance, on_chain_nonce).unwrap();
|
||||
|
||||
let mut replacement = f.validated(tx.rng_hash().inc_price());
|
||||
replacement.transaction.set_priority_fee(1);
|
||||
replacement.transaction.set_max_fee(2);
|
||||
let err =
|
||||
pool.insert_tx(replacement.clone(), on_chain_balance, on_chain_nonce).unwrap_err();
|
||||
assert!(matches!(err, InsertErr::Underpriced { .. }));
|
||||
assert!(pool.contains(first.hash()));
|
||||
assert_eq!(pool.len(), 1);
|
||||
|
||||
replacement.transaction.set_priority_fee(2);
|
||||
replacement.transaction.set_max_fee(2);
|
||||
let replaced = pool.insert_tx(replacement, on_chain_balance, on_chain_nonce).unwrap();
|
||||
assert!(replaced.replaced_tx.is_some());
|
||||
assert_eq!(pool.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_conflicting_type_normal_to_blob() {
|
||||
let on_chain_balance = U256::from(10_000);
|
||||
|
||||
@@ -455,9 +455,11 @@ impl<T: PoolTransaction> ValidPoolTransaction<T> {
|
||||
//
|
||||
// The bump is different for EIP-4844 and other transactions. See `PriceBumpConfig`.
|
||||
let price_bump = price_bumps.price_bump(self.tx_type());
|
||||
let required_bumped_fee =
|
||||
|existing_fee: u128| existing_fee.saturating_mul(100 + price_bump).div_ceil(100);
|
||||
|
||||
// Check if the max fee per gas is underpriced.
|
||||
if maybe_replacement.max_fee_per_gas() < self.max_fee_per_gas() * (100 + price_bump) / 100 {
|
||||
if maybe_replacement.max_fee_per_gas() < required_bumped_fee(self.max_fee_per_gas()) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -470,7 +472,7 @@ impl<T: PoolTransaction> ValidPoolTransaction<T> {
|
||||
if existing_max_priority_fee_per_gas != 0 &&
|
||||
replacement_max_priority_fee_per_gas != 0 &&
|
||||
replacement_max_priority_fee_per_gas <
|
||||
existing_max_priority_fee_per_gas * (100 + price_bump) / 100
|
||||
required_bumped_fee(existing_max_priority_fee_per_gas)
|
||||
{
|
||||
return true
|
||||
}
|
||||
@@ -480,8 +482,7 @@ impl<T: PoolTransaction> ValidPoolTransaction<T> {
|
||||
// This enforces that blob txs can only be replaced by blob txs
|
||||
let replacement_max_blob_fee_per_gas =
|
||||
maybe_replacement.transaction.max_fee_per_blob_gas().unwrap_or_default();
|
||||
if replacement_max_blob_fee_per_gas <
|
||||
existing_max_blob_fee_per_gas * (100 + price_bump) / 100
|
||||
if replacement_max_blob_fee_per_gas < required_bumped_fee(existing_max_blob_fee_per_gas)
|
||||
{
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user