update banking-bench to simulate mint event (#28489)
* update banking-bench to simulate mint event by specifying certain percentage of conflicting transactions with higher priority fee * set proper compute-unit for transfer transactions
This commit is contained in:
parent
d98eb97842
commit
365e32a484
|
@ -16,14 +16,14 @@ use {
|
|||
solana_measure::measure::Measure,
|
||||
solana_perf::packet::{to_packet_batches, PacketBatch},
|
||||
solana_poh::poh_recorder::{create_test_recorder, PohRecorder, WorkingBankEntry},
|
||||
solana_runtime::{
|
||||
accounts_background_service::AbsRequestSender, bank::Bank, bank_forks::BankForks,
|
||||
cost_model::CostModel,
|
||||
},
|
||||
solana_runtime::{bank::Bank, bank_forks::BankForks, cost_model::CostModel},
|
||||
solana_sdk::{
|
||||
compute_budget::ComputeBudgetInstruction,
|
||||
hash::Hash,
|
||||
signature::{Keypair, Signature},
|
||||
system_transaction,
|
||||
message::Message,
|
||||
pubkey::{self, Pubkey},
|
||||
signature::{Keypair, Signature, Signer},
|
||||
system_instruction, system_transaction,
|
||||
timing::{duration_as_us, timestamp},
|
||||
transaction::Transaction,
|
||||
},
|
||||
|
@ -36,6 +36,12 @@ use {
|
|||
},
|
||||
};
|
||||
|
||||
// transfer transaction cost = 1 * SIGNATURE_COST +
|
||||
// 2 * WRITE_LOCK_UNITS +
|
||||
// 1 * system_program
|
||||
// = 1470 CU
|
||||
const TRANSFER_TRANSACTION_COST: u32 = 1470;
|
||||
|
||||
fn check_txs(
|
||||
receiver: &Arc<Receiver<WorkingBankEntry>>,
|
||||
ref_tx_count: usize,
|
||||
|
@ -96,23 +102,44 @@ fn make_accounts_txs(
|
|||
packets_per_batch: usize,
|
||||
hash: Hash,
|
||||
contention: WriteLockContention,
|
||||
simulate_mint: bool,
|
||||
mint_txs_percentage: usize,
|
||||
) -> Vec<Transaction> {
|
||||
use solana_sdk::pubkey;
|
||||
let to_pubkey = pubkey::new_rand();
|
||||
let chunk_pubkeys: Vec<pubkey::Pubkey> = (0..total_num_transactions / packets_per_batch)
|
||||
.map(|_| pubkey::new_rand())
|
||||
.collect();
|
||||
let payer_key = Keypair::new();
|
||||
let dummy = system_transaction::transfer(&payer_key, &to_pubkey, 1, hash);
|
||||
(0..total_num_transactions)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let mut new = dummy.clone();
|
||||
let is_simulated_mint = is_simulated_mint_transaction(
|
||||
simulate_mint,
|
||||
i,
|
||||
packets_per_batch,
|
||||
mint_txs_percentage,
|
||||
);
|
||||
// simulated mint transactions have higher compute-unit-price
|
||||
let compute_unit_price = if is_simulated_mint { 5 } else { 1 };
|
||||
let mut new = make_transfer_transaction_with_compute_unit_price(
|
||||
&payer_key,
|
||||
&to_pubkey,
|
||||
1,
|
||||
hash,
|
||||
compute_unit_price,
|
||||
);
|
||||
let sig: Vec<u8> = (0..64).map(|_| thread_rng().gen::<u8>()).collect();
|
||||
new.message.account_keys[0] = pubkey::new_rand();
|
||||
new.message.account_keys[1] = match contention {
|
||||
WriteLockContention::None => pubkey::new_rand(),
|
||||
WriteLockContention::SameBatchOnly => chunk_pubkeys[i / packets_per_batch],
|
||||
WriteLockContention::SameBatchOnly => {
|
||||
// simulated mint transactions have conflict accounts
|
||||
if is_simulated_mint {
|
||||
chunk_pubkeys[i / packets_per_batch]
|
||||
} else {
|
||||
pubkey::new_rand()
|
||||
}
|
||||
}
|
||||
WriteLockContention::Full => to_pubkey,
|
||||
};
|
||||
new.signatures = vec![Signature::new(&sig[0..64])];
|
||||
|
@ -121,6 +148,35 @@ fn make_accounts_txs(
|
|||
.collect()
|
||||
}
|
||||
|
||||
// In simulating mint, `mint_txs_percentage` transactions in a batch are mint transaction
|
||||
// (eg., have conflicting account and higher priority) and remaining percentage regular
|
||||
// transactions (eg., non-conflict and low priority)
|
||||
fn is_simulated_mint_transaction(
|
||||
simulate_mint: bool,
|
||||
index: usize,
|
||||
packets_per_batch: usize,
|
||||
mint_txs_percentage: usize,
|
||||
) -> bool {
|
||||
simulate_mint && (index % packets_per_batch <= packets_per_batch * mint_txs_percentage / 100)
|
||||
}
|
||||
|
||||
fn make_transfer_transaction_with_compute_unit_price(
|
||||
from_keypair: &Keypair,
|
||||
to: &Pubkey,
|
||||
lamports: u64,
|
||||
recent_blockhash: Hash,
|
||||
compute_unit_price: u64,
|
||||
) -> Transaction {
|
||||
let from_pubkey = from_keypair.pubkey();
|
||||
let instructions = vec![
|
||||
system_instruction::transfer(&from_pubkey, to, lamports),
|
||||
ComputeBudgetInstruction::set_compute_unit_price(compute_unit_price),
|
||||
ComputeBudgetInstruction::set_compute_unit_limit(TRANSFER_TRANSACTION_COST),
|
||||
];
|
||||
let message = Message::new(&instructions, Some(&from_pubkey));
|
||||
Transaction::new(&[from_keypair], message, recent_blockhash)
|
||||
}
|
||||
|
||||
struct PacketsPerIteration {
|
||||
packet_batches: Vec<PacketBatch>,
|
||||
transactions: Vec<Transaction>,
|
||||
|
@ -133,6 +189,8 @@ impl PacketsPerIteration {
|
|||
batches_per_iteration: usize,
|
||||
genesis_hash: Hash,
|
||||
write_lock_contention: WriteLockContention,
|
||||
simulate_mint: bool,
|
||||
mint_txs_percentage: usize,
|
||||
) -> Self {
|
||||
let total_num_transactions = packets_per_batch * batches_per_iteration;
|
||||
let transactions = make_accounts_txs(
|
||||
|
@ -140,6 +198,8 @@ impl PacketsPerIteration {
|
|||
packets_per_batch,
|
||||
genesis_hash,
|
||||
write_lock_contention,
|
||||
simulate_mint,
|
||||
mint_txs_percentage,
|
||||
);
|
||||
|
||||
let packet_batches: Vec<PacketBatch> = to_packet_batches(&transactions, packets_per_batch);
|
||||
|
@ -219,6 +279,19 @@ fn main() {
|
|||
.takes_value(false)
|
||||
.help("Disable forwarding messages to TPU using QUIC"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("simulate_mint")
|
||||
.long("simulate-mint")
|
||||
.takes_value(false)
|
||||
.help("Simulate mint transactions to have higher priority"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("mint_txs_percentage")
|
||||
.long("mint-txs-percentage")
|
||||
.takes_value(true)
|
||||
.requires("simulate_mint")
|
||||
.help("In simulating mint, number of mint transactions out of 100."),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let num_banking_threads = matches
|
||||
|
@ -236,6 +309,9 @@ fn main() {
|
|||
let write_lock_contention = matches
|
||||
.value_of_t::<WriteLockContention>("write_lock_contention")
|
||||
.unwrap_or(WriteLockContention::None);
|
||||
let mint_txs_percentage = matches
|
||||
.value_of_t::<usize>("mint_txs_percentage")
|
||||
.unwrap_or(99);
|
||||
|
||||
let mint_total = 1_000_000_000_000;
|
||||
let GenesisConfigInfo {
|
||||
|
@ -263,6 +339,8 @@ fn main() {
|
|||
batches_per_iteration,
|
||||
genesis_config.hash(),
|
||||
write_lock_contention,
|
||||
matches.is_present("simulate_mint"),
|
||||
mint_txs_percentage,
|
||||
))
|
||||
})
|
||||
.take(num_chunks)
|
||||
|
@ -329,12 +407,8 @@ fn main() {
|
|||
Blockstore::open(&ledger_path).expect("Expected to be able to open database ledger"),
|
||||
);
|
||||
let leader_schedule_cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank));
|
||||
let (exit, poh_recorder, poh_service, signal_receiver) = create_test_recorder(
|
||||
&bank,
|
||||
&blockstore,
|
||||
None,
|
||||
Some(leader_schedule_cache.clone()),
|
||||
);
|
||||
let (exit, poh_recorder, poh_service, signal_receiver) =
|
||||
create_test_recorder(&bank, &blockstore, None, Some(leader_schedule_cache));
|
||||
let cluster_info = ClusterInfo::new(
|
||||
Node::new_localhost().info,
|
||||
Arc::new(Keypair::new()),
|
||||
|
@ -370,7 +444,6 @@ fn main() {
|
|||
let mut tx_total_us = 0;
|
||||
let base_tx_count = bank.transaction_count();
|
||||
let mut txs_processed = 0;
|
||||
let mut root = 1;
|
||||
let collector = solana_sdk::pubkey::new_rand();
|
||||
let mut total_sent = 0;
|
||||
for current_iteration_index in 0..iterations {
|
||||
|
@ -404,18 +477,22 @@ fn main() {
|
|||
sleep(Duration::from_millis(5));
|
||||
}
|
||||
}
|
||||
|
||||
// check if txs had been processed by bank. Returns when all transactions are
|
||||
// processed, with `FALSE` indicate there is still bank. or returns TRUE indicate a
|
||||
// bank has expired before receiving all txs.
|
||||
if check_txs(
|
||||
&signal_receiver,
|
||||
packets_for_this_iteration.transactions.len(),
|
||||
&poh_recorder,
|
||||
) {
|
||||
debug!(
|
||||
"resetting bank {} tx count: {} txs_proc: {}",
|
||||
eprintln!(
|
||||
"[iteration {}, tx sent {}, slot {} expired, bank tx count {}]",
|
||||
current_iteration_index,
|
||||
sent,
|
||||
bank.slot(),
|
||||
bank.transaction_count(),
|
||||
txs_processed
|
||||
);
|
||||
txs_processed = bank.transaction_count();
|
||||
tx_total_us += duration_as_us(&now.elapsed());
|
||||
|
||||
let mut poh_time = Measure::start("poh_time");
|
||||
|
@ -443,14 +520,6 @@ fn main() {
|
|||
|
||||
poh_recorder.write().unwrap().set_bank(&bank, false);
|
||||
assert!(poh_recorder.read().unwrap().bank().is_some());
|
||||
if bank.slot() > 32 {
|
||||
leader_schedule_cache.set_root(&bank);
|
||||
bank_forks
|
||||
.write()
|
||||
.unwrap()
|
||||
.set_root(root, &AbsRequestSender::default(), None);
|
||||
root += 1;
|
||||
}
|
||||
debug!(
|
||||
"new_bank_time: {}us insert_time: {}us poh_time: {}us",
|
||||
new_bank_time.as_us(),
|
||||
|
@ -458,6 +527,13 @@ fn main() {
|
|||
poh_time.as_us(),
|
||||
);
|
||||
} else {
|
||||
eprintln!(
|
||||
"[iteration {}, tx sent {}, slot {} active, bank tx count {}]",
|
||||
current_iteration_index,
|
||||
sent,
|
||||
bank.slot(),
|
||||
bank.transaction_count(),
|
||||
);
|
||||
tx_total_us += duration_as_us(&now.elapsed());
|
||||
}
|
||||
|
||||
|
@ -466,27 +542,25 @@ fn main() {
|
|||
// we should clear them by the time we come around again to re-use that chunk.
|
||||
bank.clear_signatures();
|
||||
total_us += duration_as_us(&now.elapsed());
|
||||
debug!(
|
||||
"time: {} us checked: {} sent: {}",
|
||||
duration_as_us(&now.elapsed()),
|
||||
total_num_transactions / num_chunks as u64,
|
||||
sent,
|
||||
);
|
||||
total_sent += sent;
|
||||
|
||||
if current_iteration_index % 16 == 0 {
|
||||
if current_iteration_index % num_chunks == 0 {
|
||||
let last_blockhash = bank.last_blockhash();
|
||||
for packets_for_single_iteration in all_packets.iter_mut() {
|
||||
packets_for_single_iteration.refresh_blockhash(last_blockhash);
|
||||
}
|
||||
}
|
||||
}
|
||||
let txs_processed = bank_forks
|
||||
txs_processed += bank_forks
|
||||
.read()
|
||||
.unwrap()
|
||||
.working_bank()
|
||||
.transaction_count();
|
||||
debug!("processed: {} base: {}", txs_processed, base_tx_count);
|
||||
|
||||
eprintln!("[total_sent: {}, base_tx_count: {}, txs_processed: {}, txs_landed: {}, total_us: {}, tx_total_us: {}]",
|
||||
total_sent, base_tx_count, txs_processed, (txs_processed - base_tx_count), total_us, tx_total_us);
|
||||
|
||||
eprintln!(
|
||||
"{{'name': 'banking_bench_total', 'median': '{:.2}'}}",
|
||||
(1000.0 * 1000.0 * total_sent as f64) / (total_us as f64),
|
||||
|
|
Loading…
Reference in New Issue