diff --git a/Cargo.toml b/Cargo.toml index 7680ec3..f625e9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "silentdragonlite-cli" -version = "1.0.0" +version = "1.1.0" edition = "2018" [dependencies] diff --git a/docker/Dockerfile b/docker/Dockerfile index 9636f82..9c78c80 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -25,3 +25,7 @@ ENV CC_armv7_unknown_linux_gnueabhihf="arm-linux-gnueabihf-gcc" # This is a bug fix for the windows cross compiler for Rust. RUN cp /usr/x86_64-w64-mingw32/lib/crt2.o /usr/local/rustup/toolchains/1.38.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/crt2.o +# For windows cross compilation, use a pre-build binary. Remember to set the +# SODIUM_LIB_DIR for windows cross compilation +RUN cd /opt && wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.17-mingw.tar.gz && \ + tar xvf libsodium-1.0.17-mingw.tar.gz \ No newline at end of file diff --git a/lib/src/commands.rs b/lib/src/commands.rs index 7a2120a..56911dd 100644 --- a/lib/src/commands.rs +++ b/lib/src/commands.rs @@ -231,6 +231,16 @@ impl Command for EncryptCommand { return self.help(); } + // Refuse to encrypt if the bip39 bug has not been fixed + use crate::lightwallet::bugs::BugBip39Derivation; + if BugBip39Derivation::has_bug(lightclient) { + let mut h = vec![]; + h.push("It looks like your wallet has the bip39bug. Please run 'fixbip39bug' to fix it"); + h.push("before encrypting your wallet."); + h.push("ERROR: Cannot encrypt while wallet has the bip39bug."); + return h.join("\n"); + } + let passwd = args[0].to_string(); match lightclient.wallet.write().unwrap().encrypt(passwd) { diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index 69d47fc..327ae02 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -244,8 +244,32 @@ impl LightClient { Ok(l) } + /// Create a brand new wallet with a new seed phrase. Will fail if a wallet file + /// already exists on disk + pub fn new(config: &LightClientConfig, latest_block: u64) -> io::Result { + if config.wallet_exists() { + return Err(Error::new(ErrorKind::AlreadyExists, + "Cannot create a new wallet from seed, because a wallet already exists")); + } + + let mut l = LightClient { + wallet : Arc::new(RwLock::new(LightWallet::new(None, config, latest_block)?)), + config : config.clone(), + sapling_output : vec![], + sapling_spend : vec![] + }; + + l.set_wallet_initial_state(); + l.read_sapling_params(); + + info!("Created new wallet with a new seed!"); + info!("Created LightClient to {}", &config.server); + + Ok(l) + } + pub fn new_from_phrase(seed_phrase: String, config: &LightClientConfig, latest_block: u64) -> io::Result { - if config.get_wallet_path().exists() { + if config.wallet_exists() { return Err(Error::new(ErrorKind::AlreadyExists, "Cannot create a new wallet from seed, because a wallet already exists")); } @@ -267,7 +291,7 @@ impl LightClient { } pub fn read_from_disk(config: &LightClientConfig) -> io::Result { - if !config.get_wallet_path().exists() { + if !config.wallet_exists() { return Err(Error::new(ErrorKind::AlreadyExists, format!("Cannot read wallet. No file at {}", config.get_wallet_path().display()))); } diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index ffe5d6d..390e3b0 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -39,7 +39,6 @@ use zcash_primitives::{ primitives::{PaymentAddress}, }; - use crate::lightclient::{LightClientConfig}; mod data; @@ -58,7 +57,6 @@ fn now() -> f64 { SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as f64 } - /// Sha256(Sha256(value)) pub fn double_sha256(payload: &[u8]) -> Vec { let h1 = Sha256::digest(&payload); diff --git a/lib/src/lightwallet/bugs.rs b/lib/src/lightwallet/bugs.rs index 48eeba7..0e9c925 100644 --- a/lib/src/lightwallet/bugs.rs +++ b/lib/src/lightwallet/bugs.rs @@ -28,6 +28,10 @@ impl BugBip39Derivation { return false; } + if wallet.is_encrypted() { + return false; + } + // The seed bytes is the raw entropy. To pass it to HD wallet generation, // we need to get the 64 byte bip39 entropy let bip39_seed = bip39::Seed::new(&Mnemonic::from_entropy(&wallet.seed, Language::English).unwrap(), ""); @@ -73,13 +77,12 @@ impl BugBip39Derivation { println!("Sending funds to ourself."); let zaddr = client.do_address()["z_addresses"][0].as_str().unwrap().to_string(); let balance_json = client.do_balance(); - let fee: u64 = DEFAULT_FEE.try_into().unwrap(); let amount: u64 = balance_json["zbalance"].as_u64().unwrap() - + balance_json["tbalance"].as_u64().unwrap() - - fee; + + balance_json["tbalance"].as_u64().unwrap(); let txid = if amount > 0 { - match client.do_send(vec![(&zaddr, amount, None)]) { + let fee: u64 = DEFAULT_FEE.try_into().unwrap(); + match client.do_send(vec![(&zaddr, amount-fee, None)]) { Ok(txid) => txid, Err(e) => { let r = object!{ diff --git a/mkrelease.sh b/mkrelease.sh index d395bc0..23bec1c 100755 --- a/mkrelease.sh +++ b/mkrelease.sh @@ -25,20 +25,28 @@ set -- "${POSITIONAL[@]}" # restore positional parameters if [ -z $APP_VERSION ]; then echo "APP_VERSION is not set"; exit 1; fi -# Clean everything first -#cargo clean +# First, do the tests +cd lib && cargo test --release +retVal=$? +if [ $retVal -ne 0 ]; then + echo "Error" + exit $retVal +fi +cd .. # Compile for mac directly -#cargo build --release +cargo build --release -# For Windows and Linux, build via docker -docker run --rm -v $(pwd)/:/opt/silentdragonlite-cli rustbuild:latest bash -c "cd /opt/silentdragonlite-cli && cargo build --release && cargo build --release --target x86_64-pc-windows-gnu" - -# Now sign and zip the binaries #macOS rm -rf target/macOS-silentdragonlite-cli-v$APP_VERSION mkdir -p target/macOS-silentdragonlite-cli-v$APP_VERSION cp target/release/silentdragonlite-cli target/macOS-silentdragonlite-cli-v$APP_VERSION/ + +# For Windows and Linux, build via docker +docker run --rm -v $(pwd)/:/opt/zecwallet-light-cli rustbuild:latest bash -c "cd /opt/zecwallet-light-cli && cargo build --release && SODIUM_LIB_DIR='/opt/libsodium-win64/lib/' cargo build --release --target x86_64-pc-windows-gnu" + +# Now sign and zip the binaries +# macOS gpg --batch --output target/macOS-silentdragonlite-cli-v$APP_VERSION/silentdragonlite-cli.sig --detach-sig target/macOS-silentdragonlite-cli-v$APP_VERSION/silentdragonlite-cli cd target cd macOS-silentdragonlite-cli-v$APP_VERSION diff --git a/src/main.rs b/src/main.rs index c2ab390..dbc69ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,7 @@ pub fn main() { // Get command line arguments use clap::{Arg, App}; let matches = App::new("SilentDragon CLI") - .version("1.0.0") + .version("1.1.0") .arg(Arg::with_name("seed") .short("s") .long("seed") @@ -120,7 +120,7 @@ pub fn main() { Some(13) => { startup_helpers::report_permission_error(); }, - _ => eprintln!("Something else!") + _ => {} } return; } @@ -162,7 +162,14 @@ fn startup(server: http::Uri, dangerous: bool, seed: Option, first_sync: let lightclient = match seed { Some(phrase) => Arc::new(LightClient::new_from_phrase(phrase, &config, latest_block_height)?), - None => Arc::new(LightClient::read_from_disk(&config)?) + None => { + if config.wallet_exists() { + Arc::new(LightClient::read_from_disk(&config)?) + } else { + println!("Creating a new wallet"); + Arc::new(LightClient::new(&config, latest_block_height)?) + } + } }; // Print startup Messages