diff --git a/programs/vote/src/vote_processor.rs b/programs/vote/src/vote_processor.rs index e20284c32e..1e946346e5 100644 --- a/programs/vote/src/vote_processor.rs +++ b/programs/vote/src/vote_processor.rs @@ -7,10 +7,7 @@ use { solana_program_runtime::{ invoke_context::InvokeContext, sysvar_cache::get_sysvar_with_account_check, }, - solana_sdk::{ - feature_set, instruction::InstructionError, keyed_account::keyed_account_at_index, - program_utils::limited_deserialize, - }, + solana_sdk::{feature_set, instruction::InstructionError, program_utils::limited_deserialize}, }; pub fn process_instruction( @@ -20,13 +17,12 @@ pub fn process_instruction( let transaction_context = &invoke_context.transaction_context; let instruction_context = transaction_context.get_current_instruction_context()?; let data = instruction_context.get_instruction_data(); - let keyed_accounts = invoke_context.get_keyed_accounts()?; trace!("process_instruction: {:?}", data); - trace!("keyed_accounts: {:?}", keyed_accounts); - let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?; - if me.owner()? != id() { + let mut me = + instruction_context.try_borrow_account(transaction_context, first_instruction_account)?; + if *me.get_owner() != id() { return Err(InstructionError::InvalidAccountOwner); } @@ -34,18 +30,18 @@ pub fn process_instruction( match limited_deserialize(data)? { VoteInstruction::InitializeAccount(vote_init) => { let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?; - if !rent.is_exempt(me.lamports()?, me.data_len()?) { + if !rent.is_exempt(me.get_lamports(), me.get_data().len()) { return Err(InstructionError::InsufficientFunds); } let clock = get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?; - vote_state::initialize_account(me, &vote_init, &signers, &clock) + vote_state::initialize_account(&mut me, &vote_init, &signers, &clock) } VoteInstruction::Authorize(voter_pubkey, vote_authorize) => { let clock = get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?; vote_state::authorize( - me, + &mut me, &voter_pubkey, vote_authorize, &signers, @@ -55,15 +51,13 @@ pub fn process_instruction( } VoteInstruction::UpdateValidatorIdentity => { instruction_context.check_number_of_instruction_accounts(2)?; - vote_state::update_validator_identity( - me, - keyed_account_at_index(keyed_accounts, first_instruction_account + 1)? - .unsigned_key(), - &signers, - ) + let node_pubkey = transaction_context.get_key_of_account_at_index( + instruction_context.get_index_in_transaction(first_instruction_account + 1)?, + )?; + vote_state::update_validator_identity(&mut me, node_pubkey, &signers) } VoteInstruction::UpdateCommission(commission) => { - vote_state::update_commission(me, commission, &signers) + vote_state::update_commission(&mut me, commission, &signers) } VoteInstruction::Vote(vote) | VoteInstruction::VoteSwitch(vote, _) => { inc_new_counter_info!("vote-native", 1); @@ -72,7 +66,7 @@ pub fn process_instruction( let clock = get_sysvar_with_account_check::clock(invoke_context, instruction_context, 2)?; vote_state::process_vote( - me, + &mut me, &slot_hashes, &clock, &vote, @@ -91,7 +85,7 @@ pub fn process_instruction( let slot_hashes = sysvar_cache.get_slot_hashes()?; let clock = sysvar_cache.get_clock()?; vote_state::process_vote_state_update( - me, + &mut me, slot_hashes.slot_hashes(), &clock, vote_state_update, @@ -103,7 +97,6 @@ pub fn process_instruction( } VoteInstruction::Withdraw(lamports) => { instruction_context.check_number_of_instruction_accounts(2)?; - let to = keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?; let rent_sysvar = if invoke_context .feature_set .is_active(&feature_set::reject_non_rent_exempt_vote_withdraws::id()) @@ -122,10 +115,13 @@ pub fn process_instruction( None }; + drop(me); vote_state::withdraw( - me, + transaction_context, + instruction_context, + first_instruction_account, lamports, - to, + first_instruction_account + 1, &signers, rent_sysvar.as_deref(), clock_if_feature_active.as_deref(), @@ -137,14 +133,16 @@ pub fn process_instruction( .is_active(&feature_set::vote_stake_checked_instructions::id()) { instruction_context.check_number_of_instruction_accounts(4)?; - let voter_pubkey = - &keyed_account_at_index(keyed_accounts, first_instruction_account + 3)? - .signer_key() - .ok_or(InstructionError::MissingRequiredSignature)?; + let voter_pubkey = transaction_context.get_key_of_account_at_index( + instruction_context.get_index_in_transaction(first_instruction_account + 3)?, + )?; + if !instruction_context.is_signer(first_instruction_account + 3)? { + return Err(InstructionError::MissingRequiredSignature); + } let clock = get_sysvar_with_account_check::clock(invoke_context, instruction_context, 1)?; vote_state::authorize( - me, + &mut me, voter_pubkey, vote_authorize, &signers, diff --git a/programs/vote/src/vote_state/mod.rs b/programs/vote/src/vote_state/mod.rs index 187e11a403..4950db096c 100644 --- a/programs/vote/src/vote_state/mod.rs +++ b/programs/vote/src/vote_state/mod.rs @@ -7,17 +7,16 @@ use { serde_derive::{Deserialize, Serialize}, solana_sdk::{ account::{AccountSharedData, ReadableAccount, WritableAccount}, - account_utils::State, clock::{Epoch, Slot, UnixTimestamp}, epoch_schedule::MAX_LEADER_SCHEDULE_EPOCH_OFFSET, feature_set::{self, filter_votes_outside_slot_hashes, FeatureSet}, hash::Hash, instruction::InstructionError, - keyed_account::KeyedAccount, pubkey::Pubkey, rent::Rent, slot_hashes::SlotHash, sysvar::clock::Clock, + transaction_context::{BorrowedAccount, InstructionContext, TransactionContext}, }, std::{ cmp::Ordering, @@ -1165,15 +1164,16 @@ impl VoteState { /// but will implicitly withdraw authorization from the previously authorized /// key pub fn authorize( - vote_account: &KeyedAccount, + vote_account: &mut BorrowedAccount, authorized: &Pubkey, vote_authorize: VoteAuthorize, signers: &HashSet, clock: &Clock, feature_set: &FeatureSet, ) -> Result<(), InstructionError> { - let mut vote_state: VoteState = - State::::state(vote_account)?.convert_to_current(); + let mut vote_state: VoteState = vote_account + .get_state::()? + .convert_to_current(); match vote_authorize { VoteAuthorize::Voter => { @@ -1211,12 +1211,13 @@ pub fn authorize( /// Update the node_pubkey, requires signature of the authorized voter pub fn update_validator_identity( - vote_account: &KeyedAccount, + vote_account: &mut BorrowedAccount, node_pubkey: &Pubkey, signers: &HashSet, ) -> Result<(), InstructionError> { - let mut vote_state: VoteState = - State::::state(vote_account)?.convert_to_current(); + let mut vote_state: VoteState = vote_account + .get_state::()? + .convert_to_current(); // current authorized withdrawer must say "yay" verify_authorized_signer(&vote_state.authorized_withdrawer, signers)?; @@ -1231,12 +1232,13 @@ pub fn update_validator_identity( /// Update the vote account's commission pub fn update_commission( - vote_account: &KeyedAccount, + vote_account: &mut BorrowedAccount, commission: u8, signers: &HashSet, ) -> Result<(), InstructionError> { - let mut vote_state: VoteState = - State::::state(vote_account)?.convert_to_current(); + let mut vote_state: VoteState = vote_account + .get_state::()? + .convert_to_current(); // current authorized withdrawer must say "yay" verify_authorized_signer(&vote_state.authorized_withdrawer, signers)?; @@ -1259,20 +1261,25 @@ fn verify_authorized_signer( /// Withdraw funds from the vote account pub fn withdraw( - vote_account: &KeyedAccount, + transaction_context: &TransactionContext, + instruction_context: &InstructionContext, + vote_account_index: usize, lamports: u64, - to_account: &KeyedAccount, + to_account_index: usize, signers: &HashSet, rent_sysvar: Option<&Rent>, clock: Option<&Clock>, ) -> Result<(), InstructionError> { - let vote_state: VoteState = - State::::state(vote_account)?.convert_to_current(); + let mut vote_account = + instruction_context.try_borrow_account(transaction_context, vote_account_index)?; + let vote_state: VoteState = vote_account + .get_state::()? + .convert_to_current(); verify_authorized_signer(&vote_state.authorized_withdrawer, signers)?; let remaining_balance = vote_account - .lamports()? + .get_lamports() .checked_sub(lamports) .ok_or(InstructionError::InsufficientFunds)?; @@ -1295,18 +1302,17 @@ pub fn withdraw( vote_account.set_state(&VoteStateVersions::new_current(VoteState::default()))?; } } else if let Some(rent_sysvar) = rent_sysvar { - let min_rent_exempt_balance = rent_sysvar.minimum_balance(vote_account.data_len()?); + let min_rent_exempt_balance = rent_sysvar.minimum_balance(vote_account.get_data().len()); if remaining_balance < min_rent_exempt_balance { return Err(InstructionError::InsufficientFunds); } } - vote_account - .try_account_ref_mut()? - .checked_sub_lamports(lamports)?; - to_account - .try_account_ref_mut()? - .checked_add_lamports(lamports)?; + vote_account.checked_sub_lamports(lamports)?; + drop(vote_account); + let mut to_account = + instruction_context.try_borrow_account(transaction_context, to_account_index)?; + to_account.checked_add_lamports(lamports)?; Ok(()) } @@ -1314,15 +1320,15 @@ pub fn withdraw( /// Assumes that the account is being init as part of a account creation or balance transfer and /// that the transaction must be signed by the staker's keys pub fn initialize_account( - vote_account: &KeyedAccount, + vote_account: &mut BorrowedAccount, vote_init: &VoteInit, signers: &HashSet, clock: &Clock, ) -> Result<(), InstructionError> { - if vote_account.data_len()? != VoteState::size_of() { + if vote_account.get_data().len() != VoteState::size_of() { return Err(InstructionError::InvalidAccountData); } - let versioned = State::::state(vote_account)?; + let versioned = vote_account.get_state::()?; if !versioned.is_uninitialized() { return Err(InstructionError::AccountAlreadyInitialized); @@ -1337,11 +1343,11 @@ pub fn initialize_account( } fn verify_and_get_vote_state( - vote_account: &KeyedAccount, + vote_account: &BorrowedAccount, clock: &Clock, signers: &HashSet, ) -> Result { - let versioned = State::::state(vote_account)?; + let versioned = vote_account.get_state::()?; if versioned.is_uninitialized() { return Err(InstructionError::UninitializedAccount); @@ -1355,7 +1361,7 @@ fn verify_and_get_vote_state( } pub fn process_vote( - vote_account: &KeyedAccount, + vote_account: &mut BorrowedAccount, slot_hashes: &[SlotHash], clock: &Clock, vote: &Vote, @@ -1376,7 +1382,7 @@ pub fn process_vote( } pub fn process_vote_state_update( - vote_account: &KeyedAccount, + vote_account: &mut BorrowedAccount, slot_hashes: &[SlotHash], clock: &Clock, mut vote_state_update: VoteStateUpdate,