Browse Source

Merge pull request #32 from MyHush/danger

Danger to dev
dev
Denio 4 years ago
committed by GitHub
parent
commit
93d0a7d42c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 84
      lib/src/commands.rs
  2. 35
      lib/src/lightclient.rs
  3. 8
      lib/src/lightwallet.rs

84
lib/src/commands.rs

@ -475,7 +475,7 @@ impl Command for SendCommand {
h.push("OR");
h.push("send '[{'address': <address>, 'amount': <amount in puposhis>, 'memo': <optional 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::<Vec<_>>();
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::<Vec<_>>();
match lightclient.do_send(tos) {
Ok(txid) => { object!{ "txid" => txid } },
Err(e) => { object!{ "error" => e } }
}.pretty(2)
}
}
@ -673,30 +668,12 @@ 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;
}
}
@ -719,21 +696,53 @@ impl Command for TImportCommand {
}
fn exec(&self, args: &[&str], lightclient: &LightClient) -> String {
if args.len() < 1 || args.len() > 2 {
return format!("Insufficient arguments\n\n{}", self.help());
}
let key = args[0];
let r = match lightclient.do_import_tk(key.to_string()){
let r = match lightclient.do_import_tk(key.to_string(), 0) {
Ok(r) => r.pretty(2),
Err(e) => return format!("Error: {}", e),
};
match lightclient.do_rescan() {
Ok(_) => {},
Err(e) => return format!("Error: Rescan failed: {}", e),
};
return r;
}
}
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("");
return r;
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)
}
}
@ -905,6 +914,7 @@ pub fn get_commands() -> Box<HashMap<String, Box<dyn Command>>> {
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{}));

35
lib/src/lightclient.rs

@ -1011,16 +1011,16 @@ impl LightClient {
}
/// Import a new private key
pub fn do_import_tk(&self, sk: String) -> Result<JsonValue, String> {
pub fn do_import_tk(&self, sk: String, birthday: u64) -> Result<JsonValue, String> {
if !self.wallet.read().unwrap().is_unlocked_for_spending() {
error!("Wallet is locked");
return Err("Wallet is locked".to_string());
}
let new_address = {
let wallet = self.wallet.write().unwrap();
let mut 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);
@ -1166,6 +1166,34 @@ impl LightClient {
}
}
pub fn do_shield(&self, address: Option<String>) -> Result<String, String> {
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<JsonValue, String> {
// 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)
)

8
lib/src/lightwallet.rs

@ -628,7 +628,7 @@ impl LightWallet {
address
}
pub fn import_taddr(&self, sk: String) -> 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
}
@ -1992,6 +1997,7 @@ impl LightWallet {
consensus_branch_id: u32,
spend_params: &[u8],
output_params: &[u8],
transparent_only: bool,
tos: Vec<(&str, u64, Option<String>)>,
broadcast_fn: F
) -> Result<(String, Vec<u8>), String>

Loading…
Cancel
Save