BenchTPS: Allow a fixed compute-unit-price (#32775)
This commit is contained in:
parent
b44c9bca89
commit
0996b5e245
|
@ -1,7 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
bench_tps_client::*,
|
||||
cli::{Config, InstructionPaddingConfig},
|
||||
cli::{ComputeUnitPrice, Config, InstructionPaddingConfig},
|
||||
perf_utils::{sample_txs, SampleStats},
|
||||
send_batch::*,
|
||||
},
|
||||
|
@ -40,30 +40,36 @@ use {
|
|||
// The point at which transactions become "too old", in seconds.
|
||||
const MAX_TX_QUEUE_AGE: u64 = (MAX_PROCESSING_AGE as f64 * DEFAULT_S_PER_SLOT) as u64;
|
||||
|
||||
// Add prioritization fee to transfer transactions, when `--use-randomized-compute-unit-price`
|
||||
// is used, compute-unit-price is randomly generated in range of (0..MAX_COMPUTE_UNIT_PRICE)
|
||||
// multiplies by COMPUTE_UNIT_PRICE_MULTIPLIER;
|
||||
// Add prioritization fee to transfer transactions, if `compute_unit_price` is set.
|
||||
// If `Random` the compute-unit-price is determined by generating a random number in the range
|
||||
// 0..MAX_RANDOM_COMPUTE_UNIT_PRICE then multiplying by COMPUTE_UNIT_PRICE_MULTIPLIER.
|
||||
// If `Fixed` the compute-unit-price is the value of the `compute-unit-price` parameter.
|
||||
// It also sets transaction's compute-unit to TRANSFER_TRANSACTION_COMPUTE_UNIT. Therefore the
|
||||
// max additional cost is:
|
||||
// `TRANSFER_TRANSACTION_COMPUTE_UNIT * MAX_COMPUTE_UNIT_PRICE * COMPUTE_UNIT_PRICE_MULTIPLIER / 1_000_000`
|
||||
const MAX_COMPUTE_UNIT_PRICE: u64 = 50;
|
||||
const MAX_RANDOM_COMPUTE_UNIT_PRICE: u64 = 50;
|
||||
const COMPUTE_UNIT_PRICE_MULTIPLIER: u64 = 1_000;
|
||||
const TRANSFER_TRANSACTION_COMPUTE_UNIT: u32 = 600; // 1 transfer is plus 3 compute_budget ixs
|
||||
/// calculate maximum possible prioritization fee, if `use-randomized-compute-unit-price` is
|
||||
/// enabled, round to nearest lamports.
|
||||
pub fn max_lamports_for_prioritization(use_randomized_compute_unit_price: bool) -> u64 {
|
||||
if use_randomized_compute_unit_price {
|
||||
const MICRO_LAMPORTS_PER_LAMPORT: u64 = 1_000_000;
|
||||
let micro_lamport_fee: u128 = (MAX_COMPUTE_UNIT_PRICE as u128)
|
||||
.saturating_mul(COMPUTE_UNIT_PRICE_MULTIPLIER as u128)
|
||||
.saturating_mul(TRANSFER_TRANSACTION_COMPUTE_UNIT as u128);
|
||||
let fee = micro_lamport_fee
|
||||
.saturating_add(MICRO_LAMPORTS_PER_LAMPORT.saturating_sub(1) as u128)
|
||||
.saturating_div(MICRO_LAMPORTS_PER_LAMPORT as u128);
|
||||
u64::try_from(fee).unwrap_or(u64::MAX)
|
||||
} else {
|
||||
0u64
|
||||
}
|
||||
pub fn max_lamports_for_prioritization(compute_unit_price: &Option<ComputeUnitPrice>) -> u64 {
|
||||
let Some(compute_unit_price) = compute_unit_price else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
let compute_unit_price = match compute_unit_price {
|
||||
ComputeUnitPrice::Random => (MAX_RANDOM_COMPUTE_UNIT_PRICE as u128)
|
||||
.saturating_mul(COMPUTE_UNIT_PRICE_MULTIPLIER as u128),
|
||||
ComputeUnitPrice::Fixed(compute_unit_price) => *compute_unit_price as u128,
|
||||
};
|
||||
|
||||
const MICRO_LAMPORTS_PER_LAMPORT: u64 = 1_000_000;
|
||||
let micro_lamport_fee: u128 =
|
||||
compute_unit_price.saturating_mul(TRANSFER_TRANSACTION_COMPUTE_UNIT as u128);
|
||||
let fee = micro_lamport_fee
|
||||
.saturating_add(MICRO_LAMPORTS_PER_LAMPORT.saturating_sub(1) as u128)
|
||||
.saturating_div(MICRO_LAMPORTS_PER_LAMPORT as u128);
|
||||
u64::try_from(fee).unwrap_or(u64::MAX)
|
||||
}
|
||||
|
||||
// set transfer transaction's loaded account data size to 30K - large enough yet smaller than
|
||||
|
@ -120,7 +126,7 @@ struct TransactionChunkGenerator<'a, 'b, T: ?Sized> {
|
|||
nonce_chunks: Option<KeypairChunks<'b>>,
|
||||
chunk_index: usize,
|
||||
reclaim_lamports_back_to_source_account: bool,
|
||||
use_randomized_compute_unit_price: bool,
|
||||
compute_unit_price: Option<ComputeUnitPrice>,
|
||||
instruction_padding_config: Option<InstructionPaddingConfig>,
|
||||
}
|
||||
|
||||
|
@ -133,7 +139,7 @@ where
|
|||
gen_keypairs: &'a [Keypair],
|
||||
nonce_keypairs: Option<&'b Vec<Keypair>>,
|
||||
chunk_size: usize,
|
||||
use_randomized_compute_unit_price: bool,
|
||||
compute_unit_price: Option<ComputeUnitPrice>,
|
||||
instruction_padding_config: Option<InstructionPaddingConfig>,
|
||||
num_conflict_groups: Option<usize>,
|
||||
) -> Self {
|
||||
|
@ -151,7 +157,7 @@ where
|
|||
nonce_chunks,
|
||||
chunk_index: 0,
|
||||
reclaim_lamports_back_to_source_account: false,
|
||||
use_randomized_compute_unit_price,
|
||||
compute_unit_price,
|
||||
instruction_padding_config,
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +194,7 @@ where
|
|||
self.reclaim_lamports_back_to_source_account,
|
||||
blockhash.unwrap(),
|
||||
&self.instruction_padding_config,
|
||||
self.use_randomized_compute_unit_price,
|
||||
&self.compute_unit_price,
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -379,7 +385,7 @@ where
|
|||
tx_count,
|
||||
sustained,
|
||||
target_slots_per_epoch,
|
||||
use_randomized_compute_unit_price,
|
||||
compute_unit_price,
|
||||
use_durable_nonce,
|
||||
instruction_padding_config,
|
||||
num_conflict_groups,
|
||||
|
@ -392,7 +398,7 @@ where
|
|||
&gen_keypairs,
|
||||
nonce_keypairs.as_ref(),
|
||||
tx_count,
|
||||
use_randomized_compute_unit_price,
|
||||
compute_unit_price,
|
||||
instruction_padding_config,
|
||||
num_conflict_groups,
|
||||
);
|
||||
|
@ -520,7 +526,7 @@ fn generate_system_txs(
|
|||
reclaim: bool,
|
||||
blockhash: &Hash,
|
||||
instruction_padding_config: &Option<InstructionPaddingConfig>,
|
||||
use_randomized_compute_unit_price: bool,
|
||||
compute_unit_price: &Option<ComputeUnitPrice>,
|
||||
) -> Vec<TimestampedTransaction> {
|
||||
let pairs: Vec<_> = if !reclaim {
|
||||
source.iter().zip(dest.iter()).collect()
|
||||
|
@ -528,16 +534,22 @@ fn generate_system_txs(
|
|||
dest.iter().zip(source.iter()).collect()
|
||||
};
|
||||
|
||||
if use_randomized_compute_unit_price {
|
||||
let mut rng = rand::thread_rng();
|
||||
let range = Uniform::from(0..MAX_COMPUTE_UNIT_PRICE);
|
||||
let compute_unit_prices: Vec<_> = (0..pairs.len())
|
||||
.map(|_| {
|
||||
range
|
||||
.sample(&mut rng)
|
||||
.saturating_mul(COMPUTE_UNIT_PRICE_MULTIPLIER)
|
||||
})
|
||||
.collect();
|
||||
if let Some(compute_unit_price) = compute_unit_price {
|
||||
let compute_unit_prices = match compute_unit_price {
|
||||
ComputeUnitPrice::Random => {
|
||||
let mut rng = rand::thread_rng();
|
||||
let range = Uniform::from(0..MAX_RANDOM_COMPUTE_UNIT_PRICE);
|
||||
(0..pairs.len())
|
||||
.map(|_| {
|
||||
range
|
||||
.sample(&mut rng)
|
||||
.saturating_mul(COMPUTE_UNIT_PRICE_MULTIPLIER)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
ComputeUnitPrice::Fixed(compute_unit_price) => vec![*compute_unit_price; pairs.len()],
|
||||
};
|
||||
|
||||
let pairs_with_compute_unit_prices: Vec<_> =
|
||||
pairs.iter().zip(compute_unit_prices.iter()).collect();
|
||||
|
||||
|
|
|
@ -43,6 +43,12 @@ pub struct InstructionPaddingConfig {
|
|||
pub data_size: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ComputeUnitPrice {
|
||||
Fixed(u64),
|
||||
Random,
|
||||
}
|
||||
|
||||
/// Holds the configuration for a single run of the benchmark
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Config {
|
||||
|
@ -68,7 +74,7 @@ pub struct Config {
|
|||
pub external_client_type: ExternalClientType,
|
||||
pub use_quic: bool,
|
||||
pub tpu_connection_pool_size: usize,
|
||||
pub use_randomized_compute_unit_price: bool,
|
||||
pub compute_unit_price: Option<ComputeUnitPrice>,
|
||||
pub use_durable_nonce: bool,
|
||||
pub instruction_padding_config: Option<InstructionPaddingConfig>,
|
||||
pub num_conflict_groups: Option<usize>,
|
||||
|
@ -103,7 +109,7 @@ impl Default for Config {
|
|||
external_client_type: ExternalClientType::default(),
|
||||
use_quic: DEFAULT_TPU_USE_QUIC,
|
||||
tpu_connection_pool_size: DEFAULT_TPU_CONNECTION_POOL_SIZE,
|
||||
use_randomized_compute_unit_price: false,
|
||||
compute_unit_price: None,
|
||||
use_durable_nonce: false,
|
||||
instruction_padding_config: None,
|
||||
num_conflict_groups: None,
|
||||
|
@ -332,10 +338,18 @@ pub fn build_args<'a>(version: &'_ str) -> App<'a, '_> {
|
|||
.help("Controls the connection pool size per remote address; only affects ThinClient (default) \
|
||||
or TpuClient sends"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("compute_unit_price")
|
||||
.long("compute-unit-price")
|
||||
.takes_value(true)
|
||||
.validator(|s| is_within_range(s, 0..))
|
||||
.help("Sets constant compute-unit-price to transfer transactions"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("use_randomized_compute_unit_price")
|
||||
.long("use-randomized-compute-unit-price")
|
||||
.takes_value(false)
|
||||
.conflicts_with("compute_unit_price")
|
||||
.help("Sets random compute-unit-price in range [0..100] to transfer transactions"),
|
||||
)
|
||||
.arg(
|
||||
|
@ -517,8 +531,14 @@ pub fn parse_args(matches: &ArgMatches) -> Result<Config, &'static str> {
|
|||
.map_err(|_| "can't parse target-slots-per-epoch")?;
|
||||
}
|
||||
|
||||
if let Some(str) = matches.value_of("compute_unit_price") {
|
||||
args.compute_unit_price = Some(ComputeUnitPrice::Fixed(
|
||||
str.parse().map_err(|_| "can't parse compute-unit-price")?,
|
||||
));
|
||||
}
|
||||
|
||||
if matches.is_present("use_randomized_compute_unit_price") {
|
||||
args.use_randomized_compute_unit_price = true;
|
||||
args.compute_unit_price = Some(ComputeUnitPrice::Random);
|
||||
}
|
||||
|
||||
if matches.is_present("use_durable_nonce") {
|
||||
|
|
|
@ -251,7 +251,7 @@ fn main() {
|
|||
external_client_type,
|
||||
use_quic,
|
||||
tpu_connection_pool_size,
|
||||
use_randomized_compute_unit_price,
|
||||
compute_unit_price,
|
||||
use_durable_nonce,
|
||||
instruction_padding_config,
|
||||
bind_address,
|
||||
|
@ -266,9 +266,7 @@ fn main() {
|
|||
let num_accounts = keypairs.len() as u64;
|
||||
let max_fee = FeeRateGovernor::new(*target_lamports_per_signature, 0)
|
||||
.max_lamports_per_signature
|
||||
.saturating_add(max_lamports_for_prioritization(
|
||||
*use_randomized_compute_unit_price,
|
||||
));
|
||||
.saturating_add(max_lamports_for_prioritization(compute_unit_price));
|
||||
let num_lamports_per_account = (num_accounts - 1 + NUM_SIGNATURES_FOR_TXS * max_fee)
|
||||
/ num_accounts
|
||||
+ num_lamports_per_account;
|
||||
|
|
Loading…
Reference in New Issue