From be0cc0273ff123b0c0f31a2ca5b5cf95b0aaea48 Mon Sep 17 00:00:00 2001 From: Trent Nelson Date: Tue, 3 Mar 2020 18:00:39 -0700 Subject: [PATCH] SDK: Re-org nonce state module to facilitate versioning (#8603) automerge --- cli/src/cli.rs | 8 +- cli/src/nonce.rs | 38 ++-- cli/tests/pay.rs | 12 +- cli/tests/stake.rs | 48 ++--- cli/tests/transfer.rs | 16 +- runtime/src/accounts.rs | 15 +- runtime/src/bank.rs | 25 ++- runtime/src/nonce_utils.rs | 30 +-- runtime/src/system_instruction_processor.rs | 60 ++---- sdk/src/lib.rs | 2 +- sdk/src/{nonce_state.rs => nonce/account.rs} | 208 ++++++++----------- sdk/src/nonce/mod.rs | 4 + sdk/src/nonce/state.rs | 44 ++++ sdk/src/system_instruction.rs | 6 +- 14 files changed, 256 insertions(+), 260 deletions(-) rename sdk/src/{nonce_state.rs => nonce/account.rs} (83%) create mode 100644 sdk/src/nonce/mod.rs create mode 100644 sdk/src/nonce/state.rs diff --git a/cli/src/cli.rs b/cli/src/cli.rs index f484ffc50..9791fc6ef 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -2482,7 +2482,7 @@ mod tests { }; use solana_sdk::{ account::Account, - nonce_state::{Meta as NonceMeta, NonceState}, + nonce, pubkey::Pubkey, signature::{keypair_from_seed, read_keypair_file, write_keypair_file, Presigner}, system_program, @@ -3266,8 +3266,8 @@ mod tests { value: json!(RpcAccount::encode( Account::new_data( 1, - &NonceState::Initialized( - NonceMeta::new(&config.signers[0].pubkey()), + &nonce::State::Initialized( + nonce::state::Meta::new(&config.signers[0].pubkey()), blockhash ), &system_program::ID, @@ -3297,7 +3297,7 @@ mod tests { value: json!(RpcAccount::encode( Account::new_data( 1, - &NonceState::Initialized(NonceMeta::new(&bob_pubkey), blockhash), + &nonce::State::Initialized(nonce::state::Meta::new(&bob_pubkey), blockhash), &system_program::ID, ) .unwrap() diff --git a/cli/src/nonce.rs b/cli/src/nonce.rs index 6927560bf..6621cc038 100644 --- a/cli/src/nonce.rs +++ b/cli/src/nonce.rs @@ -14,7 +14,7 @@ use solana_sdk::{ account_utils::StateMut, hash::Hash, message::Message, - nonce_state::{Meta, NonceState}, + nonce::{self, State}, pubkey::Pubkey, system_instruction::{ advance_nonce_account, authorize_nonce_account, create_address_with_seed, @@ -363,11 +363,11 @@ pub fn check_nonce_account( if nonce_account.owner != system_program::ID { return Err(CliError::InvalidNonce(CliNonceError::InvalidAccountOwner).into()); } - let nonce_state: NonceState = nonce_account + let nonce_state: State = nonce_account .state() .map_err(|_| Box::new(CliError::InvalidNonce(CliNonceError::InvalidAccountData)))?; match nonce_state { - NonceState::Initialized(meta, hash) => { + State::Initialized(meta, hash) => { if &hash != nonce_hash { Err(CliError::InvalidNonce(CliNonceError::InvalidHash).into()) } else if nonce_authority != &meta.nonce_authority { @@ -376,9 +376,7 @@ pub fn check_nonce_account( Ok(()) } } - NonceState::Uninitialized => { - Err(CliError::InvalidNonce(CliNonceError::InvalidState).into()) - } + State::Uninitialized => Err(CliError::InvalidNonce(CliNonceError::InvalidState).into()), } } @@ -429,7 +427,7 @@ pub fn process_create_nonce_account( if let Ok(nonce_account) = rpc_client.get_account(&nonce_account_address) { let err_msg = if nonce_account.owner == system_program::id() - && StateMut::::state(&nonce_account).is_ok() + && StateMut::::state(&nonce_account).is_ok() { format!("Nonce account {} already exists", nonce_account_address) } else { @@ -441,7 +439,7 @@ pub fn process_create_nonce_account( return Err(CliError::BadParameter(err_msg).into()); } - let minimum_balance = rpc_client.get_minimum_balance_for_rent_exemption(NonceState::size())?; + let minimum_balance = rpc_client.get_minimum_balance_for_rent_exemption(State::size())?; if lamports < minimum_balance { return Err(CliError::BadParameter(format!( "need at least {} lamports for nonce account to be rent exempt, provided lamports: {}", @@ -496,8 +494,8 @@ pub fn process_get_nonce(rpc_client: &RpcClient, nonce_account_pubkey: &Pubkey) .into()); } match nonce_account.state() { - Ok(NonceState::Uninitialized) => Ok("Nonce account is uninitialized".to_string()), - Ok(NonceState::Initialized(_, hash)) => Ok(format!("{:?}", hash)), + Ok(State::Uninitialized) => Ok("Nonce account is uninitialized".to_string()), + Ok(State::Initialized(_, hash)) => Ok(format!("{:?}", hash)), Err(err) => Err(CliError::RpcRequestError(format!( "Account data could not be deserialized to nonce state: {:?}", err @@ -554,7 +552,7 @@ pub fn process_show_nonce_account( )) .into()); } - let print_account = |data: Option<(Meta, Hash)>| { + let print_account = |data: Option<(nonce::state::Meta, Hash)>| { println!( "Balance: {}", build_balance_message(nonce_account.lamports, use_lamports_unit, true) @@ -562,7 +560,7 @@ pub fn process_show_nonce_account( println!( "Minimum Balance Required: {}", build_balance_message( - rpc_client.get_minimum_balance_for_rent_exemption(NonceState::size())?, + rpc_client.get_minimum_balance_for_rent_exemption(State::size())?, use_lamports_unit, true ) @@ -580,8 +578,8 @@ pub fn process_show_nonce_account( Ok("".to_string()) }; match nonce_account.state() { - Ok(NonceState::Uninitialized) => print_account(None), - Ok(NonceState::Initialized(meta, hash)) => print_account(Some((meta, hash))), + Ok(State::Uninitialized) => print_account(None), + Ok(State::Initialized(meta, hash)) => print_account(Some((meta, hash))), Err(err) => Err(CliError::RpcRequestError(format!( "Account data could not be deserialized to nonce state: {:?}", err @@ -627,7 +625,7 @@ mod tests { use solana_sdk::{ account::Account, hash::hash, - nonce_state::{Meta as NonceMeta, NonceState}, + nonce::{self, State}, signature::{read_keypair_file, write_keypair, Keypair, Signer}, system_program, }; @@ -905,14 +903,14 @@ mod tests { let nonce_pubkey = Pubkey::new_rand(); let valid = Account::new_data( 1, - &NonceState::Initialized(NonceMeta::new(&nonce_pubkey), blockhash), + &State::Initialized(nonce::state::Meta::new(&nonce_pubkey), blockhash), &system_program::ID, ); assert!(check_nonce_account(&valid.unwrap(), &nonce_pubkey, &blockhash).is_ok()); let invalid_owner = Account::new_data( 1, - &NonceState::Initialized(NonceMeta::new(&nonce_pubkey), blockhash), + &State::Initialized(nonce::state::Meta::new(&nonce_pubkey), blockhash), &Pubkey::new(&[1u8; 32]), ); assert_eq!( @@ -932,7 +930,7 @@ mod tests { let invalid_hash = Account::new_data( 1, - &NonceState::Initialized(NonceMeta::new(&nonce_pubkey), hash(b"invalid")), + &State::Initialized(nonce::state::Meta::new(&nonce_pubkey), hash(b"invalid")), &system_program::ID, ); assert_eq!( @@ -942,7 +940,7 @@ mod tests { let invalid_authority = Account::new_data( 1, - &NonceState::Initialized(NonceMeta::new(&Pubkey::new_rand()), blockhash), + &State::Initialized(nonce::state::Meta::new(&Pubkey::new_rand()), blockhash), &system_program::ID, ); assert_eq!( @@ -952,7 +950,7 @@ mod tests { ))), ); - let invalid_state = Account::new_data(1, &NonceState::Uninitialized, &system_program::ID); + let invalid_state = Account::new_data(1, &State::Uninitialized, &system_program::ID); assert_eq!( check_nonce_account(&invalid_state.unwrap(), &nonce_pubkey, &blockhash), Err(Box::new(CliError::InvalidNonce( diff --git a/cli/tests/pay.rs b/cli/tests/pay.rs index de9770991..466eb1688 100644 --- a/cli/tests/pay.rs +++ b/cli/tests/pay.rs @@ -11,7 +11,7 @@ use solana_faucet::faucet::run_local_faucet; use solana_sdk::{ account_utils::StateMut, fee_calculator::FeeCalculator, - nonce_state::NonceState, + nonce, pubkey::Pubkey, signature::{Keypair, Signer}, }; @@ -377,7 +377,7 @@ fn test_nonced_pay_tx() { config.signers = vec![&default_signer]; let minimum_nonce_balance = rpc_client - .get_minimum_balance_for_rent_exemption(NonceState::size()) + .get_minimum_balance_for_rent_exemption(nonce::State::size()) .unwrap(); request_and_confirm_airdrop( @@ -409,9 +409,9 @@ fn test_nonced_pay_tx() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -431,9 +431,9 @@ fn test_nonced_pay_tx() { // Verify that nonce has been used let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); match nonce_state { - NonceState::Initialized(_meta, hash) => assert_ne!(hash, nonce_hash), + nonce::State::Initialized(_meta, hash) => assert_ne!(hash, nonce_hash), _ => assert!(false, "Nonce is not initialized"), } diff --git a/cli/tests/stake.rs b/cli/tests/stake.rs index 05aac09c6..e1e77ca37 100644 --- a/cli/tests/stake.rs +++ b/cli/tests/stake.rs @@ -9,7 +9,7 @@ use solana_faucet::faucet::run_local_faucet; use solana_sdk::{ account_utils::StateMut, fee_calculator::FeeCalculator, - nonce_state::NonceState, + nonce, pubkey::Pubkey, signature::{keypair_from_seed, Keypair, Signer}, system_instruction::create_address_with_seed, @@ -457,7 +457,7 @@ fn test_nonced_stake_delegation_and_deactivation() { config.json_rpc_url = format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port()); let minimum_nonce_balance = rpc_client - .get_minimum_balance_for_rent_exemption(NonceState::size()) + .get_minimum_balance_for_rent_exemption(nonce::State::size()) .unwrap(); request_and_confirm_airdrop( @@ -500,9 +500,9 @@ fn test_nonced_stake_delegation_and_deactivation() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -523,9 +523,9 @@ fn test_nonced_stake_delegation_and_deactivation() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -700,7 +700,7 @@ fn test_stake_authorize() { // Create nonce account let minimum_nonce_balance = rpc_client - .get_minimum_balance_for_rent_exemption(NonceState::size()) + .get_minimum_balance_for_rent_exemption(nonce::State::size()) .unwrap(); let nonce_account = Keypair::new(); config.signers = vec![&default_signer, &nonce_account]; @@ -714,9 +714,9 @@ fn test_stake_authorize() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -763,9 +763,9 @@ fn test_stake_authorize() { }; assert_eq!(current_authority, online_authority_pubkey); let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let new_nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; assert_ne!(nonce_hash, new_nonce_hash); @@ -982,7 +982,7 @@ fn test_stake_split() { // Create nonce account let minimum_nonce_balance = rpc_client - .get_minimum_balance_for_rent_exemption(NonceState::size()) + .get_minimum_balance_for_rent_exemption(nonce::State::size()) .unwrap(); let nonce_account = keypair_from_seed(&[1u8; 32]).unwrap(); config.signers = vec![&default_signer, &nonce_account]; @@ -997,9 +997,9 @@ fn test_stake_split() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -1232,7 +1232,7 @@ fn test_stake_set_lockup() { // Create nonce account let minimum_nonce_balance = rpc_client - .get_minimum_balance_for_rent_exemption(NonceState::size()) + .get_minimum_balance_for_rent_exemption(nonce::State::size()) .unwrap(); let nonce_account = keypair_from_seed(&[1u8; 32]).unwrap(); let nonce_account_pubkey = nonce_account.pubkey(); @@ -1248,9 +1248,9 @@ fn test_stake_set_lockup() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account_pubkey).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -1347,7 +1347,7 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { // Create nonce account let minimum_nonce_balance = rpc_client - .get_minimum_balance_for_rent_exemption(NonceState::size()) + .get_minimum_balance_for_rent_exemption(nonce::State::size()) .unwrap(); let nonce_account = keypair_from_seed(&[3u8; 32]).unwrap(); let nonce_pubkey = nonce_account.pubkey(); @@ -1362,9 +1362,9 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -1410,9 +1410,9 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -1451,9 +1451,9 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; diff --git a/cli/tests/transfer.rs b/cli/tests/transfer.rs index 7074a773f..ac9d89832 100644 --- a/cli/tests/transfer.rs +++ b/cli/tests/transfer.rs @@ -9,7 +9,7 @@ use solana_faucet::faucet::run_local_faucet; use solana_sdk::{ account_utils::StateMut, fee_calculator::FeeCalculator, - nonce_state::NonceState, + nonce, pubkey::Pubkey, signature::{keypair_from_seed, Keypair, Signer}, }; @@ -120,7 +120,7 @@ fn test_transfer() { // Create nonce account let nonce_account = keypair_from_seed(&[3u8; 32]).unwrap(); let minimum_nonce_balance = rpc_client - .get_minimum_balance_for_rent_exemption(NonceState::size()) + .get_minimum_balance_for_rent_exemption(nonce::State::size()) .unwrap(); config.signers = vec![&default_signer, &nonce_account]; config.command = CliCommand::CreateNonceAccount { @@ -134,9 +134,9 @@ fn test_transfer() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; @@ -156,9 +156,9 @@ fn test_transfer() { check_balance(49_976 - minimum_nonce_balance, &rpc_client, &sender_pubkey); check_balance(30, &rpc_client, &recipient_pubkey); let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let new_nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; assert_ne!(nonce_hash, new_nonce_hash); @@ -175,9 +175,9 @@ fn test_transfer() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: NonceState = account.state().unwrap(); + let nonce_state: nonce::State = account.state().unwrap(); let nonce_hash = match nonce_state { - NonceState::Initialized(_meta, hash) => hash, + nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), }; diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index 381956c7a..d2d05219f 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -17,8 +17,7 @@ use solana_sdk::{ account::Account, clock::Slot, hash::Hash, - native_loader, - nonce_state::NonceState, + native_loader, nonce, pubkey::Pubkey, transaction::Result, transaction::{Transaction, TransactionError}, @@ -160,7 +159,7 @@ impl Accounts { })? { SystemAccountKind::System => 0, SystemAccountKind::Nonce => { - rent_collector.rent.minimum_balance(NonceState::size()) + rent_collector.rent.minimum_balance(nonce::State::size()) } }; @@ -681,7 +680,7 @@ mod tests { hash::Hash, instruction::CompiledInstruction, message::Message, - nonce_state, + nonce, rent::Rent, signature::{Keypair, Signer}, system_program, @@ -915,17 +914,15 @@ mod tests { ..Rent::default() }, ); - let min_balance = rent_collector - .rent - .minimum_balance(nonce_state::NonceState::size()); + let min_balance = rent_collector.rent.minimum_balance(nonce::State::size()); let fee_calculator = FeeCalculator::new(min_balance); let nonce = Keypair::new(); let mut accounts = vec![( nonce.pubkey(), Account::new_data( min_balance * 2, - &nonce_state::NonceState::Initialized( - nonce_state::Meta::new(&Pubkey::default()), + &nonce::State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), Hash::default(), ), &system_program::id(), diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 3a7598757..0b74a00e9 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -40,8 +40,7 @@ use solana_sdk::{ hard_forks::HardForks, hash::{extend_and_hash, hashv, Hash}, inflation::Inflation, - native_loader, - nonce_state::NonceState, + native_loader, nonce, pubkey::Pubkey, signature::{Keypair, Signature}, slot_hashes::SlotHashes, @@ -1691,9 +1690,10 @@ impl Bank { match self.get_account(pubkey) { Some(mut account) => { let min_balance = match get_system_account_kind(&account) { - Some(SystemAccountKind::Nonce) => { - self.rent_collector.rent.minimum_balance(NonceState::size()) - } + Some(SystemAccountKind::Nonce) => self + .rent_collector + .rent + .minimum_balance(nonce::State::size()), _ => 0, }; if lamports + min_balance > account.lamports { @@ -2173,7 +2173,7 @@ mod tests { genesis_config::create_genesis_config, instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError}, message::{Message, MessageHeader}, - nonce_state, + nonce, poh_config::PohConfig, rent::Rent, signature::{Keypair, Signer}, @@ -3421,13 +3421,12 @@ mod tests { genesis_config.rent.lamports_per_byte_year = 42; let bank = Bank::new(&genesis_config); - let min_balance = - bank.get_minimum_balance_for_rent_exemption(nonce_state::NonceState::size()); + let min_balance = bank.get_minimum_balance_for_rent_exemption(nonce::State::size()); let nonce = Keypair::new(); let nonce_account = Account::new_data( min_balance + 42, - &nonce_state::NonceState::Initialized( - nonce_state::Meta::new(&Pubkey::default()), + &nonce::State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), Hash::default(), ), &system_program::id(), @@ -5108,7 +5107,7 @@ mod tests { fn get_nonce_account(bank: &Bank, nonce_pubkey: &Pubkey) -> Option { bank.get_account(&nonce_pubkey) .and_then(|acc| match acc.state() { - Ok(nonce_state::NonceState::Initialized(_meta, hash)) => Some(hash), + Ok(nonce::State::Initialized(_meta, hash)) => Some(hash), _ => None, }) } @@ -5282,8 +5281,8 @@ mod tests { let nonce = Keypair::new(); let nonce_account = Account::new_data( 42424242, - &nonce_state::NonceState::Initialized( - nonce_state::Meta::new(&Pubkey::default()), + &nonce::State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), Hash::default(), ), &system_program::id(), diff --git a/runtime/src/nonce_utils.rs b/runtime/src/nonce_utils.rs index 2514ab697..fb8f9485a 100644 --- a/runtime/src/nonce_utils.rs +++ b/runtime/src/nonce_utils.rs @@ -3,7 +3,7 @@ use solana_sdk::{ account_utils::StateMut, hash::Hash, instruction::CompiledInstruction, - nonce_state::NonceState, + nonce::State, program_utils::limited_deserialize, pubkey::Pubkey, system_instruction::SystemInstruction, @@ -40,7 +40,7 @@ pub fn get_nonce_pubkey_from_instruction<'a>( pub fn verify_nonce_account(acc: &Account, hash: &Hash) -> bool { match acc.state() { - Ok(NonceState::Initialized(_meta, ref nonce)) => hash == nonce, + Ok(State::Initialized(_meta, ref nonce)) => hash == nonce, _ => false, } } @@ -60,9 +60,9 @@ pub fn prepare_if_nonce_account( *account = nonce_acc.clone() } // Since hash_age_kind is DurableNonce, unwrap is safe here - if let NonceState::Initialized(meta, _) = account.state().unwrap() { + if let State::Initialized(meta, _) = account.state().unwrap() { account - .set_state(&NonceState::Initialized(meta, *last_blockhash)) + .set_state(&State::Initialized(meta, *last_blockhash)) .unwrap(); } } @@ -74,10 +74,10 @@ mod tests { use super::*; use solana_sdk::{ account::Account, - account_utils::State, + account_utils::State as AccountUtilsState, hash::Hash, instruction::InstructionError, - nonce_state::{with_test_keyed_account, Meta, NonceAccount}, + nonce::{self, account::with_test_keyed_account, Account as NonceAccount}, pubkey::Pubkey, signature::{Keypair, Signer}, system_instruction, @@ -193,9 +193,9 @@ mod tests { with_test_keyed_account(42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(nonce_account.signer_key().unwrap().clone()); - let state: NonceState = nonce_account.state().unwrap(); + let state: State = nonce_account.state().unwrap(); // New is in Uninitialzed state - assert_eq!(state, NonceState::Uninitialized); + assert_eq!(state, State::Uninitialized); let recent_blockhashes = create_test_recent_blockhashes(0); let authorized = nonce_account.unsigned_key().clone(); nonce_account @@ -223,9 +223,9 @@ mod tests { with_test_keyed_account(42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(nonce_account.signer_key().unwrap().clone()); - let state: NonceState = nonce_account.state().unwrap(); + let state: State = nonce_account.state().unwrap(); // New is in Uninitialzed state - assert_eq!(state, NonceState::Uninitialized); + assert_eq!(state, State::Uninitialized); let recent_blockhashes = create_test_recent_blockhashes(0); let authorized = nonce_account.unsigned_key().clone(); nonce_account @@ -242,7 +242,7 @@ mod tests { let stored_nonce = Hash::default(); let account = Account::new_data( 42, - &NonceState::Initialized(Meta::new(&Pubkey::default()), stored_nonce), + &State::Initialized(nonce::state::Meta::new(&Pubkey::default()), stored_nonce), &system_program::id(), ) .unwrap(); @@ -297,8 +297,8 @@ mod tests { let mut expect_account = post_account.clone(); expect_account - .set_state(&NonceState::Initialized( - Meta::new(&Pubkey::default()), + .set_state(&State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), last_blockhash, )) .unwrap(); @@ -356,8 +356,8 @@ mod tests { let mut expect_account = pre_account.clone(); expect_account - .set_state(&NonceState::Initialized( - Meta::new(&Pubkey::default()), + .set_state(&State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), last_blockhash, )) .unwrap(); diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index 7d94e741c..8146f7203 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -3,7 +3,7 @@ use solana_sdk::{ account::{get_signers, Account, KeyedAccount}, account_utils::StateMut, instruction::InstructionError, - nonce_state::{NonceAccount, NonceState}, + nonce::{self, Account as NonceAccount}, program_utils::{limited_deserialize, next_keyed_account}, pubkey::Pubkey, system_instruction::{ @@ -306,7 +306,7 @@ pub fn get_system_account_kind(account: &Account) -> Option { if system_program::check_id(&account.owner) { if account.data.is_empty() { Some(SystemAccountKind::System) - } else if let Ok(NonceState::Initialized(_, _)) = account.state() { + } else if let Ok(nonce::State::Initialized(_, _)) = account.state() { Some(SystemAccountKind::Nonce) } else { None @@ -328,7 +328,7 @@ mod tests { hash::{hash, Hash}, instruction::{AccountMeta, Instruction, InstructionError}, message::Message, - nonce_state, + nonce, signature::{Keypair, Signer}, system_instruction, system_program, sysvar, transaction::TransactionError, @@ -733,8 +733,8 @@ mod tests { let nonce = Pubkey::new_rand(); let nonce_account = Account::new_ref_data( 42, - &nonce_state::NonceState::Initialized( - nonce_state::Meta::new(&Pubkey::default()), + &nonce::State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), Hash::default(), ), &system_program::id(), @@ -875,7 +875,7 @@ mod tests { let from = Pubkey::new_rand(); let from_account = Account::new_ref_data( 100, - &nonce_state::NonceState::Initialized(nonce_state::Meta::new(&from), Hash::default()), + &nonce::State::Initialized(nonce::state::Meta::new(&from), Hash::default()), &system_program::id(), ) .unwrap(); @@ -1089,7 +1089,7 @@ mod tests { #[test] fn test_process_nonce_ix_ok() { - let nonce_acc = nonce_state::create_account(1_000_000); + let nonce_acc = nonce::create_account(1_000_000); super::process_instruction( &Pubkey::default(), &[ @@ -1193,11 +1193,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &[ - KeyedAccount::new( - &Pubkey::default(), - true, - &nonce_state::create_account(1_000_000), - ), + KeyedAccount::new(&Pubkey::default(), true, &nonce::create_account(1_000_000),), KeyedAccount::new(&Pubkey::default(), true, &create_default_account()), KeyedAccount::new( &sysvar::recent_blockhashes::id(), @@ -1218,11 +1214,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &[ - KeyedAccount::new( - &Pubkey::default(), - true, - &nonce_state::create_account(1_000_000), - ), + KeyedAccount::new(&Pubkey::default(), true, &nonce::create_account(1_000_000),), KeyedAccount::new(&Pubkey::default(), true, &create_default_account()), KeyedAccount::new( &sysvar::recent_blockhashes::id(), @@ -1257,7 +1249,7 @@ mod tests { &[KeyedAccount::new( &Pubkey::default(), true, - &nonce_state::create_account(1_000_000), + &nonce::create_account(1_000_000), ),], &serialize(&SystemInstruction::InitializeNonceAccount(Pubkey::default())).unwrap(), ), @@ -1271,11 +1263,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &[ - KeyedAccount::new( - &Pubkey::default(), - true, - &nonce_state::create_account(1_000_000), - ), + KeyedAccount::new(&Pubkey::default(), true, &nonce::create_account(1_000_000),), KeyedAccount::new( &sysvar::recent_blockhashes::id(), false, @@ -1294,11 +1282,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &[ - KeyedAccount::new( - &Pubkey::default(), - true, - &nonce_state::create_account(1_000_000), - ), + KeyedAccount::new(&Pubkey::default(), true, &nonce::create_account(1_000_000),), KeyedAccount::new( &sysvar::recent_blockhashes::id(), false, @@ -1318,11 +1302,7 @@ mod tests { super::process_instruction( &Pubkey::default(), &[ - KeyedAccount::new( - &Pubkey::default(), - true, - &nonce_state::create_account(1_000_000), - ), + KeyedAccount::new(&Pubkey::default(), true, &nonce::create_account(1_000_000),), KeyedAccount::new( &sysvar::recent_blockhashes::id(), false, @@ -1338,7 +1318,7 @@ mod tests { #[test] fn test_process_authorize_ix_ok() { - let nonce_acc = nonce_state::create_account(1_000_000); + let nonce_acc = nonce::create_account(1_000_000); super::process_instruction( &Pubkey::default(), &[ @@ -1388,8 +1368,8 @@ mod tests { fn test_get_system_account_kind_nonce_ok() { let nonce_account = Account::new_data( 42, - &nonce_state::NonceState::Initialized( - nonce_state::Meta::new(&Pubkey::default()), + &nonce::State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), Hash::default(), ), &system_program::id(), @@ -1404,7 +1384,7 @@ mod tests { #[test] fn test_get_system_account_kind_uninitialized_nonce_account_fail() { assert_eq!( - get_system_account_kind(&nonce_state::create_account(42).borrow()), + get_system_account_kind(&nonce::create_account(42).borrow()), None ); } @@ -1416,11 +1396,11 @@ mod tests { } #[test] - fn test_get_system_account_kind_nonsystem_owner_with_nonce_state_data_fail() { + fn test_get_system_account_kind_nonsystem_owner_with_nonce_data_fail() { let nonce_account = Account::new_data( 42, - &nonce_state::NonceState::Initialized( - nonce_state::Meta::new(&Pubkey::default()), + &nonce::State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), Hash::default(), ), &Pubkey::new_rand(), diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index fd7466875..e78081b2e 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -17,7 +17,7 @@ pub mod message; pub mod move_loader; pub mod native_loader; pub mod native_token; -pub mod nonce_state; +pub mod nonce; pub mod packet; pub mod poh_config; pub mod program_utils; diff --git a/sdk/src/nonce_state.rs b/sdk/src/nonce/account.rs similarity index 83% rename from sdk/src/nonce_state.rs rename to sdk/src/nonce/account.rs index 5c9a100b3..658c591a4 100644 --- a/sdk/src/nonce_state.rs +++ b/sdk/src/nonce/account.rs @@ -1,49 +1,16 @@ use crate::{ - account::{Account, KeyedAccount}, - account_utils::State, - hash::Hash, + account::{self, KeyedAccount}, + account_utils::State as AccountUtilsState, instruction::InstructionError, + nonce::{self, State}, pubkey::Pubkey, system_instruction::NonceError, system_program, sysvar::{recent_blockhashes::RecentBlockhashes, rent::Rent}, }; -use serde_derive::{Deserialize, Serialize}; use std::{cell::RefCell, collections::HashSet}; -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy)] -pub struct Meta { - pub nonce_authority: Pubkey, -} - -impl Meta { - pub fn new(nonce_authority: &Pubkey) -> Self { - Self { - nonce_authority: *nonce_authority, - } - } -} - -#[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 { +pub trait Account { fn advance_nonce_account( &self, recent_blockhashes: &RecentBlockhashes, @@ -70,7 +37,7 @@ pub trait NonceAccount { ) -> Result<(), InstructionError>; } -impl<'a> NonceAccount for KeyedAccount<'a> { +impl<'a> Account for KeyedAccount<'a> { fn advance_nonce_account( &self, recent_blockhashes: &RecentBlockhashes, @@ -81,7 +48,7 @@ impl<'a> NonceAccount for KeyedAccount<'a> { } let meta = match self.state()? { - NonceState::Initialized(meta, ref hash) => { + State::Initialized(meta, ref hash) => { if !signers.contains(&meta.nonce_authority) { return Err(InstructionError::MissingRequiredSignature); } @@ -93,7 +60,7 @@ impl<'a> NonceAccount for KeyedAccount<'a> { _ => return Err(NonceError::BadAccountState.into()), }; - self.set_state(&NonceState::Initialized(meta, recent_blockhashes[0])) + self.set_state(&State::Initialized(meta, recent_blockhashes[0])) } fn withdraw_nonce_account( @@ -105,13 +72,13 @@ impl<'a> NonceAccount for KeyedAccount<'a> { signers: &HashSet, ) -> Result<(), InstructionError> { let signer = match self.state()? { - NonceState::Uninitialized => { + State::Uninitialized => { if lamports > self.lamports()? { return Err(InstructionError::InsufficientFunds); } *self.unsigned_key() } - NonceState::Initialized(meta, ref hash) => { + State::Initialized(meta, ref hash) => { if lamports == self.lamports()? { if *hash == recent_blockhashes[0] { return Err(NonceError::NotExpired.into()); @@ -147,17 +114,17 @@ impl<'a> NonceAccount for KeyedAccount<'a> { } let meta = match self.state()? { - NonceState::Uninitialized => { + State::Uninitialized => { let min_balance = rent.minimum_balance(self.data_len()?); if self.lamports()? < min_balance { return Err(InstructionError::InsufficientFunds); } - Meta::new(nonce_authority) + nonce::state::Meta::new(nonce_authority) } _ => return Err(NonceError::BadAccountState.into()), }; - self.set_state(&NonceState::Initialized(meta, recent_blockhashes[0])) + self.set_state(&State::Initialized(meta, recent_blockhashes[0])) } fn authorize_nonce_account( @@ -166,23 +133,26 @@ impl<'a> NonceAccount for KeyedAccount<'a> { signers: &HashSet, ) -> Result<(), InstructionError> { match self.state()? { - NonceState::Initialized(meta, nonce) => { + State::Initialized(meta, nonce) => { if !signers.contains(&meta.nonce_authority) { return Err(InstructionError::MissingRequiredSignature); } - self.set_state(&NonceState::Initialized(Meta::new(nonce_authority), nonce)) + self.set_state(&State::Initialized( + nonce::state::Meta::new(nonce_authority), + nonce, + )) } _ => Err(NonceError::BadAccountState.into()), } } } -pub fn create_account(lamports: u64) -> RefCell { +pub fn create_account(lamports: u64) -> RefCell { RefCell::new( - Account::new_data_with_space( + account::Account::new_data_with_space( lamports, - &NonceState::Uninitialized, - NonceState::size(), + &State::Uninitialized, + State::size(), &system_program::id(), ) .expect("nonce_account"), @@ -206,6 +176,7 @@ mod test { use super::*; use crate::{ account::KeyedAccount, + nonce::{self, State}, system_instruction::NonceError, sysvar::recent_blockhashes::{create_test_recent_blockhashes, RecentBlockhashes}, }; @@ -213,13 +184,16 @@ mod test { #[test] fn default_is_uninitialized() { - assert_eq!(NonceState::default(), NonceState::Uninitialized) + assert_eq!(State::default(), State::Uninitialized) } #[test] fn new_meta() { let nonce_authority = Pubkey::default(); - assert_eq!(Meta::new(&nonce_authority), Meta { nonce_authority }); + assert_eq!( + nonce::state::Meta::new(&nonce_authority), + nonce::state::Meta { nonce_authority } + ); } #[test] @@ -228,39 +202,39 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { - let meta = Meta::new(&keyed_account.unsigned_key()); + let meta = nonce::state::Meta::new(&keyed_account.unsigned_key()); let mut signers = HashSet::new(); signers.insert(keyed_account.signer_key().unwrap().clone()); - let state: NonceState = keyed_account.state().unwrap(); + let state: State = keyed_account.state().unwrap(); // New is in Uninitialzed state - assert_eq!(state, NonceState::Uninitialized); + assert_eq!(state, State::Uninitialized); let recent_blockhashes = create_test_recent_blockhashes(95); let authorized = keyed_account.unsigned_key().clone(); keyed_account .initialize_nonce_account(&authorized, &recent_blockhashes, &rent) .unwrap(); - let state: NonceState = keyed_account.state().unwrap(); + let state: State = 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)); + assert_eq!(state, State::Initialized(meta, stored)); let recent_blockhashes = create_test_recent_blockhashes(63); keyed_account .advance_nonce_account(&recent_blockhashes, &signers) .unwrap(); - let state: NonceState = keyed_account.state().unwrap(); + let state: State = keyed_account.state().unwrap(); let stored = recent_blockhashes[0]; // Second nonce instruction consumes and replaces stored nonce - assert_eq!(state, NonceState::Initialized(meta, stored)); + assert_eq!(state, State::Initialized(meta, stored)); let recent_blockhashes = create_test_recent_blockhashes(31); keyed_account .advance_nonce_account(&recent_blockhashes, &signers) .unwrap(); - let state: NonceState = keyed_account.state().unwrap(); + let state: State = keyed_account.state().unwrap(); let stored = recent_blockhashes[0]; // Third nonce instruction for fun and profit - assert_eq!(state, NonceState::Initialized(meta, stored)); + assert_eq!(state, State::Initialized(meta, stored)); with_test_keyed_account(42, false, |to_keyed| { let recent_blockhashes = create_test_recent_blockhashes(0); let withdraw_lamports = keyed_account.account.borrow().lamports; @@ -276,12 +250,12 @@ mod test { &signers, ) .unwrap(); - // Empties NonceAccount balance + // Empties Account balance assert_eq!( keyed_account.account.borrow().lamports, expect_nonce_lamports ); - // NonceAccount balance goes to `to` + // Account balance goes to `to` assert_eq!(to_keyed.account.borrow().lamports, expect_to_lamports); }) }) @@ -293,19 +267,19 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { let recent_blockhashes = create_test_recent_blockhashes(31); let stored = recent_blockhashes[0]; let authorized = nonce_account.unsigned_key().clone(); - let meta = Meta::new(&authorized); + let meta = nonce::state::Meta::new(&authorized); nonce_account .initialize_nonce_account(&authorized, &recent_blockhashes, &rent) .unwrap(); let pubkey = nonce_account.account.borrow().owner.clone(); let nonce_account = KeyedAccount::new(&pubkey, false, nonce_account.account); - let state: NonceState = nonce_account.state().unwrap(); - assert_eq!(state, NonceState::Initialized(meta, stored)); + let state: State = nonce_account.state().unwrap(); + assert_eq!(state, State::Initialized(meta, stored)); let signers = HashSet::new(); let recent_blockhashes = create_test_recent_blockhashes(0); let result = nonce_account.advance_nonce_account(&recent_blockhashes, &signers); @@ -319,7 +293,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let mut signers = HashSet::new(); signers.insert(keyed_account.signer_key().unwrap().clone()); @@ -340,7 +314,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let mut signers = HashSet::new(); signers.insert(keyed_account.signer_key().unwrap().clone()); @@ -360,7 +334,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let mut signers = HashSet::new(); signers.insert(keyed_account.signer_key().unwrap().clone()); @@ -376,7 +350,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { with_test_keyed_account(42, true, |nonce_authority| { let mut signers = HashSet::new(); @@ -401,7 +375,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { with_test_keyed_account(42, false, |nonce_authority| { let mut signers = HashSet::new(); @@ -423,10 +397,10 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - let state: NonceState = nonce_keyed.state().unwrap(); - assert_eq!(state, NonceState::Uninitialized); + let state: State = nonce_keyed.state().unwrap(); + assert_eq!(state, State::Uninitialized); with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); signers.insert(nonce_keyed.signer_key().unwrap().clone()); @@ -444,13 +418,13 @@ mod test { &signers, ) .unwrap(); - let state: NonceState = nonce_keyed.state().unwrap(); + let state: State = nonce_keyed.state().unwrap(); // Withdraw instruction... - // Deinitializes NonceAccount state - assert_eq!(state, NonceState::Uninitialized); - // Empties NonceAccount balance + // Deinitializes Account state + assert_eq!(state, State::Uninitialized); + // Empties Account balance assert_eq!(nonce_keyed.account.borrow().lamports, expect_nonce_lamports); - // NonceAccount balance goes to `to` + // Account balance goes to `to` assert_eq!(to_keyed.account.borrow().lamports, expect_to_lamports); }) }) @@ -462,10 +436,10 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, false, |nonce_keyed| { - let state: NonceState = nonce_keyed.state().unwrap(); - assert_eq!(state, NonceState::Uninitialized); + let state: State = nonce_keyed.state().unwrap(); + assert_eq!(state, State::Uninitialized); with_test_keyed_account(42, false, |to_keyed| { let signers = HashSet::new(); let recent_blockhashes = create_test_recent_blockhashes(0); @@ -488,10 +462,10 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - let state: NonceState = nonce_keyed.state().unwrap(); - assert_eq!(state, NonceState::Uninitialized); + let state: State = nonce_keyed.state().unwrap(); + assert_eq!(state, State::Uninitialized); with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); signers.insert(nonce_keyed.signer_key().unwrap().clone()); @@ -515,7 +489,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); @@ -534,8 +508,8 @@ mod test { &signers, ) .unwrap(); - let state: NonceState = nonce_keyed.state().unwrap(); - assert_eq!(state, NonceState::Uninitialized); + let state: State = nonce_keyed.state().unwrap(); + assert_eq!(state, State::Uninitialized); 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; @@ -551,8 +525,8 @@ mod test { &signers, ) .unwrap(); - let state: NonceState = nonce_keyed.state().unwrap(); - assert_eq!(state, NonceState::Uninitialized); + let state: State = nonce_keyed.state().unwrap(); + assert_eq!(state, State::Uninitialized); assert_eq!(nonce_keyed.account.borrow().lamports, nonce_expect_lamports); assert_eq!(to_keyed.account.borrow().lamports, to_expect_lamports); }) @@ -565,19 +539,19 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::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); let authorized = nonce_keyed.unsigned_key().clone(); - let meta = Meta::new(&authorized); + let meta = nonce::state::Meta::new(&authorized); nonce_keyed .initialize_nonce_account(&authorized, &recent_blockhashes, &rent) .unwrap(); - let state: NonceState = nonce_keyed.state().unwrap(); + let state: State = nonce_keyed.state().unwrap(); let stored = recent_blockhashes[0]; - assert_eq!(state, NonceState::Initialized(meta, stored)); + assert_eq!(state, State::Initialized(meta, stored)); with_test_keyed_account(42, false, |to_keyed| { let withdraw_lamports = nonce_keyed.account.borrow().lamports - min_lamports; let nonce_expect_lamports = @@ -592,9 +566,9 @@ mod test { &signers, ) .unwrap(); - let state: NonceState = nonce_keyed.state().unwrap(); + let state: State = nonce_keyed.state().unwrap(); let stored = recent_blockhashes[0]; - assert_eq!(state, NonceState::Initialized(meta, stored)); + assert_eq!(state, State::Initialized(meta, stored)); assert_eq!(nonce_keyed.account.borrow().lamports, nonce_expect_lamports); assert_eq!(to_keyed.account.borrow().lamports, to_expect_lamports); let recent_blockhashes = create_test_recent_blockhashes(0); @@ -623,7 +597,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { let recent_blockhashes = create_test_recent_blockhashes(0); let authorized = nonce_keyed.unsigned_key().clone(); @@ -652,7 +626,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { let recent_blockhashes = create_test_recent_blockhashes(95); let authorized = nonce_keyed.unsigned_key().clone(); @@ -682,7 +656,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { let recent_blockhashes = create_test_recent_blockhashes(95); let authorized = nonce_keyed.unsigned_key().clone(); @@ -712,21 +686,21 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { - let state: NonceState = keyed_account.state().unwrap(); - assert_eq!(state, NonceState::Uninitialized); + let state: State = keyed_account.state().unwrap(); + assert_eq!(state, State::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]; let authorized = keyed_account.unsigned_key().clone(); - let meta = Meta::new(&authorized); + let meta = nonce::state::Meta::new(&authorized); let result = keyed_account.initialize_nonce_account(&authorized, &recent_blockhashes, &rent); assert_eq!(result, Ok(())); - let state: NonceState = keyed_account.state().unwrap(); - assert_eq!(state, NonceState::Initialized(meta, stored)); + let state: State = keyed_account.state().unwrap(); + assert_eq!(state, State::Initialized(meta, stored)); }) } @@ -736,7 +710,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let mut signers = HashSet::new(); signers.insert(keyed_account.signer_key().unwrap().clone()); @@ -754,7 +728,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { let recent_blockhashes = create_test_recent_blockhashes(31); let authorized = keyed_account.unsigned_key().clone(); @@ -774,7 +748,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports - 42, true, |keyed_account| { let recent_blockhashes = create_test_recent_blockhashes(63); let authorized = keyed_account.unsigned_key().clone(); @@ -790,7 +764,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(nonce_account.signer_key().unwrap().clone()); @@ -801,11 +775,11 @@ mod test { .initialize_nonce_account(&authorized, &recent_blockhashes, &rent) .unwrap(); let authorized = &Pubkey::default().clone(); - let meta = Meta::new(&authorized); + let meta = nonce::state::Meta::new(&authorized); let result = nonce_account.authorize_nonce_account(&Pubkey::default(), &signers); assert_eq!(result, Ok(())); - let state: NonceState = nonce_account.state().unwrap(); - assert_eq!(state, NonceState::Initialized(meta, stored)); + let state: State = nonce_account.state().unwrap(); + assert_eq!(state, State::Initialized(meta, stored)); }) } @@ -815,7 +789,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(nonce_account.signer_key().unwrap().clone()); @@ -830,7 +804,7 @@ mod test { lamports_per_byte_year: 42, ..Rent::default() }; - let min_lamports = rent.minimum_balance(NonceState::size()); + let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_account| { let mut signers = HashSet::new(); signers.insert(nonce_account.signer_key().unwrap().clone()); diff --git a/sdk/src/nonce/mod.rs b/sdk/src/nonce/mod.rs new file mode 100644 index 000000000..c38595384 --- /dev/null +++ b/sdk/src/nonce/mod.rs @@ -0,0 +1,4 @@ +pub mod account; +pub use account::{create_account, Account}; +pub mod state; +pub use state::State; diff --git a/sdk/src/nonce/state.rs b/sdk/src/nonce/state.rs new file mode 100644 index 000000000..30c76c7c1 --- /dev/null +++ b/sdk/src/nonce/state.rs @@ -0,0 +1,44 @@ +use crate::{hash::Hash, pubkey::Pubkey}; +use serde_derive::{Deserialize, Serialize}; + +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub struct Meta { + pub nonce_authority: Pubkey, +} + +impl Meta { + pub fn new(nonce_authority: &Pubkey) -> Self { + Self { + nonce_authority: *nonce_authority, + } + } +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)] +pub enum State { + Uninitialized, + Initialized(Meta, Hash), +} + +impl Default for State { + fn default() -> Self { + State::Uninitialized + } +} + +impl State { + pub fn size() -> usize { + bincode::serialized_size(&State::Initialized(Meta::default(), Hash::default())).unwrap() + as usize + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn default_is_uninitialized() { + assert_eq!(State::default(), State::Uninitialized) + } +} diff --git a/sdk/src/system_instruction.rs b/sdk/src/system_instruction.rs index 74e08f5d6..b05e6d19b 100644 --- a/sdk/src/system_instruction.rs +++ b/sdk/src/system_instruction.rs @@ -1,7 +1,7 @@ use crate::{ hash::hashv, instruction::{AccountMeta, Instruction, WithSigner}, - nonce_state::NonceState, + nonce, program_utils::DecodeError, pubkey::Pubkey, system_program, @@ -322,7 +322,7 @@ pub fn create_nonce_account_with_seed( base, seed, lamports, - NonceState::size() as u64, + nonce::State::size() as u64, &system_program::id(), ), Instruction::new( @@ -348,7 +348,7 @@ pub fn create_nonce_account( from_pubkey, nonce_pubkey, lamports, - NonceState::size() as u64, + nonce::State::size() as u64, &system_program::id(), ), Instruction::new(