Refactor: Prepare stake_instruction.rs to remove `KeyedAccount`s (#23375)

* Adds instruction_account_indices to stake instruction.

* Uses instruction_account_indices in stake instruction.

* Replaces get_sysvar_with_account_check by get_sysvar_with_account_check2 in stake instruction.

* Adds check_number_of_instruction_accounts().
This commit is contained in:
Alexander Meißner 2022-02-28 16:24:40 +01:00 committed by GitHub
parent fe18ea35a2
commit ee3fc39f1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 251 additions and 82 deletions

View File

@ -7,12 +7,12 @@ use {
crate::{config, stake_state::StakeAccount}, crate::{config, stake_state::StakeAccount},
log::*, log::*,
solana_program_runtime::{ solana_program_runtime::{
invoke_context::InvokeContext, sysvar_cache::get_sysvar_with_account_check, invoke_context::InvokeContext, sysvar_cache::get_sysvar_with_account_check2,
}, },
solana_sdk::{ solana_sdk::{
feature_set, feature_set,
instruction::InstructionError, instruction::InstructionError,
keyed_account::{get_signers, keyed_account_at_index}, keyed_account::keyed_account_at_index,
program_utils::limited_deserialize, program_utils::limited_deserialize,
stake::{ stake::{
instruction::StakeInstruction, instruction::StakeInstruction,
@ -23,27 +23,118 @@ use {
}, },
}; };
pub mod instruction_account_indices {
pub enum Initialize {
StakeAccount = 0,
Rent = 1,
}
pub enum Authorize {
StakeAccount = 0,
Clock = 1,
// CurrentAuthority = 2,
Custodian = 3,
}
pub enum AuthorizeWithSeed {
StakeAccount = 0,
AuthorityBase = 1,
Clock = 2,
Custodian = 3,
}
pub enum DelegateStake {
StakeAccount = 0,
VoteAccount = 1,
Clock = 2,
StakeHistory = 3,
ConfigAccount = 4,
}
pub enum Split {
StakeAccount = 0,
SplitTo = 1,
}
pub enum Merge {
StakeAccount = 0,
MergeFrom = 1,
Clock = 2,
StakeHistory = 3,
}
pub enum Withdraw {
StakeAccount = 0,
Recipient = 1,
Clock = 2,
StakeHistory = 3,
WithdrawAuthority = 4,
Custodian = 5,
}
pub enum Deactivate {
StakeAccount = 0,
Clock = 1,
}
pub enum SetLockup {
StakeAccount = 0,
// Clock = 1,
}
pub enum InitializeChecked {
StakeAccount = 0,
Rent = 1,
AuthorizedStaker = 2,
AuthorizedWithdrawer = 3,
}
pub enum AuthorizeChecked {
StakeAccount = 0,
Clock = 1,
// CurrentAuthority = 2,
Authorized = 3,
Custodian = 4,
}
pub enum AuthorizeCheckedWithSeed {
StakeAccount = 0,
AuthorityBase = 1,
Clock = 2,
Authorized = 3,
Custodian = 4,
}
pub enum SetLockupChecked {
StakeAccount = 0,
// Clock = 1,
Custodian = 2,
}
}
pub fn process_instruction( pub fn process_instruction(
first_instruction_account: usize, first_instruction_account: usize,
data: &[u8], data: &[u8],
invoke_context: &mut InvokeContext, invoke_context: &mut InvokeContext,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let transaction_context = &invoke_context.transaction_context;
let instruction_context = transaction_context.get_current_instruction_context()?;
let keyed_accounts = invoke_context.get_keyed_accounts()?; let keyed_accounts = invoke_context.get_keyed_accounts()?;
trace!("process_instruction: {:?}", data); trace!("process_instruction: {:?}", data);
trace!("keyed_accounts: {:?}", keyed_accounts);
let me = &keyed_account_at_index(keyed_accounts, first_instruction_account)?; let me = &keyed_account_at_index(keyed_accounts, first_instruction_account)?;
if me.owner()? != id() { if me.owner()? != id() {
return Err(InstructionError::InvalidAccountOwner); return Err(InstructionError::InvalidAccountOwner);
} }
let signers = get_signers(&keyed_accounts[first_instruction_account..]); let signers = instruction_context.get_signers(transaction_context);
match limited_deserialize(data)? { match limited_deserialize(data)? {
StakeInstruction::Initialize(authorized, lockup) => { StakeInstruction::Initialize(authorized, lockup) => {
let rent = get_sysvar_with_account_check::rent( let rent = get_sysvar_with_account_check2::rent(
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::Initialize::Rent as usize,
)?; )?;
me.initialize(&authorized, &lockup, &rent) me.initialize(&authorized, &lockup, &rent)
} }
@ -53,16 +144,18 @@ pub fn process_instruction(
.is_active(&feature_set::require_custodian_for_locked_stake_authorize::id()); .is_active(&feature_set::require_custodian_for_locked_stake_authorize::id());
if require_custodian_for_locked_stake_authorize { if require_custodian_for_locked_stake_authorize {
let clock = get_sysvar_with_account_check::clock( let clock = get_sysvar_with_account_check2::clock(
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::Authorize::Clock as usize,
)?; )?;
let _current_authority = let custodian = keyed_account_at_index(
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?; keyed_accounts,
let custodian = first_instruction_account
keyed_account_at_index(keyed_accounts, first_instruction_account + 3) + instruction_account_indices::Authorize::Custodian as usize,
.ok() )
.map(|ka| ka.unsigned_key()); .ok()
.map(|ka| ka.unsigned_key());
me.authorize( me.authorize(
&signers, &signers,
@ -84,21 +177,29 @@ pub fn process_instruction(
} }
} }
StakeInstruction::AuthorizeWithSeed(args) => { StakeInstruction::AuthorizeWithSeed(args) => {
let authority_base = instruction_context.check_number_of_instruction_accounts(2)?;
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?; let authority_base = keyed_account_at_index(
keyed_accounts,
first_instruction_account
+ instruction_account_indices::AuthorizeWithSeed::AuthorityBase as usize,
)?;
let require_custodian_for_locked_stake_authorize = invoke_context let require_custodian_for_locked_stake_authorize = invoke_context
.feature_set .feature_set
.is_active(&feature_set::require_custodian_for_locked_stake_authorize::id()); .is_active(&feature_set::require_custodian_for_locked_stake_authorize::id());
if require_custodian_for_locked_stake_authorize { if require_custodian_for_locked_stake_authorize {
let clock = get_sysvar_with_account_check::clock( let clock = get_sysvar_with_account_check2::clock(
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::AuthorizeWithSeed::Clock as usize,
)?; )?;
let custodian = let custodian = keyed_account_at_index(
keyed_account_at_index(keyed_accounts, first_instruction_account + 3) keyed_accounts,
.ok() first_instruction_account
.map(|ka| ka.unsigned_key()); + instruction_account_indices::AuthorizeWithSeed::Custodian as usize,
)
.ok()
.map(|ka| ka.unsigned_key());
me.authorize_with_seed( me.authorize_with_seed(
authority_base, authority_base,
@ -124,17 +225,28 @@ pub fn process_instruction(
} }
} }
StakeInstruction::DelegateStake => { StakeInstruction::DelegateStake => {
let vote = keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?; instruction_context.check_number_of_instruction_accounts(2)?;
let clock = get_sysvar_with_account_check::clock( let vote = keyed_account_at_index(
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?, keyed_accounts,
invoke_context, first_instruction_account
+ instruction_account_indices::DelegateStake::VoteAccount as usize,
)?; )?;
let stake_history = get_sysvar_with_account_check::stake_history( let clock = get_sysvar_with_account_check2::clock(
keyed_account_at_index(keyed_accounts, first_instruction_account + 3)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::DelegateStake::Clock as usize,
)?;
let stake_history = get_sysvar_with_account_check2::stake_history(
invoke_context,
instruction_context,
instruction_account_indices::DelegateStake::StakeHistory as usize,
)?;
instruction_context.check_number_of_instruction_accounts(5)?;
let config_account = keyed_account_at_index(
keyed_accounts,
first_instruction_account
+ instruction_account_indices::DelegateStake::ConfigAccount as usize,
)?; )?;
let config_account =
keyed_account_at_index(keyed_accounts, first_instruction_account + 4)?;
if !config::check_id(config_account.unsigned_key()) { if !config::check_id(config_account.unsigned_key()) {
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
@ -143,20 +255,28 @@ pub fn process_instruction(
me.delegate(vote, &clock, &stake_history, &config, &signers) me.delegate(vote, &clock, &stake_history, &config, &signers)
} }
StakeInstruction::Split(lamports) => { StakeInstruction::Split(lamports) => {
let split_stake = instruction_context.check_number_of_instruction_accounts(2)?;
&keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?; let split_stake = &keyed_account_at_index(
keyed_accounts,
first_instruction_account + instruction_account_indices::Split::SplitTo as usize,
)?;
me.split(lamports, split_stake, &signers) me.split(lamports, split_stake, &signers)
} }
StakeInstruction::Merge => { StakeInstruction::Merge => {
let source_stake = instruction_context.check_number_of_instruction_accounts(2)?;
&keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?; let source_stake = &keyed_account_at_index(
let clock = get_sysvar_with_account_check::clock( keyed_accounts,
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?, first_instruction_account + instruction_account_indices::Merge::MergeFrom as usize,
invoke_context,
)?; )?;
let stake_history = get_sysvar_with_account_check::stake_history( let clock = get_sysvar_with_account_check2::clock(
keyed_account_at_index(keyed_accounts, first_instruction_account + 3)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::Merge::Clock as usize,
)?;
let stake_history = get_sysvar_with_account_check2::stake_history(
invoke_context,
instruction_context,
instruction_account_indices::Merge::StakeHistory as usize,
)?; )?;
me.merge( me.merge(
invoke_context, invoke_context,
@ -167,28 +287,46 @@ pub fn process_instruction(
) )
} }
StakeInstruction::Withdraw(lamports) => { StakeInstruction::Withdraw(lamports) => {
let to = &keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?; instruction_context.check_number_of_instruction_accounts(2)?;
let clock = get_sysvar_with_account_check::clock( let to = &keyed_account_at_index(
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?, keyed_accounts,
invoke_context, first_instruction_account
+ instruction_account_indices::Withdraw::Recipient as usize,
)?; )?;
let stake_history = get_sysvar_with_account_check::stake_history( let clock = get_sysvar_with_account_check2::clock(
keyed_account_at_index(keyed_accounts, first_instruction_account + 3)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::Withdraw::Clock as usize,
)?; )?;
let stake_history = get_sysvar_with_account_check2::stake_history(
invoke_context,
instruction_context,
instruction_account_indices::Withdraw::StakeHistory as usize,
)?;
instruction_context.check_number_of_instruction_accounts(5)?;
me.withdraw( me.withdraw(
lamports, lamports,
to, to,
&clock, &clock,
&stake_history, &stake_history,
keyed_account_at_index(keyed_accounts, first_instruction_account + 4)?, keyed_account_at_index(
keyed_account_at_index(keyed_accounts, first_instruction_account + 5).ok(), keyed_accounts,
first_instruction_account
+ instruction_account_indices::Withdraw::WithdrawAuthority as usize,
)?,
keyed_account_at_index(
keyed_accounts,
first_instruction_account
+ instruction_account_indices::Withdraw::Custodian as usize,
)
.ok(),
) )
} }
StakeInstruction::Deactivate => { StakeInstruction::Deactivate => {
let clock = get_sysvar_with_account_check::clock( let clock = get_sysvar_with_account_check2::clock(
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::Deactivate::Clock as usize,
)?; )?;
me.deactivate(&clock, &signers) me.deactivate(&clock, &signers)
} }
@ -201,20 +339,29 @@ pub fn process_instruction(
.feature_set .feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id()) .is_active(&feature_set::vote_stake_checked_instructions::id())
{ {
instruction_context.check_number_of_instruction_accounts(4)?;
let authorized = Authorized { let authorized = Authorized {
staker: *keyed_account_at_index(keyed_accounts, first_instruction_account + 2)? staker: *keyed_account_at_index(
.unsigned_key(), keyed_accounts,
first_instruction_account
+ instruction_account_indices::InitializeChecked::AuthorizedStaker
as usize,
)?
.unsigned_key(),
withdrawer: *keyed_account_at_index( withdrawer: *keyed_account_at_index(
keyed_accounts, keyed_accounts,
first_instruction_account + 3, first_instruction_account
+ instruction_account_indices::InitializeChecked::AuthorizedWithdrawer
as usize,
)? )?
.signer_key() .signer_key()
.ok_or(InstructionError::MissingRequiredSignature)?, .ok_or(InstructionError::MissingRequiredSignature)?,
}; };
let rent = get_sysvar_with_account_check::rent( let rent = get_sysvar_with_account_check2::rent(
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::InitializeChecked::Rent as usize,
)?; )?;
me.initialize(&authorized, &Lockup::default(), &rent) me.initialize(&authorized, &Lockup::default(), &rent)
} else { } else {
@ -226,20 +373,26 @@ pub fn process_instruction(
.feature_set .feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id()) .is_active(&feature_set::vote_stake_checked_instructions::id())
{ {
let clock = get_sysvar_with_account_check::clock( let clock = get_sysvar_with_account_check2::clock(
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
invoke_context, invoke_context,
instruction_context,
instruction_account_indices::AuthorizeChecked::Clock as usize,
)?; )?;
let _current_authority = instruction_context.check_number_of_instruction_accounts(4)?;
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?; let authorized_pubkey = &keyed_account_at_index(
let authorized_pubkey = keyed_accounts,
&keyed_account_at_index(keyed_accounts, first_instruction_account + 3)? first_instruction_account
.signer_key() + instruction_account_indices::AuthorizeChecked::Authorized as usize,
.ok_or(InstructionError::MissingRequiredSignature)?; )?
let custodian = .signer_key()
keyed_account_at_index(keyed_accounts, first_instruction_account + 4) .ok_or(InstructionError::MissingRequiredSignature)?;
.ok() let custodian = keyed_account_at_index(
.map(|ka| ka.unsigned_key()); keyed_accounts,
first_instruction_account
+ instruction_account_indices::AuthorizeChecked::Custodian as usize,
)
.ok()
.map(|ka| ka.unsigned_key());
me.authorize( me.authorize(
&signers, &signers,
@ -258,20 +411,34 @@ pub fn process_instruction(
.feature_set .feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id()) .is_active(&feature_set::vote_stake_checked_instructions::id())
{ {
let authority_base = instruction_context.check_number_of_instruction_accounts(2)?;
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?; let authority_base = keyed_account_at_index(
let clock = get_sysvar_with_account_check::clock( keyed_accounts,
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?, first_instruction_account
invoke_context, + instruction_account_indices::AuthorizeCheckedWithSeed::AuthorityBase
as usize,
)?; )?;
let authorized_pubkey = let clock = get_sysvar_with_account_check2::clock(
&keyed_account_at_index(keyed_accounts, first_instruction_account + 3)? invoke_context,
.signer_key() instruction_context,
.ok_or(InstructionError::MissingRequiredSignature)?; instruction_account_indices::AuthorizeCheckedWithSeed::Clock as usize,
let custodian = )?;
keyed_account_at_index(keyed_accounts, first_instruction_account + 4) instruction_context.check_number_of_instruction_accounts(4)?;
.ok() let authorized_pubkey = &keyed_account_at_index(
.map(|ka| ka.unsigned_key()); keyed_accounts,
first_instruction_account
+ instruction_account_indices::AuthorizeCheckedWithSeed::Authorized
as usize,
)?
.signer_key()
.ok_or(InstructionError::MissingRequiredSignature)?;
let custodian = keyed_account_at_index(
keyed_accounts,
first_instruction_account
+ instruction_account_indices::AuthorizeCheckedWithSeed::Custodian as usize,
)
.ok()
.map(|ka| ka.unsigned_key());
me.authorize_with_seed( me.authorize_with_seed(
authority_base, authority_base,
@ -292,9 +459,11 @@ pub fn process_instruction(
.feature_set .feature_set
.is_active(&feature_set::vote_stake_checked_instructions::id()) .is_active(&feature_set::vote_stake_checked_instructions::id())
{ {
let custodian = if let Ok(custodian) = let custodian = if let Ok(custodian) = keyed_account_at_index(
keyed_account_at_index(keyed_accounts, first_instruction_account + 2) keyed_accounts,
{ first_instruction_account
+ instruction_account_indices::SetLockupChecked::Custodian as usize,
) {
Some( Some(
*custodian *custodian
.signer_key() .signer_key()