Nonce gets blockhash from invoke_context (#18950)

This commit is contained in:
Jack May
2021-07-29 01:50:20 -07:00
committed by GitHub
parent c0d2e81e89
commit 9529284194
6 changed files with 306 additions and 394 deletions

View File

@@ -1,6 +1,4 @@
use log::*;
#[allow(deprecated)]
use solana_sdk::sysvar::recent_blockhashes::RecentBlockhashes;
use solana_sdk::{
account::{AccountSharedData, ReadableAccount, WritableAccount},
account_utils::StateMut,
@@ -12,7 +10,7 @@ use solana_sdk::{
process_instruction::InvokeContext,
program_utils::limited_deserialize,
pubkey::Pubkey,
system_instruction::{SystemError, SystemInstruction, MAX_PERMITTED_DATA_LENGTH},
system_instruction::{NonceError, SystemError, SystemInstruction, MAX_PERMITTED_DATA_LENGTH},
system_program,
sysvar::{self, rent::Rent},
};
@@ -353,27 +351,30 @@ pub fn process_instruction(
}
SystemInstruction::AdvanceNonceAccount => {
let me = &mut keyed_account_at_index(keyed_accounts, 0)?;
me.advance_nonce_account(
#[allow(deprecated)]
&from_keyed_account::<RecentBlockhashes>(keyed_account_at_index(
keyed_accounts,
1,
)?)?,
&signers,
invoke_context,
)
#[allow(deprecated)]
if from_keyed_account::<solana_sdk::sysvar::recent_blockhashes::RecentBlockhashes>(
keyed_account_at_index(keyed_accounts, 1)?,
)?
.is_empty()
{
ic_msg!(
invoke_context,
"Advance nonce account: recent blockhash list is empty",
);
return Err(NonceError::NoRecentBlockhashes.into());
}
me.advance_nonce_account(&signers, invoke_context)
}
SystemInstruction::WithdrawNonceAccount(lamports) => {
let me = &mut keyed_account_at_index(keyed_accounts, 0)?;
let to = &mut keyed_account_at_index(keyed_accounts, 1)?;
#[allow(deprecated)]
let _ = from_keyed_account::<solana_sdk::sysvar::recent_blockhashes::RecentBlockhashes>(
keyed_account_at_index(keyed_accounts, 2)?,
)?;
me.withdraw_nonce_account(
lamports,
to,
#[allow(deprecated)]
&from_keyed_account::<RecentBlockhashes>(keyed_account_at_index(
keyed_accounts,
2,
)?)?,
&from_keyed_account::<Rent>(keyed_account_at_index(keyed_accounts, 3)?)?,
&signers,
invoke_context,
@@ -381,13 +382,20 @@ pub fn process_instruction(
}
SystemInstruction::InitializeNonceAccount(authorized) => {
let me = &mut keyed_account_at_index(keyed_accounts, 0)?;
#[allow(deprecated)]
if from_keyed_account::<solana_sdk::sysvar::recent_blockhashes::RecentBlockhashes>(
keyed_account_at_index(keyed_accounts, 1)?,
)?
.is_empty()
{
ic_msg!(
invoke_context,
"Initialize nonce account: recent blockhash list is empty",
);
return Err(NonceError::NoRecentBlockhashes.into());
}
me.initialize_nonce_account(
&authorized,
#[allow(deprecated)]
&from_keyed_account::<RecentBlockhashes>(keyed_account_at_index(
keyed_accounts,
1,
)?)?,
&from_keyed_account::<Rent>(keyed_account_at_index(keyed_accounts, 2)?)?,
invoke_context,
)
@@ -1562,33 +1570,30 @@ mod tests {
&serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(),
)
.unwrap();
let blockhash = &hash(&serialize(&0).unwrap());
let new_recent_blockhashes_account = RefCell::new(
#[allow(deprecated)]
solana_sdk::recent_blockhashes_account::create_account_with_data_for_test(
vec![
IterItem(
0u64,
&hash(&serialize(&0).unwrap()),
&FeeCalculator::default()
);
IterItem(0u64, blockhash, &FeeCalculator::default());
sysvar::recent_blockhashes::MAX_ENTRIES
]
.into_iter(),
),
);
let owner = Pubkey::default();
#[allow(deprecated)]
let blockhash_id = sysvar::recent_blockhashes::id();
let mut invoke_context = &mut MockInvokeContext::new(vec![
KeyedAccount::new(&owner, true, &nonce_acc),
KeyedAccount::new(&blockhash_id, false, &new_recent_blockhashes_account),
]);
invoke_context.blockhash = *blockhash;
assert_eq!(
process_instruction(
super::process_instruction(
&Pubkey::default(),
vec![
KeyedAccount::new(&Pubkey::default(), true, &nonce_acc,),
#[allow(deprecated)]
KeyedAccount::new(
&sysvar::recent_blockhashes::id(),
false,
&new_recent_blockhashes_account,
),
],
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(),
invoke_context,
),
Ok(()),
);
@@ -1902,4 +1907,75 @@ mod tests {
.unwrap();
assert_eq!(get_system_account_kind(&nonce_account), None);
}
#[test]
fn test_nonce_initialize_with_empty_recent_blockhashes_fail() {
let nonce_acc = nonce_account::create_account(1_000_000);
let new_recent_blockhashes_account = RefCell::new(
#[allow(deprecated)]
solana_sdk::recent_blockhashes_account::create_account_with_data_for_test(
vec![].into_iter(),
),
);
assert_eq!(
process_instruction(
&Pubkey::default(),
vec![
KeyedAccount::new(&Pubkey::default(), true, &nonce_acc),
KeyedAccount::new(
#[allow(deprecated)]
&sysvar::recent_blockhashes::id(),
false,
&new_recent_blockhashes_account,
),
KeyedAccount::new(&sysvar::rent::id(), false, &create_default_rent_account()),
],
&serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(),
),
Err(NonceError::NoRecentBlockhashes.into())
);
}
#[test]
fn test_nonce_advance_with_empty_recent_blockhashes_fail() {
let nonce_acc = nonce_account::create_account(1_000_000);
process_instruction(
&Pubkey::default(),
vec![
KeyedAccount::new(&Pubkey::default(), true, &nonce_acc),
KeyedAccount::new(
#[allow(deprecated)]
&sysvar::recent_blockhashes::id(),
false,
&create_default_recent_blockhashes_account(),
),
KeyedAccount::new(&sysvar::rent::id(), false, &create_default_rent_account()),
],
&serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(),
)
.unwrap();
let blockhash = &hash(&serialize(&0).unwrap());
let new_recent_blockhashes_account = RefCell::new(
#[allow(deprecated)]
solana_sdk::recent_blockhashes_account::create_account_with_data_for_test(
vec![].into_iter(),
),
);
let owner = Pubkey::default();
#[allow(deprecated)]
let blockhash_id = sysvar::recent_blockhashes::id();
let mut invoke_context = &mut MockInvokeContext::new(vec![
KeyedAccount::new(&owner, true, &nonce_acc),
KeyedAccount::new(&blockhash_id, false, &new_recent_blockhashes_account),
]);
invoke_context.blockhash = *blockhash;
assert_eq!(
super::process_instruction(
&Pubkey::default(),
&serialize(&SystemInstruction::AdvanceNonceAccount).unwrap(),
invoke_context,
),
Err(NonceError::NoRecentBlockhashes.into()),
);
}
}