Replaces `KeyedAccount` by `BorrowedAccount` in `nonce_keyed_account`. (#23214)
* Adds get_sysvar_with_account_check2 for ABIv2. * Replaces get_signers() and get_sysvar_with_account_check() in system_instruction_processor. * Replaces KeyedAccount by BorrowedAccount in nonce_keyed_account.
This commit is contained in:
parent
da00b39f4f
commit
1a68f81f89
|
@ -11,6 +11,7 @@ use {
|
|||
clock::Clock, epoch_schedule::EpochSchedule, rent::Rent, slot_hashes::SlotHashes,
|
||||
stake_history::StakeHistory, Sysvar, SysvarId,
|
||||
},
|
||||
transaction_context::{InstructionContext, TransactionContext},
|
||||
},
|
||||
std::sync::Arc,
|
||||
};
|
||||
|
@ -231,3 +232,86 @@ pub mod get_sysvar_with_account_check {
|
|||
invoke_context.get_sysvar_cache().get_stake_history()
|
||||
}
|
||||
}
|
||||
|
||||
pub mod get_sysvar_with_account_check2 {
|
||||
use super::*;
|
||||
|
||||
fn check_sysvar_account<S: Sysvar>(
|
||||
transaction_context: &TransactionContext,
|
||||
instruction_context: &InstructionContext,
|
||||
index_in_instruction: usize,
|
||||
) -> Result<(), InstructionError> {
|
||||
let index_in_transaction =
|
||||
instruction_context.get_index_in_transaction(index_in_instruction)?;
|
||||
if !S::check_id(transaction_context.get_key_of_account_at_index(index_in_transaction)?) {
|
||||
return Err(InstructionError::InvalidArgument);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clock(
|
||||
invoke_context: &InvokeContext,
|
||||
instruction_context: &InstructionContext,
|
||||
index_in_instruction: usize,
|
||||
) -> Result<Arc<Clock>, InstructionError> {
|
||||
check_sysvar_account::<Clock>(
|
||||
invoke_context.transaction_context,
|
||||
instruction_context,
|
||||
index_in_instruction,
|
||||
)?;
|
||||
invoke_context.get_sysvar_cache().get_clock()
|
||||
}
|
||||
|
||||
pub fn rent(
|
||||
invoke_context: &InvokeContext,
|
||||
instruction_context: &InstructionContext,
|
||||
index_in_instruction: usize,
|
||||
) -> Result<Arc<Rent>, InstructionError> {
|
||||
check_sysvar_account::<Rent>(
|
||||
invoke_context.transaction_context,
|
||||
instruction_context,
|
||||
index_in_instruction,
|
||||
)?;
|
||||
invoke_context.get_sysvar_cache().get_rent()
|
||||
}
|
||||
|
||||
pub fn slot_hashes(
|
||||
invoke_context: &InvokeContext,
|
||||
instruction_context: &InstructionContext,
|
||||
index_in_instruction: usize,
|
||||
) -> Result<Arc<SlotHashes>, InstructionError> {
|
||||
check_sysvar_account::<SlotHashes>(
|
||||
invoke_context.transaction_context,
|
||||
instruction_context,
|
||||
index_in_instruction,
|
||||
)?;
|
||||
invoke_context.get_sysvar_cache().get_slot_hashes()
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub fn recent_blockhashes(
|
||||
invoke_context: &InvokeContext,
|
||||
instruction_context: &InstructionContext,
|
||||
index_in_instruction: usize,
|
||||
) -> Result<Arc<RecentBlockhashes>, InstructionError> {
|
||||
check_sysvar_account::<RecentBlockhashes>(
|
||||
invoke_context.transaction_context,
|
||||
instruction_context,
|
||||
index_in_instruction,
|
||||
)?;
|
||||
invoke_context.get_sysvar_cache().get_recent_blockhashes()
|
||||
}
|
||||
|
||||
pub fn stake_history(
|
||||
invoke_context: &InvokeContext,
|
||||
instruction_context: &InstructionContext,
|
||||
index_in_instruction: usize,
|
||||
) -> Result<Arc<StakeHistory>, InstructionError> {
|
||||
check_sysvar_account::<StakeHistory>(
|
||||
invoke_context.transaction_context,
|
||||
instruction_context,
|
||||
index_in_instruction,
|
||||
)?;
|
||||
invoke_context.get_sysvar_cache().get_stake_history()
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,15 +1,18 @@
|
|||
use {
|
||||
crate::nonce_keyed_account::NonceKeyedAccount,
|
||||
crate::nonce_keyed_account::{
|
||||
advance_nonce_account, authorize_nonce_account, initialize_nonce_account,
|
||||
withdraw_nonce_account, NONCE_ACCOUNT_INDEX, WITHDRAW_TO_ACCOUNT_INDEX,
|
||||
},
|
||||
log::*,
|
||||
solana_program_runtime::{
|
||||
ic_msg, invoke_context::InvokeContext, sysvar_cache::get_sysvar_with_account_check,
|
||||
ic_msg, invoke_context::InvokeContext, sysvar_cache::get_sysvar_with_account_check2,
|
||||
},
|
||||
solana_sdk::{
|
||||
account::{AccountSharedData, ReadableAccount, WritableAccount},
|
||||
account_utils::StateMut,
|
||||
feature_set,
|
||||
instruction::InstructionError,
|
||||
keyed_account::{get_signers, keyed_account_at_index, KeyedAccount},
|
||||
keyed_account::{keyed_account_at_index, KeyedAccount},
|
||||
nonce,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
|
@ -265,14 +268,15 @@ pub fn process_instruction(
|
|||
instruction_data: &[u8],
|
||||
invoke_context: &mut InvokeContext,
|
||||
) -> 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 instruction = limited_deserialize(instruction_data)?;
|
||||
|
||||
trace!("process_instruction: {:?}", instruction);
|
||||
trace!("keyed_accounts: {:?}", keyed_accounts);
|
||||
|
||||
let _ = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
let signers = get_signers(&keyed_accounts[first_instruction_account..]);
|
||||
let signers = instruction_context.get_signers(transaction_context);
|
||||
match instruction {
|
||||
SystemInstruction::CreateAccount {
|
||||
lamports,
|
||||
|
@ -348,11 +352,12 @@ pub fn process_instruction(
|
|||
)
|
||||
}
|
||||
SystemInstruction::AdvanceNonceAccount => {
|
||||
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
let _me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
#[allow(deprecated)]
|
||||
let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
|
||||
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
|
||||
let recent_blockhashes = get_sysvar_with_account_check2::recent_blockhashes(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
first_instruction_account + 1,
|
||||
)?;
|
||||
if recent_blockhashes.is_empty() {
|
||||
ic_msg!(
|
||||
|
@ -361,28 +366,44 @@ pub fn process_instruction(
|
|||
);
|
||||
return Err(NonceError::NoRecentBlockhashes.into());
|
||||
}
|
||||
me.advance_nonce_account(&signers, invoke_context)
|
||||
advance_nonce_account(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
&signers,
|
||||
NONCE_ACCOUNT_INDEX,
|
||||
)
|
||||
}
|
||||
SystemInstruction::WithdrawNonceAccount(lamports) => {
|
||||
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
let to = &mut keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?;
|
||||
let _me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
let _to = &mut keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?;
|
||||
#[allow(deprecated)]
|
||||
let _recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
|
||||
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?,
|
||||
let _recent_blockhashes = get_sysvar_with_account_check2::recent_blockhashes(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
first_instruction_account + 2,
|
||||
)?;
|
||||
let rent = get_sysvar_with_account_check::rent(
|
||||
keyed_account_at_index(keyed_accounts, first_instruction_account + 3)?,
|
||||
let rent = get_sysvar_with_account_check2::rent(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
first_instruction_account + 3,
|
||||
)?;
|
||||
me.withdraw_nonce_account(lamports, to, &rent, &signers, invoke_context)
|
||||
withdraw_nonce_account(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
&signers,
|
||||
NONCE_ACCOUNT_INDEX,
|
||||
WITHDRAW_TO_ACCOUNT_INDEX,
|
||||
lamports,
|
||||
&rent,
|
||||
)
|
||||
}
|
||||
SystemInstruction::InitializeNonceAccount(authorized) => {
|
||||
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
let _me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
#[allow(deprecated)]
|
||||
let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
|
||||
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
|
||||
let recent_blockhashes = get_sysvar_with_account_check2::recent_blockhashes(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
first_instruction_account + 1,
|
||||
)?;
|
||||
if recent_blockhashes.is_empty() {
|
||||
ic_msg!(
|
||||
|
@ -391,15 +412,28 @@ pub fn process_instruction(
|
|||
);
|
||||
return Err(NonceError::NoRecentBlockhashes.into());
|
||||
}
|
||||
let rent = get_sysvar_with_account_check::rent(
|
||||
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?,
|
||||
let rent = get_sysvar_with_account_check2::rent(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
first_instruction_account + 2,
|
||||
)?;
|
||||
me.initialize_nonce_account(&authorized, &rent, invoke_context)
|
||||
initialize_nonce_account(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
NONCE_ACCOUNT_INDEX,
|
||||
&authorized,
|
||||
&rent,
|
||||
)
|
||||
}
|
||||
SystemInstruction::AuthorizeNonceAccount(nonce_authority) => {
|
||||
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
me.authorize_nonce_account(&nonce_authority, &signers, invoke_context)
|
||||
let _me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
authorize_nonce_account(
|
||||
invoke_context,
|
||||
instruction_context,
|
||||
&signers,
|
||||
NONCE_ACCOUNT_INDEX,
|
||||
&nonce_authority,
|
||||
)
|
||||
}
|
||||
SystemInstruction::Allocate { space } => {
|
||||
let keyed_account = keyed_account_at_index(keyed_accounts, first_instruction_account)?;
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::{
|
|||
instruction::InstructionError,
|
||||
lamports::LamportsError,
|
||||
pubkey::Pubkey,
|
||||
sysvar::Sysvar,
|
||||
};
|
||||
use std::{
|
||||
cell::{RefCell, RefMut},
|
||||
|
@ -111,17 +110,6 @@ impl TransactionContext {
|
|||
.ok_or(InstructionError::NotEnoughAccountKeys)
|
||||
}
|
||||
|
||||
/// Checks if the account key at the given index is the belongs to the given sysvar
|
||||
pub fn check_sysvar<S: Sysvar>(
|
||||
&self,
|
||||
index_in_transaction: usize,
|
||||
) -> Result<(), InstructionError> {
|
||||
if !S::check_id(&self.account_keys[index_in_transaction]) {
|
||||
return Err(InstructionError::InvalidArgument);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Searches for an account by its key
|
||||
pub fn find_index_of_account(&self, pubkey: &Pubkey) -> Option<usize> {
|
||||
self.account_keys.iter().position(|key| key == pubkey)
|
||||
|
|
Loading…
Reference in New Issue