diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 5a34b0a6d..ac9c863d0 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -390,6 +390,7 @@ pub fn process_instruction( #[cfg(test)] mod tests { use super::*; + use bincode::serialize; use solana_sdk::{ account::{self, Account, AccountSharedData}, process_instruction::MockInvokeContext, @@ -398,6 +399,10 @@ mod tests { use std::cell::RefCell; use std::str::FromStr; + fn create_default_account() -> RefCell { + RefCell::new(AccountSharedData::default()) + } + // these are for 100% coverage in this file #[test] fn test_vote_process_instruction_decode_bail() { @@ -538,6 +543,105 @@ mod tests { ); } + #[test] + fn test_vote_authorize_checked() { + let vote_pubkey = Pubkey::new_unique(); + let authorized_pubkey = Pubkey::new_unique(); + let new_authorized_pubkey = Pubkey::new_unique(); + + // Test with vanilla authorize accounts + let mut instruction = authorize_checked( + &vote_pubkey, + &authorized_pubkey, + &new_authorized_pubkey, + VoteAuthorize::Voter, + ); + instruction.accounts = instruction.accounts[0..2].to_vec(); + assert_eq!( + process_instruction(&instruction), + Err(InstructionError::NotEnoughAccountKeys), + ); + + let mut instruction = authorize_checked( + &vote_pubkey, + &authorized_pubkey, + &new_authorized_pubkey, + VoteAuthorize::Withdrawer, + ); + instruction.accounts = instruction.accounts[0..2].to_vec(); + assert_eq!( + process_instruction(&instruction), + Err(InstructionError::NotEnoughAccountKeys), + ); + + // Test with non-signing new_authorized_pubkey + let mut instruction = authorize_checked( + &vote_pubkey, + &authorized_pubkey, + &new_authorized_pubkey, + VoteAuthorize::Voter, + ); + instruction.accounts[3] = AccountMeta::new_readonly(new_authorized_pubkey, false); + assert_eq!( + process_instruction(&instruction), + Err(InstructionError::MissingRequiredSignature), + ); + + let mut instruction = authorize_checked( + &vote_pubkey, + &authorized_pubkey, + &new_authorized_pubkey, + VoteAuthorize::Withdrawer, + ); + instruction.accounts[3] = AccountMeta::new_readonly(new_authorized_pubkey, false); + assert_eq!( + process_instruction(&instruction), + Err(InstructionError::MissingRequiredSignature), + ); + + // Test with new_authorized_pubkey signer + let vote_account = AccountSharedData::new_ref(100, VoteState::size_of(), &id()); + let clock_address = sysvar::clock::id(); + let clock_account = RefCell::new(account::create_account_shared_data_for_test( + &Clock::default(), + )); + let default_authorized_pubkey = Pubkey::default(); + let authorized_account = create_default_account(); + let new_authorized_account = create_default_account(); + let keyed_accounts = vec![ + KeyedAccount::new(&vote_pubkey, false, &vote_account), + KeyedAccount::new(&clock_address, false, &clock_account), + KeyedAccount::new(&default_authorized_pubkey, true, &authorized_account), + KeyedAccount::new(&new_authorized_pubkey, true, &new_authorized_account), + ]; + assert_eq!( + super::process_instruction( + &Pubkey::default(), + &serialize(&VoteInstruction::AuthorizeChecked(VoteAuthorize::Voter)).unwrap(), + &mut MockInvokeContext::new(keyed_accounts) + ), + Ok(()) + ); + + let keyed_accounts = vec![ + KeyedAccount::new(&vote_pubkey, false, &vote_account), + KeyedAccount::new(&clock_address, false, &clock_account), + KeyedAccount::new(&default_authorized_pubkey, true, &authorized_account), + KeyedAccount::new(&new_authorized_pubkey, true, &new_authorized_account), + ]; + assert_eq!( + super::process_instruction( + &Pubkey::default(), + &serialize(&VoteInstruction::AuthorizeChecked( + VoteAuthorize::Withdrawer + )) + .unwrap(), + &mut MockInvokeContext::new(keyed_accounts) + ), + Ok(()) + ); + } + #[test] fn test_minimum_balance() { let rent = solana_sdk::rent::Rent::default();