mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat: add queued pool truncate benchmarks (#6684)
This commit is contained in:
@ -9,7 +9,7 @@ use proptest::{
|
|||||||
};
|
};
|
||||||
use reth_primitives::{hex_literal::hex, Address};
|
use reth_primitives::{hex_literal::hex, Address};
|
||||||
use reth_transaction_pool::{
|
use reth_transaction_pool::{
|
||||||
pool::{BasefeeOrd, ParkedPool, PendingPool},
|
pool::{BasefeeOrd, ParkedPool, PendingPool, QueuedOrd},
|
||||||
test_utils::{MockOrdering, MockTransaction, MockTransactionFactory},
|
test_utils::{MockOrdering, MockTransaction, MockTransactionFactory},
|
||||||
SubPoolLimit,
|
SubPoolLimit,
|
||||||
};
|
};
|
||||||
@ -84,6 +84,23 @@ fn generate_many_transactions(senders: usize, max_depth: usize) -> Vec<MockTrans
|
|||||||
txs
|
txs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Benchmarks all pool types for the truncate function.
|
||||||
|
fn benchmark_pools(group: &mut BenchmarkGroup<'_, WallTime>, senders: usize, max_depth: usize) {
|
||||||
|
println!("Generating transactions for benchmark with {senders} unique senders and a max depth of {max_depth}...");
|
||||||
|
let txs = generate_many_transactions(senders, max_depth);
|
||||||
|
|
||||||
|
// benchmark parked pool
|
||||||
|
truncate_basefee(group, "BasefeePool", txs.clone(), senders, max_depth);
|
||||||
|
|
||||||
|
// benchmark pending pool
|
||||||
|
truncate_pending(group, "PendingPool", txs.clone(), senders, max_depth);
|
||||||
|
|
||||||
|
// benchmark queued pool
|
||||||
|
truncate_queued(group, "QueuedPool", txs, senders, max_depth);
|
||||||
|
|
||||||
|
// TODO: benchmark blob truncate
|
||||||
|
}
|
||||||
|
|
||||||
fn txpool_truncate(c: &mut Criterion) {
|
fn txpool_truncate(c: &mut Criterion) {
|
||||||
let mut group = c.benchmark_group("Transaction Pool Truncate");
|
let mut group = c.benchmark_group("Transaction Pool Truncate");
|
||||||
|
|
||||||
@ -95,17 +112,8 @@ fn txpool_truncate(c: &mut Criterion) {
|
|||||||
for senders in [5, 10, 20, 100, 1000, 2000] {
|
for senders in [5, 10, 20, 100, 1000, 2000] {
|
||||||
// the max we'll be benching is 20, because MAX_ACCOUNT_SLOTS so far is 16. So 20 should be
|
// the max we'll be benching is 20, because MAX_ACCOUNT_SLOTS so far is 16. So 20 should be
|
||||||
// a reasonable worst-case benchmark
|
// a reasonable worst-case benchmark
|
||||||
for max_depth in [5, 10, 20] {
|
for max_depth in [1, 5, 10, 20] {
|
||||||
println!("Generating transactions for benchmark with {senders} unique senders and a max depth of {max_depth}...");
|
benchmark_pools(&mut group, senders, max_depth);
|
||||||
let txs = generate_many_transactions(senders, max_depth);
|
|
||||||
|
|
||||||
// benchmark parked pool
|
|
||||||
truncate_parked(&mut group, "ParkedPool", txs.clone(), senders, max_depth);
|
|
||||||
|
|
||||||
// benchmark pending pool
|
|
||||||
truncate_pending(&mut group, "PendingPool", txs, senders, max_depth);
|
|
||||||
|
|
||||||
// TODO: benchmark blob truncate
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,14 +122,12 @@ fn txpool_truncate(c: &mut Criterion) {
|
|||||||
|
|
||||||
// let's run a benchmark that includes a large number of senders and max_depth of 16 to ensure
|
// let's run a benchmark that includes a large number of senders and max_depth of 16 to ensure
|
||||||
// we hit the TXPOOL_SUBPOOL_MAX_TXS_DEFAULT limit, which is currently 10k
|
// we hit the TXPOOL_SUBPOOL_MAX_TXS_DEFAULT limit, which is currently 10k
|
||||||
println!("Generating transactions for large benchmark with {large_senders} unique senders and a max depth of {max_depth}...");
|
benchmark_pools(&mut group, large_senders, max_depth);
|
||||||
let txs = generate_many_transactions(large_senders, max_depth);
|
|
||||||
|
|
||||||
// benchmark parked
|
// now we'll run a more realistic benchmark, with max depth of 1 and 15000 senders
|
||||||
truncate_parked(&mut group, "ParkedPool", txs.clone(), large_senders, max_depth);
|
let realistic_senders = 15000;
|
||||||
|
let realistic_max_depth = 1;
|
||||||
// benchmark pending
|
benchmark_pools(&mut group, realistic_senders, realistic_max_depth);
|
||||||
truncate_pending(&mut group, "PendingPool", txs, large_senders, max_depth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn truncate_pending(
|
fn truncate_pending(
|
||||||
@ -159,7 +165,41 @@ fn truncate_pending(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn truncate_parked(
|
fn truncate_queued(
|
||||||
|
group: &mut BenchmarkGroup<'_, WallTime>,
|
||||||
|
description: &str,
|
||||||
|
seed: Vec<MockTransaction>,
|
||||||
|
senders: usize,
|
||||||
|
max_depth: usize,
|
||||||
|
) {
|
||||||
|
let setup = || {
|
||||||
|
let mut txpool = ParkedPool::<QueuedOrd<_>>::default();
|
||||||
|
let mut f = MockTransactionFactory::default();
|
||||||
|
|
||||||
|
for tx in seed.iter() {
|
||||||
|
txpool.add_transaction(f.validated_arc(tx.clone()));
|
||||||
|
}
|
||||||
|
txpool
|
||||||
|
};
|
||||||
|
|
||||||
|
let group_id = format!(
|
||||||
|
"txpool | total txs: {} | total senders: {} | max depth: {} | {}",
|
||||||
|
seed.len(),
|
||||||
|
senders,
|
||||||
|
max_depth,
|
||||||
|
description,
|
||||||
|
);
|
||||||
|
|
||||||
|
// for now we just use the default SubPoolLimit
|
||||||
|
group.bench_function(group_id, |b| {
|
||||||
|
b.iter_with_setup(setup, |mut txpool| {
|
||||||
|
txpool.truncate_pool(SubPoolLimit::default());
|
||||||
|
std::hint::black_box(());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn truncate_basefee(
|
||||||
group: &mut BenchmarkGroup<'_, WallTime>,
|
group: &mut BenchmarkGroup<'_, WallTime>,
|
||||||
description: &str,
|
description: &str,
|
||||||
seed: Vec<MockTransaction>,
|
seed: Vec<MockTransaction>,
|
||||||
|
|||||||
@ -108,7 +108,7 @@ pub use best::BestTransactionFilter;
|
|||||||
pub use blob::{blob_tx_priority, fee_delta};
|
pub use blob::{blob_tx_priority, fee_delta};
|
||||||
pub use events::{FullTransactionEvent, TransactionEvent};
|
pub use events::{FullTransactionEvent, TransactionEvent};
|
||||||
pub use listener::{AllTransactionsEvents, TransactionEvents};
|
pub use listener::{AllTransactionsEvents, TransactionEvents};
|
||||||
pub use parked::{BasefeeOrd, ParkedOrd, ParkedPool};
|
pub use parked::{BasefeeOrd, ParkedOrd, ParkedPool, QueuedOrd};
|
||||||
pub use pending::PendingPool;
|
pub use pending::PendingPool;
|
||||||
|
|
||||||
mod best;
|
mod best;
|
||||||
|
|||||||
@ -442,7 +442,7 @@ impl<T: PoolTransaction> Ord for BasefeeOrd<T> {
|
|||||||
/// The primary order function always compares the transaction costs first. In case these
|
/// The primary order function always compares the transaction costs first. In case these
|
||||||
/// are equal, it compares the timestamps when the transactions were created.
|
/// are equal, it compares the timestamps when the transactions were created.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct QueuedOrd<T: PoolTransaction>(Arc<ValidPoolTransaction<T>>);
|
pub struct QueuedOrd<T: PoolTransaction>(Arc<ValidPoolTransaction<T>>);
|
||||||
|
|
||||||
impl_ord_wrapper!(QueuedOrd);
|
impl_ord_wrapper!(QueuedOrd);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user