diff --git a/lib/src/commands.rs b/lib/src/commands.rs index 442790ca8..172f8c4fd 100644 --- a/lib/src/commands.rs +++ b/lib/src/commands.rs @@ -161,27 +161,6 @@ impl Command for SyncCommand { } } -struct EncryptionStatusCommand {} -impl Command for EncryptionStatusCommand { - fn help(&self) -> String { - let mut h = vec![]; - h.push("Check if the wallet is encrypted and if it is locked"); - h.push("Usage:"); - h.push("encryptionstatus"); - h.push(""); - - h.join("\n") - } - - fn short_help(&self) -> String { - "Check if the wallet is encrypted and if it is locked".to_string() - } - - fn exec(&self, _args: &[&str], lightclient: &LightClient) -> String { - RT.block_on(async move { lightclient.do_encryption_status().await.pretty(2) }) - } -} - struct SyncStatusCommand {} impl Command for SyncStatusCommand { fn help(&self) -> String { @@ -534,178 +513,6 @@ impl Command for ExportCommand { } } -struct EncryptCommand {} -impl Command for EncryptCommand { - fn help(&self) -> String { - let mut h = vec![]; - h.push("Encrypt the wallet with a password"); - h.push("Note 1: This will encrypt the seed and the sapling and transparent private keys."); - h.push(" Use 'unlock' to temporarily unlock the wallet for spending or 'decrypt' "); - h.push(" to permanatly remove the encryption"); - h.push( - "Note 2: If you forget the password, the only way to recover the wallet is to restore", - ); - h.push(" from the seed phrase."); - h.push("Usage:"); - h.push("encrypt password"); - h.push(""); - h.push("Example:"); - h.push("encrypt my_strong_password"); - - h.join("\n") - } - - fn short_help(&self) -> String { - "Encrypt the wallet with a password".to_string() - } - - fn exec(&self, args: &[&str], lightclient: &LightClient) -> String { - if args.len() != 1 { - return self.help(); - } - - let passwd = args[0].to_string(); - - RT.block_on(async move { - match lightclient.wallet.encrypt(passwd).await { - Ok(_) => object! { "result" => "success" }, - Err(e) => object! { - "result" => "error", - "error" => e.to_string() - }, - } - .pretty(2) - }) - } -} - -struct DecryptCommand {} -impl Command for DecryptCommand { - fn help(&self) -> String { - let mut h = vec![]; - h.push("Completely remove wallet encryption, storing the wallet in plaintext on disk"); - h.push( - "Note 1: This will decrypt the seed and the sapling and transparent private keys and store them on disk.", - ); - h.push(" Use 'unlock' to temporarily unlock the wallet for spending"); - h.push("Note 2: If you've forgotten the password, the only way to recover the wallet is to restore"); - h.push(" from the seed phrase."); - h.push("Usage:"); - h.push("decrypt password"); - h.push(""); - h.push("Example:"); - h.push("decrypt my_strong_password"); - - h.join("\n") - } - - fn short_help(&self) -> String { - "Completely remove wallet encryption".to_string() - } - - fn exec(&self, args: &[&str], lightclient: &LightClient) -> String { - if args.len() != 1 { - return self.help(); - } - - let passwd = args[0].to_string(); - RT.block_on(async move { - match lightclient.wallet.remove_encryption(passwd).await { - Ok(_) => object! { "result" => "success" }, - Err(e) => object! { - "result" => "error", - "error" => e.to_string() - }, - } - .pretty(2) - }) - } -} - -struct UnlockCommand {} -impl Command for UnlockCommand { - fn help(&self) -> String { - let mut h = vec![]; - h.push("Unlock the wallet's encryption in memory, allowing spending from this wallet."); - h.push("Note 1: This will decrypt spending keys in memory only. The wallet remains encrypted on disk"); - h.push(" Use 'decrypt' to remove the encryption permanatly."); - h.push("Note 2: If you've forgotten the password, the only way to recover the wallet is to restore"); - h.push(" from the seed phrase."); - h.push("Usage:"); - h.push("unlock password"); - h.push(""); - h.push("Example:"); - h.push("unlock my_strong_password"); - - h.join("\n") - } - - fn short_help(&self) -> String { - "Unlock wallet encryption for spending".to_string() - } - - fn exec(&self, args: &[&str], lightclient: &LightClient) -> String { - if args.len() != 1 { - return self.help(); - } - - let passwd = args[0].to_string(); - RT.block_on(async move { - match lightclient.wallet.unlock(passwd).await { - Ok(_) => object! { "result" => "success" }, - Err(e) => object! { - "result" => "error", - "error" => e.to_string() - }, - } - .pretty(2) - }) - } -} - -struct LockCommand {} -impl Command for LockCommand { - fn help(&self) -> String { - let mut h = vec![]; - h.push("Lock a wallet that's been temporarily unlocked. You should already have encryption enabled."); - h.push("Note 1: This will remove all spending keys from memory. The wallet remains encrypted on disk"); - h.push("Note 2: If you've forgotten the password, the only way to recover the wallet is to restore"); - h.push(" from the seed phrase."); - h.push("Usage:"); - h.push("lock"); - h.push(""); - h.push("Example:"); - h.push("lock"); - - h.join("\n") - } - - fn short_help(&self) -> String { - "Lock a wallet that's been temporarily unlocked".to_string() - } - - fn exec(&self, args: &[&str], lightclient: &LightClient) -> String { - if args.len() != 0 { - let mut h = vec![]; - h.push("Extra arguments to lock. Did you mean 'encrypt'?"); - h.push(""); - - return format!("{}\n{}", h.join("\n"), self.help()); - } - - RT.block_on(async move { - match lightclient.wallet.lock().await { - Ok(_) => object! { "result" => "success" }, - Err(e) => object! { - "result" => "error", - "error" => e.to_string() - }, - } - .pretty(2) - }) - } -} - struct ShieldCommand {} impl Command for ShieldCommand { fn help(&self) -> String { @@ -1483,10 +1290,6 @@ pub fn get_commands() -> Box>> { map.insert("sync".to_string(), Box::new(SyncCommand {})); map.insert("syncstatus".to_string(), Box::new(SyncStatusCommand {})); - map.insert( - "encryptionstatus".to_string(), - Box::new(EncryptionStatusCommand {}), - ); map.insert( "encryptmessage".to_string(), Box::new(EncryptMessageCommand {}), @@ -1524,10 +1327,6 @@ pub fn get_commands() -> Box>> { map.insert("new".to_string(), Box::new(NewAddressCommand {})); map.insert("defaultfee".to_string(), Box::new(DefaultFeeCommand {})); map.insert("seed".to_string(), Box::new(SeedCommand {})); - map.insert("encrypt".to_string(), Box::new(EncryptCommand {})); - map.insert("decrypt".to_string(), Box::new(DecryptCommand {})); - map.insert("unlock".to_string(), Box::new(UnlockCommand {})); - map.insert("lock".to_string(), Box::new(LockCommand {})); Box::new(map) } diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index f3750f8ce..3554da3e5 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -526,21 +526,6 @@ impl LightClient { pub async fn do_save(&self) -> Result<(), String> { // On mobile platforms, disable the save, because the saves will be handled by the native layer, and not in rust if cfg!(all(not(target_os = "ios"), not(target_os = "android"))) { - // If the wallet is encrypted but unlocked, lock it again. - { - if self.wallet.is_encrypted().await && self.wallet.is_unlocked_for_spending().await - { - match self.wallet.lock().await { - Ok(_) => {} - Err(e) => { - let err = format!("ERR: {}", e); - error!("{}", err); - return Err(e.to_string()); - } - } - } - } - { // Prevent any overlapping syncs during save, and don't save in the middle of a sync let _lock = self.sync_lock.lock().await; @@ -573,20 +558,6 @@ impl LightClient { } pub async fn do_save_to_buffer(&self) -> Result, String> { - // If the wallet is encrypted but unlocked, lock it again. - { - if self.wallet.is_encrypted().await && self.wallet.is_unlocked_for_spending().await { - match self.wallet.lock().await { - Ok(_) => {} - Err(e) => { - let err = format!("ERR: {}", e); - error!("{}", err); - return Err(e.to_string()); - } - } - } - } - let mut buffer: Vec = vec![]; match self.wallet.write(&mut buffer).await { Ok(_) => Ok(buffer), @@ -665,11 +636,6 @@ impl LightClient { } pub async fn do_seed_phrase(&self) -> Result { - if !self.wallet.is_unlocked_for_spending().await { - error!("Wallet is locked"); - return Err("Wallet is locked"); - } - Ok(object! { "seed" => self.wallet.mnemonic().to_string(), "birthday" => self.wallet.get_birthday().await @@ -880,13 +846,6 @@ impl LightClient { } } - pub async fn do_encryption_status(&self) -> JsonValue { - object! { - "encrypted" => self.wallet.is_encrypted().await, - "locked" => !self.wallet.is_unlocked_for_spending().await - } - } - pub async fn do_list_transactions(&self, include_memo_hex: bool) -> JsonValue { // Create a list of TransactionItems from wallet transactions let unified_spend_capability_arc = self.wallet.unified_spend_capability(); @@ -1057,11 +1016,6 @@ impl LightClient { /// Create a new address, deriving it from the seed. pub async fn do_new_address(&self, addr_type: &str) -> Result { - if !self.wallet.is_unlocked_for_spending().await { - error!("Wallet is locked"); - return Err("Wallet is locked".to_string()); - } - //TODO: Placeholder interface let desired_receivers = ReceiverSelection { sapling: addr_type.contains('z'), @@ -1092,10 +1046,6 @@ impl LightClient { } pub async fn do_rescan(&self) -> Result { - if !self.wallet.is_unlocked_for_spending().await { - warn!("Wallet is locked, new HD addresses won't be added!"); - } - info!("Rescan starting"); self.clear_state().await; diff --git a/lib/src/wallet.rs b/lib/src/wallet.rs index a02b62f09..aebd3c260 100644 --- a/lib/src/wallet.rs +++ b/lib/src/wallet.rs @@ -387,15 +387,6 @@ impl LightWallet { } pub async fn write(&self, mut writer: W) -> io::Result<()> { - if self.transaction_context.key.read().await.encrypted - && self.transaction_context.key.read().await.unlocked - { - return Err(Error::new( - ErrorKind::InvalidInput, - format!("Cannot write while wallet is unlocked while encrypted."), - )); - } - // Write the version writer.write_u64::(Self::serialized_version())?; @@ -573,21 +564,6 @@ impl LightWallet { let _ = std::mem::replace(&mut *g, SendProgress::new(next_id)); } - pub async fn is_unlocked_for_spending(&self) -> bool { - match &*self.transaction_context.key.read().await { - UnifiedSpendCapability { - encrypted: true, - unlocked: false, - .. - } => false, - _otherwise => true, - } - } - - pub async fn is_encrypted(&self) -> bool { - self.transaction_context.key.read().await.encrypted - } - // Get the first block that this wallet has a transaction in. This is often used as the wallet's "birthday" // If there are no transactions, then the actual birthday (which is recorder at wallet creation) is returned // If no birthday was recorded, return the sapling activation height @@ -1185,10 +1161,6 @@ impl LightWallet { F: Fn(Box<[u8]>) -> Fut, Fut: Future>, { - if !self.unified_spend_capability().read().await.unlocked { - return Err("Cannot spend while wallet is locked".to_string()); - } - let start_time = now(); if tos.len() == 0 { return Err("Need at least one destination address".to_string()); @@ -1577,28 +1549,6 @@ impl LightWallet { .clone() } } - - pub async fn encrypt(&self, passwd: String) -> io::Result<()> { - self.unified_spend_capability() - .write() - .await - .encrypt(passwd) - } - - pub async fn lock(&self) -> io::Result<()> { - self.unified_spend_capability().write().await.lock() - } - - pub async fn unlock(&self, passwd: String) -> io::Result<()> { - self.unified_spend_capability().write().await.unlock(passwd) - } - - pub async fn remove_encryption(&self, passwd: String) -> io::Result<()> { - self.unified_spend_capability() - .write() - .await - .remove_encryption(passwd) - } } //This function will likely be used again if/when we re-implement key import diff --git a/lib/src/wallet/keys/unified.rs b/lib/src/wallet/keys/unified.rs index 243084378..6d262ec71 100644 --- a/lib/src/wallet/keys/unified.rs +++ b/lib/src/wallet/keys/unified.rs @@ -27,11 +27,8 @@ pub struct UnifiedSpendCapability { // Not all diversifier indexes produce valid sapling addresses. // Because of this, the index isn't necessarily equal to addresses.len() next_sapling_diversifier_index: DiversifierIndex, - // Note that unified spend authority encryption is not yet implemented, // These are placeholder fields, and are currenly always false - pub(crate) encrypted: bool, - pub(crate) unlocked: bool, } #[derive(Debug, Clone, Copy)] @@ -194,8 +191,6 @@ impl UnifiedSpendCapability { transparent_child_keys: vec![], addresses: vec![], next_sapling_diversifier_index: DiversifierIndex::new(), - encrypted: false, - unlocked: true, } } @@ -245,19 +240,6 @@ impl UnifiedSpendCapability { // create it with a suitable first address self.addresses()[0].sapling().unwrap() } - - pub fn encrypt(&mut self, _passwd: String) -> std::io::Result<()> { - todo!() - } - pub fn lock(&mut self) -> std::io::Result<()> { - todo!() - } - pub fn unlock(&mut self, _passwd: String) -> std::io::Result<()> { - todo!() - } - pub fn remove_encryption(&mut self, _passwd: String) -> std::io::Result<()> { - todo!() - } } impl ReadableWriteable<()> for UnifiedSpendCapability { const VERSION: u8 = 1; @@ -275,16 +257,6 @@ impl ReadableWriteable<()> for UnifiedSpendCapability { super::extended_transparent::ExtendedPrivKey::read(&mut reader, ())?; let receivers_selected = Vector::read(&mut reader, |mut r| ReceiverSelection::read(&mut r, ()))?; - let encrypted = match reader.read_u8()? { - 0 => false, - 1 => true, - _ => { - return Err(io::Error::new( - io::ErrorKind::InvalidData, - "encrypted status is not bool!", - )) - } - }; let mut unifiedspendauth = Self { orchard_key, sapling_key, @@ -292,8 +264,6 @@ impl ReadableWriteable<()> for UnifiedSpendCapability { transparent_child_keys: vec![], addresses: vec![], next_sapling_diversifier_index: DiversifierIndex::new(), - encrypted, - unlocked: true, }; for receiver_selection in receivers_selected { unifiedspendauth @@ -317,12 +287,11 @@ impl ReadableWriteable<()> for UnifiedSpendCapability { transparent: address.transparent().is_some(), }) } - Vector::write( + Ok(Vector::write( &mut writer, &receivers_per_address, |mut w, receiver_selection| receiver_selection.write(&mut w), - )?; - writer.write_u8(self.encrypted as u8) + )?) } }