Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tx-pool): Add new TransactionPool trait for getting the best transactions with blob fee #4834

Merged
merged 3 commits into from
Sep 29, 2023
Merged
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
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 @@ -245,6 +245,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(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mattsse please let me know your opinion about this function and then I can also write the related unit tests

&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
Loading