mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
fix(txpool): pending subpool basefee update (#4610)
This commit is contained in:
@ -65,6 +65,19 @@ impl<T: TransactionOrdering> PendingPool<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all transactions from the pool without resetting other values.
|
||||
/// Used for atomic reordering during basefee update.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns all transactions by id.
|
||||
fn clear_transactions(&mut self) -> BTreeMap<TransactionId, PendingTransaction<T>> {
|
||||
self.independent_transactions.clear();
|
||||
self.all.clear();
|
||||
self.size_of.reset();
|
||||
std::mem::take(&mut self.by_id)
|
||||
}
|
||||
|
||||
/// Returns an iterator over all transactions that are _currently_ ready.
|
||||
///
|
||||
/// 1. The iterator _always_ returns transaction in order: It never returns a transaction with
|
||||
@ -150,44 +163,38 @@ impl<T: TransactionOrdering> PendingPool<T> {
|
||||
&mut self,
|
||||
base_fee: u64,
|
||||
) -> Vec<Arc<ValidPoolTransaction<T::Transaction>>> {
|
||||
// Create a collection for txs to remove .
|
||||
let mut to_remove = Vec::new();
|
||||
// Create a collection for removed transactions.
|
||||
let mut removed = Vec::new();
|
||||
|
||||
// Iterate over transactions, find the ones we need to remove and update others in place.
|
||||
{
|
||||
let mut iter = self.by_id.iter_mut().peekable();
|
||||
while let Some((id, tx)) = iter.next() {
|
||||
if tx.transaction.max_fee_per_gas() < base_fee as u128 {
|
||||
// This transaction no longer satisfies the basefee: remove it and all its
|
||||
// descendants.
|
||||
to_remove.push(*id);
|
||||
'this: while let Some((peek, _)) = iter.peek() {
|
||||
if peek.sender != id.sender {
|
||||
break 'this
|
||||
}
|
||||
to_remove.push(**peek);
|
||||
iter.next();
|
||||
// Drain and iterate over all transactions.
|
||||
let mut transactions_iter = self.clear_transactions().into_iter().peekable();
|
||||
while let Some((id, mut tx)) = transactions_iter.next() {
|
||||
if tx.transaction.max_fee_per_gas() < base_fee as u128 {
|
||||
// Add this tx to the removed collection since it no longer satisfies the base fee
|
||||
// condition. Decrease the total pool size.
|
||||
removed.push(Arc::clone(&tx.transaction));
|
||||
|
||||
// Remove all dependent transactions.
|
||||
'this: while let Some((next_id, next_tx)) = transactions_iter.peek() {
|
||||
if next_id.sender != id.sender {
|
||||
break 'this
|
||||
}
|
||||
} else {
|
||||
// Update the transaction with new priority.
|
||||
let new_priority =
|
||||
self.ordering.priority(&tx.transaction.transaction, base_fee);
|
||||
tx.priority = new_priority;
|
||||
|
||||
self.all.insert(tx.clone());
|
||||
removed.push(Arc::clone(&next_tx.transaction));
|
||||
transactions_iter.next();
|
||||
}
|
||||
} else {
|
||||
// Re-insert the transaction with new priority.
|
||||
tx.priority = self.ordering.priority(&tx.transaction.transaction, base_fee);
|
||||
|
||||
self.size_of += tx.transaction.size();
|
||||
if self.ancestor(&id).is_none() {
|
||||
self.independent_transactions.insert(tx.clone());
|
||||
}
|
||||
self.all.insert(tx.clone());
|
||||
self.by_id.insert(id, tx);
|
||||
}
|
||||
}
|
||||
|
||||
let mut removed = Vec::with_capacity(to_remove.len());
|
||||
for id in to_remove {
|
||||
removed.push(self.remove_transaction(&id).expect("transaction exists"));
|
||||
}
|
||||
|
||||
// Clear ordered lists since the priority would be changed.
|
||||
self.independent_transactions.clear();
|
||||
self.all.clear();
|
||||
|
||||
removed
|
||||
}
|
||||
|
||||
@ -261,8 +268,8 @@ impl<T: TransactionOrdering> PendingPool<T> {
|
||||
id: &TransactionId,
|
||||
) -> Option<Arc<ValidPoolTransaction<T::Transaction>>> {
|
||||
let tx = self.by_id.remove(id)?;
|
||||
self.all.remove(&tx);
|
||||
self.size_of -= tx.transaction.size();
|
||||
self.all.remove(&tx);
|
||||
self.independent_transactions.remove(&tx);
|
||||
Some(tx.transaction)
|
||||
}
|
||||
|
||||
@ -10,6 +10,13 @@ use std::ops::{AddAssign, SubAssign};
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub struct SizeTracker(isize);
|
||||
|
||||
impl SizeTracker {
|
||||
/// Reset the size tracker.
|
||||
pub fn reset(&mut self) {
|
||||
self.0 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<usize> for SizeTracker {
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
self.0 += rhs as isize
|
||||
|
||||
Reference in New Issue
Block a user