Refactor: Remove trait from nonce keyed account (#23811)

* Removes the trait `NonceKeyedAccount`.
This commit is contained in:
Alexander Meißner
2022-03-23 02:09:30 +01:00
committed by GitHub
parent 3d7c8442c7
commit 9f0ca6d88a
2 changed files with 519 additions and 441 deletions

View File

@ -14,37 +14,8 @@ use {
std::collections::HashSet, std::collections::HashSet,
}; };
pub trait NonceKeyedAccount { pub fn advance_nonce_account(
fn advance_nonce_account( account: &KeyedAccount,
&self,
signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
fn withdraw_nonce_account(
&self,
lamports: u64,
to: &KeyedAccount,
rent: &Rent,
signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
fn initialize_nonce_account(
&self,
nonce_authority: &Pubkey,
rent: &Rent,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
fn authorize_nonce_account(
&self,
nonce_authority: &Pubkey,
signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext,
) -> Result<(), InstructionError>;
}
impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
fn advance_nonce_account(
&self,
signers: &HashSet<Pubkey>, signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext, invoke_context: &InvokeContext,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
@ -55,17 +26,17 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
if invoke_context if invoke_context
.feature_set .feature_set
.is_active(&nonce_must_be_writable::id()) .is_active(&nonce_must_be_writable::id())
&& !self.is_writable() && !account.is_writable()
{ {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Advance nonce account: Account {} must be writeable", "Advance nonce account: Account {} must be writeable",
self.unsigned_key() account.unsigned_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
let state = AccountUtilsState::<Versions>::state(self)?.convert_to_current(); let state = AccountUtilsState::<Versions>::state(account)?.convert_to_current();
match state { match state {
State::Initialized(data) => { State::Initialized(data) => {
if !signers.contains(&data.authority) { if !signers.contains(&data.authority) {
@ -93,13 +64,13 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
recent_blockhash, recent_blockhash,
invoke_context.lamports_per_signature, invoke_context.lamports_per_signature,
); );
self.set_state(&Versions::new_current(State::Initialized(new_data))) account.set_state(&Versions::new_current(State::Initialized(new_data)))
} }
_ => { _ => {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Advance nonce account: Account {} state is invalid", "Advance nonce account: Account {} state is invalid",
self.unsigned_key() account.unsigned_key()
); );
Err(nonce_to_instruction_error( Err(nonce_to_instruction_error(
NonceError::BadAccountState, NonceError::BadAccountState,
@ -109,8 +80,8 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
} }
} }
fn withdraw_nonce_account( pub fn withdraw_nonce_account(
&self, from: &KeyedAccount,
lamports: u64, lamports: u64,
to: &KeyedAccount, to: &KeyedAccount,
rent: &Rent, rent: &Rent,
@ -124,31 +95,31 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
if invoke_context if invoke_context
.feature_set .feature_set
.is_active(&nonce_must_be_writable::id()) .is_active(&nonce_must_be_writable::id())
&& !self.is_writable() && !from.is_writable()
{ {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Withdraw nonce account: Account {} must be writeable", "Withdraw nonce account: Account {} must be writeable",
self.unsigned_key() from.unsigned_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
let signer = match AccountUtilsState::<Versions>::state(self)?.convert_to_current() { let signer = match AccountUtilsState::<Versions>::state(from)?.convert_to_current() {
State::Uninitialized => { State::Uninitialized => {
if lamports > self.lamports()? { if lamports > from.lamports()? {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Withdraw nonce account: insufficient lamports {}, need {}", "Withdraw nonce account: insufficient lamports {}, need {}",
self.lamports()?, from.lamports()?,
lamports, lamports,
); );
return Err(InstructionError::InsufficientFunds); return Err(InstructionError::InsufficientFunds);
} }
*self.unsigned_key() *from.unsigned_key()
} }
State::Initialized(ref data) => { State::Initialized(ref data) => {
if lamports == self.lamports()? { if lamports == from.lamports()? {
if data.blockhash == invoke_context.blockhash { if data.blockhash == invoke_context.blockhash {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
@ -159,15 +130,15 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
merge_nonce_error_into_system_error, merge_nonce_error_into_system_error,
)); ));
} }
self.set_state(&Versions::new_current(State::Uninitialized))?; from.set_state(&Versions::new_current(State::Uninitialized))?;
} else { } else {
let min_balance = rent.minimum_balance(self.data_len()?); let min_balance = rent.minimum_balance(from.data_len()?);
let amount = checked_add(lamports, min_balance)?; let amount = checked_add(lamports, min_balance)?;
if amount > self.lamports()? { if amount > from.lamports()? {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Withdraw nonce account: insufficient lamports {}, need {}", "Withdraw nonce account: insufficient lamports {}, need {}",
self.lamports()?, from.lamports()?,
amount, amount,
); );
return Err(InstructionError::InsufficientFunds); return Err(InstructionError::InsufficientFunds);
@ -186,8 +157,8 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
return Err(InstructionError::MissingRequiredSignature); return Err(InstructionError::MissingRequiredSignature);
} }
let nonce_balance = self.try_account_ref_mut()?.lamports(); let nonce_balance = from.try_account_ref_mut()?.lamports();
self.try_account_ref_mut()?.set_lamports( from.try_account_ref_mut()?.set_lamports(
nonce_balance nonce_balance
.checked_sub(lamports) .checked_sub(lamports)
.ok_or(InstructionError::ArithmeticOverflow)?, .ok_or(InstructionError::ArithmeticOverflow)?,
@ -202,8 +173,8 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
Ok(()) Ok(())
} }
fn initialize_nonce_account( pub fn initialize_nonce_account(
&self, account: &KeyedAccount,
nonce_authority: &Pubkey, nonce_authority: &Pubkey,
rent: &Rent, rent: &Rent,
invoke_context: &InvokeContext, invoke_context: &InvokeContext,
@ -215,24 +186,24 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
if invoke_context if invoke_context
.feature_set .feature_set
.is_active(&nonce_must_be_writable::id()) .is_active(&nonce_must_be_writable::id())
&& !self.is_writable() && !account.is_writable()
{ {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Initialize nonce account: Account {} must be writeable", "Initialize nonce account: Account {} must be writeable",
self.unsigned_key() account.unsigned_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
match AccountUtilsState::<Versions>::state(self)?.convert_to_current() { match AccountUtilsState::<Versions>::state(account)?.convert_to_current() {
State::Uninitialized => { State::Uninitialized => {
let min_balance = rent.minimum_balance(self.data_len()?); let min_balance = rent.minimum_balance(account.data_len()?);
if self.lamports()? < min_balance { if account.lamports()? < min_balance {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Initialize nonce account: insufficient lamports {}, need {}", "Initialize nonce account: insufficient lamports {}, need {}",
self.lamports()?, account.lamports()?,
min_balance min_balance
); );
return Err(InstructionError::InsufficientFunds); return Err(InstructionError::InsufficientFunds);
@ -242,13 +213,13 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
invoke_context.blockhash, invoke_context.blockhash,
invoke_context.lamports_per_signature, invoke_context.lamports_per_signature,
); );
self.set_state(&Versions::new_current(State::Initialized(data))) account.set_state(&Versions::new_current(State::Initialized(data)))
} }
_ => { _ => {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Initialize nonce account: Account {} state is invalid", "Initialize nonce account: Account {} state is invalid",
self.unsigned_key() account.unsigned_key()
); );
Err(nonce_to_instruction_error( Err(nonce_to_instruction_error(
NonceError::BadAccountState, NonceError::BadAccountState,
@ -258,8 +229,8 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
} }
} }
fn authorize_nonce_account( pub fn authorize_nonce_account(
&self, account: &KeyedAccount,
nonce_authority: &Pubkey, nonce_authority: &Pubkey,
signers: &HashSet<Pubkey>, signers: &HashSet<Pubkey>,
invoke_context: &InvokeContext, invoke_context: &InvokeContext,
@ -271,17 +242,17 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
if invoke_context if invoke_context
.feature_set .feature_set
.is_active(&nonce_must_be_writable::id()) .is_active(&nonce_must_be_writable::id())
&& !self.is_writable() && !account.is_writable()
{ {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Authorize nonce account: Account {} must be writeable", "Authorize nonce account: Account {} must be writeable",
self.unsigned_key() account.unsigned_key()
); );
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
match AccountUtilsState::<Versions>::state(self)?.convert_to_current() { match AccountUtilsState::<Versions>::state(account)?.convert_to_current() {
State::Initialized(data) => { State::Initialized(data) => {
if !signers.contains(&data.authority) { if !signers.contains(&data.authority) {
ic_msg!( ic_msg!(
@ -296,13 +267,13 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
data.blockhash, data.blockhash,
data.get_lamports_per_signature(), data.get_lamports_per_signature(),
); );
self.set_state(&Versions::new_current(State::Initialized(new_data))) account.set_state(&Versions::new_current(State::Initialized(new_data)))
} }
_ => { _ => {
ic_msg!( ic_msg!(
invoke_context, invoke_context,
"Authorize nonce account: Account {} state is invalid", "Authorize nonce account: Account {} state is invalid",
self.unsigned_key() account.unsigned_key()
); );
Err(nonce_to_instruction_error( Err(nonce_to_instruction_error(
NonceError::BadAccountState, NonceError::BadAccountState,
@ -311,7 +282,6 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
} }
} }
} }
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
@ -417,8 +387,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -436,8 +410,11 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] advance_nonce_account(
.advance_nonce_account(&signers, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -455,8 +432,11 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] advance_nonce_account(
.advance_nonce_account(&signers, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&signers,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -482,8 +462,8 @@ mod test {
let expect_to_lamports = to_account.get_lamports() + withdraw_lamports; let expect_to_lamports = to_account.get_lamports() + withdraw_lamports;
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -524,8 +504,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authority, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authority,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -544,8 +528,11 @@ mod test {
// 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 = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = advance_nonce_account(
.advance_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));
} }
@ -566,11 +553,18 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = advance_nonce_account(
.advance_nonce_account(&signers, &invoke_context); &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()));
} }
@ -590,8 +584,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);
drop(nonce_account); drop(nonce_account);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = advance_nonce_account(
.advance_nonce_account(&signers, &invoke_context); &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));
} }
@ -616,14 +613,21 @@ mod test {
let authorized = *nonce_authority.get_key(); let authorized = *nonce_authority.get_key();
drop(nonce_account); drop(nonce_account);
drop(nonce_authority); drop(nonce_authority);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .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 = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = advance_nonce_account(
.advance_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(()));
} }
@ -648,11 +652,18 @@ mod test {
let authorized = *nonce_authority.get_key(); let authorized = *nonce_authority.get_key();
drop(nonce_account); drop(nonce_account);
drop(nonce_authority); drop(nonce_authority);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = advance_nonce_account(
.advance_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));
} }
@ -684,8 +695,8 @@ mod test {
let expect_to_lamports = to_account.get_lamports() + withdraw_lamports; let expect_to_lamports = to_account.get_lamports() + withdraw_lamports;
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -733,8 +744,8 @@ mod test {
let withdraw_lamports = nonce_account.get_lamports(); let withdraw_lamports = nonce_account.get_lamports();
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -766,8 +777,8 @@ mod test {
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let withdraw_lamports = nonce_account.get_lamports() + 1; let withdraw_lamports = nonce_account.get_lamports() + 1;
drop(nonce_account); drop(nonce_account);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -800,8 +811,8 @@ mod test {
let to_expect_lamports = to_account.get_lamports() + withdraw_lamports; let to_expect_lamports = to_account.get_lamports() + withdraw_lamports;
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -827,8 +838,8 @@ mod test {
let to_expect_lamports = to_account.get_lamports() + withdraw_lamports; let to_expect_lamports = to_account.get_lamports() + withdraw_lamports;
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -872,8 +883,12 @@ mod test {
let authority = *nonce_account.get_key(); let authority = *nonce_account.get_key();
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authority, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authority,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -896,8 +911,8 @@ mod test {
let to_expect_lamports = to_account.get_lamports() + withdraw_lamports; let to_expect_lamports = to_account.get_lamports() + withdraw_lamports;
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -929,8 +944,8 @@ mod test {
let to_expect_lamports = to_account.get_lamports() + withdraw_lamports; let to_expect_lamports = to_account.get_lamports() + withdraw_lamports;
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -972,8 +987,12 @@ mod test {
let authorized = *nonce_account.get_key(); let authorized = *nonce_account.get_key();
drop(nonce_account); drop(nonce_account);
drop(to_account); drop(to_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -982,8 +1001,8 @@ mod test {
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);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -1008,8 +1027,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 63); set_invoke_context_blockhash!(invoke_context, 63);
let nonce_account = instruction_context let nonce_account = instruction_context
@ -1019,8 +1042,8 @@ mod test {
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 = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -1045,8 +1068,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -1056,8 +1083,8 @@ mod test {
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 = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -1082,8 +1109,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -1093,8 +1124,8 @@ mod test {
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 = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = withdraw_nonce_account(
.withdraw_nonce_account( &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
withdraw_lamports, withdraw_lamports,
&invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX], &invoke_context.get_keyed_accounts().unwrap()[1 + WITHDRAW_TO_ACCOUNT_INDEX],
&rent, &rent,
@ -1126,8 +1157,12 @@ mod test {
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); drop(nonce_account);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = initialize_nonce_account(
.initialize_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 let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
.unwrap(); .unwrap();
@ -1159,12 +1194,20 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 0); set_invoke_context_blockhash!(invoke_context, 0);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = initialize_nonce_account(
.initialize_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::InvalidAccountData)); assert_eq!(result, Err(InstructionError::InvalidAccountData));
} }
@ -1184,8 +1227,12 @@ mod test {
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); drop(nonce_account);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = initialize_nonce_account(
.initialize_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));
} }
@ -1206,8 +1253,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let authority = Pubkey::default(); let authority = Pubkey::default();
let data = nonce::state::Data::new( let data = nonce::state::Data::new(
@ -1215,8 +1266,12 @@ mod test {
invoke_context.blockhash, invoke_context.blockhash,
invoke_context.lamports_per_signature, invoke_context.lamports_per_signature,
); );
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] authorize_nonce_account(
.authorize_nonce_account(&authority, &signers, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authority,
&signers,
&invoke_context,
)
.unwrap(); .unwrap();
let nonce_account = instruction_context let nonce_account = instruction_context
.try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX)
@ -1243,8 +1298,12 @@ mod test {
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); drop(nonce_account);
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = authorize_nonce_account(
.authorize_nonce_account(&Pubkey::default(), &signers, &invoke_context); &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&Pubkey::default(),
&signers,
&invoke_context,
);
assert_eq!(result, Err(InstructionError::InvalidAccountData)); assert_eq!(result, Err(InstructionError::InvalidAccountData));
} }
@ -1265,11 +1324,19 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
let result = invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] let result = authorize_nonce_account(
.authorize_nonce_account(&authorized, &signers, &invoke_context); &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));
} }
@ -1293,8 +1360,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &rent, &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&rent,
&invoke_context,
)
.unwrap(); .unwrap();
assert!(verify_nonce_account( assert!(verify_nonce_account(
&transaction_context &transaction_context
@ -1343,8 +1414,12 @@ mod test {
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); drop(nonce_account);
invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX] initialize_nonce_account(
.initialize_nonce_account(&authorized, &Rent::free(), &invoke_context) &invoke_context.get_keyed_accounts().unwrap()[1 + NONCE_ACCOUNT_INDEX],
&authorized,
&Rent::free(),
&invoke_context,
)
.unwrap(); .unwrap();
set_invoke_context_blockhash!(invoke_context, 1); set_invoke_context_blockhash!(invoke_context, 1);
assert!(!verify_nonce_account( assert!(!verify_nonce_account(

View File

@ -1,5 +1,8 @@
use { use {
crate::nonce_keyed_account::NonceKeyedAccount, crate::nonce_keyed_account::{
advance_nonce_account, authorize_nonce_account, initialize_nonce_account,
withdraw_nonce_account,
},
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_check,
@ -361,7 +364,7 @@ pub fn process_instruction(
); );
return Err(NonceError::NoRecentBlockhashes.into()); return Err(NonceError::NoRecentBlockhashes.into());
} }
me.advance_nonce_account(&signers, invoke_context) advance_nonce_account(me, &signers, invoke_context)
} }
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)?;
@ -375,7 +378,7 @@ pub fn process_instruction(
keyed_account_at_index(keyed_accounts, first_instruction_account + 3)?, keyed_account_at_index(keyed_accounts, first_instruction_account + 3)?,
invoke_context, invoke_context,
)?; )?;
me.withdraw_nonce_account(lamports, to, &rent, &signers, invoke_context) withdraw_nonce_account(me, lamports, to, &rent, &signers, invoke_context)
} }
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)?;
@ -395,11 +398,11 @@ pub fn process_instruction(
keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?, keyed_account_at_index(keyed_accounts, first_instruction_account + 2)?,
invoke_context, invoke_context,
)?; )?;
me.initialize_nonce_account(&authorized, &rent, invoke_context) initialize_nonce_account(me, &authorized, &rent, invoke_context)
} }
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(me, &nonce_authority, &signers, invoke_context)
} }
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)?;