2022-01-14 01:10:17 -08:00
|
|
|
#![feature(test)]
|
|
|
|
|
|
|
|
extern crate test;
|
|
|
|
|
|
|
|
use {
|
2022-01-31 08:53:50 -08:00
|
|
|
solana_program_runtime::invoke_context::InvokeContext,
|
2022-01-14 01:10:17 -08:00
|
|
|
solana_sdk::{
|
|
|
|
account::{create_account_for_test, Account, AccountSharedData},
|
|
|
|
clock::{Clock, Slot},
|
|
|
|
hash::Hash,
|
|
|
|
pubkey::Pubkey,
|
|
|
|
slot_hashes::{SlotHashes, MAX_ENTRIES},
|
|
|
|
sysvar,
|
2022-02-25 08:22:54 -08:00
|
|
|
transaction_context::{InstructionAccount, TransactionAccount, TransactionContext},
|
2022-01-14 01:10:17 -08:00
|
|
|
},
|
|
|
|
solana_vote_program::{
|
|
|
|
vote_instruction::VoteInstruction,
|
2022-01-25 10:47:31 -08:00
|
|
|
vote_state::{
|
2022-02-25 08:22:54 -08:00
|
|
|
Vote, VoteInit, VoteState, VoteStateUpdate, VoteStateVersions, MAX_LOCKOUT_HISTORY,
|
2022-01-25 10:47:31 -08:00
|
|
|
},
|
2022-01-14 01:10:17 -08:00
|
|
|
},
|
|
|
|
test::Bencher,
|
|
|
|
};
|
|
|
|
|
2022-02-25 08:22:54 -08:00
|
|
|
fn create_accounts() -> (
|
|
|
|
Slot,
|
|
|
|
SlotHashes,
|
|
|
|
Vec<TransactionAccount>,
|
|
|
|
Vec<InstructionAccount>,
|
|
|
|
) {
|
|
|
|
// vote accounts are usually almost full of votes in normal operation
|
|
|
|
let num_initial_votes = MAX_LOCKOUT_HISTORY as Slot;
|
2022-01-14 01:10:17 -08:00
|
|
|
|
|
|
|
let clock = Clock::default();
|
|
|
|
let mut slot_hashes = SlotHashes::new(&[]);
|
|
|
|
for i in 0..MAX_ENTRIES {
|
|
|
|
// slot hashes is full in normal operation
|
2022-01-25 10:47:31 -08:00
|
|
|
slot_hashes.add(i as Slot, Hash::new_unique());
|
2022-01-14 01:10:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
);
|
|
|
|
|
2022-01-25 10:47:31 -08:00
|
|
|
for next_vote_slot in 0..num_initial_votes {
|
2022-01-14 01:10:17 -08:00
|
|
|
vote_state.process_next_vote_slot(next_vote_slot, 0);
|
|
|
|
}
|
|
|
|
let mut vote_account_data: Vec<u8> = vec![0; VoteState::size_of()];
|
2022-02-25 08:22:54 -08:00
|
|
|
let versioned = VoteStateVersions::new_current(vote_state);
|
2022-01-14 01:10:17 -08:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
};
|
2022-01-25 10:47:31 -08:00
|
|
|
|
2022-02-25 08:22:54 -08:00
|
|
|
let transaction_accounts = vec![
|
|
|
|
(solana_vote_program::id(), AccountSharedData::default()),
|
|
|
|
(vote_pubkey, AccountSharedData::from(vote_account)),
|
|
|
|
(
|
|
|
|
sysvar::slot_hashes::id(),
|
|
|
|
AccountSharedData::from(create_account_for_test(&slot_hashes)),
|
|
|
|
),
|
|
|
|
(
|
|
|
|
sysvar::clock::id(),
|
|
|
|
AccountSharedData::from(create_account_for_test(&clock)),
|
|
|
|
),
|
|
|
|
(authority_pubkey, AccountSharedData::default()),
|
|
|
|
];
|
|
|
|
let mut instruction_accounts = (0..4)
|
|
|
|
.map(|index| InstructionAccount {
|
|
|
|
index_in_transaction: 1usize.saturating_add(index),
|
|
|
|
index_in_caller: 1usize.saturating_add(index),
|
|
|
|
is_signer: false,
|
|
|
|
is_writable: false,
|
|
|
|
})
|
|
|
|
.collect::<Vec<InstructionAccount>>();
|
|
|
|
instruction_accounts[0].is_writable = true;
|
|
|
|
instruction_accounts[3].is_signer = true;
|
2022-01-25 10:47:31 -08:00
|
|
|
|
2022-02-25 08:22:54 -08:00
|
|
|
(
|
|
|
|
num_initial_votes,
|
2022-01-25 10:47:31 -08:00
|
|
|
slot_hashes,
|
2022-02-25 08:22:54 -08:00
|
|
|
transaction_accounts,
|
|
|
|
instruction_accounts,
|
|
|
|
)
|
|
|
|
}
|
2022-01-14 01:10:17 -08:00
|
|
|
|
2022-02-25 08:22:54 -08:00
|
|
|
fn bench_process_vote_instruction(
|
|
|
|
bencher: &mut Bencher,
|
|
|
|
transaction_accounts: Vec<TransactionAccount>,
|
|
|
|
instruction_accounts: Vec<InstructionAccount>,
|
|
|
|
instruction_data: Vec<u8>,
|
|
|
|
) {
|
2022-01-14 01:10:17 -08:00
|
|
|
bencher.iter(|| {
|
2022-02-25 08:22:54 -08:00
|
|
|
let mut transaction_context = TransactionContext::new(transaction_accounts.clone(), 1, 1);
|
2022-01-31 08:53:50 -08:00
|
|
|
let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]);
|
2022-01-14 01:10:17 -08:00
|
|
|
invoke_context
|
2022-02-25 08:22:54 -08:00
|
|
|
.push(&instruction_accounts, &[0], &instruction_data)
|
2022-01-14 01:10:17 -08:00
|
|
|
.unwrap();
|
2022-04-01 06:48:05 -07:00
|
|
|
assert!(
|
|
|
|
solana_vote_program::vote_processor::process_instruction(1, &mut invoke_context)
|
|
|
|
.is_ok()
|
|
|
|
);
|
2022-02-25 08:22:54 -08:00
|
|
|
invoke_context.pop().unwrap();
|
2022-01-25 10:47:31 -08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-02-25 08:22:54 -08:00
|
|
|
#[bench]
|
|
|
|
fn bench_process_vote(bencher: &mut Bencher) {
|
|
|
|
let (num_initial_votes, slot_hashes, transaction_accounts, instruction_accounts) =
|
|
|
|
create_accounts();
|
2022-01-25 10:47:31 -08:00
|
|
|
|
|
|
|
let num_vote_slots = 4;
|
|
|
|
let last_vote_slot = num_initial_votes
|
|
|
|
.saturating_add(num_vote_slots)
|
|
|
|
.saturating_sub(1);
|
|
|
|
let last_vote_hash = slot_hashes
|
|
|
|
.iter()
|
|
|
|
.find(|(slot, _hash)| *slot == last_vote_slot)
|
|
|
|
.unwrap()
|
|
|
|
.1;
|
|
|
|
let vote = Vote::new(
|
|
|
|
(num_initial_votes..=last_vote_slot).collect(),
|
|
|
|
last_vote_hash,
|
|
|
|
);
|
2022-02-25 08:22:54 -08:00
|
|
|
let instruction_data = bincode::serialize(&VoteInstruction::Vote(vote)).unwrap();
|
2022-01-25 10:47:31 -08:00
|
|
|
|
2022-02-25 08:22:54 -08:00
|
|
|
bench_process_vote_instruction(
|
|
|
|
bencher,
|
|
|
|
transaction_accounts,
|
|
|
|
instruction_accounts,
|
|
|
|
instruction_data,
|
|
|
|
);
|
2022-01-25 10:47:31 -08:00
|
|
|
}
|
|
|
|
|
2022-02-25 08:22:54 -08:00
|
|
|
#[bench]
|
|
|
|
fn bench_process_vote_state_update(bencher: &mut Bencher) {
|
|
|
|
let (num_initial_votes, slot_hashes, transaction_accounts, instruction_accounts) =
|
|
|
|
create_accounts();
|
2022-01-25 10:47:31 -08:00
|
|
|
|
|
|
|
let num_vote_slots = MAX_LOCKOUT_HISTORY as Slot;
|
|
|
|
let last_vote_slot = num_initial_votes
|
|
|
|
.saturating_add(num_vote_slots)
|
|
|
|
.saturating_sub(1);
|
|
|
|
let last_vote_hash = slot_hashes
|
|
|
|
.iter()
|
|
|
|
.find(|(slot, _hash)| *slot == last_vote_slot)
|
|
|
|
.unwrap()
|
|
|
|
.1;
|
|
|
|
let slots_and_lockouts: Vec<(Slot, u32)> =
|
|
|
|
((num_initial_votes.saturating_add(1)..=last_vote_slot).zip((1u32..=31).rev())).collect();
|
|
|
|
let mut vote_state_update = VoteStateUpdate::from(slots_and_lockouts);
|
|
|
|
vote_state_update.root = Some(num_initial_votes);
|
|
|
|
vote_state_update.hash = last_vote_hash;
|
2022-02-25 08:22:54 -08:00
|
|
|
let instruction_data =
|
|
|
|
bincode::serialize(&VoteInstruction::UpdateVoteState(vote_state_update)).unwrap();
|
|
|
|
|
|
|
|
bench_process_vote_instruction(
|
|
|
|
bencher,
|
|
|
|
transaction_accounts,
|
|
|
|
instruction_accounts,
|
|
|
|
instruction_data,
|
|
|
|
);
|
2022-01-14 01:10:17 -08:00
|
|
|
}
|