Remove `KeyedAccount` in builtin program "nonce keyed account" (#24436)

* Makes sure that there is only one KeyedAccount at a time.
Moves keyed_account_at_index() into withdraw_nonce_account() to do so.

* Replaces KeyedAccount by BorrowedAccount.

* Removes unused code.
This commit is contained in:
Alexander Meißner 2022-04-18 22:19:51 +02:00 committed by GitHub
parent ee384f7254
commit 8b854d4141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 160 additions and 322 deletions

View File

@ -1,21 +1,19 @@
use { use {
solana_program_runtime::{ic_msg, invoke_context::InvokeContext}, solana_program_runtime::{ic_msg, invoke_context::InvokeContext},
solana_sdk::{ solana_sdk::{
account::{ReadableAccount, WritableAccount},
account_utils::State as AccountUtilsState,
feature_set::{self, nonce_must_be_writable}, feature_set::{self, nonce_must_be_writable},
instruction::{checked_add, InstructionError}, instruction::{checked_add, InstructionError},
keyed_account::KeyedAccount,
nonce::{self, state::Versions, State}, nonce::{self, state::Versions, State},
pubkey::Pubkey, pubkey::Pubkey,
system_instruction::{nonce_to_instruction_error, NonceError}, system_instruction::{nonce_to_instruction_error, NonceError},
sysvar::rent::Rent, sysvar::rent::Rent,
transaction_context::{BorrowedAccount, InstructionContext, TransactionContext},
}, },
std::collections::HashSet, std::collections::HashSet,
}; };
pub fn advance_nonce_account( pub fn advance_nonce_account(
account: &KeyedAccount, account: &mut BorrowedAccount,
signers: &HashSet<Pubkey>, signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext, invoke_context: &InvokeContext,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
@ -31,13 +29,13 @@ pub fn advance_nonce_account(
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Advance nonce account: Account {} must be writeable", "Advance nonce account: Account {} must be writeable",
account.unsigned_key() account.get_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
let state = AccountUtilsState::<Versions>::state(account)?.convert_to_current(); let state: Versions = account.get_state()?;
match state { match state.convert_to_current() {
State::Initialized(data) => { State::Initialized(data) => {
if !signers.contains(&data.authority) { if !signers.contains(&data.authority) {
ic_msg!( ic_msg!(
@ -70,7 +68,7 @@ pub fn advance_nonce_account(
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Advance nonce account: Account {} state is invalid", "Advance nonce account: Account {} state is invalid",
account.unsigned_key() account.get_key()
); );
Err(nonce_to_instruction_error( Err(nonce_to_instruction_error(
NonceError::BadAccountState, NonceError::BadAccountState,
@ -81,13 +79,17 @@ pub fn advance_nonce_account(
} }
pub fn withdraw_nonce_account( pub fn withdraw_nonce_account(
from: &KeyedAccount, from_account_index: usize,
lamports: u64, lamports: u64,
to: &KeyedAccount, to_account_index: usize,
rent: &Rent, rent: &Rent,
signers: &HashSet<Pubkey>, signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext, invoke_context: &InvokeContext,
transaction_context: &TransactionContext,
instruction_context: &InstructionContext,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
let mut from =
instruction_context.try_borrow_account(transaction_context, from_account_index)?;
let merge_nonce_error_into_system_error = invoke_context let merge_nonce_error_into_system_error = invoke_context
.feature_set .feature_set
.is_active(&feature_set::merge_nonce_error_into_system_error::id()); .is_active(&feature_set::merge_nonce_error_into_system_error::id());
@ -100,26 +102,27 @@ pub fn withdraw_nonce_account(
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Withdraw nonce account: Account {} must be writeable", "Withdraw nonce account: Account {} must be writeable",
from.unsigned_key() from.get_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
let signer = match AccountUtilsState::<Versions>::state(from)?.convert_to_current() { let state: Versions = from.get_state()?;
let signer = match state.convert_to_current() {
State::Uninitialized => { State::Uninitialized => {
if lamports > from.lamports()? { if lamports > from.get_lamports() {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Withdraw nonce account: insufficient lamports {}, need {}", "Withdraw nonce account: insufficient lamports {}, need {}",
from.lamports()?, from.get_lamports(),
lamports, lamports,
); );
return Err(InstructionError::InsufficientFunds); return Err(InstructionError::InsufficientFunds);
} }
*from.unsigned_key() *from.get_key()
} }
State::Initialized(ref data) => { State::Initialized(ref data) => {
if lamports == from.lamports()? { if lamports == from.get_lamports() {
if data.blockhash == invoke_context.blockhash { if data.blockhash == invoke_context.blockhash {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
@ -132,13 +135,13 @@ pub fn withdraw_nonce_account(
} }
from.set_state(&Versions::new_current(State::Uninitialized))?; from.set_state(&Versions::new_current(State::Uninitialized))?;
} else { } else {
let min_balance = rent.minimum_balance(from.data_len()?); let min_balance = rent.minimum_balance(from.get_data().len());
let amount = checked_add(lamports, min_balance)?; let amount = checked_add(lamports, min_balance)?;
if amount > from.lamports()? { if amount > from.get_lamports() {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Withdraw nonce account: insufficient lamports {}, need {}", "Withdraw nonce account: insufficient lamports {}, need {}",
from.lamports()?, from.get_lamports(),
amount, amount,
); );
return Err(InstructionError::InsufficientFunds); return Err(InstructionError::InsufficientFunds);
@ -157,24 +160,18 @@ pub fn withdraw_nonce_account(
return Err(InstructionError::MissingRequiredSignature); return Err(InstructionError::MissingRequiredSignature);
} }
let nonce_balance = from.try_account_ref_mut()?.lamports(); from.checked_sub_lamports(lamports)
from.try_account_ref_mut()?.set_lamports( .map_err(|_| InstructionError::ArithmeticOverflow)?;
nonce_balance drop(from);
.checked_sub(lamports) let mut to = instruction_context.try_borrow_account(transaction_context, to_account_index)?;
.ok_or(InstructionError::ArithmeticOverflow)?, to.checked_add_lamports(lamports)
); .map_err(|_| InstructionError::ArithmeticOverflow)?;
let to_balance = to.try_account_ref_mut()?.lamports();
to.try_account_ref_mut()?.set_lamports(
to_balance
.checked_add(lamports)
.ok_or(InstructionError::ArithmeticOverflow)?,
);
Ok(()) Ok(())
} }
pub fn initialize_nonce_account( pub fn initialize_nonce_account(
account: &KeyedAccount, account: &mut BorrowedAccount,
nonce_authority: &Pubkey, nonce_authority: &Pubkey,
rent: &Rent, rent: &Rent,
invoke_context: &InvokeContext, invoke_context: &InvokeContext,
@ -191,19 +188,20 @@ pub fn initialize_nonce_account(
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Initialize nonce account: Account {} must be writeable", "Initialize nonce account: Account {} must be writeable",
account.unsigned_key() account.get_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
match AccountUtilsState::<Versions>::state(account)?.convert_to_current() { let state: Versions = account.get_state()?;
match state.convert_to_current() {
State::Uninitialized => { State::Uninitialized => {
let min_balance = rent.minimum_balance(account.data_len()?); let min_balance = rent.minimum_balance(account.get_data().len());
if account.lamports()? < min_balance { if account.get_lamports() < min_balance {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Initialize nonce account: insufficient lamports {}, need {}", "Initialize nonce account: insufficient lamports {}, need {}",
account.lamports()?, account.get_lamports(),
min_balance min_balance
); );
return Err(InstructionError::InsufficientFunds); return Err(InstructionError::InsufficientFunds);
@ -219,7 +217,7 @@ pub fn initialize_nonce_account(
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Initialize nonce account: Account {} state is invalid", "Initialize nonce account: Account {} state is invalid",
account.unsigned_key() account.get_key()
); );
Err(nonce_to_instruction_error( Err(nonce_to_instruction_error(
NonceError::BadAccountState, NonceError::BadAccountState,
@ -230,7 +228,7 @@ pub fn initialize_nonce_account(
} }
pub fn authorize_nonce_account( pub fn authorize_nonce_account(
account: &KeyedAccount, account: &mut BorrowedAccount,
nonce_authority: &Pubkey, nonce_authority: &Pubkey,
signers: &HashSet<Pubkey>, signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext, invoke_context: &InvokeContext,
@ -247,12 +245,13 @@ pub fn authorize_nonce_account(
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Authorize nonce account: Account {} must be writeable", "Authorize nonce account: Account {} must be writeable",
account.unsigned_key() account.get_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
match AccountUtilsState::<Versions>::state(account)?.convert_to_current() { let state: Versions = account.get_state()?;
match state.convert_to_current() {
State::Initialized(data) => { State::Initialized(data) => {
if !signers.contains(&data.authority) { if !signers.contains(&data.authority) {
ic_msg!( ic_msg!(
@ -273,7 +272,7 @@ pub fn authorize_nonce_account(
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Authorize nonce account: Account {} state is invalid", "Authorize nonce account: Account {} state is invalid",
account.unsigned_key() account.get_key()
); );
Err(nonce_to_instruction_error( Err(nonce_to_instruction_error(
NonceError::BadAccountState, NonceError::BadAccountState,
@ -369,7 +368,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let data = nonce::state::Data { let data = nonce::state::Data {
@ -386,17 +385,7 @@ mod test {
assert_eq!(state, State::Uninitialized); assert_eq!(state, State::Uninitialized);
set_invoke_context_blockhash!(invoke_context, 95); set_invoke_context_blockhash!(invoke_context, 95);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let state = nonce_account let state = nonce_account
.get_state::<Versions>() .get_state::<Versions>()
.unwrap() .unwrap()
@ -409,16 +398,7 @@ mod test {
// First nonce instruction drives state from Uninitialized to Initialized // First nonce instruction drives state from Uninitialized to Initialized
assert_eq!(state, State::Initialized(data.clone())); assert_eq!(state, State::Initialized(data.clone()));
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
drop(nonce_account); advance_nonce_account(&mut nonce_account, &signers, &invoke_context).unwrap();
advance_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let state = nonce_account let state = nonce_account
.get_state::<Versions>() .get_state::<Versions>()
.unwrap() .unwrap()
@ -431,16 +411,7 @@ mod test {
// Second nonce instruction consumes and replaces stored nonce // Second nonce instruction consumes and replaces stored nonce
assert_eq!(state, State::Initialized(data.clone())); assert_eq!(state, State::Initialized(data.clone()));
set_invoke_context_blockhash!(invoke_context, 31); set_invoke_context_blockhash!(invoke_context, 31);
drop(nonce_account); advance_nonce_account(&mut nonce_account, &signers, &invoke_context).unwrap();
advance_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let state = nonce_account let state = nonce_account
.get_state::<Versions>() .get_state::<Versions>()
.unwrap() .unwrap()
@ -463,12 +434,14 @@ mod test {
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
withdraw_nonce_account( withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
) )
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
@ -498,22 +471,12 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 31); set_invoke_context_blockhash!(invoke_context, 31);
let authority = *nonce_account.get_key(); let authority = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authority, &rent, &invoke_context).unwrap();
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authority,
&rent,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let state = nonce_account let state = nonce_account
.get_state::<Versions>() .get_state::<Versions>()
.unwrap() .unwrap()
@ -524,15 +487,10 @@ mod test {
invoke_context.lamports_per_signature, invoke_context.lamports_per_signature,
); );
assert_eq!(state, State::Initialized(data)); assert_eq!(state, State::Initialized(data));
drop(nonce_account);
// Nonce account did not sign // Nonce account did not sign
let signers = HashSet::new(); let signers = HashSet::new();
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let result = advance_nonce_account( let result = advance_nonce_account(&mut nonce_account, &signers, &invoke_context);
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
);
assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); assert_eq!(result, Err(InstructionError::MissingRequiredSignature));
} }
@ -545,26 +503,15 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account( let result = advance_nonce_account(&mut nonce_account, &signers, &invoke_context);
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let result = advance_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
);
assert_eq!(result, Err(SystemError::NonceBlockhashNotExpired.into())); assert_eq!(result, Err(SystemError::NonceBlockhashNotExpired.into()));
} }
@ -577,18 +524,13 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
drop(nonce_account); let result = advance_nonce_account(&mut nonce_account, &signers, &invoke_context);
let result = advance_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
);
assert_eq!(result, Err(InstructionError::InvalidAccountData)); assert_eq!(result, Err(InstructionError::InvalidAccountData));
} }
@ -601,7 +543,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let nonce_authority = instruction_context let nonce_authority = instruction_context
@ -611,23 +553,11 @@ mod test {
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let authorized = *nonce_authority.get_key(); let authorized = *nonce_authority.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
drop(nonce_authority);
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(authorized); signers.insert(authorized);
set_invoke_context_blockhash!(invoke_context, 31); set_invoke_context_blockhash!(invoke_context, 31);
let result = advance_nonce_account( let result = advance_nonce_account(&mut nonce_account, &signers, &invoke_context);
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
);
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
} }
@ -640,7 +570,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let nonce_authority = instruction_context let nonce_authority = instruction_context
@ -650,20 +580,8 @@ mod test {
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let authorized = *nonce_authority.get_key(); let authorized = *nonce_authority.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
drop(nonce_authority); let result = advance_nonce_account(&mut nonce_account, &signers, &invoke_context);
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let result = advance_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
);
assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); assert_eq!(result, Err(InstructionError::MissingRequiredSignature));
} }
@ -696,12 +614,14 @@ mod test {
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
withdraw_nonce_account( withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
) )
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
@ -745,12 +665,14 @@ mod test {
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
let result = withdraw_nonce_account( let result = withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
); );
assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); assert_eq!(result, Err(InstructionError::MissingRequiredSignature));
} }
@ -778,12 +700,14 @@ mod test {
let withdraw_lamports = nonce_account.get_lamports() + 1; let withdraw_lamports = nonce_account.get_lamports() + 1;
drop(nonce_account); drop(nonce_account);
let result = withdraw_nonce_account( let result = withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
); );
assert_eq!(result, Err(InstructionError::InsufficientFunds)); assert_eq!(result, Err(InstructionError::InsufficientFunds));
} }
@ -812,12 +736,14 @@ mod test {
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
withdraw_nonce_account( withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
) )
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
@ -839,12 +765,14 @@ mod test {
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
withdraw_nonce_account( withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
) )
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
@ -871,7 +799,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let to_account = instruction_context let to_account = instruction_context
@ -881,21 +809,7 @@ mod test {
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 31); set_invoke_context_blockhash!(invoke_context, 31);
let authority = *nonce_account.get_key(); let authority = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authority, &rent, &invoke_context).unwrap();
drop(to_account);
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authority,
&rent,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let to_account = instruction_context
.try_borrow_instruction_account(transaction_context, WITHDRAW_TO_ACCOUNT_INDEX)
.unwrap();
let state = nonce_account let state = nonce_account
.get_state::<Versions>() .get_state::<Versions>()
.unwrap() .unwrap()
@ -912,12 +826,14 @@ mod test {
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
withdraw_nonce_account( withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
) )
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
@ -945,12 +861,14 @@ mod test {
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
withdraw_nonce_account( withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
) )
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
@ -977,7 +895,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let to_account = instruction_context let to_account = instruction_context
@ -985,29 +903,21 @@ mod test {
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
drop(to_account);
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
let withdraw_lamports = nonce_account.get_lamports(); let withdraw_lamports = nonce_account.get_lamports();
drop(nonce_account); drop(nonce_account);
drop(to_account);
let result = withdraw_nonce_account( let result = withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
); );
assert_eq!(result, Err(SystemError::NonceBlockhashNotExpired.into())); assert_eq!(result, Err(SystemError::NonceBlockhashNotExpired.into()));
} }
@ -1021,34 +931,26 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 95); set_invoke_context_blockhash!(invoke_context, 95);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
let withdraw_lamports = nonce_account.get_lamports() + 1; let withdraw_lamports = nonce_account.get_lamports() + 1;
drop(nonce_account); drop(nonce_account);
let result = withdraw_nonce_account( let result = withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
); );
assert_eq!(result, Err(InstructionError::InsufficientFunds)); assert_eq!(result, Err(InstructionError::InsufficientFunds));
} }
@ -1062,34 +964,26 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 95); set_invoke_context_blockhash!(invoke_context, 95);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
let withdraw_lamports = 42 + 1; let withdraw_lamports = 42 + 1;
drop(nonce_account); drop(nonce_account);
let result = withdraw_nonce_account( let result = withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
); );
assert_eq!(result, Err(InstructionError::InsufficientFunds)); assert_eq!(result, Err(InstructionError::InsufficientFunds));
} }
@ -1103,34 +997,26 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 95); set_invoke_context_blockhash!(invoke_context, 95);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
let withdraw_lamports = u64::MAX - 54; let withdraw_lamports = u64::MAX - 54;
drop(nonce_account); drop(nonce_account);
let result = withdraw_nonce_account( let result = withdraw_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], 1 + NONCE_ACCOUNT_INDEX,
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], 1 + WITHDRAW_TO_ACCOUNT_INDEX,
&rent, &rent,
&signers, &signers,
&invoke_context, &invoke_context,
transaction_context,
instruction_context,
); );
assert_eq!(result, Err(InstructionError::InsufficientFunds)); assert_eq!(result, Err(InstructionError::InsufficientFunds));
} }
@ -1144,7 +1030,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let state = nonce_account let state = nonce_account
@ -1156,16 +1042,8 @@ mod test {
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); let result =
let result = initialize_nonce_account( initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context);
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
);
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let data = nonce::state::Data::new( let data = nonce::state::Data::new(
authorized, authorized,
invoke_context.blockhash, invoke_context.blockhash,
@ -1188,26 +1066,15 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 31); set_invoke_context_blockhash!(invoke_context, 31);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let result = initialize_nonce_account( let result =
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context);
&authorized,
&rent,
&invoke_context,
);
assert_eq!(result, Err(InstructionError::InvalidAccountData)); assert_eq!(result, Err(InstructionError::InvalidAccountData));
} }
@ -1226,13 +1093,8 @@ mod test {
nonce_account.checked_sub_lamports(42 * 2).unwrap(); nonce_account.checked_sub_lamports(42 * 2).unwrap();
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); let result =
let result = initialize_nonce_account( initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context);
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
);
assert_eq!(result, Err(InstructionError::InsufficientFunds)); assert_eq!(result, Err(InstructionError::InsufficientFunds));
} }
@ -1245,37 +1107,21 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 31); set_invoke_context_blockhash!(invoke_context, 31);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let authority = Pubkey::default(); let authority = Pubkey::default();
let data = nonce::state::Data::new( let data = nonce::state::Data::new(
authority, authority,
invoke_context.blockhash, invoke_context.blockhash,
invoke_context.lamports_per_signature, invoke_context.lamports_per_signature,
); );
authorize_nonce_account( authorize_nonce_account(&mut nonce_account, &authority, &signers, &invoke_context).unwrap();
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authority,
&signers,
&invoke_context,
)
.unwrap();
let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap();
let state = nonce_account let state = nonce_account
.get_state::<Versions>() .get_state::<Versions>()
.unwrap() .unwrap()
@ -1292,14 +1138,13 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
drop(nonce_account);
let result = authorize_nonce_account( let result = authorize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], &mut nonce_account,
&Pubkey::default(), &Pubkey::default(),
&signers, &signers,
&invoke_context, &invoke_context,
@ -1316,27 +1161,16 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
signers.insert(*nonce_account.get_key()); signers.insert(*nonce_account.get_key());
set_invoke_context_blockhash!(invoke_context, 31); set_invoke_context_blockhash!(invoke_context, 31);
let authorized = Pubkey::default(); let authorized = Pubkey::default();
drop(nonce_account); initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
initialize_nonce_account( let result =
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], authorize_nonce_account(&mut nonce_account, &authorized, &signers, &invoke_context);
&authorized,
&rent,
&invoke_context,
)
.unwrap();
let result = authorize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&signers,
&invoke_context,
);
assert_eq!(result, Err(InstructionError::MissingRequiredSignature)); assert_eq!(result, Err(InstructionError::MissingRequiredSignature));
} }
@ -1349,7 +1183,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
@ -1359,14 +1193,8 @@ mod test {
assert_eq!(state, State::Uninitialized); assert_eq!(state, State::Uninitialized);
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
initialize_nonce_account(&mut nonce_account, &authorized, &rent, &invoke_context).unwrap();
drop(nonce_account); drop(nonce_account);
initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap();
assert!(verify_nonce_account( assert!(verify_nonce_account(
&transaction_context &transaction_context
.get_account_at_index(NONCE_ACCOUNT_INDEX) .get_account_at_index(NONCE_ACCOUNT_INDEX)
@ -1403,7 +1231,7 @@ mod test {
instruction_context, instruction_context,
instruction_accounts instruction_accounts
); );
let nonce_account = instruction_context let mut nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
let mut signers = HashSet::new(); let mut signers = HashSet::new();
@ -1413,15 +1241,15 @@ mod test {
assert_eq!(state, State::Uninitialized); assert_eq!(state, State::Uninitialized);
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account);
initialize_nonce_account( initialize_nonce_account(
&invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX], &mut nonce_account,
&authorized, &authorized,
&Rent::free(), &Rent::free(),
&invoke_context, &invoke_context,
) )
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 1); set_invoke_context_blockhash!(invoke_context, 1);
drop(nonce_account);
assert!(!verify_nonce_account( assert!(!verify_nonce_account(
&transaction_context &transaction_context
.get_account_at_index(NONCE_ACCOUNT_INDEX) .get_account_at_index(NONCE_ACCOUNT_INDEX)

View File

@ -359,7 +359,8 @@ pub fn process_instruction(
} }
SystemInstruction::AdvanceNonceAccount => { SystemInstruction::AdvanceNonceAccount => {
instruction_context.check_number_of_instruction_accounts(1)?; instruction_context.check_number_of_instruction_accounts(1)?;
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?; let mut me =
instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
#[allow(deprecated)] #[allow(deprecated)]
let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes( let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
invoke_context, invoke_context,
@ -373,12 +374,10 @@ pub fn process_instruction(
); );
return Err(NonceError::NoRecentBlockhashes.into()); return Err(NonceError::NoRecentBlockhashes.into());
} }
advance_nonce_account(me, &signers, invoke_context) advance_nonce_account(&mut me, &signers, invoke_context)
} }
SystemInstruction::WithdrawNonceAccount(lamports) => { SystemInstruction::WithdrawNonceAccount(lamports) => {
instruction_context.check_number_of_instruction_accounts(2)?; instruction_context.check_number_of_instruction_accounts(2)?;
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)] #[allow(deprecated)]
let _recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes( let _recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
invoke_context, invoke_context,
@ -386,11 +385,21 @@ pub fn process_instruction(
2, 2,
)?; )?;
let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 3)?; let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 3)?;
withdraw_nonce_account(me, lamports, to, &rent, &signers, invoke_context) withdraw_nonce_account(
first_instruction_account,
lamports,
first_instruction_account + 1,
&rent,
&signers,
invoke_context,
transaction_context,
instruction_context,
)
} }
SystemInstruction::InitializeNonceAccount(authorized) => { SystemInstruction::InitializeNonceAccount(authorized) => {
instruction_context.check_number_of_instruction_accounts(1)?; instruction_context.check_number_of_instruction_accounts(1)?;
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?; let mut me =
instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
#[allow(deprecated)] #[allow(deprecated)]
let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes( let recent_blockhashes = get_sysvar_with_account_check::recent_blockhashes(
invoke_context, invoke_context,
@ -405,12 +414,13 @@ pub fn process_instruction(
return Err(NonceError::NoRecentBlockhashes.into()); return Err(NonceError::NoRecentBlockhashes.into());
} }
let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 2)?; let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 2)?;
initialize_nonce_account(me, &authorized, &rent, invoke_context) initialize_nonce_account(&mut me, &authorized, &rent, invoke_context)
} }
SystemInstruction::AuthorizeNonceAccount(nonce_authority) => { SystemInstruction::AuthorizeNonceAccount(nonce_authority) => {
instruction_context.check_number_of_instruction_accounts(1)?; instruction_context.check_number_of_instruction_accounts(1)?;
let me = &mut keyed_account_at_index(keyed_accounts, first_instruction_account)?; let mut me =
authorize_nonce_account(me, &nonce_authority, &signers, invoke_context) instruction_context.try_borrow_instruction_account(transaction_context, 0)?;
authorize_nonce_account(&mut me, &nonce_authority, &signers, invoke_context)
} }
SystemInstruction::Allocate { space } => { SystemInstruction::Allocate { space } => {
instruction_context.check_number_of_instruction_accounts(1)?; instruction_context.check_number_of_instruction_accounts(1)?;