2018-08-22 07:57:07 -07:00
|
|
|
#![feature(test)]
|
2023-09-01 00:26:13 -07:00
|
|
|
#![allow(clippy::arithmetic_side_effects)]
|
2018-12-08 21:44:20 -08:00
|
|
|
|
2018-08-22 07:57:07 -07:00
|
|
|
extern crate test;
|
2018-07-10 14:19:42 -07:00
|
|
|
|
2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
log::*,
|
2023-05-18 13:18:28 -07:00
|
|
|
solana_program_runtime::declare_process_instruction,
|
2022-04-11 08:42:24 -07:00
|
|
|
solana_runtime::{
|
|
|
|
bank::{test_utils::goto_end_of_slot, *},
|
|
|
|
bank_client::BankClient,
|
|
|
|
loader_utils::create_invoke_instruction,
|
|
|
|
},
|
2021-12-03 09:00:31 -08:00
|
|
|
solana_sdk::{
|
|
|
|
client::{AsyncClient, SyncClient},
|
|
|
|
clock::MAX_RECENT_BLOCKHASHES,
|
|
|
|
genesis_config::create_genesis_config,
|
|
|
|
message::Message,
|
|
|
|
pubkey::Pubkey,
|
|
|
|
signature::{Keypair, Signer},
|
|
|
|
transaction::Transaction,
|
|
|
|
},
|
|
|
|
std::{sync::Arc, thread::sleep, time::Duration},
|
|
|
|
test::Bencher,
|
2020-01-28 17:03:20 -08:00
|
|
|
};
|
2018-07-10 14:19:42 -07:00
|
|
|
|
2019-04-29 13:09:11 -07:00
|
|
|
const BUILTIN_PROGRAM_ID: [u8; 32] = [
|
2020-06-08 17:38:14 -07:00
|
|
|
98, 117, 105, 108, 116, 105, 110, 95, 112, 114, 111, 103, 114, 97, 109, 95, 105, 100, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
2019-04-29 13:09:11 -07:00
|
|
|
];
|
|
|
|
|
2019-07-15 12:16:09 -07:00
|
|
|
const NOOP_PROGRAM_ID: [u8; 32] = [
|
2020-06-08 17:38:14 -07:00
|
|
|
98, 117, 105, 108, 116, 105, 110, 95, 112, 114, 111, 103, 114, 97, 109, 95, 105, 100, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
2019-07-15 12:16:09 -07:00
|
|
|
];
|
|
|
|
|
2019-04-29 13:09:11 -07:00
|
|
|
pub fn create_builtin_transactions(
|
|
|
|
bank_client: &BankClient,
|
|
|
|
mint_keypair: &Keypair,
|
|
|
|
) -> Vec<Transaction> {
|
2023-01-21 10:06:27 -08:00
|
|
|
let program_id = Pubkey::from(BUILTIN_PROGRAM_ID);
|
2019-04-29 13:09:11 -07:00
|
|
|
|
2019-04-19 06:29:07 -07:00
|
|
|
(0..4096)
|
2018-10-12 15:20:53 -07:00
|
|
|
.map(|_| {
|
2019-04-29 13:09:11 -07:00
|
|
|
// Seed the signer account
|
2018-08-09 07:56:04 -07:00
|
|
|
let rando0 = Keypair::new();
|
2019-04-29 13:09:11 -07:00
|
|
|
bank_client
|
2021-06-18 06:34:46 -07:00
|
|
|
.transfer_and_confirm(10_000, mint_keypair, &rando0.pubkey())
|
2020-06-08 17:38:14 -07:00
|
|
|
.unwrap_or_else(|_| panic!("{}:{}", line!(), file!()));
|
2019-04-29 13:09:11 -07:00
|
|
|
|
2019-10-25 16:22:41 -07:00
|
|
|
let instruction = create_invoke_instruction(rando0.pubkey(), program_id, &1u8);
|
2021-08-13 09:08:20 -07:00
|
|
|
let blockhash = bank_client.get_latest_blockhash().unwrap();
|
2020-06-24 13:52:38 -07:00
|
|
|
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
|
|
|
|
Transaction::new(&[&rando0], message, blockhash)
|
2018-12-07 19:01:28 -08:00
|
|
|
})
|
2019-04-19 06:29:07 -07:00
|
|
|
.collect()
|
|
|
|
}
|
2018-07-10 14:19:42 -07:00
|
|
|
|
2019-04-29 13:09:11 -07:00
|
|
|
pub fn create_native_loader_transactions(
|
|
|
|
bank_client: &BankClient,
|
|
|
|
mint_keypair: &Keypair,
|
|
|
|
) -> Vec<Transaction> {
|
2023-01-21 10:06:27 -08:00
|
|
|
let program_id = Pubkey::from(NOOP_PROGRAM_ID);
|
2019-04-19 06:29:07 -07:00
|
|
|
|
2019-04-29 13:09:11 -07:00
|
|
|
(0..4096)
|
|
|
|
.map(|_| {
|
|
|
|
// Seed the signer account©41
|
|
|
|
let rando0 = Keypair::new();
|
|
|
|
bank_client
|
2021-06-18 06:34:46 -07:00
|
|
|
.transfer_and_confirm(10_000, mint_keypair, &rando0.pubkey())
|
2020-06-08 17:38:14 -07:00
|
|
|
.unwrap_or_else(|_| panic!("{}:{}", line!(), file!()));
|
2019-04-29 13:09:11 -07:00
|
|
|
|
2019-10-25 16:22:41 -07:00
|
|
|
let instruction = create_invoke_instruction(rando0.pubkey(), program_id, &1u8);
|
2021-08-13 09:08:20 -07:00
|
|
|
let blockhash = bank_client.get_latest_blockhash().unwrap();
|
2020-06-24 13:52:38 -07:00
|
|
|
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
|
|
|
|
Transaction::new(&[&rando0], message, blockhash)
|
2019-04-29 13:09:11 -07:00
|
|
|
})
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
2023-08-18 14:46:34 -07:00
|
|
|
fn sync_bencher(bank: &Bank, _bank_client: &BankClient, transactions: &[Transaction]) {
|
2021-07-15 20:51:27 -07:00
|
|
|
let results = bank.process_transactions(transactions.iter());
|
2019-04-19 06:29:07 -07:00
|
|
|
assert!(results.iter().all(Result::is_ok));
|
2019-04-29 13:09:11 -07:00
|
|
|
}
|
2018-10-17 16:28:26 -07:00
|
|
|
|
2023-08-18 14:46:34 -07:00
|
|
|
fn async_bencher(bank: &Bank, bank_client: &BankClient, transactions: &[Transaction]) {
|
2022-01-21 16:01:22 -08:00
|
|
|
for transaction in transactions.iter().cloned() {
|
2019-04-29 13:09:11 -07:00
|
|
|
bank_client.async_send_transaction(transaction).unwrap();
|
|
|
|
}
|
|
|
|
for _ in 0..1_000_000_000_u64 {
|
|
|
|
if bank
|
2021-06-18 06:34:46 -07:00
|
|
|
.get_signature_status(transactions.last().unwrap().signatures.get(0).unwrap())
|
2019-04-29 13:09:11 -07:00
|
|
|
.is_some()
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sleep(Duration::from_nanos(1));
|
2018-10-17 16:28:26 -07:00
|
|
|
}
|
2020-06-08 17:38:14 -07:00
|
|
|
if bank
|
2021-06-18 06:34:46 -07:00
|
|
|
.get_signature_status(transactions.last().unwrap().signatures.get(0).unwrap())
|
2019-04-29 13:09:11 -07:00
|
|
|
.unwrap()
|
2020-06-08 17:38:14 -07:00
|
|
|
.is_err()
|
2019-04-29 13:09:11 -07:00
|
|
|
{
|
|
|
|
error!(
|
|
|
|
"transaction failed: {:?}",
|
2021-06-18 06:34:46 -07:00
|
|
|
bank.get_signature_status(transactions.last().unwrap().signatures.get(0).unwrap())
|
2019-04-29 13:09:11 -07:00
|
|
|
.unwrap()
|
|
|
|
);
|
2020-06-08 17:38:14 -07:00
|
|
|
panic!();
|
2019-04-29 13:09:11 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-30 19:14:33 -07:00
|
|
|
#[allow(clippy::type_complexity)]
|
2019-04-29 13:09:11 -07:00
|
|
|
fn do_bench_transactions(
|
|
|
|
bencher: &mut Bencher,
|
2023-08-18 14:46:34 -07:00
|
|
|
bench_work: &dyn Fn(&Bank, &BankClient, &[Transaction]),
|
2019-09-19 14:21:09 -07:00
|
|
|
create_transactions: &dyn Fn(&BankClient, &Keypair) -> Vec<Transaction>,
|
2019-04-29 13:09:11 -07:00
|
|
|
) {
|
|
|
|
solana_logger::setup();
|
|
|
|
let ns_per_s = 1_000_000_000;
|
2022-01-12 21:36:21 -08:00
|
|
|
let (mut genesis_config, mint_keypair) = create_genesis_config(100_000_000_000_000);
|
2019-11-08 20:56:57 -08:00
|
|
|
genesis_config.ticks_per_slot = 100;
|
2022-01-12 21:36:21 -08:00
|
|
|
|
|
|
|
let bank = Bank::new_for_benches(&genesis_config);
|
|
|
|
// freeze bank so that slot hashes is populated
|
|
|
|
bank.freeze();
|
|
|
|
|
2023-04-21 09:08:32 -07:00
|
|
|
declare_process_instruction!(process_instruction, 1, |_invoke_context| {
|
|
|
|
// Do nothing
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
|
2023-08-18 14:46:34 -07:00
|
|
|
let mut bank = Bank::new_from_parent(Arc::new(bank), &Pubkey::default(), 1);
|
2023-05-18 13:18:28 -07:00
|
|
|
bank.add_mockup_builtin(Pubkey::from(BUILTIN_PROGRAM_ID), process_instruction);
|
2023-01-21 10:06:27 -08:00
|
|
|
bank.add_builtin_account("solana_noop_program", &Pubkey::from(NOOP_PROGRAM_ID), false);
|
2019-04-29 13:09:11 -07:00
|
|
|
let bank = Arc::new(bank);
|
2023-08-18 14:46:34 -07:00
|
|
|
let bank_client = BankClient::new_shared(bank.clone());
|
2019-04-29 13:09:11 -07:00
|
|
|
let transactions = create_transactions(&bank_client, &mint_keypair);
|
|
|
|
|
|
|
|
// Do once to fund accounts, load modules, etc...
|
2021-07-15 20:51:27 -07:00
|
|
|
let results = bank.process_transactions(transactions.iter());
|
2019-04-29 13:09:11 -07:00
|
|
|
assert!(results.iter().all(Result::is_ok));
|
2018-10-17 16:28:26 -07:00
|
|
|
|
2018-08-22 07:57:07 -07:00
|
|
|
bencher.iter(|| {
|
2019-04-29 13:09:11 -07:00
|
|
|
// Since bencher runs this multiple times, we need to clear the signatures.
|
2018-08-22 07:57:07 -07:00
|
|
|
bank.clear_signatures();
|
2019-04-29 13:09:11 -07:00
|
|
|
bench_work(&bank, &bank_client, &transactions);
|
|
|
|
});
|
|
|
|
|
2022-11-09 14:15:03 -08:00
|
|
|
let summary = bencher.bench(|_bencher| Ok(())).unwrap().unwrap();
|
2019-04-29 13:09:11 -07:00
|
|
|
info!(" {:?} transactions", transactions.len());
|
|
|
|
info!(" {:?} ns/iter median", summary.median as u64);
|
|
|
|
assert!(0f64 != summary.median);
|
|
|
|
let tps = transactions.len() as u64 * (ns_per_s / summary.median as u64);
|
|
|
|
info!(" {:?} TPS", tps);
|
2018-07-10 15:30:56 -07:00
|
|
|
}
|
2019-04-19 06:29:07 -07:00
|
|
|
|
|
|
|
#[bench]
|
2019-07-30 13:48:46 -07:00
|
|
|
#[ignore]
|
2019-04-29 13:09:11 -07:00
|
|
|
fn bench_bank_sync_process_builtin_transactions(bencher: &mut Bencher) {
|
|
|
|
do_bench_transactions(bencher, &sync_bencher, &create_builtin_transactions);
|
|
|
|
}
|
2019-04-19 06:29:07 -07:00
|
|
|
|
2019-04-29 13:09:11 -07:00
|
|
|
#[bench]
|
2019-07-30 13:48:46 -07:00
|
|
|
#[ignore]
|
2019-04-29 13:09:11 -07:00
|
|
|
fn bench_bank_sync_process_native_loader_transactions(bencher: &mut Bencher) {
|
|
|
|
do_bench_transactions(bencher, &sync_bencher, &create_native_loader_transactions);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2019-07-30 13:48:46 -07:00
|
|
|
#[ignore]
|
2019-04-29 13:09:11 -07:00
|
|
|
fn bench_bank_async_process_builtin_transactions(bencher: &mut Bencher) {
|
|
|
|
do_bench_transactions(bencher, &async_bencher, &create_builtin_transactions);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2019-07-30 13:48:46 -07:00
|
|
|
#[ignore]
|
2019-04-29 13:09:11 -07:00
|
|
|
fn bench_bank_async_process_native_loader_transactions(bencher: &mut Bencher) {
|
|
|
|
do_bench_transactions(bencher, &async_bencher, &create_native_loader_transactions);
|
2019-04-19 06:29:07 -07:00
|
|
|
}
|
2019-11-04 09:51:15 -08:00
|
|
|
|
|
|
|
#[bench]
|
|
|
|
#[ignore]
|
|
|
|
fn bench_bank_update_recent_blockhashes(bencher: &mut Bencher) {
|
2019-11-08 20:56:57 -08:00
|
|
|
let (genesis_config, _mint_keypair) = create_genesis_config(100);
|
2021-08-04 15:30:43 -07:00
|
|
|
let mut bank = Arc::new(Bank::new_for_benches(&genesis_config));
|
2019-11-04 09:51:15 -08:00
|
|
|
goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
|
2019-11-08 20:56:57 -08:00
|
|
|
let genesis_hash = bank.last_blockhash();
|
2019-11-04 09:51:15 -08:00
|
|
|
// Prime blockhash_queue
|
|
|
|
for i in 0..(MAX_RECENT_BLOCKHASHES + 1) {
|
|
|
|
bank = Arc::new(Bank::new_from_parent(
|
2023-08-18 14:46:34 -07:00
|
|
|
bank,
|
2019-11-04 09:51:15 -08:00
|
|
|
&Pubkey::default(),
|
|
|
|
(i + 1) as u64,
|
|
|
|
));
|
|
|
|
goto_end_of_slot(Arc::get_mut(&mut bank).unwrap());
|
|
|
|
}
|
2019-11-08 20:56:57 -08:00
|
|
|
// Verify blockhash_queue is full (genesis hash has been kicked out)
|
2022-04-20 20:57:17 -07:00
|
|
|
assert!(!bank.is_hash_valid_for_age(&genesis_hash, MAX_RECENT_BLOCKHASHES));
|
2019-11-04 09:51:15 -08:00
|
|
|
bencher.iter(|| {
|
|
|
|
bank.update_recent_blockhashes();
|
|
|
|
});
|
|
|
|
}
|