From 37cb3a99f7e5f77f9f6e957620a33402154cce9e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 1 Oct 2020 16:40:48 +0200 Subject: [PATCH 1/4] dont force to resync at import --- lib/src/commands.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/lib/src/commands.rs b/lib/src/commands.rs index 3d853fa..33d4d75 100644 --- a/lib/src/commands.rs +++ b/lib/src/commands.rs @@ -674,29 +674,11 @@ impl Command for ImportCommand { let key = args[0]; - - let rescan = if args.len() == 3 { - if args[2] == "norescan" || args[2] == "false" || args[2] == "no" { - false - } else { - return format!("Couldn't undestand the argument '{}'. Please pass 'norescan' to prevent rescanning the wallet", args[2]); - } - } else { - true - }; - let r = match lightclient.do_import_key(key.to_string(), 0) { Ok(r) => r.pretty(2), Err(e) => return format!("Error: {}", e), }; - if rescan { - match lightclient.do_rescan() { - Ok(_) => {}, - Err(e) => return format!("Error: Rescan failed: {}", e), - }; - } - return r; } } @@ -727,12 +709,6 @@ impl Command for TImportCommand { Err(e) => return format!("Error: {}", e), }; - match lightclient.do_rescan() { - Ok(_) => {}, - Err(e) => return format!("Error: Rescan failed: {}", e), - }; - - return r; } } From ac696847c4fb33efd17cf48be8275e757e169e28 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 1 Oct 2020 17:30:23 +0200 Subject: [PATCH 2/4] add shielded command --- lib/src/commands.rs | 55 +++++++++++++++++++++++++++++++++--------- lib/src/lightclient.rs | 29 ++++++++++++++++++++++ lib/src/lightwallet.rs | 1 + 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/lib/src/commands.rs b/lib/src/commands.rs index 33d4d75..9f1934e 100644 --- a/lib/src/commands.rs +++ b/lib/src/commands.rs @@ -475,7 +475,7 @@ impl Command for SendCommand { h.push("OR"); h.push("send '[{'address':
, 'amount': , 'memo': }, ...]'"); h.push(""); - h.push("NOTE: The fee required to send this transaction (currently HUSH 0.0001) is additionally detected from your balance."); + h.push("NOTE: The fee required to send this transaction (currently HUSH 0.0001) is additionally deducted from your balance."); h.push("Example:"); h.push("send ztestsapling1x65nq4dgp0qfywgxcwk9n0fvm4fysmapgr2q00p85ju252h6l7mmxu2jg9cqqhtvzd69jwhgv8d 200000 \"Hello from the command line\""); h.push(""); @@ -548,17 +548,12 @@ impl Command for SendCommand { return self.help() }; - match lightclient.do_sync(true) { - Ok(_) => { - // Convert to the right format. String -> &str. - let tos = send_args.iter().map(|(a, v, m)| (a.as_str(), *v, m.clone()) ).collect::>(); - match lightclient.do_send(tos) { - Ok(txid) => { object!{ "txid" => txid } }, - Err(e) => { object!{ "error" => e } } - }.pretty(2) - }, - Err(e) => e - } + // Convert to the right format. String -> &str. + let tos = send_args.iter().map(|(a, v, m)| (a.as_str(), *v, m.clone()) ).collect::>(); + match lightclient.do_send(tos) { + Ok(txid) => { object!{ "txid" => txid } }, + Err(e) => { object!{ "error" => e } } + }.pretty(2) } } @@ -713,6 +708,41 @@ impl Command for TImportCommand { } } +struct ShieldCommand {} +impl Command for ShieldCommand { + fn help(&self) -> String { + let mut h = vec![]; + h.push("Shield all your transparent funds"); + h.push("Usage:"); + h.push("shield [optional address]"); + h.push(""); + h.push("NOTE: The fee required to send this transaction (currently HUSH 0.0001) is additionally deducted from your balance."); + h.push("Example:"); + h.push("shield"); + h.push(""); + + h.join("\n") + } + + fn short_help(&self) -> String { + "Shield your transparent HUSH into a sapling address".to_string() + } + + fn exec(&self, args: &[&str], lightclient: &LightClient) -> String { + // Parse the address or amount + let address = if args.len() > 0 { + Some(args[0].to_string()) + } else { + None + }; + + match lightclient.do_shield(address) { + Ok(txid) => { object!{ "txid" => txid } }, + Err(e) => { object!{ "error" => e } } + }.pretty(2) + } +} + struct HeightCommand {} impl Command for HeightCommand { fn help(&self) -> String { @@ -881,6 +911,7 @@ pub fn get_commands() -> Box>> { map.insert("info".to_string(), Box::new(InfoCommand{})); map.insert("coinsupply".to_string(), Box::new(CoinsupplyCommand{})); map.insert("send".to_string(), Box::new(SendCommand{})); + map.insert("shield".to_string(), Box::new(ShieldCommand{})); map.insert("save".to_string(), Box::new(SaveCommand{})); map.insert("quit".to_string(), Box::new(QuitCommand{})); map.insert("list".to_string(), Box::new(TransactionsCommand{})); diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index 38c48ea..1e4d668 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -1166,6 +1166,34 @@ impl LightClient { } } + pub fn do_shield(&self, address: Option) -> Result { + use zcash_primitives::transaction::components::amount::DEFAULT_FEE; + use std::convert::TryInto; + + let fee = DEFAULT_FEE.try_into().unwrap(); + let tbal = self.wallet.read().unwrap().tbalance(None); + + // Make sure there is a balance, and it is greated than the amount + if tbal <= fee { + return Err(format!("Not enough transparent balance to shield. Have {} puposhis, need more than {} puposhis to cover tx fee", tbal, fee)); + } + + let addr = address.or(self.wallet.read().unwrap().get_all_zaddresses().get(0).map(|s| s.clone())).unwrap(); + + let result = { + let _lock = self.sync_lock.lock().unwrap(); + self.wallet.read().unwrap().send_to_address( + u32::from_str_radix(&self.config.consensus_branch_id, 16).unwrap(), + &self.sapling_spend, &self.sapling_output, + true, + vec![(&addr, tbal - fee, None)], + |txbytes| broadcast_raw_tx(&self.get_server_uri(),self.config.no_cert_verification, txbytes) + ) + }; + + result.map(|(txid, _)| txid) + } + fn do_sync_internal(&self, print_updates: bool, retry_count: u32) -> Result { // We can only do one sync at a time because we sync blocks in serial order // If we allow multiple syncs, they'll all get jumbled up. @@ -1477,6 +1505,7 @@ impl LightClient { self.wallet.write().unwrap().send_to_address( u32::from_str_radix(&self.config.consensus_branch_id, 16).unwrap(), &self.sapling_spend, &self.sapling_output, + false, addrs, |txbytes| broadcast_raw_tx(&self.get_server_uri(), self.config.no_cert_verification, txbytes) ) diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index 083f20e..e8f24b9 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -1992,6 +1992,7 @@ impl LightWallet { consensus_branch_id: u32, spend_params: &[u8], output_params: &[u8], + transparent_only: bool, tos: Vec<(&str, u64, Option)>, broadcast_fn: F ) -> Result<(String, Vec), String> From 980c341d0e42c9967f25c78ead28d2a8c51138e4 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 1 Oct 2020 20:23:43 +0200 Subject: [PATCH 3/4] sync for imported privkeys from 0 --- lib/src/commands.rs | 9 ++++++--- lib/src/lightclient.rs | 4 ++-- lib/src/lightwallet.rs | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/src/commands.rs b/lib/src/commands.rs index 9f1934e..9f00664 100644 --- a/lib/src/commands.rs +++ b/lib/src/commands.rs @@ -696,10 +696,13 @@ impl Command for TImportCommand { } fn exec(&self, args: &[&str], lightclient: &LightClient) -> String { - - let key = args[0]; + if args.len() < 1 || args.len() > 2 { + return format!("Insufficient arguments\n\n{}", self.help()); + } - let r = match lightclient.do_import_tk(key.to_string()){ + let key = args[0]; + + let r = match lightclient.do_import_tk(key.to_string(), 0) { Ok(r) => r.pretty(2), Err(e) => return format!("Error: {}", e), }; diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index 1e4d668..fcc980d 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -1011,7 +1011,7 @@ impl LightClient { } /// Import a new private key - pub fn do_import_tk(&self, sk: String) -> Result { + pub fn do_import_tk(&self, sk: String, birthday: u64) -> Result { if !self.wallet.read().unwrap().is_unlocked_for_spending() { error!("Wallet is locked"); return Err("Wallet is locked".to_string()); @@ -1020,7 +1020,7 @@ impl LightClient { let new_address = { let wallet = self.wallet.write().unwrap(); - let addr = wallet.import_taddr(sk); + let addr = wallet.import_taddr(sk, birthday); if addr.starts_with("Error") { let e = format!("Error creating new address{}", addr); error!("{}", e); diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index e8f24b9..c92373e 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -628,7 +628,7 @@ impl LightWallet { address } - pub fn import_taddr(&self, sk: String) -> String { + pub fn import_taddr(&self, sk: String, birthday: u64) -> String { if !self.unlocked { return "Error: Can't add key while wallet is locked".to_string(); } From 8535a11e3774d79de2ebeaa5540567ccb4988f81 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 1 Oct 2020 20:40:16 +0200 Subject: [PATCH 4/4] fix command --- lib/src/commands.rs | 4 ++-- lib/src/lightclient.rs | 2 +- lib/src/lightwallet.rs | 7 ++++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/src/commands.rs b/lib/src/commands.rs index 9f00664..732235c 100644 --- a/lib/src/commands.rs +++ b/lib/src/commands.rs @@ -668,7 +668,7 @@ impl Command for ImportCommand { } let key = args[0]; - + let r = match lightclient.do_import_key(key.to_string(), 0) { Ok(r) => r.pretty(2), Err(e) => return format!("Error: {}", e), @@ -701,7 +701,7 @@ impl Command for TImportCommand { } let key = args[0]; - + let r = match lightclient.do_import_tk(key.to_string(), 0) { Ok(r) => r.pretty(2), Err(e) => return format!("Error: {}", e), diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index fcc980d..fa181a1 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -1018,7 +1018,7 @@ impl LightClient { } let new_address = { - let wallet = self.wallet.write().unwrap(); + let mut wallet = self.wallet.write().unwrap(); let addr = wallet.import_taddr(sk, birthday); if addr.starts_with("Error") { diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index c92373e..9c66639 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -628,7 +628,7 @@ impl LightWallet { address } - pub fn import_taddr(&self, sk: String, birthday: u64) -> String { + pub fn import_taddr(&mut self, sk: String, birthday: u64) -> String { if !self.unlocked { return "Error: Can't add key while wallet is locked".to_string(); } @@ -657,6 +657,11 @@ impl LightWallet { //// Add to tkeys self.tkeys.write().unwrap().push(WalletTKey::import_hdkey(sk_raw , address.clone())); + // Adjust wallet birthday + if birthday < self.birthday { + self.birthday = if birthday < self.config.sapling_activation_height {self.config.sapling_activation_height} else {birthday}; + } + address }