-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add blob transactions subpool (#4608)
- Loading branch information
Showing
5 changed files
with
175 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
#![allow(dead_code, unused)] | ||
use crate::{ | ||
identifier::TransactionId, pool::size::SizeTracker, PoolTransaction, ValidPoolTransaction, | ||
}; | ||
use std::{ | ||
cmp::Ordering, | ||
collections::{BTreeMap, BTreeSet}, | ||
sync::Arc, | ||
}; | ||
|
||
/// A set of __all__ validated blob transactions in the pool. | ||
/// | ||
/// The purpose of this pool is keep track of blob transactions that are either pending or queued | ||
/// and to evict the worst blob transactions once the sub-pool is full. | ||
/// | ||
/// This expects that certain constraints are met: | ||
/// - blob transactions are always gap less | ||
pub(crate) struct BlobTransactions<T: PoolTransaction> { | ||
/// Keeps track of transactions inserted in the pool. | ||
/// | ||
/// This way we can determine when transactions were submitted to the pool. | ||
submission_id: u64, | ||
/// _All_ Transactions that are currently inside the pool grouped by their identifier. | ||
by_id: BTreeMap<TransactionId, Arc<ValidPoolTransaction<T>>>, | ||
/// _All_ transactions sorted by blob priority. | ||
all: BTreeSet<BlobTransaction<T>>, | ||
/// Keeps track of the size of this pool. | ||
/// | ||
/// See also [`PoolTransaction::size`](crate::traits::PoolTransaction::size). | ||
size_of: SizeTracker, | ||
} | ||
|
||
// === impl BlobTransactions === | ||
|
||
impl<T: PoolTransaction> BlobTransactions<T> { | ||
/// Adds a new transactions to the pending queue. | ||
/// | ||
/// # Panics | ||
/// | ||
/// - If the transaction is not a blob tx. | ||
/// - If the transaction is already included. | ||
pub(crate) fn add_transaction(&mut self, tx: Arc<ValidPoolTransaction<T>>) { | ||
assert!(tx.is_eip4844(), "transaction is not a blob tx"); | ||
let id = *tx.id(); | ||
assert!( | ||
!self.by_id.contains_key(&id), | ||
"transaction already included {:?}", | ||
self.by_id.contains_key(&id) | ||
); | ||
let submission_id = self.next_id(); | ||
|
||
// keep track of size | ||
self.size_of += tx.size(); | ||
|
||
self.by_id.insert(id, tx.clone()); | ||
|
||
let ord = BlobOrd { submission_id }; | ||
let transaction = BlobTransaction { ord, transaction: tx }; | ||
self.all.insert(transaction); | ||
} | ||
|
||
/// Removes the transaction from the pool | ||
pub(crate) fn remove_transaction( | ||
&mut self, | ||
id: &TransactionId, | ||
) -> Option<Arc<ValidPoolTransaction<T>>> { | ||
// remove from queues | ||
let tx = self.by_id.remove(id)?; | ||
|
||
// TODO: remove from ordered set | ||
// self.best.remove(&tx); | ||
|
||
// keep track of size | ||
self.size_of -= tx.transaction.size(); | ||
|
||
Some(tx) | ||
} | ||
|
||
fn next_id(&mut self) -> u64 { | ||
let id = self.submission_id; | ||
self.submission_id = self.submission_id.wrapping_add(1); | ||
id | ||
} | ||
|
||
/// The reported size of all transactions in this pool. | ||
pub(crate) fn size(&self) -> usize { | ||
self.size_of.into() | ||
} | ||
|
||
/// Number of transactions in the entire pool | ||
pub(crate) fn len(&self) -> usize { | ||
self.by_id.len() | ||
} | ||
|
||
/// Returns `true` if the transaction with the given id is already included in this pool. | ||
#[cfg(test)] | ||
#[allow(unused)] | ||
pub(crate) fn contains(&self, id: &TransactionId) -> bool { | ||
self.by_id.contains_key(id) | ||
} | ||
} | ||
|
||
impl<T: PoolTransaction> Default for BlobTransactions<T> { | ||
fn default() -> Self { | ||
Self { | ||
submission_id: 0, | ||
by_id: Default::default(), | ||
all: Default::default(), | ||
size_of: Default::default(), | ||
} | ||
} | ||
} | ||
|
||
/// A transaction that is ready to be included in a block. | ||
struct BlobTransaction<T: PoolTransaction> { | ||
/// Actual blob transaction. | ||
transaction: Arc<ValidPoolTransaction<T>>, | ||
/// The value that determines the order of this transaction. | ||
ord: BlobOrd, | ||
} | ||
|
||
impl<T: PoolTransaction> Eq for BlobTransaction<T> {} | ||
|
||
impl<T: PoolTransaction> PartialEq<Self> for BlobTransaction<T> { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.cmp(other) == Ordering::Equal | ||
} | ||
} | ||
|
||
impl<T: PoolTransaction> PartialOrd<Self> for BlobTransaction<T> { | ||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
Some(self.cmp(other)) | ||
} | ||
} | ||
|
||
impl<T: PoolTransaction> Ord for BlobTransaction<T> { | ||
fn cmp(&self, other: &Self) -> Ordering { | ||
self.ord.cmp(&other.ord) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
struct BlobOrd { | ||
/// Identifier that tags when transaction was submitted in the pool. | ||
pub(crate) submission_id: u64, | ||
// TODO(mattsse): add ord values | ||
} | ||
|
||
impl Eq for BlobOrd {} | ||
|
||
impl PartialEq<Self> for BlobOrd { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.cmp(other) == Ordering::Equal | ||
} | ||
} | ||
|
||
impl PartialOrd<Self> for BlobOrd { | ||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
Some(self.cmp(other)) | ||
} | ||
} | ||
|
||
impl Ord for BlobOrd { | ||
fn cmp(&self, other: &Self) -> Ordering { | ||
other.submission_id.cmp(&self.submission_id) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters