Skip to content

Commit

Permalink
feat(tx-pool): Add new TransactionPool trait for getting the best tra…
Browse files Browse the repository at this point in the history
…nsactions with blob fee (#4834)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
  • Loading branch information
PanGan21 and mattsse authored Sep 29, 2023
1 parent 6b29454 commit 25aed7b
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 5 deletions.
8 changes: 8 additions & 0 deletions crates/transaction-pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ use std::{
};
use tokio::sync::mpsc::Receiver;
use tracing::{instrument, trace};
use traits::BestTransactionsAttributes;

pub use crate::{
blobstore::{BlobStore, BlobStoreError},
Expand Down Expand Up @@ -419,6 +420,13 @@ where
self.pool.best_transactions_with_base_fee(base_fee)
}

fn best_transactions_with_attributes(
&self,
best_transactions_attributes: BestTransactionsAttributes,
) -> Box<dyn BestTransactions<Item = Arc<ValidPoolTransaction<Self::Transaction>>>> {
self.pool.best_transactions_with_attributes(best_transactions_attributes)
}

fn pending_transactions(&self) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
self.pool.pending_transactions()
}
Expand Down
12 changes: 11 additions & 1 deletion crates/transaction-pool/src/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
use crate::{
blobstore::BlobStoreError,
error::PoolError,
traits::{GetPooledTransactionLimit, NewBlobSidecar, TransactionListenerKind},
traits::{
BestTransactionsAttributes, GetPooledTransactionLimit, NewBlobSidecar,
TransactionListenerKind,
},
validate::ValidTransaction,
AllPoolTransactions, AllTransactionsEvents, BestTransactions, BlockInfo, EthPooledTransaction,
NewTransactionEvent, PoolResult, PoolSize, PoolTransaction, PropagatedTransactions,
Expand Down Expand Up @@ -144,6 +147,13 @@ impl TransactionPool for NoopTransactionPool {
Box::new(std::iter::empty())
}

fn best_transactions_with_attributes(
&self,
_: BestTransactionsAttributes,
) -> Box<dyn BestTransactions<Item = Arc<ValidPoolTransaction<Self::Transaction>>>> {
Box::new(std::iter::empty())
}

fn pending_transactions(&self) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
Expand Down
11 changes: 10 additions & 1 deletion crates/transaction-pool/src/pool/blob.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![allow(dead_code, unused)]
use crate::{
identifier::TransactionId, pool::size::SizeTracker, PoolTransaction, ValidPoolTransaction,
identifier::TransactionId, pool::size::SizeTracker, traits::BestTransactionsAttributes,
PoolTransaction, ValidPoolTransaction,
};
use std::{
cmp::Ordering,
Expand Down Expand Up @@ -76,6 +77,14 @@ impl<T: PoolTransaction> BlobTransactions<T> {
Some(tx)
}

/// Returns all transactions that satisfy the given basefee and blob_fee.
pub(crate) fn satisfy_attributes(
&self,
best_transactions_attributes: BestTransactionsAttributes,
) -> Vec<Arc<ValidPoolTransaction<T>>> {
Vec::new()
}

fn next_id(&mut self) -> u64 {
let id = self.submission_id;
self.submission_id = self.submission_id.wrapping_add(1);
Expand Down
14 changes: 12 additions & 2 deletions crates/transaction-pool/src/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ use crate::{
txpool::{SenderInfo, TxPool},
},
traits::{
AllPoolTransactions, BlockInfo, NewTransactionEvent, PoolSize, PoolTransaction,
PropagatedTransactions, TransactionOrigin,
AllPoolTransactions, BestTransactionsAttributes, BlockInfo, NewTransactionEvent, PoolSize,
PoolTransaction, PropagatedTransactions, TransactionOrigin,
},
validate::{TransactionValidationOutcome, ValidPoolTransaction},
CanonicalStateUpdate, ChangedAccount, PoolConfig, TransactionOrdering, TransactionValidator,
Expand Down Expand Up @@ -664,6 +664,16 @@ where
self.pool.read().best_transactions_with_base_fee(base_fee)
}

/// Returns an iterator that yields transactions that are ready to be included in the block with
/// the given base fee and optional blob fee attributes.
pub(crate) fn best_transactions_with_attributes(
&self,
best_transactions_attributes: BestTransactionsAttributes,
) -> Box<dyn crate::traits::BestTransactions<Item = Arc<ValidPoolTransaction<T::Transaction>>>>
{
self.pool.read().best_transactions_with_attributes(best_transactions_attributes)
}

/// Returns all transactions from the pending sub-pool
pub(crate) fn pending_transactions(&self) -> Vec<Arc<ValidPoolTransaction<T::Transaction>>> {
self.pool.read().pending_transactions()
Expand Down
34 changes: 33 additions & 1 deletion crates/transaction-pool/src/pool/txpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
update::{Destination, PoolUpdate},
AddedPendingTransaction, AddedTransaction, OnNewCanonicalStateOutcome,
},
traits::{BlockInfo, PoolSize},
traits::{BestTransactionsAttributes, BlockInfo, PoolSize},
PoolConfig, PoolResult, PoolTransaction, PriceBumpConfig, TransactionOrdering,
ValidPoolTransaction, U256,
};
Expand Down Expand Up @@ -244,6 +244,38 @@ impl<T: TransactionOrdering> TxPool<T> {
}
}

