From 97c6567139f68b42aad68cd4e1d09a51f83423de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Wed, 11 May 2022 17:19:41 +0200 Subject: [PATCH] wallet: restore unit tests --- .../src/operations/mixnet/account.rs | 72 +++++++------------ .../src-tauri/src/wallet_storage/mod.rs | 32 ++++----- 2 files changed, 39 insertions(+), 65 deletions(-) diff --git a/nym-wallet/src-tauri/src/operations/mixnet/account.rs b/nym-wallet/src-tauri/src/operations/mixnet/account.rs index 497f6fc26c..19eeae5c18 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/account.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/account.rs @@ -386,24 +386,15 @@ pub async fn sign_in_with_password( // Currently we only support a single, default, id in the wallet let id = wallet_storage::AccountId::new(DEFAULT_WALLET_ACCOUNT_ID.to_string()); let password = wallet_storage::UserPassword::new(password); - let stored_account = wallet_storage::load_existing_wallet_login_information(&id, &password)?; - let (mnemonic, all_accounts) = extract_first_mnemonic_and_all_accounts(stored_account, id)?; + let stored_login = wallet_storage::load_existing_wallet_login_information(&id, &password)?; - { - for account in &all_accounts { - log::trace!("account: {:?}", account); - } - let mut w_state = state.write().await; - w_state.set_all_accounts(all_accounts); - } + let mnemonic = extract_first_mnemonic(&stored_login)?; + set_state_with_all_accounts(stored_login, id, state.clone()).await?; _connect_with_mnemonic(mnemonic, state).await } -fn extract_first_mnemonic_and_all_accounts( - stored_account: StoredLogin, - login_id: wallet_storage::AccountId, -) -> Result<(Mnemonic, Vec), BackendError> { +fn extract_first_mnemonic(stored_account: &StoredLogin) -> Result { let mnemonic = match stored_account { StoredLogin::Mnemonic(ref account) => account.mnemonic().clone(), StoredLogin::Multiple(ref accounts) => { @@ -418,12 +409,7 @@ fn extract_first_mnemonic_and_all_accounts( } }; - // Keep track of all accounts for that id - let all_accounts: Vec<_> = stored_account - .unwrap_into_multiple_accounts(login_id) - .into_accounts() - .collect(); - Ok((mnemonic, all_accounts)) + Ok(mnemonic) } #[tauri::command] @@ -449,23 +435,24 @@ pub async fn add_account_for_password( let password = wallet_storage::UserPassword::new(password.to_string()); // Creating the returned account entry could fail, so do it before attempting to store to wallet - let address = { - let state = state.read().await; - let network: Network = state.current_network().into(); - derive_address(mnemonic.clone(), network.bech32_prefix())?.to_string() - }; - wallet_storage::append_account_to_wallet_login_information( - mnemonic, + mnemonic.clone(), hd_path, id.clone(), inner_id.clone(), &password, )?; + let address = { + let state = state.read().await; + let network: Network = state.current_network().into(); + derive_address(mnemonic, network.bech32_prefix())?.to_string() + }; + // Re-read all the acccounts from the wallet to reset the state, rather than updating it // incrementally - reset_state_with_all_accounts_from_file(&id, &password, state).await?; + let stored_login = wallet_storage::load_existing_wallet_login_information(&id, &password)?; + set_state_with_all_accounts(stored_login, id, state).await?; Ok(AccountEntry { id: inner_id.to_string(), @@ -473,17 +460,21 @@ pub async fn add_account_for_password( }) } -async fn reset_state_with_all_accounts_from_file( - id: &wallet_storage::AccountId, - password: &wallet_storage::UserPassword, +async fn set_state_with_all_accounts( + stored_login: StoredLogin, + id: wallet_storage::AccountId, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - let stored_account = wallet_storage::load_existing_wallet_login_information(id, password)?; - let all_accounts: Vec<_> = stored_account + log::trace!("Set state with accounts:"); + let all_accounts: Vec<_> = stored_login .unwrap_into_multiple_accounts(id.clone()) .into_accounts() .collect(); + for account in &all_accounts { + log::trace!("account: {:?}", account); + } + let mut w_state = state.write().await; w_state.set_all_accounts(all_accounts); Ok(()) @@ -502,7 +493,9 @@ pub async fn remove_account_for_password( let password = wallet_storage::UserPassword::new(password.to_string()); wallet_storage::remove_account_from_wallet_login(&id, &inner_id, &password)?; - reset_state_with_all_accounts_from_file(&id, &password, state).await + // Load to reset the internal state + let stored_login = wallet_storage::load_existing_wallet_login_information(&id, &password)?; + set_state_with_all_accounts(stored_login, id, state).await } fn derive_address( @@ -606,24 +599,13 @@ mod tests { let wallet_file = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(SAVED_WALLET); let id = wallet_storage::AccountId::new("first".to_string()); let password = wallet_storage::UserPassword::new("password".to_string()); - let hd_path: DerivationPath = COSMOS_DERIVATION_PATH.parse().unwrap(); let stored_account = wallet_storage::load_existing_wallet_login_information_at_file(wallet_file, &id, &password) .unwrap(); - let (mnemonic, all_accounts) = - extract_first_mnemonic_and_all_accounts(&stored_account, id.clone()).unwrap(); + let mnemonic = extract_first_mnemonic(&stored_account).unwrap(); let expected_mnemonic = bip39::Mnemonic::from_str("country mean universe text phone begin deputy reject result good cram illness common cluster proud swamp digital patrol spread bar face december base kick").unwrap(); assert_eq!(mnemonic, expected_mnemonic); - - assert_eq!( - all_accounts, - vec![wallet_storage::WalletAccount::new_mnemonic_backed_account( - id, - expected_mnemonic, - hd_path, - )] - ); } } diff --git a/nym-wallet/src-tauri/src/wallet_storage/mod.rs b/nym-wallet/src-tauri/src/wallet_storage/mod.rs index ac328fde2d..9792c877b2 100644 --- a/nym-wallet/src-tauri/src/wallet_storage/mod.rs +++ b/nym-wallet/src-tauri/src/wallet_storage/mod.rs @@ -1,7 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub(crate) use crate::wallet_storage::account_data::{StoredLogin, WalletAccount}; +pub(crate) use crate::wallet_storage::account_data::StoredLogin; pub(crate) use crate::wallet_storage::password::{AccountId, UserPassword}; use crate::error::BackendError; @@ -157,7 +157,9 @@ fn append_account_to_wallet_login_information_at_file( let decrypted_login = stored_wallet.decrypt_login(&id, password)?; - // Add accounts to the inner structure + // Add accounts to the inner structure. + // Note that in case we only have single account entry, without an inner_id, we convert to + // multiple accounts and we set the first inner_id to id. let mut accounts = decrypted_login.unwrap_into_multiple_accounts(id.clone()); accounts.add(inner_id, mnemonic, hd_path)?; @@ -287,7 +289,7 @@ fn remove_account_from_wallet_login_at_file( #[cfg(test)] mod tests { - use crate::wallet_storage::WalletAccount; + use crate::wallet_storage::account_data::WalletAccount; use super::*; use config::defaults::COSMOS_DERIVATION_PATH; @@ -721,7 +723,6 @@ mod tests { let id1 = AccountId::new("first".to_string()); let id2 = AccountId::new("second".to_string()); - let default_id = AccountId::new(DEFAULT_NAME_FIRST_ACCOUNT.to_string()); store_wallet_login_information_at_file( wallet_file.clone(), @@ -754,7 +755,7 @@ mod tests { load_existing_wallet_login_information_at_file(wallet_file, &id1, &password).unwrap(); let accounts = loaded_accounts.as_multiple_accounts().unwrap(); let expected = vec![ - WalletAccount::new_mnemonic_backed_account(default_id, dummy_account1, hd_path.clone()), + WalletAccount::new_mnemonic_backed_account(id1, dummy_account1, hd_path.clone()), WalletAccount::new_mnemonic_backed_account(id2, dummy_account2, hd_path), ] .into(); @@ -778,7 +779,6 @@ mod tests { let id2 = AccountId::new("second".to_string()); let id3 = AccountId::new("third".to_string()); let id4 = AccountId::new("fourth".to_string()); - let default_id = AccountId::new(DEFAULT_NAME_FIRST_ACCOUNT.to_string()); store_wallet_login_information_at_file( wallet_file.clone(), @@ -836,7 +836,7 @@ mod tests { load_existing_wallet_login_information_at_file(wallet_file, &id2, &password).unwrap(); let accounts = loaded_accounts.as_multiple_accounts().unwrap(); let expected = vec![ - WalletAccount::new_mnemonic_backed_account(default_id, dummy_account2, hd_path.clone()), + WalletAccount::new_mnemonic_backed_account(id2, dummy_account2, hd_path.clone()), WalletAccount::new_mnemonic_backed_account(id3, dummy_account3, hd_path.clone()), WalletAccount::new_mnemonic_backed_account(id4, dummy_account4, hd_path), ] @@ -900,7 +900,6 @@ mod tests { let id1 = AccountId::new("first".to_string()); let id2 = AccountId::new("second".to_string()); let id3 = AccountId::new("third".to_string()); - let default_id = AccountId::new(DEFAULT_NAME_FIRST_ACCOUNT.to_string()); store_wallet_login_information_at_file( wallet_file.clone(), @@ -937,7 +936,7 @@ mod tests { load_existing_wallet_login_information_at_file(wallet_file, &id2, &password).unwrap(); let accounts = loaded_accounts.as_multiple_accounts().unwrap(); let expected = vec![ - WalletAccount::new_mnemonic_backed_account(default_id, dummy_account2, hd_path.clone()), + WalletAccount::new_mnemonic_backed_account(id2, dummy_account2, hd_path.clone()), WalletAccount::new_mnemonic_backed_account(id3, dummy_account3, hd_path), ] .into(); @@ -957,7 +956,6 @@ mod tests { let id1 = AccountId::new("first".to_string()); let id2 = AccountId::new("second".to_string()); - let default_id = AccountId::new(DEFAULT_NAME_FIRST_ACCOUNT.to_string()); store_wallet_login_information_at_file( wallet.clone(), @@ -978,7 +976,7 @@ mod tests { ) .unwrap(); - remove_account_from_wallet_login_at_file(wallet.clone(), &id1, &default_id, &password).unwrap(); + remove_account_from_wallet_login_at_file(wallet.clone(), &id1, &id1, &password).unwrap(); remove_account_from_wallet_login_at_file(wallet.clone(), &id1, &id2, &password).unwrap(); // The file should now be removed @@ -1006,7 +1004,6 @@ mod tests { let id1 = AccountId::new("first".to_string()); let id2 = AccountId::new("second".to_string()); let id3 = AccountId::new("third".to_string()); - let default_id = AccountId::new(DEFAULT_NAME_FIRST_ACCOUNT.to_string()); store_wallet_login_information_at_file( wallet.clone(), @@ -1036,7 +1033,7 @@ mod tests { ) .unwrap(); - remove_account_from_wallet_login_at_file(wallet.clone(), &id1, &default_id, &password).unwrap(); + remove_account_from_wallet_login_at_file(wallet.clone(), &id1, &id1, &password).unwrap(); remove_account_from_wallet_login_at_file(wallet.clone(), &id1, &id2, &password).unwrap(); // And trying to load when the file is gone fails @@ -1070,7 +1067,6 @@ mod tests { let id2 = AccountId::new("second".to_string()); let id3 = AccountId::new("third".to_string()); let id4 = AccountId::new("fourth".to_string()); - let default_id = AccountId::new(DEFAULT_NAME_FIRST_ACCOUNT.to_string()); store_wallet_login_information_at_file( wallet.clone(), @@ -1118,18 +1114,14 @@ mod tests { load_existing_wallet_login_information_at_file(wallet.clone(), &id2, &password).unwrap(); let accounts = loaded_accounts.as_multiple_accounts().unwrap(); let expected = vec![ - WalletAccount::new_mnemonic_backed_account( - default_id.clone(), - dummy_account2, - hd_path.clone(), - ), + WalletAccount::new_mnemonic_backed_account(id2.clone(), dummy_account2, hd_path.clone()), WalletAccount::new_mnemonic_backed_account(id4.clone(), dummy_account4, hd_path.clone()), ] .into(); assert_eq!(accounts, &expected); // Delete the second and fourth mnemonic from the second login entry removes the login entry - remove_account_from_wallet_login_at_file(wallet.clone(), &id2, &default_id, &password).unwrap(); + remove_account_from_wallet_login_at_file(wallet.clone(), &id2, &id2, &password).unwrap(); remove_account_from_wallet_login_at_file(wallet.clone(), &id2, &id4, &password).unwrap(); assert!(matches!( load_existing_wallet_login_information_at_file(wallet.clone(), &id2, &password),