From 1f05ac6955a9442ddf027b53f00bc0f3b170c08c Mon Sep 17 00:00:00 2001 From: HaoranYi Date: Fri, 4 Aug 2023 15:44:13 +0000 Subject: [PATCH] reviews --- program-test/tests/stake.rs | 31 +++++-- program-test/tests/test_utils.rs | 150 ------------------------------- program-test/tests/warp.rs | 52 ++++++++++- 3 files changed, 70 insertions(+), 163 deletions(-) delete mode 100644 program-test/tests/test_utils.rs diff --git a/program-test/tests/stake.rs b/program-test/tests/stake.rs index 6d19d7df02224f..371cce9d9181fe 100644 --- a/program-test/tests/stake.rs +++ b/program-test/tests/stake.rs @@ -1,15 +1,16 @@ #![allow(clippy::integer_arithmetic)] -mod test_utils; +mod setup; use { + setup::{setup_stake, setup_vote}, solana_program_test::ProgramTest, solana_sdk::{ + instruction::InstructionError, signature::{Keypair, Signer}, - stake::instruction as stake_instruction, - transaction::Transaction, + stake::{instruction as stake_instruction, instruction::StakeError}, + transaction::{Transaction, TransactionError}, }, - test_utils::{setup_stake, setup_vote, setup_vote_no_warp}, }; #[derive(PartialEq)] @@ -24,6 +25,7 @@ async fn test_stake_redelegation_pending_activation(merge_flag: PendingStakeActi let mut context = program_test.start_with_context().await; // 1. create first vote accounts + context.warp_to_slot(100).unwrap(); let vote_address = setup_vote(&mut context).await; // 1.1 advance to normal epoch @@ -58,10 +60,13 @@ async fn test_stake_redelegation_pending_activation(merge_flag: PendingStakeActi context.last_blockhash, ); let r = context.banks_client.process_transaction(transaction).await; - assert!(format!("{}", r.err().unwrap()).contains("insufficient funds for instruction")); + assert_eq!( + r.unwrap_err().unwrap(), + TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + ); // 3. create 2nd vote account - let vote_address2 = setup_vote_no_warp(&mut context).await; + let vote_address2 = setup_vote(&mut context).await; // 3.1 relegate 1st stake account to 2nd stake account. let stake_keypair2 = Keypair::new(); @@ -132,8 +137,13 @@ async fn test_stake_redelegation_pending_activation(merge_flag: PendingStakeActi ); let r = context.banks_client.process_transaction(transaction).await; assert_eq!( - format!("{}", r.err().unwrap()), - "transport transaction error: Error processing Instruction 0: custom program error: 0xf" + r.unwrap_err().unwrap(), + TransactionError::InstructionError( + 0, + InstructionError::Custom( + StakeError::RedelegatedStakeMustFullyActivateBeforeDeactivationIsPermitted as u32 + ) + ) ); // 3.4 withdraw from 2nd stake account should also fail because of pending stake activation. @@ -150,7 +160,10 @@ async fn test_stake_redelegation_pending_activation(merge_flag: PendingStakeActi context.last_blockhash, ); let r = context.banks_client.process_transaction(transaction).await; - assert!(format!("{}", r.err().unwrap()).contains("insufficient funds for instruction")); + assert_eq!( + r.unwrap_err().unwrap(), + TransactionError::InstructionError(0, InstructionError::InsufficientFunds) + ); // 4. advance to new epoch so that the 2nd stake account is fully activated current_slot += slots_per_epoch; diff --git a/program-test/tests/test_utils.rs b/program-test/tests/test_utils.rs deleted file mode 100644 index eee3dc75d404a1..00000000000000 --- a/program-test/tests/test_utils.rs +++ /dev/null @@ -1,150 +0,0 @@ -#![allow(clippy::integer_arithmetic)] -use { - bincode::deserialize, - solana_banks_client::BanksClient, - solana_program_test::ProgramTestContext, - solana_sdk::{ - account_info::{next_account_info, AccountInfo}, - clock::Clock, - entrypoint::ProgramResult, - program_error::ProgramError, - pubkey::Pubkey, - rent::Rent, - signature::{Keypair, Signer}, - stake::{ - instruction as stake_instruction, - state::{Authorized, Lockup, StakeState}, - }, - system_instruction, system_program, - sysvar::Sysvar, - transaction::Transaction, - }, - solana_vote_program::{ - vote_instruction, - vote_state::{self, VoteInit, VoteState}, - }, - std::convert::TryInto, -}; - -// Use a big number to be sure that we get the right error -#[allow(dead_code)] -pub const WRONG_SLOT_ERROR: u32 = 123456; - -pub async fn setup_stake( - context: &mut ProgramTestContext, - user: &Keypair, - vote_address: &Pubkey, - stake_lamports: u64, -) -> Pubkey { - let stake_keypair = Keypair::new(); - let transaction = Transaction::new_signed_with_payer( - &stake_instruction::create_account_and_delegate_stake( - &context.payer.pubkey(), - &stake_keypair.pubkey(), - vote_address, - &Authorized::auto(&user.pubkey()), - &Lockup::default(), - stake_lamports, - ), - Some(&context.payer.pubkey()), - &vec![&context.payer, &stake_keypair, user], - context.last_blockhash, - ); - context - .banks_client - .process_transaction(transaction) - .await - .unwrap(); - stake_keypair.pubkey() -} - -pub async fn setup_vote(context: &mut ProgramTestContext) -> Pubkey { - _setup_vote(context, true).await -} - -#[allow(dead_code)] -pub async fn setup_vote_no_warp(context: &mut ProgramTestContext) -> Pubkey { - _setup_vote(context, false).await -} - -async fn _setup_vote(context: &mut ProgramTestContext, do_warp: bool) -> Pubkey { - if do_warp { - // warp once to make sure stake config doesn't get rent-collected - context.warp_to_slot(100).unwrap(); - } - let mut instructions = vec![]; - let validator_keypair = Keypair::new(); - instructions.push(system_instruction::create_account( - &context.payer.pubkey(), - &validator_keypair.pubkey(), - Rent::default().minimum_balance(0), - 0, - &system_program::id(), - )); - let vote_lamports = Rent::default().minimum_balance(VoteState::size_of()); - let vote_keypair = Keypair::new(); - let user_keypair = Keypair::new(); - instructions.append(&mut vote_instruction::create_account_with_config( - &context.payer.pubkey(), - &vote_keypair.pubkey(), - &VoteInit { - node_pubkey: validator_keypair.pubkey(), - authorized_voter: user_keypair.pubkey(), - ..VoteInit::default() - }, - vote_lamports, - vote_instruction::CreateVoteAccountConfig { - space: vote_state::VoteStateVersions::vote_state_size_of(true) as u64, - ..vote_instruction::CreateVoteAccountConfig::default() - }, - )); - - let transaction = Transaction::new_signed_with_payer( - &instructions, - Some(&context.payer.pubkey()), - &vec![&context.payer, &validator_keypair, &vote_keypair], - context.last_blockhash, - ); - context - .banks_client - .process_transaction(transaction) - .await - .unwrap(); - - vote_keypair.pubkey() -} - -#[allow(dead_code)] -pub fn process_instruction( - _program_id: &Pubkey, - accounts: &[AccountInfo], - input: &[u8], -) -> ProgramResult { - let account_info_iter = &mut accounts.iter(); - let clock_info = next_account_info(account_info_iter)?; - let clock = &Clock::from_account_info(clock_info)?; - let expected_slot = u64::from_le_bytes(input.try_into().unwrap()); - if clock.slot == expected_slot { - Ok(()) - } else { - Err(ProgramError::Custom(WRONG_SLOT_ERROR)) - } -} - -#[allow(dead_code)] -pub async fn check_credits_observed( - banks_client: &mut BanksClient, - stake_address: Pubkey, - expected_credits: u64, -) { - let stake_account = banks_client - .get_account(stake_address) - .await - .unwrap() - .unwrap(); - let stake_state: StakeState = deserialize(&stake_account.data).unwrap(); - assert_eq!( - stake_state.stake().unwrap().credits_observed, - expected_credits - ); -} diff --git a/program-test/tests/warp.rs b/program-test/tests/warp.rs index 21cc5092f32b14..fcefbc658c045c 100644 --- a/program-test/tests/warp.rs +++ b/program-test/tests/warp.rs @@ -1,15 +1,20 @@ #![allow(clippy::integer_arithmetic)] -mod test_utils; +mod setup; use { bincode::deserialize, log::debug, + setup::{setup_stake, setup_vote}, + solana_banks_client::BanksClient, solana_program_test::{processor, ProgramTest, ProgramTestBanksClientExt, ProgramTestError}, solana_sdk::{ account::Account, + account_info::{next_account_info, AccountInfo}, clock::Clock, + entrypoint::ProgramResult, instruction::{AccountMeta, Instruction, InstructionError}, + program_error::ProgramError, pubkey::Pubkey, rent::Rent, signature::{Keypair, Signer}, @@ -20,16 +25,34 @@ use { sysvar::{ clock, stake_history::{self, StakeHistory}, + Sysvar, }, transaction::{Transaction, TransactionError}, }, solana_stake_program::stake_state, solana_vote_program::vote_state::{self}, - test_utils::{ - check_credits_observed, process_instruction, setup_stake, setup_vote, WRONG_SLOT_ERROR, - }, + std::convert::TryInto, }; +// Use a big number to be sure that we get the right error +const WRONG_SLOT_ERROR: u32 = 123456; + +fn process_instruction( + _program_id: &Pubkey, + accounts: &[AccountInfo], + input: &[u8], +) -> ProgramResult { + let account_info_iter = &mut accounts.iter(); + let clock_info = next_account_info(account_info_iter)?; + let clock = &Clock::from_account_info(clock_info)?; + let expected_slot = u64::from_le_bytes(input.try_into().unwrap()); + if clock.slot == expected_slot { + Ok(()) + } else { + Err(ProgramError::Custom(WRONG_SLOT_ERROR)) + } +} + #[tokio::test] async fn clock_sysvar_updated_from_warp() { let program_id = Pubkey::new_unique(); @@ -111,11 +134,30 @@ async fn clock_sysvar_updated_from_warp() { ); } +async fn check_credits_observed( + banks_client: &mut BanksClient, + stake_address: Pubkey, + expected_credits: u64, +) { + let stake_account = banks_client + .get_account(stake_address) + .await + .unwrap() + .unwrap(); + let stake_state: StakeState = deserialize(&stake_account.data).unwrap(); + assert_eq!( + stake_state.stake().unwrap().credits_observed, + expected_credits + ); +} + #[tokio::test] async fn stake_rewards_from_warp() { // Initialize and start the test network let program_test = ProgramTest::default(); let mut context = program_test.start_with_context().await; + + context.warp_to_slot(100).unwrap(); let vote_address = setup_vote(&mut context).await; let user_keypair = Keypair::new(); @@ -305,6 +347,8 @@ async fn stake_rewards_filter_bench_core(num_stake_accounts: u64) { async fn stake_merge_immediately_after_activation() { let program_test = ProgramTest::default(); let mut context = program_test.start_with_context().await; + + context.warp_to_slot(100).unwrap(); let vote_address = setup_vote(&mut context).await; context.increment_vote_account_credits(&vote_address, 100);