diff --git a/Cargo.lock b/Cargo.lock index 4eb9eccbee44fd..465a956834a279 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2980,6 +2980,12 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iai" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71a816c97c42258aa5834d07590b718b4c9a598944cd39a52dc25b351185d678" + [[package]] name = "iana-time-zone" version = "0.1.46" @@ -8305,6 +8311,7 @@ dependencies = [ "bincode", "criterion", "criterion-perf-events", + "iai", "log", "perfcnt", "proptest", diff --git a/programs/stake/Cargo.toml b/programs/stake/Cargo.toml index aedf97f6f3a91c..8027cae60cba05 100644 --- a/programs/stake/Cargo.toml +++ b/programs/stake/Cargo.toml @@ -24,6 +24,7 @@ solana-vote-program = { workspace = true } assert_matches = { workspace = true } criterion = { workspace = true } criterion-perf-events = "0.4.0" +iai = "0.1" perfcnt = "0.8.0" proptest = { workspace = true } solana-compute-budget = { workspace = true } @@ -41,5 +42,10 @@ targets = ["x86_64-unknown-linux-gnu"] name = "stake" harness = false + +[[bench]] +name = "stake_iai" +harness = false + [lints] workspace = true diff --git a/programs/stake/benches/stake_iai.rs b/programs/stake/benches/stake_iai.rs new file mode 100644 index 00000000000000..64fd10f960b509 --- /dev/null +++ b/programs/stake/benches/stake_iai.rs @@ -0,0 +1,770 @@ +use { + bincode::serialize, + iai::{black_box, main}, + perfcnt::linux::{HardwareEventType as Hardware, PerfCounterBuilderLinux as Builder}, + solana_feature_set::FeatureSet, + solana_program_runtime::invoke_context::mock_process_instruction, + solana_sdk::{ + account::{create_account_shared_data_for_test, AccountSharedData, WritableAccount}, + clock::{Clock, Epoch}, + instruction::AccountMeta, + pubkey::Pubkey, + stake::{ + instruction::{ + self, AuthorizeCheckedWithSeedArgs, AuthorizeWithSeedArgs, LockupArgs, + LockupCheckedArgs, StakeInstruction, + }, + stake_flags::StakeFlags, + state::{Authorized, Lockup, StakeAuthorize, StakeStateV2}, + }, + stake_history::StakeHistory, + sysvar::{ + clock, + rent::{self, Rent}, + stake_history, + }, + }, + solana_stake_program::{ + stake_instruction, + stake_state::{Delegation, Meta, Stake}, + }, + solana_vote_program::vote_state::{self, VoteState, VoteStateVersions}, + std::sync::Arc, +}; + +struct TestSetup { + feature_set: Arc, + stake_address: Pubkey, + stake_account: AccountSharedData, + transaction_accounts: Vec<(Pubkey, AccountSharedData)>, + instruction_accounts: Vec, + + instruction_data: Vec, +} + +impl TestSetup { + fn new() -> Self { + let stake_account = AccountSharedData::new( + u64::MAX / 2, + StakeStateV2::size_of(), + &solana_stake_program::id(), + ); + let stake_address = solana_sdk::pubkey::Pubkey::new_unique(); + Self { + feature_set: Arc::new(FeatureSet::all_enabled()), + stake_address, + stake_account: stake_account.clone(), + transaction_accounts: vec![(stake_address, stake_account)], + instruction_accounts: vec![AccountMeta { + pubkey: stake_address, + is_signer: false, + is_writable: true, + }], + instruction_data: vec![], + } + } + + fn add_account(&mut self, id: Pubkey, account: AccountSharedData) { + self.transaction_accounts.push((id, account)); + self.instruction_accounts.push(AccountMeta { + pubkey: id, + is_signer: false, + is_writable: true, + }); + } + + fn add_account_signer(&mut self, id: Pubkey, account: AccountSharedData) { + self.transaction_accounts.push((id, account)); + self.instruction_accounts.push(AccountMeta { + pubkey: id, + is_signer: true, + is_writable: true, + }); + } + + fn initialize_stake_account(&mut self) { + let initialized_stake_account = AccountSharedData::new_data_with_space( + u64::MAX / 2, + &StakeStateV2::Initialized(Meta::auto(&self.stake_address)), + StakeStateV2::size_of(), + &solana_stake_program::id(), + ) + .unwrap(); + + self.stake_account = initialized_stake_account.clone(); + self.transaction_accounts[0] = (self.stake_address, initialized_stake_account); + // also make stake address a signer + self.instruction_accounts[0] = AccountMeta { + pubkey: self.stake_address, + is_signer: true, + is_writable: true, + }; + } + + fn initialize_stake_account_with_seed(&mut self, seed: &str, authorized_owner: &Pubkey) { + self.stake_address = + Pubkey::create_with_seed(authorized_owner, seed, authorized_owner).unwrap(); + self.initialize_stake_account(); + } + + // config withdraw authority, returns authorized withdrwer's pubkey + fn config_withdraw_authority(&mut self) -> Pubkey { + let withdraw_authority_address = Pubkey::new_unique(); + + let instruction = instruction::authorize( + &self.stake_address, + &self.stake_address, + &withdraw_authority_address, + StakeAuthorize::Withdrawer, + None, + ); + + let transaction_accounts = vec![ + (self.stake_address, self.stake_account.clone()), + ( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ), + (withdraw_authority_address, AccountSharedData::default()), + ]; + + let accounts = mock_process_instruction( + &solana_stake_program::id(), + Vec::new(), + &instruction.data, + transaction_accounts, + instruction.accounts.clone(), + Ok(()), + stake_instruction::Entrypoint::vm, + |invoke_context| { + invoke_context.mock_set_feature_set(Arc::clone(&self.feature_set)); + }, + |_invoke_context| {}, + ); + // update stake account + self.transaction_accounts[0] = (self.stake_address, accounts[0].clone()); + + withdraw_authority_address + } + + fn delegate_stake(&mut self) { + let vote_address = Pubkey::new_unique(); + + let instruction = + instruction::delegate_stake(&self.stake_address, &self.stake_address, &vote_address); + + let transaction_accounts = vec![ + (self.stake_address, self.stake_account.clone()), + ( + vote_address, + vote_state::create_account(&vote_address, &Pubkey::new_unique(), 0, 100), + ), + ( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ), + ( + stake_history::id(), + create_account_shared_data_for_test(&StakeHistory::default()), + ), + ]; + + let accounts = mock_process_instruction( + &solana_stake_program::id(), + Vec::new(), + &instruction.data, + transaction_accounts, + instruction.accounts.clone(), + Ok(()), + stake_instruction::Entrypoint::vm, + |invoke_context| { + invoke_context.mock_set_feature_set(Arc::clone(&self.feature_set)); + }, + |_invoke_context| {}, + ); + self.stake_account = accounts[0].clone(); + self.stake_account.set_lamports(u64::MAX - 100); // Hack: replenish stake account, but not to hit + // MAX. + // update stake account + self.transaction_accounts[0] = (self.stake_address, self.stake_account.clone()); + } + + fn run(&self) { + mock_process_instruction( + &solana_stake_program::id(), + Vec::new(), + &self.instruction_data, + self.transaction_accounts.clone(), + self.instruction_accounts.clone(), + Ok(()), //expected_result, + stake_instruction::Entrypoint::vm, + |invoke_context| { + invoke_context.mock_set_feature_set(Arc::clone(&self.feature_set)); + }, + |_invoke_context| {}, + ); + } +} + +fn bench_setup_initialize() -> TestSetup { + let mut test_setup = TestSetup::new(); + test_setup.add_account( + solana_sdk::sysvar::rent::id(), + create_account_shared_data_for_test(&Rent::default()), + ); + + test_setup.instruction_data = serialize(&StakeInstruction::Initialize( + Authorized::auto(&test_setup.stake_address), + Lockup::default(), + )) + .unwrap(); + + test_setup +} + +fn bench_initialize() { + bench_setup_initialize().run(); +} + +iai::main!(bench_setup_initialize, bench_initialize); + +/* +fn bench_initialize_checked(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.add_account( + solana_sdk::sysvar::rent::id(), + create_account_shared_data_for_test(&Rent::default()), + ); + // add staker account + test_setup.add_account(Pubkey::new_unique(), AccountSharedData::default()); + // add withdrawer account + test_setup.add_account_signer(Pubkey::new_unique(), AccountSharedData::default()); + + let instruction_data = serialize(&StakeInstruction::InitializeChecked).unwrap(); + + c.bench_function("initialize_checked", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_staker(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + let authority_address = Pubkey::new_unique(); + test_setup.add_account(authority_address, AccountSharedData::default()); + + let instruction_data = serialize(&StakeInstruction::Authorize( + authority_address, + StakeAuthorize::Staker, + )) + .unwrap(); + + c.bench_function("authorize_staker", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_withdrawer(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + // add authority address + let authority_address = Pubkey::new_unique(); + test_setup.add_account(authority_address, AccountSharedData::default()); + + let instruction_data = serialize(&StakeInstruction::Authorize( + authority_address, + StakeAuthorize::Withdrawer, + )) + .unwrap(); + + c.bench_function("authorize_withdrawer", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_staker_with_seed(c: &mut Criterion) { + let seed = "test test"; + let authorize_address = Pubkey::new_unique(); + + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account_with_seed(seed, &authorize_address); + test_setup.add_account_signer(authorize_address, AccountSharedData::default()); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + + let instruction_data = serialize(&StakeInstruction::AuthorizeWithSeed( + AuthorizeWithSeedArgs { + new_authorized_pubkey: Pubkey::new_unique(), + stake_authorize: StakeAuthorize::Staker, + authority_seed: seed.to_string(), + authority_owner: authorize_address, + }, + )) + .unwrap(); + + c.bench_function("authorize_staker_with_seed", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_withdrawer_with_seed(c: &mut Criterion) { + let seed = "test test"; + let authorize_address = Pubkey::new_unique(); + + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account_with_seed(seed, &authorize_address); + test_setup.add_account_signer(authorize_address, AccountSharedData::default()); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + + let instruction_data = serialize(&StakeInstruction::AuthorizeWithSeed( + AuthorizeWithSeedArgs { + new_authorized_pubkey: Pubkey::new_unique(), + stake_authorize: StakeAuthorize::Withdrawer, + authority_seed: seed.to_string(), + authority_owner: authorize_address, + }, + )) + .unwrap(); + + c.bench_function("authorize_withdrawer_with_seed", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_staker_checked(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + // add authorized address as signer + test_setup.add_account_signer(Pubkey::new_unique(), AccountSharedData::default()); + // add staker account as signer + test_setup.add_account_signer(Pubkey::new_unique(), AccountSharedData::default()); + + let instruction_data = + serialize(&StakeInstruction::AuthorizeChecked(StakeAuthorize::Staker)).unwrap(); + + c.bench_function("authorize_staker_checked", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_withdrawer_checked(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + // add authorized address as signer + test_setup.add_account_signer(Pubkey::new_unique(), AccountSharedData::default()); + // add staker account as signer + test_setup.add_account_signer(Pubkey::new_unique(), AccountSharedData::default()); + + let instruction_data = serialize(&StakeInstruction::AuthorizeChecked( + StakeAuthorize::Withdrawer, + )) + .unwrap(); + + c.bench_function("authorize_withdrawer_checked", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_staker_checked_with_seed(c: &mut Criterion) { + let seed = "test test"; + let authorize_address = Pubkey::new_unique(); + + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account_with_seed(seed, &authorize_address); + // add authorized address as signer + test_setup.add_account_signer(authorize_address, AccountSharedData::default()); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + // add new authorize account as signer + test_setup.add_account_signer(Pubkey::new_unique(), AccountSharedData::default()); + + let instruction_data = serialize(&StakeInstruction::AuthorizeCheckedWithSeed( + AuthorizeCheckedWithSeedArgs { + stake_authorize: StakeAuthorize::Staker, + authority_seed: seed.to_string(), + authority_owner: authorize_address, + }, + )) + .unwrap(); + + c.bench_function("authorize_staker_checked_with_seed", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_authorize_withdrawer_checked_with_seed(c: &mut Criterion) { + let seed = "test test"; + let authorize_address = Pubkey::new_unique(); + + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account_with_seed(seed, &authorize_address); + // add authorized address as signer + test_setup.add_account_signer(authorize_address, AccountSharedData::default()); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + // add new authorize account as signer + test_setup.add_account_signer(Pubkey::new_unique(), AccountSharedData::default()); + + let instruction_data = serialize(&StakeInstruction::AuthorizeCheckedWithSeed( + AuthorizeCheckedWithSeedArgs { + stake_authorize: StakeAuthorize::Withdrawer, + authority_seed: seed.to_string(), + authority_owner: authorize_address, + }, + )) + .unwrap(); + + c.bench_function("authorize_withdrawer_checked_with_seed", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_set_lockup(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + + let instruction_data = serialize(&StakeInstruction::SetLockup(LockupArgs { + unix_timestamp: None, + epoch: Some(1), + custodian: None, + })) + .unwrap(); + + c.bench_function("set_lockup", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_set_lockup_checked(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + + let instruction_data = serialize(&StakeInstruction::SetLockupChecked(LockupCheckedArgs { + unix_timestamp: None, + epoch: Some(1), + })) + .unwrap(); + + c.bench_function("set_lockup_checked", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_withdraw(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + let withdraw_authority_address = test_setup.config_withdraw_authority(); + + // withdraw to pubkey + test_setup.add_account(Pubkey::new_unique(), AccountSharedData::default()); + // clock + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + // stake history + test_setup.add_account( + stake_history::id(), + create_account_shared_data_for_test(&StakeHistory::default()), + ); + // withdrawer pubkey + test_setup.add_account_signer(withdraw_authority_address, AccountSharedData::default()); + + let instruction_data = serialize(&StakeInstruction::Withdraw(1)).unwrap(); + + c.bench_function("withdraw", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_delegate_stake(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + + let vote_address = Pubkey::new_unique(); + let vote_account = vote_state::create_account(&vote_address, &Pubkey::new_unique(), 0, 100); + test_setup.add_account(vote_address, vote_account); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + test_setup.add_account( + stake_history::id(), + create_account_shared_data_for_test(&StakeHistory::default()), + ); + // dummy config account to pass check + test_setup.add_account(Pubkey::new_unique(), AccountSharedData::default()); + let instruction_data = serialize(&StakeInstruction::DelegateStake).unwrap(); + + c.bench_function("delegate_stake", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_deactivate(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.delegate_stake(); + + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + + let instruction_data = serialize(&StakeInstruction::Deactivate).unwrap(); + + c.bench_function("deactivate", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_split(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + + let split_to_address = Pubkey::new_unique(); + let split_to_account = AccountSharedData::new_data_with_space( + 0, + &StakeStateV2::Uninitialized, + StakeStateV2::size_of(), + &solana_stake_program::id(), + ) + .unwrap(); + + test_setup.add_account(split_to_address, split_to_account); + test_setup.add_account( + rent::id(), + create_account_shared_data_for_test(&Rent { + lamports_per_byte_year: 0, + ..Rent::default() + }), + ); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + test_setup.add_account( + stake_history::id(), + create_account_shared_data_for_test(&StakeHistory::default()), + ); + + let instruction_data = serialize(&StakeInstruction::Split(1)).unwrap(); + + c.bench_function("split", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_merge(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + + let merge_from_address = Pubkey::new_unique(); + // merge from account has same authority as stake account for simplicity, + // it also has lamports 0 to avoid `ArithmeticOverflow` to current stake account + let merge_from_account = AccountSharedData::new_data_with_space( + 1, + &StakeStateV2::Initialized(Meta::auto(&test_setup.stake_address)), + StakeStateV2::size_of(), + &solana_stake_program::id(), + ) + .unwrap(); + + test_setup.add_account(merge_from_address, merge_from_account); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock::default()), + ); + test_setup.add_account( + stake_history::id(), + create_account_shared_data_for_test(&StakeHistory::default()), + ); + + let instruction_data = serialize(&StakeInstruction::Merge).unwrap(); + + c.bench_function("merge", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_get_minimum_delegation(c: &mut Criterion) { + let test_setup = TestSetup::new(); + let instruction_data = serialize(&StakeInstruction::GetMinimumDelegation).unwrap(); + + c.bench_function("get_minimum_delegation", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_deactivate_delinquent(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + + // reference vote account has been consistently voting + let mut vote_state = VoteState::default(); + for epoch in 0..=solana_sdk::stake::MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION { + vote_state.increment_credits(epoch as Epoch, 1); + } + let reference_vote_address = Pubkey::new_unique(); + let reference_vote_account = AccountSharedData::new_data_with_space( + 1, + &VoteStateVersions::new_current(vote_state), + VoteState::size_of(), + &solana_vote_program::id(), + ) + .unwrap(); + + let vote_address = Pubkey::new_unique(); + let vote_account = vote_state::create_account(&vote_address, &Pubkey::new_unique(), 0, 100); + test_setup.stake_account = AccountSharedData::new_data_with_space( + 1, + &StakeStateV2::Stake( + Meta::default(), + Stake { + delegation: Delegation::new(&vote_address, 1, 1), + credits_observed: VoteState::default().credits(), + }, + StakeFlags::empty(), + ), + StakeStateV2::size_of(), + &solana_stake_program::id(), + ) + .unwrap(); + test_setup.transaction_accounts[0] = + (test_setup.stake_address, test_setup.stake_account.clone()); + + test_setup.add_account(vote_address, vote_account); + test_setup.add_account(reference_vote_address, reference_vote_account); + test_setup.add_account( + clock::id(), + create_account_shared_data_for_test(&Clock { + epoch: solana_sdk::stake::MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION as u64, + ..Clock::default() + }), + ); + + let instruction_data = serialize(&StakeInstruction::DeactivateDelinquent).unwrap(); + + c.bench_function("deactivate_delinquent", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_move_stake(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.delegate_stake(); + + let destination_stake_address = Pubkey::new_unique(); + let destination_stake_account = test_setup.transaction_accounts[0].1.clone(); + test_setup.add_account(destination_stake_address, destination_stake_account); + test_setup.add_account_signer(test_setup.stake_address, AccountSharedData::default()); + test_setup.add_account( + clock::id(), + // advance epoch to fully activate source account + create_account_shared_data_for_test(&Clock { + epoch: 1 as u64, + ..Clock::default() + }), + ); + test_setup.add_account( + stake_history::id(), + create_account_shared_data_for_test(&StakeHistory::default()), + ); + + let instruction_data = serialize(&StakeInstruction::MoveStake(1)).unwrap(); + + c.bench_function("move_stake", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +fn bench_move_lamports(c: &mut Criterion) { + let mut test_setup = TestSetup::new(); + test_setup.initialize_stake_account(); + test_setup.delegate_stake(); + + let destination_stake_address = Pubkey::new_unique(); + let destination_stake_account = test_setup.transaction_accounts[0].1.clone(); + test_setup.add_account(destination_stake_address, destination_stake_account); + test_setup.add_account_signer(test_setup.stake_address, AccountSharedData::default()); + test_setup.add_account( + clock::id(), + // advance epoch to fully activate source account + create_account_shared_data_for_test(&Clock { + epoch: 1 as u64, + ..Clock::default() + }), + ); + test_setup.add_account( + stake_history::id(), + create_account_shared_data_for_test(&StakeHistory::default()), + ); + + let instruction_data = serialize(&StakeInstruction::MoveLamports(1)).unwrap(); + + c.bench_function("move_lamports", |bencher| { + bencher.iter(|| test_setup.run(black_box(&instruction_data))) + }); +} + +criterion_group!( + name = stake_instructions_bench; + config = Criterion::default().with_measurement(Perf::new(Builder::from_hardware_event(Hardware::Instructions))); + targets = + bench_initialize, + bench_initialize_checked, + bench_authorize_staker, + bench_authorize_withdrawer, + bench_authorize_staker_with_seed, + bench_authorize_withdrawer_with_seed, + bench_authorize_staker_checked, + bench_authorize_withdrawer_checked, + bench_authorize_staker_checked_with_seed, + bench_authorize_withdrawer_checked_with_seed, + bench_set_lockup, + bench_set_lockup_checked, + bench_withdraw, + bench_delegate_stake, + bench_deactivate, + bench_split, + bench_merge, + bench_get_minimum_delegation, + bench_deactivate_delinquent, + bench_move_stake, + bench_move_lamports, +); +criterion_main!(stake_instructions_bench); +// */