/// Returns an iterator that yields transactions that are ready to be included in the block with
/// the given base fee and optional blob fee.
pub(crate) fn best_transactions_with_attributes(
&self,
best_transactions_attributes: BestTransactionsAttributes,
) -> Box<dyn crate::traits::BestTransactions<Item = Arc<ValidPoolTransaction<T::Transaction>>>>
{
match best_transactions_attributes.basefee.cmp(&self.all_transactions.pending_basefee) {
Ordering::Equal => {
// fee unchanged, nothing to shift
Box::new(self.best_transactions())
}
Ordering::Greater => {
// base fee increased, we only need to enforce this on the pending pool
Box::new(self.pending_pool.best_with_basefee(best_transactions_attributes.basefee))
}
Ordering::Less => {
// base fee decreased, we need to move transactions from the basefee pool to the
// pending pool and satisfy blob fee transactions as well
let unlocked_with_blob =
self.blob_transactions.satisfy_attributes(best_transactions_attributes);

Box::new(
self.pending_pool.best_with_unlocked(
unlocked_with_blob,
self.all_transactions.pending_basefee,
),
)
}
}
}

/// Returns all transactions from the pending sub-pool
pub(crate) fn pending_transactions(&self) -> Vec<Arc<ValidPoolTransaction<T::Transaction>>> {
self.pending_pool.all().collect()
Expand Down
38 changes: 38 additions & 0 deletions crates/transaction-pool/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,15 @@ pub trait TransactionPool: Send + Sync + Clone {
base_fee: u64,
) -> Box<dyn BestTransactions<Item = Arc<ValidPoolTransaction<Self::Transaction>>>>;

/// Returns an iterator that yields transactions that are ready for block production with the
/// given base fee and optional blob fee attributes.
///
/// Consumer: Block production
fn best_transactions_with_attributes(
&self,
best_transactions_attributes: BestTransactionsAttributes,
) -> Box<dyn BestTransactions<Item = Arc<ValidPoolTransaction<Self::Transaction>>>>;

/// Returns all transactions that can be included in the next block.
///
/// This is primarily used for the `txpool_` RPC namespace: <https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-txpool> which distinguishes between `pending` and `queued` transactions, where `pending` are transactions ready for inclusion in the next block and `queued` are transactions that are ready for inclusion in future blocks.
Expand Down Expand Up @@ -622,6 +631,35 @@ impl<T> BestTransactions for std::iter::Empty<T> {
fn set_skip_blobs(&mut self, _skip_blobs: bool) {}
}

/// A Helper type that bundles best transactions attributes together.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct BestTransactionsAttributes {
/// The base fee attribute for best transactions.
pub basefee: u64,
/// The blob fee attribute for best transactions.
pub blob_fee: Option<u64>,
}

// === impl BestTransactionsAttributes ===

impl BestTransactionsAttributes {
/// Creates a new `BestTransactionsAttributes` with the given basefee and blob fee.
pub fn new(basefee: u64, blob_fee: Option<u64>) -> Self {
Self { basefee, blob_fee }
}

/// Creates a new `BestTransactionsAttributes` with the given basefee.
pub fn base_fee(basefee: u64) -> Self {
Self::new(basefee, None)
}

/// Sets the given blob fee.
pub fn with_blob_fee(mut self, blob_fee: u64) -> Self {
self.blob_fee = Some(blob_fee);
self
}
}

/// Trait for transaction types used inside the pool
pub trait PoolTransaction:
fmt::Debug
Expand Down

0 comments on commit 25aed7b

Please sign in to comment.