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:
Alexander Meißner 2022-02-17 17:36:55 +01:00 committed by GitHub
parent da00b39f4f
commit 1a68f81f89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1450 additions and 972 deletions

View File

@ -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

View File

@ -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)?;

View File

@ -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)