Add benchmark for vote processing (#22486)
This commit is contained in:
@ -236,6 +236,27 @@ impl<'a> InvokeContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_mock_with_sysvars_and_features(
|
||||||
|
transaction_context: &'a mut TransactionContext,
|
||||||
|
sysvar_cache: &'a SysvarCache,
|
||||||
|
feature_set: Arc<FeatureSet>,
|
||||||
|
) -> Self {
|
||||||
|
Self::new(
|
||||||
|
transaction_context,
|
||||||
|
Rent::default(),
|
||||||
|
&[],
|
||||||
|
Cow::Borrowed(sysvar_cache),
|
||||||
|
Some(LogCollector::new_ref()),
|
||||||
|
ComputeBudget::default(),
|
||||||
|
Rc::new(RefCell::new(Executors::default())),
|
||||||
|
None,
|
||||||
|
feature_set,
|
||||||
|
Hash::default(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_mock(
|
pub fn new_mock(
|
||||||
transaction_context: &'a mut TransactionContext,
|
transaction_context: &'a mut TransactionContext,
|
||||||
builtin_programs: &'a [BuiltinProgram],
|
builtin_programs: &'a [BuiltinProgram],
|
||||||
|
169
programs/vote/benches/process_vote.rs
Normal file
169
programs/vote/benches/process_vote.rs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#![feature(test)]
|
||||||
|
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
|
use {
|
||||||
|
solana_program_runtime::{invoke_context::InvokeContext, sysvar_cache::SysvarCache},
|
||||||
|
solana_sdk::{
|
||||||
|
account::{create_account_for_test, Account, AccountSharedData},
|
||||||
|
clock::{Clock, Slot},
|
||||||
|
feature_set::FeatureSet,
|
||||||
|
hash::Hash,
|
||||||
|
instruction::{AccountMeta, Instruction},
|
||||||
|
pubkey::Pubkey,
|
||||||
|
slot_hashes::{SlotHashes, MAX_ENTRIES},
|
||||||
|
sysvar,
|
||||||
|
transaction_context::{InstructionAccount, TransactionContext},
|
||||||
|
},
|
||||||
|
solana_vote_program::{
|
||||||
|
vote_instruction::VoteInstruction,
|
||||||
|
vote_state::{Vote, VoteInit, VoteState, VoteStateVersions, MAX_LOCKOUT_HISTORY},
|
||||||
|
},
|
||||||
|
std::sync::Arc,
|
||||||
|
test::Bencher,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// `feature` can be used to change vote program behavior per bench run.
|
||||||
|
fn do_bench(bencher: &mut Bencher, feature: Option<Pubkey>) {
|
||||||
|
// vote accounts are usually almost full of votes in normal operation
|
||||||
|
let num_initial_votes = MAX_LOCKOUT_HISTORY;
|
||||||
|
let num_vote_slots: usize = 4;
|
||||||
|
let last_vote_slot = num_initial_votes
|
||||||
|
.saturating_add(num_vote_slots)
|
||||||
|
.saturating_sub(1);
|
||||||
|
let last_vote_hash = Hash::new_unique();
|
||||||
|
|
||||||
|
let clock = Clock::default();
|
||||||
|
let mut slot_hashes = SlotHashes::new(&[]);
|
||||||
|
for i in 0..MAX_ENTRIES {
|
||||||
|
// slot hashes is full in normal operation
|
||||||
|
slot_hashes.add(
|
||||||
|
i as Slot,
|
||||||
|
if i == last_vote_slot {
|
||||||
|
last_vote_hash
|
||||||
|
} else {
|
||||||
|
Hash::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let vote_pubkey = Pubkey::new_unique();
|
||||||
|
let authority_pubkey = Pubkey::new_unique();
|
||||||
|
let vote_account = {
|
||||||
|
let mut vote_state = VoteState::new(
|
||||||
|
&VoteInit {
|
||||||
|
node_pubkey: authority_pubkey,
|
||||||
|
authorized_voter: authority_pubkey,
|
||||||
|
authorized_withdrawer: authority_pubkey,
|
||||||
|
commission: 0,
|
||||||
|
},
|
||||||
|
&clock,
|
||||||
|
);
|
||||||
|
|
||||||
|
for next_vote_slot in 0..num_initial_votes as u64 {
|
||||||
|
vote_state.process_next_vote_slot(next_vote_slot, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut vote_account_data: Vec<u8> = vec![0; VoteState::size_of()];
|
||||||
|
let versioned = VoteStateVersions::new_current(vote_state);
|
||||||
|
VoteState::serialize(&versioned, &mut vote_account_data).unwrap();
|
||||||
|
|
||||||
|
Account {
|
||||||
|
lamports: 1,
|
||||||
|
data: vote_account_data,
|
||||||
|
owner: solana_vote_program::id(),
|
||||||
|
executable: false,
|
||||||
|
rent_epoch: 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let slot_hashes_account = create_account_for_test(&slot_hashes);
|
||||||
|
let clock_account = create_account_for_test(&clock);
|
||||||
|
let authority_account = Account::default();
|
||||||
|
|
||||||
|
let mut sysvar_cache = SysvarCache::default();
|
||||||
|
sysvar_cache.set_clock(clock);
|
||||||
|
sysvar_cache.set_slot_hashes(slot_hashes);
|
||||||
|
|
||||||
|
let mut feature_set = FeatureSet::all_enabled();
|
||||||
|
if let Some(feature) = feature {
|
||||||
|
feature_set.activate(&feature, 0);
|
||||||
|
}
|
||||||
|
let feature_set = Arc::new(feature_set);
|
||||||
|
|
||||||
|
let vote_ix_data = bincode::serialize(&VoteInstruction::Vote(Vote::new(
|
||||||
|
(num_initial_votes as u64..).take(num_vote_slots).collect(),
|
||||||
|
last_vote_hash,
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let instruction = Instruction {
|
||||||
|
program_id: solana_vote_program::id(),
|
||||||
|
data: vote_ix_data,
|
||||||
|
accounts: vec![
|
||||||
|
AccountMeta::new(vote_pubkey, false),
|
||||||
|
AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
|
||||||
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
|
AccountMeta::new_readonly(authority_pubkey, true),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
let program_indices = vec![4];
|
||||||
|
let instruction_accounts = instruction
|
||||||
|
.accounts
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index_in_transaction, account_meta)| InstructionAccount {
|
||||||
|
index_in_transaction,
|
||||||
|
index_in_caller: index_in_transaction,
|
||||||
|
is_signer: account_meta.is_signer,
|
||||||
|
is_writable: account_meta.is_writable,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
bencher.iter(|| {
|
||||||
|
let mut transaction_context = TransactionContext::new(
|
||||||
|
vec![
|
||||||
|
(vote_pubkey, AccountSharedData::from(vote_account.clone())),
|
||||||
|
(
|
||||||
|
sysvar::slot_hashes::id(),
|
||||||
|
AccountSharedData::from(slot_hashes_account.clone()),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
sysvar::clock::id(),
|
||||||
|
AccountSharedData::from(clock_account.clone()),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
authority_pubkey,
|
||||||
|
AccountSharedData::from(authority_account.clone()),
|
||||||
|
),
|
||||||
|
(solana_vote_program::id(), AccountSharedData::default()),
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut invoke_context = InvokeContext::new_mock_with_sysvars_and_features(
|
||||||
|
&mut transaction_context,
|
||||||
|
&sysvar_cache,
|
||||||
|
feature_set.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
invoke_context
|
||||||
|
.push(&instruction_accounts, &program_indices, &[])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let first_instruction_account = 1;
|
||||||
|
assert_eq!(
|
||||||
|
solana_vote_program::vote_instruction::process_instruction(
|
||||||
|
first_instruction_account,
|
||||||
|
&instruction.data,
|
||||||
|
&mut invoke_context
|
||||||
|
),
|
||||||
|
Ok(())
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_process_vote_instruction(bencher: &mut Bencher) {
|
||||||
|
do_bench(bencher, None);
|
||||||
|
}
|
@ -17,10 +17,6 @@ use {
|
|||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
transaction::Transaction,
|
transaction::Transaction,
|
||||||
},
|
},
|
||||||
solana_vote_program::{
|
|
||||||
vote_instruction,
|
|
||||||
vote_state::{Vote, VoteInit},
|
|
||||||
},
|
|
||||||
std::{sync::Arc, thread::sleep, time::Duration},
|
std::{sync::Arc, thread::sleep, time::Duration},
|
||||||
test::Bencher,
|
test::Bencher,
|
||||||
};
|
};
|
||||||
@ -66,52 +62,6 @@ pub fn create_builtin_transactions(
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_vote_transactions(
|
|
||||||
bank_client: &BankClient,
|
|
||||||
mint_keypair: &Keypair,
|
|
||||||
) -> Vec<Transaction> {
|
|
||||||
let blockhash = bank_client.get_latest_blockhash().unwrap();
|
|
||||||
(0..4096)
|
|
||||||
.map(|_| {
|
|
||||||
// Seed the signer account
|
|
||||||
let payer_keypair = Keypair::new();
|
|
||||||
bank_client
|
|
||||||
.transfer_and_confirm(27_000_000, mint_keypair, &payer_keypair.pubkey())
|
|
||||||
.unwrap_or_else(|_| panic!("{}:{}", line!(), file!()));
|
|
||||||
|
|
||||||
// Setup vote
|
|
||||||
let vote_keypair = Keypair::new();
|
|
||||||
let instructions = vote_instruction::create_account(
|
|
||||||
&payer_keypair.pubkey(),
|
|
||||||
&vote_keypair.pubkey(),
|
|
||||||
&VoteInit {
|
|
||||||
node_pubkey: payer_keypair.pubkey(),
|
|
||||||
authorized_voter: payer_keypair.pubkey(),
|
|
||||||
authorized_withdrawer: payer_keypair.pubkey(),
|
|
||||||
commission: 100u8,
|
|
||||||
},
|
|
||||||
26_858_640,
|
|
||||||
);
|
|
||||||
let message = Message::new(&instructions, Some(&payer_keypair.pubkey()));
|
|
||||||
bank_client
|
|
||||||
.send_and_confirm_message(&[&payer_keypair, &vote_keypair], message)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let vote_ix = vote_instruction::vote(
|
|
||||||
&vote_keypair.pubkey(),
|
|
||||||
&payer_keypair.pubkey(),
|
|
||||||
Vote {
|
|
||||||
slots: vec![0],
|
|
||||||
hash: blockhash,
|
|
||||||
timestamp: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
let message = Message::new(&[vote_ix], Some(&payer_keypair.pubkey()));
|
|
||||||
Transaction::new(&[&payer_keypair], message, blockhash)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_native_loader_transactions(
|
pub fn create_native_loader_transactions(
|
||||||
bank_client: &BankClient,
|
bank_client: &BankClient,
|
||||||
mint_keypair: &Keypair,
|
mint_keypair: &Keypair,
|
||||||
@ -221,12 +171,6 @@ fn bench_bank_sync_process_native_loader_transactions(bencher: &mut Bencher) {
|
|||||||
do_bench_transactions(bencher, &sync_bencher, &create_native_loader_transactions);
|
do_bench_transactions(bencher, &sync_bencher, &create_native_loader_transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
|
||||||
#[ignore]
|
|
||||||
fn bench_bank_sync_process_vote_transactions(bencher: &mut Bencher) {
|
|
||||||
do_bench_transactions(bencher, &sync_bencher, &create_vote_transactions);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn bench_bank_async_process_builtin_transactions(bencher: &mut Bencher) {
|
fn bench_bank_async_process_builtin_transactions(bencher: &mut Bencher) {
|
||||||
|
Reference in New Issue
Block a user