2019-12-07 12:54:10 -07:00
|
|
|
use crate::{
|
|
|
|
account::{Account, KeyedAccount},
|
|
|
|
account_utils::State,
|
|
|
|
hash::Hash,
|
|
|
|
instruction::InstructionError,
|
|
|
|
pubkey::Pubkey,
|
2020-01-03 19:34:58 -05:00
|
|
|
system_instruction::NonceError,
|
|
|
|
system_program,
|
2019-12-07 12:54:10 -07:00
|
|
|
sysvar::recent_blockhashes::RecentBlockhashes,
|
|
|
|
sysvar::rent::Rent,
|
|
|
|
};
|
|
|
|
use serde_derive::{Deserialize, Serialize};
|
2020-01-22 09:11:56 -08:00
|
|
|
use std::{cell::RefCell, collections::HashSet};
|
2019-12-07 12:54:10 -07:00
|
|
|
|
|
|
|
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy)]
|
2019-12-17 09:34:21 -05:00
|
|
|
pub struct Meta {
|
|
|
|
pub nonce_authority: Pubkey,
|
|
|
|
}
|
2019-12-07 12:54:10 -07:00
|
|
|
|
|
|
|
impl Meta {
|
2019-12-17 09:34:21 -05:00
|
|
|
pub fn new(nonce_authority: &Pubkey) -> Self {
|
|
|
|
Self {
|
|
|
|
nonce_authority: *nonce_authority,
|
|
|
|
}
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
|
|
|
|
pub enum NonceState {
|
|
|
|
Uninitialized,
|
|
|
|
Initialized(Meta, Hash),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for NonceState {
|
|
|
|
fn default() -> Self {
|
|
|
|
NonceState::Uninitialized
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl NonceState {
|
|
|
|
pub fn size() -> usize {
|
|
|
|
bincode::serialized_size(&NonceState::Initialized(Meta::default(), Hash::default()))
|
|
|
|
.unwrap() as usize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait NonceAccount {
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_advance(
|
2019-12-07 12:54:10 -07:00
|
|
|
&mut self,
|
|
|
|
recent_blockhashes: &RecentBlockhashes,
|
|
|
|
signers: &HashSet<Pubkey>,
|
|
|
|
) -> Result<(), InstructionError>;
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
&mut self,
|
|
|
|
lamports: u64,
|
|
|
|
to: &mut KeyedAccount,
|
|
|
|
recent_blockhashes: &RecentBlockhashes,
|
|
|
|
rent: &Rent,
|
|
|
|
signers: &HashSet<Pubkey>,
|
|
|
|
) -> Result<(), InstructionError>;
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_initialize(
|
2019-12-08 10:16:55 -07:00
|
|
|
&mut self,
|
2019-12-17 09:34:21 -05:00
|
|
|
nonce_authority: &Pubkey,
|
2019-12-08 10:16:55 -07:00
|
|
|
recent_blockhashes: &RecentBlockhashes,
|
|
|
|
rent: &Rent,
|
|
|
|
) -> Result<(), InstructionError>;
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_authorize(
|
2019-12-17 09:34:21 -05:00
|
|
|
&mut self,
|
|
|
|
nonce_authority: &Pubkey,
|
|
|
|
signers: &HashSet<Pubkey>,
|
|
|
|
) -> Result<(), InstructionError>;
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> NonceAccount for KeyedAccount<'a> {
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_advance(
|
2019-12-07 12:54:10 -07:00
|
|
|
&mut self,
|
|
|
|
recent_blockhashes: &RecentBlockhashes,
|
|
|
|
signers: &HashSet<Pubkey>,
|
|
|
|
) -> Result<(), InstructionError> {
|
|
|
|
if recent_blockhashes.is_empty() {
|
|
|
|
return Err(NonceError::NoRecentBlockhashes.into());
|
|
|
|
}
|
|
|
|
|
|
|
|
let meta = match self.state()? {
|
|
|
|
NonceState::Initialized(meta, ref hash) => {
|
2019-12-17 09:34:21 -05:00
|
|
|
if !signers.contains(&meta.nonce_authority) {
|
|
|
|
return Err(InstructionError::MissingRequiredSignature);
|
|
|
|
}
|
2019-12-07 12:54:10 -07:00
|
|
|
if *hash == recent_blockhashes[0] {
|
|
|
|
return Err(NonceError::NotExpired.into());
|
|
|
|
}
|
|
|
|
meta
|
|
|
|
}
|
2019-12-08 10:16:55 -07:00
|
|
|
_ => return Err(NonceError::BadAccountState.into()),
|
2019-12-07 12:54:10 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
self.set_state(&NonceState::Initialized(meta, recent_blockhashes[0]))
|
|
|
|
}
|
|
|
|
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
&mut self,
|
|
|
|
lamports: u64,
|
|
|
|
to: &mut KeyedAccount,
|
|
|
|
recent_blockhashes: &RecentBlockhashes,
|
|
|
|
rent: &Rent,
|
|
|
|
signers: &HashSet<Pubkey>,
|
|
|
|
) -> Result<(), InstructionError> {
|
2019-12-17 09:34:21 -05:00
|
|
|
let signer = match self.state()? {
|
2019-12-07 12:54:10 -07:00
|
|
|
NonceState::Uninitialized => {
|
2020-01-22 09:11:56 -08:00
|
|
|
if lamports > self.lamports()? {
|
2019-12-07 12:54:10 -07:00
|
|
|
return Err(InstructionError::InsufficientFunds);
|
|
|
|
}
|
2019-12-17 09:34:21 -05:00
|
|
|
*self.unsigned_key()
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|
2019-12-17 09:34:21 -05:00
|
|
|
NonceState::Initialized(meta, ref hash) => {
|
2020-01-22 09:11:56 -08:00
|
|
|
if lamports == self.lamports()? {
|
2019-12-07 12:54:10 -07:00
|
|
|
if *hash == recent_blockhashes[0] {
|
|
|
|
return Err(NonceError::NotExpired.into());
|
|
|
|
}
|
|
|
|
} else {
|
2020-01-22 09:11:56 -08:00
|
|
|
let min_balance = rent.minimum_balance(self.data_len()?);
|
|
|
|
if lamports + min_balance > self.lamports()? {
|
2019-12-07 12:54:10 -07:00
|
|
|
return Err(InstructionError::InsufficientFunds);
|
|
|
|
}
|
|
|
|
}
|
2019-12-17 09:34:21 -05:00
|
|
|
meta.nonce_authority
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|
2019-12-17 09:34:21 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
if !signers.contains(&signer) {
|
|
|
|
return Err(InstructionError::MissingRequiredSignature);
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|
|
|
|
|
2020-01-22 09:11:56 -08:00
|
|
|
self.try_account_ref_mut()?.lamports -= lamports;
|
|
|
|
to.try_account_ref_mut()?.lamports += lamports;
|
2019-12-07 12:54:10 -07:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2019-12-08 10:16:55 -07:00
|
|
|
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_initialize(
|
2019-12-08 10:16:55 -07:00
|
|
|
&mut self,
|
2019-12-17 09:34:21 -05:00
|
|
|
nonce_authority: &Pubkey,
|
2019-12-08 10:16:55 -07:00
|
|
|
recent_blockhashes: &RecentBlockhashes,
|
|
|
|
rent: &Rent,
|
|
|
|
) -> Result<(), InstructionError> {
|
|
|
|
if recent_blockhashes.is_empty() {
|
|
|
|
return Err(NonceError::NoRecentBlockhashes.into());
|
|
|
|
}
|
|
|
|
|
|
|
|
let meta = match self.state()? {
|
|
|
|
NonceState::Uninitialized => {
|
2020-01-22 09:11:56 -08:00
|
|
|
let min_balance = rent.minimum_balance(self.data_len()?);
|
|
|
|
if self.lamports()? < min_balance {
|
2019-12-08 10:16:55 -07:00
|
|
|
return Err(InstructionError::InsufficientFunds);
|
|
|
|
}
|
2019-12-17 09:34:21 -05:00
|
|
|
Meta::new(nonce_authority)
|
2019-12-08 10:16:55 -07:00
|
|
|
}
|
|
|
|
_ => return Err(NonceError::BadAccountState.into()),
|
|
|
|
};
|
|
|
|
|
|
|
|
self.set_state(&NonceState::Initialized(meta, recent_blockhashes[0]))
|
|
|
|
}
|
2019-12-17 09:34:21 -05:00
|
|
|
|
2020-01-03 19:34:58 -05:00
|
|
|
fn nonce_authorize(
|
2019-12-17 09:34:21 -05:00
|
|
|
&mut self,
|
|
|
|
nonce_authority: &Pubkey,
|
|
|
|
signers: &HashSet<Pubkey>,
|
|
|
|
) -> Result<(), InstructionError> {
|
|
|
|
match self.state()? {
|
|
|
|
NonceState::Initialized(meta, nonce) => {
|
|
|
|
if !signers.contains(&meta.nonce_authority) {
|
|
|
|
return Err(InstructionError::MissingRequiredSignature);
|
|
|
|
}
|
|
|
|
self.set_state(&NonceState::Initialized(Meta::new(nonce_authority), nonce))
|
|
|
|
}
|
|
|
|
_ => Err(NonceError::BadAccountState.into()),
|
|
|
|
}
|
|
|
|
}
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|
|
|
|
|
2020-01-22 09:11:56 -08:00
|
|
|
pub fn create_account(lamports: u64) -> RefCell<Account> {
|
|
|
|
RefCell::new(
|
|
|
|
Account::new_data_with_space(
|
|
|
|
lamports,
|
|
|
|
&NonceState::Uninitialized,
|
|
|
|
NonceState::size(),
|
|
|
|
&system_program::id(),
|
|
|
|
)
|
|
|
|
.expect("nonce_account"),
|
2019-12-07 12:54:10 -07:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convenience function for working with keyed accounts in tests
|
|
|
|
#[cfg(not(feature = "program"))]
|
|
|
|
pub fn with_test_keyed_account<F>(lamports: u64, signer: bool, mut f: F)
|
|
|
|
where
|
|
|
|
F: FnMut(&mut KeyedAccount),
|
|
|
|
{
|
|
|
|
let pubkey = Pubkey::new_rand();
|
2020-01-22 09:11:56 -08:00
|
|
|
let account = create_account(lamports);
|
|
|
|
let mut keyed_account = KeyedAccount::new(&pubkey, signer, &account);
|
2019-12-07 12:54:10 -07:00
|
|
|
f(&mut keyed_account)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::*;
|
|
|
|
use crate::{
|
|
|
|
account::KeyedAccount,
|
2020-01-03 19:34:58 -05:00
|
|
|
system_instruction::NonceError,
|
2019-12-07 12:54:10 -07:00
|
|
|
sysvar::recent_blockhashes::{create_test_recent_blockhashes, RecentBlockhashes},
|
|
|
|
};
|
|
|
|
use std::iter::FromIterator;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn default_is_uninitialized() {
|
|
|
|
assert_eq!(NonceState::default(), NonceState::Uninitialized)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn new_meta() {
|
2019-12-17 09:34:21 -05:00
|
|
|
let nonce_authority = Pubkey::default();
|
|
|
|
assert_eq!(Meta::new(&nonce_authority), Meta { nonce_authority });
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn keyed_account_expected_behavior() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |keyed_account| {
|
2019-12-17 09:34:21 -05:00
|
|
|
let meta = Meta::new(&keyed_account.unsigned_key());
|
2019-12-07 12:54:10 -07:00
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(keyed_account.signer_key().unwrap().clone());
|
|
|
|
let state: NonceState = keyed_account.state().unwrap();
|
|
|
|
// New is in Uninitialzed state
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(95);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = keyed_account.unsigned_key().clone();
|
2019-12-07 12:54:10 -07:00
|
|
|
keyed_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-07 12:54:10 -07:00
|
|
|
.unwrap();
|
|
|
|
let state: NonceState = keyed_account.state().unwrap();
|
|
|
|
let stored = recent_blockhashes[0];
|
|
|
|
// First nonce instruction drives state from Uninitialized to Initialized
|
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
2020-01-03 19:34:58 -05:00
|
|
|
keyed_account
|
|
|
|
.nonce_advance(&recent_blockhashes, &signers)
|
|
|
|
.unwrap();
|
2019-12-07 12:54:10 -07:00
|
|
|
let state: NonceState = keyed_account.state().unwrap();
|
|
|
|
let stored = recent_blockhashes[0];
|
|
|
|
// Second nonce instruction consumes and replaces stored nonce
|
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(31);
|
2020-01-03 19:34:58 -05:00
|
|
|
keyed_account
|
|
|
|
.nonce_advance(&recent_blockhashes, &signers)
|
|
|
|
.unwrap();
|
2019-12-07 12:54:10 -07:00
|
|
|
let state: NonceState = keyed_account.state().unwrap();
|
|
|
|
let stored = recent_blockhashes[0];
|
|
|
|
// Third nonce instruction for fun and profit
|
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = keyed_account.account.borrow().lamports;
|
|
|
|
let expect_nonce_lamports =
|
|
|
|
keyed_account.account.borrow().lamports - withdraw_lamports;
|
|
|
|
let expect_to_lamports = to_keyed.account.borrow().lamports + withdraw_lamports;
|
2019-12-07 12:54:10 -07:00
|
|
|
keyed_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
// Empties NonceAccount balance
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(
|
|
|
|
keyed_account.account.borrow().lamports,
|
|
|
|
expect_nonce_lamports
|
|
|
|
);
|
2019-12-07 12:54:10 -07:00
|
|
|
// NonceAccount balance goes to `to`
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(to_keyed.account.borrow().lamports, expect_to_lamports);
|
2019-12-07 12:54:10 -07:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nonce_inx_initialized_account_not_signer_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_account| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(31);
|
|
|
|
let stored = recent_blockhashes[0];
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = nonce_account.unsigned_key().clone();
|
|
|
|
let meta = Meta::new(&authorized);
|
2019-12-07 12:54:10 -07:00
|
|
|
nonce_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-07 12:54:10 -07:00
|
|
|
.unwrap();
|
2020-01-22 09:11:56 -08:00
|
|
|
let pubkey = nonce_account.account.borrow().owner.clone();
|
2019-12-07 12:54:10 -07:00
|
|
|
let mut nonce_account = KeyedAccount::new(&pubkey, false, nonce_account.account);
|
|
|
|
let state: NonceState = nonce_account.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
|
|
|
let signers = HashSet::new();
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_account.nonce_advance(&recent_blockhashes, &signers);
|
2019-12-07 12:54:10 -07:00
|
|
|
assert_eq!(result, Err(InstructionError::MissingRequiredSignature),);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nonce_inx_with_empty_recent_blockhashes_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |keyed_account| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(keyed_account.signer_key().unwrap().clone());
|
2019-12-08 10:16:55 -07:00
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = keyed_account.unsigned_key().clone();
|
2019-12-08 10:16:55 -07:00
|
|
|
keyed_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-08 10:16:55 -07:00
|
|
|
.unwrap();
|
2019-12-07 12:54:10 -07:00
|
|
|
let recent_blockhashes = RecentBlockhashes::from_iter(vec![].into_iter());
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = keyed_account.nonce_advance(&recent_blockhashes, &signers);
|
2019-12-07 12:54:10 -07:00
|
|
|
assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into()));
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nonce_inx_too_early_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |keyed_account| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(keyed_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = keyed_account.unsigned_key().clone();
|
2019-12-07 12:54:10 -07:00
|
|
|
keyed_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-07 12:54:10 -07:00
|
|
|
.unwrap();
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = keyed_account.nonce_advance(&recent_blockhashes, &signers);
|
2019-12-07 12:54:10 -07:00
|
|
|
assert_eq!(result, Err(NonceError::NotExpired.into()));
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2019-12-08 10:16:55 -07:00
|
|
|
fn nonce_inx_uninitialized_account_fail() {
|
2019-12-07 12:54:10 -07:00
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
2019-12-08 10:16:55 -07:00
|
|
|
with_test_keyed_account(min_lamports + 42, true, |keyed_account| {
|
2019-12-07 12:54:10 -07:00
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(keyed_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = keyed_account.nonce_advance(&recent_blockhashes, &signers);
|
2019-12-08 10:16:55 -07:00
|
|
|
assert_eq!(result, Err(NonceError::BadAccountState.into()));
|
2019-12-07 12:54:10 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-12-17 09:34:21 -05:00
|
|
|
#[test]
|
|
|
|
fn nonce_inx_independent_nonce_authority_ok() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_account| {
|
|
|
|
with_test_keyed_account(42, true, |nonce_authority| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
|
|
|
let authorized = nonce_authority.unsigned_key().clone();
|
|
|
|
nonce_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_authority.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(31);
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_account.nonce_advance(&recent_blockhashes, &signers);
|
2019-12-17 09:34:21 -05:00
|
|
|
assert_eq!(result, Ok(()));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn nonce_inx_no_nonce_authority_sig_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_account| {
|
|
|
|
with_test_keyed_account(42, false, |nonce_authority| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
|
|
|
let authorized = nonce_authority.unsigned_key().clone();
|
|
|
|
nonce_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_account.nonce_advance(&recent_blockhashes, &signers);
|
2019-12-17 09:34:21 -05:00
|
|
|
assert_eq!(result, Err(InstructionError::MissingRequiredSignature),);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-12-07 12:54:10 -07:00
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_unintialized_acc_ok() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| {
|
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_keyed.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports;
|
|
|
|
let expect_nonce_lamports =
|
|
|
|
nonce_keyed.account.borrow().lamports - withdraw_lamports;
|
|
|
|
let expect_to_lamports = to_keyed.account.borrow().lamports + withdraw_lamports;
|
2019-12-07 12:54:10 -07:00
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
// Withdraw instruction...
|
|
|
|
// Deinitializes NonceAccount state
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
|
|
|
// Empties NonceAccount balance
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(nonce_keyed.account.borrow().lamports, expect_nonce_lamports);
|
2019-12-07 12:54:10 -07:00
|
|
|
// NonceAccount balance goes to `to`
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(to_keyed.account.borrow().lamports, expect_to_lamports);
|
2019-12-07 12:54:10 -07:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_unintialized_acc_unsigned_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, false, |nonce_keyed| {
|
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let signers = HashSet::new();
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-22 09:11:56 -08:00
|
|
|
let lamports = nonce_keyed.account.borrow().lamports;
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_keyed.nonce_withdraw(
|
2020-01-22 09:11:56 -08:00
|
|
|
lamports,
|
2019-12-07 12:54:10 -07:00
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
);
|
|
|
|
assert_eq!(result, Err(InstructionError::MissingRequiredSignature),);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_unintialized_acc_insuff_funds_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| {
|
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_keyed.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-22 09:11:56 -08:00
|
|
|
let lamports = nonce_keyed.account.borrow().lamports + 1;
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_keyed.nonce_withdraw(
|
2020-01-22 09:11:56 -08:00
|
|
|
lamports,
|
2019-12-07 12:54:10 -07:00
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
);
|
|
|
|
assert_eq!(result, Err(InstructionError::InsufficientFunds));
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_uninitialized_acc_two_withdraws_ok() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| {
|
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_keyed.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports / 2;
|
|
|
|
let nonce_expect_lamports =
|
|
|
|
nonce_keyed.account.borrow().lamports - withdraw_lamports;
|
|
|
|
let to_expect_lamports = to_keyed.account.borrow().lamports + withdraw_lamports;
|
2019-12-07 12:54:10 -07:00
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(nonce_keyed.account.borrow().lamports, nonce_expect_lamports);
|
|
|
|
assert_eq!(to_keyed.account.borrow().lamports, to_expect_lamports);
|
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports;
|
|
|
|
let nonce_expect_lamports =
|
|
|
|
nonce_keyed.account.borrow().lamports - withdraw_lamports;
|
|
|
|
let to_expect_lamports = to_keyed.account.borrow().lamports + withdraw_lamports;
|
2019-12-07 12:54:10 -07:00
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(nonce_keyed.account.borrow().lamports, nonce_expect_lamports);
|
|
|
|
assert_eq!(to_keyed.account.borrow().lamports, to_expect_lamports);
|
2019-12-07 12:54:10 -07:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_initialized_acc_two_withdraws_ok() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_keyed.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(31);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = nonce_keyed.unsigned_key().clone();
|
|
|
|
let meta = Meta::new(&authorized);
|
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
2019-12-07 12:54:10 -07:00
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
let stored = recent_blockhashes[0];
|
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports - min_lamports;
|
|
|
|
let nonce_expect_lamports =
|
|
|
|
nonce_keyed.account.borrow().lamports - withdraw_lamports;
|
|
|
|
let to_expect_lamports = to_keyed.account.borrow().lamports + withdraw_lamports;
|
2019-12-07 12:54:10 -07:00
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
let state: NonceState = nonce_keyed.state().unwrap();
|
|
|
|
let stored = recent_blockhashes[0];
|
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(nonce_keyed.account.borrow().lamports, nonce_expect_lamports);
|
|
|
|
assert_eq!(to_keyed.account.borrow().lamports, to_expect_lamports);
|
2019-12-07 12:54:10 -07:00
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports;
|
|
|
|
let nonce_expect_lamports =
|
|
|
|
nonce_keyed.account.borrow().lamports - withdraw_lamports;
|
|
|
|
let to_expect_lamports = to_keyed.account.borrow().lamports + withdraw_lamports;
|
2019-12-07 12:54:10 -07:00
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
)
|
|
|
|
.unwrap();
|
2020-01-22 09:11:56 -08:00
|
|
|
assert_eq!(nonce_keyed.account.borrow().lamports, nonce_expect_lamports);
|
|
|
|
assert_eq!(to_keyed.account.borrow().lamports, to_expect_lamports);
|
2019-12-07 12:54:10 -07:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_initialized_acc_nonce_too_early_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = nonce_keyed.unsigned_key().clone();
|
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
2019-12-07 12:54:10 -07:00
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_keyed.signer_key().unwrap().clone());
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports;
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_keyed.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
);
|
|
|
|
assert_eq!(result, Err(NonceError::NotExpired.into()));
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_initialized_acc_insuff_funds_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(95);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = nonce_keyed.unsigned_key().clone();
|
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
2019-12-07 12:54:10 -07:00
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_keyed.signer_key().unwrap().clone());
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports + 1;
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_keyed.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
);
|
|
|
|
assert_eq!(result, Err(InstructionError::InsufficientFunds));
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn withdraw_inx_initialized_acc_insuff_rent_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(95);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = nonce_keyed.unsigned_key().clone();
|
|
|
|
nonce_keyed
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
2019-12-07 12:54:10 -07:00
|
|
|
with_test_keyed_account(42, false, |mut to_keyed| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_keyed.signer_key().unwrap().clone());
|
2020-01-22 09:11:56 -08:00
|
|
|
let withdraw_lamports = nonce_keyed.account.borrow().lamports - min_lamports + 1;
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_keyed.nonce_withdraw(
|
2019-12-07 12:54:10 -07:00
|
|
|
withdraw_lamports,
|
|
|
|
&mut to_keyed,
|
|
|
|
&recent_blockhashes,
|
|
|
|
&rent,
|
|
|
|
&signers,
|
|
|
|
);
|
|
|
|
assert_eq!(result, Err(InstructionError::InsufficientFunds));
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
2019-12-08 10:16:55 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn initialize_inx_ok() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |keyed_account| {
|
|
|
|
let state: NonceState = keyed_account.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Uninitialized);
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(keyed_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
|
|
|
let stored = recent_blockhashes[0];
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = keyed_account.unsigned_key().clone();
|
|
|
|
let meta = Meta::new(&authorized);
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = keyed_account.nonce_initialize(&authorized, &recent_blockhashes, &rent);
|
2019-12-08 10:16:55 -07:00
|
|
|
assert_eq!(result, Ok(()));
|
|
|
|
let state: NonceState = keyed_account.state().unwrap();
|
2019-12-17 09:34:21 -05:00
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
2019-12-08 10:16:55 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn initialize_inx_empty_recent_blockhashes_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |keyed_account| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(keyed_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = RecentBlockhashes::from_iter(vec![].into_iter());
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = keyed_account.unsigned_key().clone();
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = keyed_account.nonce_initialize(&authorized, &recent_blockhashes, &rent);
|
2019-12-08 10:16:55 -07:00
|
|
|
assert_eq!(result, Err(NonceError::NoRecentBlockhashes.into()));
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn initialize_inx_initialized_account_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |keyed_account| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(31);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = keyed_account.unsigned_key().clone();
|
2019-12-08 10:16:55 -07:00
|
|
|
keyed_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-08 10:16:55 -07:00
|
|
|
.unwrap();
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(0);
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = keyed_account.nonce_initialize(&authorized, &recent_blockhashes, &rent);
|
2019-12-08 10:16:55 -07:00
|
|
|
assert_eq!(result, Err(NonceError::BadAccountState.into()));
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn initialize_inx_uninitialized_acc_insuff_funds_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports - 42, true, |keyed_account| {
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(63);
|
2019-12-17 09:34:21 -05:00
|
|
|
let authorized = keyed_account.unsigned_key().clone();
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = keyed_account.nonce_initialize(&authorized, &recent_blockhashes, &rent);
|
2019-12-08 10:16:55 -07:00
|
|
|
assert_eq!(result, Err(InstructionError::InsufficientFunds));
|
|
|
|
})
|
|
|
|
}
|
2019-12-17 09:34:21 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn authorize_inx_ok() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_account| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(31);
|
|
|
|
let stored = recent_blockhashes[0];
|
|
|
|
let authorized = nonce_account.unsigned_key().clone();
|
|
|
|
nonce_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
|
|
|
let authorized = &Pubkey::default().clone();
|
|
|
|
let meta = Meta::new(&authorized);
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_account.nonce_authorize(&Pubkey::default(), &signers);
|
2019-12-17 09:34:21 -05:00
|
|
|
assert_eq!(result, Ok(()));
|
|
|
|
let state: NonceState = nonce_account.state().unwrap();
|
|
|
|
assert_eq!(state, NonceState::Initialized(meta, stored));
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn authorize_inx_uninitialized_state_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_account| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_account.signer_key().unwrap().clone());
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_account.nonce_authorize(&Pubkey::default(), &signers);
|
2019-12-17 09:34:21 -05:00
|
|
|
assert_eq!(result, Err(NonceError::BadAccountState.into()));
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn authorize_inx_bad_authority_fail() {
|
|
|
|
let rent = Rent {
|
|
|
|
lamports_per_byte_year: 42,
|
|
|
|
..Rent::default()
|
|
|
|
};
|
|
|
|
let min_lamports = rent.minimum_balance(NonceState::size());
|
|
|
|
with_test_keyed_account(min_lamports + 42, true, |nonce_account| {
|
|
|
|
let mut signers = HashSet::new();
|
|
|
|
signers.insert(nonce_account.signer_key().unwrap().clone());
|
|
|
|
let recent_blockhashes = create_test_recent_blockhashes(31);
|
|
|
|
let authorized = &Pubkey::default().clone();
|
|
|
|
nonce_account
|
2020-01-03 19:34:58 -05:00
|
|
|
.nonce_initialize(&authorized, &recent_blockhashes, &rent)
|
2019-12-17 09:34:21 -05:00
|
|
|
.unwrap();
|
2020-01-03 19:34:58 -05:00
|
|
|
let result = nonce_account.nonce_authorize(&Pubkey::default(), &signers);
|
2019-12-17 09:34:21 -05:00
|
|
|
assert_eq!(result, Err(InstructionError::MissingRequiredSignature));
|
|
|
|
})
|
|
|
|
}
|
2019-12-07 12:54:10 -07:00
|
|
|
}
|