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, clock::Clock, epoch_schedule::EpochSchedule, rent::Rent, slot_hashes::SlotHashes,
stake_history::StakeHistory, Sysvar, SysvarId, stake_history::StakeHistory, Sysvar, SysvarId,
}, },
transaction_context::{InstructionContext, TransactionContext},
}, },
std::sync::Arc, std::sync::Arc,
}; };
@ -231,3 +232,86 @@ pub mod get_sysvar_with_account_check {
invoke_context.get_sysvar_cache().get_stake_history() 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 { 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::*, log::*,
solana_program_runtime::{ 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::{ solana_sdk::{
account::{AccountSharedData, ReadableAccount, WritableAccount}, account::{AccountSharedData, ReadableAccount, WritableAccount},
account_utils::StateMut, account_utils::StateMut,
feature_set, feature_set,
instruction::InstructionError, instruction::InstructionError,
keyed_account::{get_signers, keyed_account_at_index, KeyedAccount}, keyed_account::{keyed_account_at_index, KeyedAccount},
nonce, nonce,
program_utils::limited_deserialize, program_utils::limited_deserialize,
pubkey::Pubkey, pubkey::Pubkey,
@ -265,14 +268,15 @@ pub fn process_instruction(
instruction_data: &[u8], instruction_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()?;
let instruction = limited_deserialize(instruction_data)?; let instruction = limited_deserialize(instruction_data)?;
trace!("process_instruction: {:?}", instruction); trace!("process_instruction: {:?}", instruction);
trace!("keyed_accounts: {:?}", keyed_accounts); trace!("keyed_accounts: {:?}", keyed_accounts);
let _ = keyed_account_at_index(keyed_accounts, first_instruction_account)?; let signers = instruction_context.get_signers(transaction_context);
let signers = get_signers(&keyed_accounts[first_instruction_account..]);
match instruction { match instruction {
SystemInstruction::CreateAccount { SystemInstruction::CreateAccount {
lamports, lamports,
@ -348,11 +352,12 @@ pub fn process_instruction(
) )
} }
SystemInstruction::AdvanceNonceAccount => { 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)] #[allow(deprecated)]
let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes( let recent_blockhashes = get_sysvar_with_account_check2::recent_blockhashes(
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
invoke_context, invoke_context,
instruction_context,
first_instruction_account + 1,
)?; )?;
if recent_blockhashes.is_empty() { if recent_blockhashes.is_empty() {
ic_msg!( ic_msg!(
@ -361,28 +366,44 @@ pub fn process_instruction(
); );
return Err(NonceError::NoRecentBlockhashes.into()); 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) => { SystemInstruction::WithdrawNonceAccount(lamports) => {
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?; 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 _to = &mut keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?;
#[allow(deprecated)] #[allow(deprecated)]
let _recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes( let _recent_blockhashes = get_sysvar_with_account_check2::recent_blockhashes(
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?,
invoke_context, invoke_context,
instruction_context,
first_instruction_account + 2,
)?; )?;
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 + 3)?,
invoke_context, 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) => { 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)] #[allow(deprecated)]
let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes( let recent_blockhashes = get_sysvar_with_account_check2::recent_blockhashes(
keyed_account_at_index(keyed_accounts, first_instruction_account + 1)?,
invoke_context, invoke_context,
instruction_context,
first_instruction_account + 1,
)?; )?;
if recent_blockhashes.is_empty() { if recent_blockhashes.is_empty() {
ic_msg!( ic_msg!(
@ -391,15 +412,28 @@ pub fn process_instruction(
); );
return Err(NonceError::NoRecentBlockhashes.into()); return Err(NonceError::NoRecentBlockhashes.into());
} }
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 + 2)?,
invoke_context, 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) => { SystemInstruction::AuthorizeNonceAccount(nonce_authority) => {
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?; let _me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?;
me.authorize_nonce_account(&nonce_authority, &signers, invoke_context) authorize_nonce_account(
invoke_context,
instruction_context,
&signers,
NONCE_ACCOUNT_INDEX,
&nonce_authority,
)
} }
SystemInstruction::Allocate { space } => { SystemInstruction::Allocate { space } => {
let keyed_account = keyed_account_at_index(keyed_accounts, first_instruction_account)?; let keyed_account = keyed_account_at_index(keyed_accounts, first_instruction_account)?;

View File

@ -5,7 +5,6 @@ use crate::{
instruction::InstructionError, instruction::InstructionError,
lamports::LamportsError, lamports::LamportsError,
pubkey::Pubkey, pubkey::Pubkey,
sysvar::Sysvar,
}; };
use std::{ use std::{
cell::{RefCell, RefMut}, cell::{RefCell, RefMut},
@ -111,17 +110,6 @@ impl TransactionContext {
.ok_or(InstructionError::NotEnoughAccountKeys) .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 /// Searches for an account by its key
pub fn find_index_of_account(&self, pubkey: &Pubkey) -> Option<usize> { pub fn find_index_of_account(&self, pubkey: &Pubkey) -> Option<usize> {
self.account_keys.iter().position(|key| key == pubkey) self.account_keys.iter().position(|key| key == pubkey)