diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 9791fc6efd..692dbad49f 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -3261,18 +3261,14 @@ mod tests { // Nonced pay let blockhash = Hash::default(); + let data = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Meta::new(&config.signers[0].pubkey()), + blockhash, + )); let nonce_response = json!(Response { context: RpcResponseContext { slot: 1 }, value: json!(RpcAccount::encode( - Account::new_data( - 1, - &nonce::State::Initialized( - nonce::state::Meta::new(&config.signers[0].pubkey()), - blockhash - ), - &system_program::ID, - ) - .unwrap() + Account::new_data(1, &data, &system_program::ID,).unwrap() )), }); let mut mocks = HashMap::new(); @@ -3292,15 +3288,14 @@ mod tests { let bob_keypair = Keypair::new(); let bob_pubkey = bob_keypair.pubkey(); let blockhash = Hash::default(); + let data = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Meta::new(&bob_pubkey), + blockhash, + )); let nonce_authority_response = json!(Response { context: RpcResponseContext { slot: 1 }, value: json!(RpcAccount::encode( - Account::new_data( - 1, - &nonce::State::Initialized(nonce::state::Meta::new(&bob_pubkey), blockhash), - &system_program::ID, - ) - .unwrap() + Account::new_data(1, &data, &system_program::ID,).unwrap() )), }); let mut mocks = HashMap::new(); diff --git a/cli/src/nonce.rs b/cli/src/nonce.rs index 6621cc038a..1a87e99be4 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::{self, State}, + nonce::{self, state::Versions, State}, pubkey::Pubkey, system_instruction::{ advance_nonce_account, authorize_nonce_account, create_address_with_seed, @@ -363,8 +363,8 @@ pub fn check_nonce_account( if nonce_account.owner != system_program::ID { return Err(CliError::InvalidNonce(CliNonceError::InvalidAccountOwner).into()); } - let nonce_state: State = nonce_account - .state() + let nonce_state = StateMut::::state(nonce_account) + .map(|v| v.convert_to_current()) .map_err(|_| Box::new(CliError::InvalidNonce(CliNonceError::InvalidAccountData)))?; match nonce_state { State::Initialized(meta, hash) => { @@ -427,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 { @@ -493,7 +493,8 @@ pub fn process_get_nonce(rpc_client: &RpcClient, nonce_account_pubkey: &Pubkey) )) .into()); } - match nonce_account.state() { + let nonce_state = StateMut::::state(&nonce_account).map(|v| v.convert_to_current()); + match nonce_state { Ok(State::Uninitialized) => Ok("Nonce account is uninitialized".to_string()), Ok(State::Initialized(_, hash)) => Ok(format!("{:?}", hash)), Err(err) => Err(CliError::RpcRequestError(format!( @@ -577,7 +578,8 @@ pub fn process_show_nonce_account( } Ok("".to_string()) }; - match nonce_account.state() { + let nonce_state = StateMut::::state(&nonce_account).map(|v| v.convert_to_current()); + match nonce_state { Ok(State::Uninitialized) => print_account(None), Ok(State::Initialized(meta, hash)) => print_account(Some((meta, hash))), Err(err) => Err(CliError::RpcRequestError(format!( @@ -901,18 +903,14 @@ mod tests { fn test_check_nonce_account() { let blockhash = Hash::default(); let nonce_pubkey = Pubkey::new_rand(); - let valid = Account::new_data( - 1, - &State::Initialized(nonce::state::Meta::new(&nonce_pubkey), blockhash), - &system_program::ID, - ); + let data = Versions::new_current(State::Initialized( + nonce::state::Meta::new(&nonce_pubkey), + blockhash, + )); + let valid = Account::new_data(1, &data, &system_program::ID); assert!(check_nonce_account(&valid.unwrap(), &nonce_pubkey, &blockhash).is_ok()); - let invalid_owner = Account::new_data( - 1, - &State::Initialized(nonce::state::Meta::new(&nonce_pubkey), blockhash), - &Pubkey::new(&[1u8; 32]), - ); + let invalid_owner = Account::new_data(1, &data, &Pubkey::new(&[1u8; 32])); assert_eq!( check_nonce_account(&invalid_owner.unwrap(), &nonce_pubkey, &blockhash), Err(Box::new(CliError::InvalidNonce( @@ -928,21 +926,21 @@ mod tests { ))), ); - let invalid_hash = Account::new_data( - 1, - &State::Initialized(nonce::state::Meta::new(&nonce_pubkey), hash(b"invalid")), - &system_program::ID, - ); + let data = Versions::new_current(State::Initialized( + nonce::state::Meta::new(&nonce_pubkey), + hash(b"invalid"), + )); + let invalid_hash = Account::new_data(1, &data, &system_program::ID); assert_eq!( check_nonce_account(&invalid_hash.unwrap(), &nonce_pubkey, &blockhash), Err(Box::new(CliError::InvalidNonce(CliNonceError::InvalidHash))), ); - let invalid_authority = Account::new_data( - 1, - &State::Initialized(nonce::state::Meta::new(&Pubkey::new_rand()), blockhash), - &system_program::ID, - ); + let data = Versions::new_current(State::Initialized( + nonce::state::Meta::new(&Pubkey::new_rand()), + blockhash, + )); + let invalid_authority = Account::new_data(1, &data, &system_program::ID); assert_eq!( check_nonce_account(&invalid_authority.unwrap(), &nonce_pubkey, &blockhash), Err(Box::new(CliError::InvalidNonce( @@ -950,7 +948,8 @@ mod tests { ))), ); - let invalid_state = Account::new_data(1, &State::Uninitialized, &system_program::ID); + let data = Versions::new_current(State::Uninitialized); + let invalid_state = Account::new_data(1, &data, &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 466eb1688f..1c58c1d6ea 100644 --- a/cli/tests/pay.rs +++ b/cli/tests/pay.rs @@ -409,7 +409,9 @@ fn test_nonced_pay_tx() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -431,7 +433,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: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); match nonce_state { 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 e1e77ca377..7791bb59c9 100644 --- a/cli/tests/stake.rs +++ b/cli/tests/stake.rs @@ -500,7 +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: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -523,7 +525,9 @@ fn test_nonced_stake_delegation_and_deactivation() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -714,7 +718,9 @@ fn test_stake_authorize() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -763,7 +769,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: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let new_nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -997,7 +1005,9 @@ fn test_stake_split() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -1248,7 +1258,9 @@ fn test_stake_set_lockup() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account_pubkey).unwrap(); - let nonce_state: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -1362,7 +1374,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: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -1410,7 +1424,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: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -1451,7 +1467,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: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), diff --git a/cli/tests/transfer.rs b/cli/tests/transfer.rs index ac9d89832f..eaab8f84cb 100644 --- a/cli/tests/transfer.rs +++ b/cli/tests/transfer.rs @@ -134,7 +134,9 @@ fn test_transfer() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -156,7 +158,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: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let new_nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), @@ -175,7 +179,9 @@ fn test_transfer() { // Fetch nonce hash let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); - let nonce_state: nonce::State = account.state().unwrap(); + let nonce_state = StateMut::::state(&account) + .unwrap() + .convert_to_current(); let nonce_hash = match nonce_state { nonce::State::Initialized(_meta, hash) => hash, _ => panic!("Nonce is not initialized"), diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 0b74a00e95..46202845fc 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5105,11 +5105,14 @@ mod tests { } fn get_nonce_account(bank: &Bank, nonce_pubkey: &Pubkey) -> Option { - bank.get_account(&nonce_pubkey) - .and_then(|acc| match acc.state() { + bank.get_account(&nonce_pubkey).and_then(|acc| { + let state = + StateMut::::state(&acc).map(|v| v.convert_to_current()); + match state { Ok(nonce::State::Initialized(_meta, hash)) => Some(hash), _ => None, - }) + } + }) } fn nonce_setup( diff --git a/runtime/src/nonce_utils.rs b/runtime/src/nonce_utils.rs index fb8f9485ae..5ed4f02e69 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, + nonce::{state::Versions, State}, program_utils::limited_deserialize, pubkey::Pubkey, system_instruction::SystemInstruction, @@ -39,7 +39,7 @@ pub fn get_nonce_pubkey_from_instruction<'a>( } pub fn verify_nonce_account(acc: &Account, hash: &Hash) -> bool { - match acc.state() { + match StateMut::::state(acc).map(|v| v.convert_to_current()) { Ok(State::Initialized(_meta, ref nonce)) => hash == nonce, _ => false, } @@ -60,10 +60,12 @@ pub fn prepare_if_nonce_account( *account = nonce_acc.clone() } // Since hash_age_kind is DurableNonce, unwrap is safe here - if let State::Initialized(meta, _) = account.state().unwrap() { - account - .set_state(&State::Initialized(meta, *last_blockhash)) - .unwrap(); + let state = StateMut::::state(nonce_acc) + .unwrap() + .convert_to_current(); + if let State::Initialized(meta, _) = state { + let new_data = Versions::new_current(State::Initialized(meta, *last_blockhash)); + account.set_state(&new_data).unwrap(); } } } @@ -239,13 +241,11 @@ mod tests { } fn create_accounts_prepare_if_nonce_account() -> (Pubkey, Account, Account, Hash) { - let stored_nonce = Hash::default(); - let account = Account::new_data( - 42, - &State::Initialized(nonce::state::Meta::new(&Pubkey::default()), stored_nonce), - &system_program::id(), - ) - .unwrap(); + let data = Versions::new_current(State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), + Hash::default(), + )); + let account = Account::new_data(42, &data, &system_program::id()).unwrap(); let pre_account = Account { lamports: 43, ..account.clone() @@ -296,12 +296,11 @@ mod tests { let post_account_pubkey = pre_account_pubkey; let mut expect_account = post_account.clone(); - expect_account - .set_state(&State::Initialized( - nonce::state::Meta::new(&Pubkey::default()), - last_blockhash, - )) - .unwrap(); + let data = Versions::new_current(State::Initialized( + nonce::state::Meta::new(&Pubkey::default()), + last_blockhash, + )); + expect_account.set_state(&data).unwrap(); assert!(run_prepare_if_nonce_account_test( &mut post_account, @@ -356,10 +355,10 @@ mod tests { let mut expect_account = pre_account.clone(); expect_account - .set_state(&State::Initialized( + .set_state(&Versions::new_current(State::Initialized( nonce::state::Meta::new(&Pubkey::default()), last_blockhash, - )) + ))) .unwrap(); assert!(run_prepare_if_nonce_account_test( diff --git a/sdk/src/nonce/account.rs b/sdk/src/nonce/account.rs index 658c591a40..4e243a24f6 100644 --- a/sdk/src/nonce/account.rs +++ b/sdk/src/nonce/account.rs @@ -2,7 +2,7 @@ use crate::{ account::{self, KeyedAccount}, account_utils::State as AccountUtilsState, instruction::InstructionError, - nonce::{self, State}, + nonce::{self, state::Versions, State}, pubkey::Pubkey, system_instruction::NonceError, system_program, @@ -47,7 +47,8 @@ impl<'a> Account for KeyedAccount<'a> { return Err(NonceError::NoRecentBlockhashes.into()); } - let meta = match self.state()? { + let state = AccountUtilsState::::state(self)?.convert_to_current(); + let meta = match state { State::Initialized(meta, ref hash) => { if !signers.contains(&meta.nonce_authority) { return Err(InstructionError::MissingRequiredSignature); @@ -60,7 +61,10 @@ impl<'a> Account for KeyedAccount<'a> { _ => return Err(NonceError::BadAccountState.into()), }; - self.set_state(&State::Initialized(meta, recent_blockhashes[0])) + self.set_state(&Versions::new_current(State::Initialized( + meta, + recent_blockhashes[0], + ))) } fn withdraw_nonce_account( @@ -71,7 +75,7 @@ impl<'a> Account for KeyedAccount<'a> { rent: &Rent, signers: &HashSet, ) -> Result<(), InstructionError> { - let signer = match self.state()? { + let signer = match AccountUtilsState::::state(self)?.convert_to_current() { State::Uninitialized => { if lamports > self.lamports()? { return Err(InstructionError::InsufficientFunds); @@ -113,7 +117,7 @@ impl<'a> Account for KeyedAccount<'a> { return Err(NonceError::NoRecentBlockhashes.into()); } - let meta = match self.state()? { + let meta = match AccountUtilsState::::state(self)?.convert_to_current() { State::Uninitialized => { let min_balance = rent.minimum_balance(self.data_len()?); if self.lamports()? < min_balance { @@ -124,7 +128,10 @@ impl<'a> Account for KeyedAccount<'a> { _ => return Err(NonceError::BadAccountState.into()), }; - self.set_state(&State::Initialized(meta, recent_blockhashes[0])) + self.set_state(&Versions::new_current(State::Initialized( + meta, + recent_blockhashes[0], + ))) } fn authorize_nonce_account( @@ -132,15 +139,15 @@ impl<'a> Account for KeyedAccount<'a> { nonce_authority: &Pubkey, signers: &HashSet, ) -> Result<(), InstructionError> { - match self.state()? { + match AccountUtilsState::::state(self)?.convert_to_current() { State::Initialized(meta, nonce) => { if !signers.contains(&meta.nonce_authority) { return Err(InstructionError::MissingRequiredSignature); } - self.set_state(&State::Initialized( + self.set_state(&Versions::new_current(State::Initialized( nonce::state::Meta::new(nonce_authority), nonce, - )) + ))) } _ => Err(NonceError::BadAccountState.into()), } @@ -176,6 +183,7 @@ mod test { use super::*; use crate::{ account::KeyedAccount, + account_utils::State as AccountUtilsState, nonce::{self, State}, system_instruction::NonceError, sysvar::recent_blockhashes::{create_test_recent_blockhashes, RecentBlockhashes}, @@ -207,7 +215,9 @@ mod test { 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: State = keyed_account.state().unwrap(); + let state = AccountUtilsState::::state(keyed_account) + .unwrap() + .convert_to_current(); // New is in Uninitialzed state assert_eq!(state, State::Uninitialized); let recent_blockhashes = create_test_recent_blockhashes(95); @@ -215,7 +225,9 @@ mod test { keyed_account .initialize_nonce_account(&authorized, &recent_blockhashes, &rent) .unwrap(); - let state: State = keyed_account.state().unwrap(); + let state = AccountUtilsState::::state(keyed_account) + .unwrap() + .convert_to_current(); let stored = recent_blockhashes[0]; // First nonce instruction drives state from Uninitialized to Initialized assert_eq!(state, State::Initialized(meta, stored)); @@ -223,7 +235,9 @@ mod test { keyed_account .advance_nonce_account(&recent_blockhashes, &signers) .unwrap(); - let state: State = keyed_account.state().unwrap(); + let state = AccountUtilsState::::state(keyed_account) + .unwrap() + .convert_to_current(); let stored = recent_blockhashes[0]; // Second nonce instruction consumes and replaces stored nonce assert_eq!(state, State::Initialized(meta, stored)); @@ -231,7 +245,9 @@ mod test { keyed_account .advance_nonce_account(&recent_blockhashes, &signers) .unwrap(); - let state: State = keyed_account.state().unwrap(); + let state = AccountUtilsState::::state(keyed_account) + .unwrap() + .convert_to_current(); let stored = recent_blockhashes[0]; // Third nonce instruction for fun and profit assert_eq!(state, State::Initialized(meta, stored)); @@ -278,7 +294,9 @@ mod test { .unwrap(); let pubkey = nonce_account.account.borrow().owner.clone(); let nonce_account = KeyedAccount::new(&pubkey, false, nonce_account.account); - let state: State = nonce_account.state().unwrap(); + let state = AccountUtilsState::::state(&nonce_account) + .unwrap() + .convert_to_current(); assert_eq!(state, State::Initialized(meta, stored)); let signers = HashSet::new(); let recent_blockhashes = create_test_recent_blockhashes(0); @@ -399,7 +417,9 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); assert_eq!(state, State::Uninitialized); with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); @@ -418,7 +438,9 @@ mod test { &signers, ) .unwrap(); - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); // Withdraw instruction... // Deinitializes Account state assert_eq!(state, State::Uninitialized); @@ -438,7 +460,9 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, false, |nonce_keyed| { - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); assert_eq!(state, State::Uninitialized); with_test_keyed_account(42, false, |to_keyed| { let signers = HashSet::new(); @@ -464,7 +488,9 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |nonce_keyed| { - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); assert_eq!(state, State::Uninitialized); with_test_keyed_account(42, false, |to_keyed| { let mut signers = HashSet::new(); @@ -508,7 +534,9 @@ mod test { &signers, ) .unwrap(); - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); 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); @@ -525,7 +553,9 @@ mod test { &signers, ) .unwrap(); - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); 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); @@ -549,7 +579,9 @@ mod test { nonce_keyed .initialize_nonce_account(&authorized, &recent_blockhashes, &rent) .unwrap(); - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); let stored = recent_blockhashes[0]; assert_eq!(state, State::Initialized(meta, stored)); with_test_keyed_account(42, false, |to_keyed| { @@ -566,7 +598,9 @@ mod test { &signers, ) .unwrap(); - let state: State = nonce_keyed.state().unwrap(); + let state = AccountUtilsState::::state(nonce_keyed) + .unwrap() + .convert_to_current(); let stored = recent_blockhashes[0]; assert_eq!(state, State::Initialized(meta, stored)); assert_eq!(nonce_keyed.account.borrow().lamports, nonce_expect_lamports); @@ -688,7 +722,9 @@ mod test { }; let min_lamports = rent.minimum_balance(State::size()); with_test_keyed_account(min_lamports + 42, true, |keyed_account| { - let state: State = keyed_account.state().unwrap(); + let state = AccountUtilsState::::state(keyed_account) + .unwrap() + .convert_to_current(); assert_eq!(state, State::Uninitialized); let mut signers = HashSet::new(); signers.insert(keyed_account.signer_key().unwrap().clone()); @@ -699,7 +735,9 @@ mod test { let result = keyed_account.initialize_nonce_account(&authorized, &recent_blockhashes, &rent); assert_eq!(result, Ok(())); - let state: State = keyed_account.state().unwrap(); + let state = AccountUtilsState::::state(keyed_account) + .unwrap() + .convert_to_current(); assert_eq!(state, State::Initialized(meta, stored)); }) } @@ -778,7 +816,9 @@ mod test { let meta = nonce::state::Meta::new(&authorized); let result = nonce_account.authorize_nonce_account(&Pubkey::default(), &signers); assert_eq!(result, Ok(())); - let state: State = nonce_account.state().unwrap(); + let state = AccountUtilsState::::state(nonce_account) + .unwrap() + .convert_to_current(); assert_eq!(state, State::Initialized(meta, stored)); }) } diff --git a/sdk/src/nonce/state.rs b/sdk/src/nonce/state.rs index 30c76c7c14..a07af73ab8 100644 --- a/sdk/src/nonce/state.rs +++ b/sdk/src/nonce/state.rs @@ -28,8 +28,25 @@ impl Default for State { impl State { pub fn size() -> usize { - bincode::serialized_size(&State::Initialized(Meta::default(), Hash::default())).unwrap() - as usize + let data = Versions::new_current(State::Initialized(Meta::default(), Hash::default())); + bincode::serialized_size(&data).unwrap() as usize + } +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] +pub enum Versions { + Current(Box), +} + +impl Versions { + pub fn new_current(state: State) -> Self { + Self::Current(Box::new(state)) + } + + pub fn convert_to_current(self) -> State { + match self { + Self::Current(state) => *state, + } } }