From 9b1416b4f4a4fe805fa4b386e6329368ab4bf66b Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Fri, 17 Nov 2023 14:09:06 -0500 Subject: [PATCH] feat: add benchmark for blob_tx_priority and fee_delta (#5468) --- crates/transaction-pool/Cargo.toml | 5 ++ crates/transaction-pool/benches/priority.rs | 70 +++++++++++++++++++++ crates/transaction-pool/src/lib.rs | 4 +- crates/transaction-pool/src/pool/blob.rs | 28 ++++++++- crates/transaction-pool/src/pool/mod.rs | 1 + 5 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 crates/transaction-pool/benches/priority.rs diff --git a/crates/transaction-pool/Cargo.toml b/crates/transaction-pool/Cargo.toml index 93548f83f..52ceaf937 100644 --- a/crates/transaction-pool/Cargo.toml +++ b/crates/transaction-pool/Cargo.toml @@ -78,3 +78,8 @@ optimism = [ name = "reorder" required-features = ["test-utils", "arbitrary"] harness = false + +[[bench]] +name = "priority" +required-features = ["arbitrary"] +harness = false diff --git a/crates/transaction-pool/benches/priority.rs b/crates/transaction-pool/benches/priority.rs new file mode 100644 index 000000000..65218c4a2 --- /dev/null +++ b/crates/transaction-pool/benches/priority.rs @@ -0,0 +1,70 @@ +use criterion::{ + black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, +}; +use proptest::{ + prelude::*, + strategy::{Strategy, ValueTree}, + test_runner::TestRunner, +}; +use reth_transaction_pool::{blob_tx_priority, fee_delta}; + +fn generate_test_data_fee_delta() -> (u128, u128) { + let config = ProptestConfig::default(); + let mut runner = TestRunner::new(config); + prop::arbitrary::any::<(u128, u128)>().new_tree(&mut runner).unwrap().current() +} + +fn generate_test_data_priority() -> (u128, u128, u128, u128) { + let config = ProptestConfig::default(); + let mut runner = TestRunner::new(config); + prop::arbitrary::any::<(u128, u128, u128, u128)>().new_tree(&mut runner).unwrap().current() +} + +fn priority_bench( + group: &mut BenchmarkGroup, + description: &str, + input_data: (u128, u128, u128, u128), +) { + let group_id = format!("txpool | {}", description); + + group.bench_function(group_id, |b| { + b.iter(|| { + black_box(blob_tx_priority( + black_box(input_data.0), + black_box(input_data.1), + black_box(input_data.2), + black_box(input_data.3), + )); + }); + }); +} + +fn fee_jump_bench( + group: &mut BenchmarkGroup, + description: &str, + input_data: (u128, u128), +) { + let group_id = format!("txpool | {}", description); + + group.bench_function(group_id, |b| { + b.iter(|| { + black_box(fee_delta(black_box(input_data.0), black_box(input_data.1))); + }); + }); +} + +pub fn blob_priority_calculation(c: &mut Criterion) { + let mut group = c.benchmark_group("Blob priority calculation"); + let fee_jump_input = generate_test_data_fee_delta(); + + // Unstable sorting of unsorted collection + fee_jump_bench(&mut group, "BenchmarkDynamicFeeJumpCalculation", fee_jump_input); + + let blob_priority_input = generate_test_data_priority(); + + // BinaryHeap that is resorted on each update + priority_bench(&mut group, "BenchmarkPriorityCalculation", blob_priority_input); +} + +criterion_group!(priority, blob_priority_calculation); +criterion_main!(priority); diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index a1d8b4ba7..de60ab7c5 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -162,8 +162,8 @@ pub use crate::{ error::PoolResult, ordering::{CoinbaseTipOrdering, Priority, TransactionOrdering}, pool::{ - state::SubPool, AllTransactionsEvents, FullTransactionEvent, TransactionEvent, - TransactionEvents, + blob_tx_priority, fee_delta, state::SubPool, AllTransactionsEvents, FullTransactionEvent, + TransactionEvent, TransactionEvents, }, traits::*, validate::{ diff --git a/crates/transaction-pool/src/pool/blob.rs b/crates/transaction-pool/src/pool/blob.rs index 15677bf55..24c1fa6ca 100644 --- a/crates/transaction-pool/src/pool/blob.rs +++ b/crates/transaction-pool/src/pool/blob.rs @@ -272,6 +272,9 @@ impl Ord for BlobTransaction { } } +/// This is the log base 2 of 1.125, which we'll use to calculate the priority +const LOG_2_1_125: f64 = 0.16992500144231237; + /// The blob step function, attempting to compute the delta given the `max_tx_fee`, and /// `current_fee`. /// @@ -284,9 +287,28 @@ impl Ord for BlobTransaction { /// /// This is supposed to get the number of fee jumps required to get from the current fee to the fee /// cap, or where the transaction would not be executable any more. -fn fee_delta(max_tx_fee: u128, current_fee: u128) -> i64 { +pub fn fee_delta(max_tx_fee: u128, current_fee: u128) -> i64 { + if max_tx_fee == current_fee { + // if these are equal, then there's no fee jump + return 0; + } + + let max_tx_fee_jumps = if max_tx_fee == 0 { + // we can't take log2 of 0, so we set this to zero here + 0f64 + } else { + (max_tx_fee.ilog2() as f64) / LOG_2_1_125 + }; + + let current_fee_jumps = if current_fee == 0 { + // we can't take log2 of 0, so we set this to zero here + 0f64 + } else { + (current_fee.ilog2() as f64) / LOG_2_1_125 + }; + // jumps = log1.125(txfee) - log1.125(basefee) - let jumps = (max_tx_fee as f64).log(1.125) - (current_fee as f64).log(1.125); + let jumps = max_tx_fee_jumps - current_fee_jumps; // delta = sign(jumps) * log(abs(jumps)) match (jumps as i64).cmp(&0) { @@ -300,7 +322,7 @@ fn fee_delta(max_tx_fee: u128, current_fee: u128) -> i64 { } /// Returns the priority for the transaction, based on the "delta" blob fee and priority fee. -fn blob_tx_priority( +pub fn blob_tx_priority( blob_fee_cap: u128, blob_fee: u128, max_priority_fee: u128, diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 55f4cbb1b..7242099c1 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -110,6 +110,7 @@ pub use listener::{AllTransactionsEvents, TransactionEvents}; mod best; mod blob; +pub use blob::{blob_tx_priority, fee_delta}; mod parked; pub(crate) mod pending; pub(crate) mod size;