Browse Source

Merge pull request #36 from adityapk00/master

Merge
checkpoints
Denio 5 years ago
committed by GitHub
parent
commit
a21008f9a2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      README.md
  2. 24
      docker/Dockerfile
  3. 67
      lib/src/commands.rs
  4. 8
      lib/src/lightclient.rs
  5. 4
      lib/src/lightwallet.rs
  6. 13
      lib/src/lightwallet/tests.rs

2
README.md

@ -21,7 +21,7 @@ Run `silentdragonlite-cli help` to see a list of all commands.
### Note Management
silentdragonlite does automatic note and utxo management, which means it doesn't allow you to manually select which address to send outgoing transactions from. It follows these principles:
* Defaults to sending shielded transactions, even if you're sending to a transparent address
* Sapling funds need at least 4 confirmations before they can be spent
* Sapling funds need at least 5 confirmations before they can be spent
* Can select funds from multiple shielded addresses in the same transaction
* Will automatically shield your transparent funds at the first opportunity
* When sending an outgoing transaction to a shielded address, silentdragonlite can decide to use the transaction to additionally shield your transparent funds (i.e., send your transparent funds to your own shielded address in the same transaction)

24
docker/Dockerfile

@ -1,35 +1,41 @@
FROM rust:1.38
FROM ubuntu:16.04
LABEL Description="Rust compile env for Linux + Windows (cross)"
RUN apt update
RUN apt install -y build-essential mingw-w64 gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf
RUN apt install -y build-essential mingw-w64 gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf curl vim wget
# Get Rust
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
RUN rustup target add x86_64-pc-windows-gnu
RUN rustup target add aarch64-unknown-linux-gnu
RUN rustup target add armv7-unknown-linux-gnueabihf
# Append the linker to the cargo config for Windows cross compile
RUN echo "[target.x86_64-pc-windows-gnu]" >> /usr/local/cargo/config && \
echo "linker = '/usr/bin/x86_64-w64-mingw32-gcc'" >> /usr/local/cargo/config
RUN echo "[target.x86_64-pc-windows-gnu]" >> /root/.cargo/config && \
echo "linker = '/usr/bin/x86_64-w64-mingw32-gcc'" >> /root/.cargo/config
RUN echo "[target.aarch64-unknown-linux-gnu]" >> /usr/local/cargo/config && \
echo "linker = '/usr/bin/aarch64-linux-gnu-gcc'" >> /usr/local/cargo/config
RUN echo "[target.aarch64-unknown-linux-gnu]" >> /root/.cargo/config && \
echo "linker = '/usr/bin/aarch64-linux-gnu-gcc'" >> /root/.cargo/config
RUN echo "[target.armv7-unknown-linux-gnueabihf]" >> /usr/local/cargo/config && \
echo "linker = '/usr/bin/arm-linux-gnueabihf-gcc'" >> /usr/local/cargo/config
RUN echo "[target.armv7-unknown-linux-gnueabihf]" >> /root/.cargo/config && \
echo "linker = '/usr/bin/arm-linux-gnueabihf-gcc'" >> /root/.cargo/config
ENV CC_x86_64_unknown_linux_musl="gcc"
ENV CC_aarch64_unknown_linux_gnu="aarch64-linux-gnu-gcc"
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
RUN cp /usr/x86_64-w64-mingw32/lib/crt2.o /root/.rustup/toolchains/stable-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
RUN apt install -y git
# Cargo fetch the dependencies so we don't download them over and over again
RUN cd /tmp && git clone https://github.com/adityapk00/silentdragonlite-light-cli.git && \
cd silentdragonlite-light-cli && \

67
lib/src/commands.rs

@ -35,6 +35,26 @@ 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 {
lightclient.do_encryption_status().pretty(2)
}
}
struct SyncStatusCommand {}
impl Command for SyncStatusCommand {
@ -440,9 +460,7 @@ impl Command for SendCommand {
// Check for a single argument that can be parsed as JSON
let send_args = if args.len() == 1 {
// Sometimes on the command line, people use "'" for the quotes, which json::parse doesn't
// understand. So replace it with double-quotes
let arg_list = args[0].replace("'", "\"");
let arg_list = args[0];
let json_args = match json::parse(&arg_list) {
Ok(j) => j,
@ -731,27 +749,28 @@ impl Command for QuitCommand {
pub fn get_commands() -> Box<HashMap<String, Box<dyn Command>>> {
let mut map: HashMap<String, Box<dyn Command>> = HashMap::new();
map.insert("sync".to_string(), Box::new(SyncCommand{}));
map.insert("syncstatus".to_string(), Box::new(SyncStatusCommand{}));
map.insert("rescan".to_string(), Box::new(RescanCommand{}));
map.insert("help".to_string(), Box::new(HelpCommand{}));
map.insert("balance".to_string(), Box::new(BalanceCommand{}));
map.insert("addresses".to_string(), Box::new(AddressCommand{}));
map.insert("height".to_string(), Box::new(HeightCommand{}));
map.insert("export".to_string(), Box::new(ExportCommand{}));
map.insert("info".to_string(), Box::new(InfoCommand{}));
map.insert("send".to_string(), Box::new(SendCommand{}));
map.insert("save".to_string(), Box::new(SaveCommand{}));
map.insert("quit".to_string(), Box::new(QuitCommand{}));
map.insert("list".to_string(), Box::new(TransactionsCommand{}));
map.insert("notes".to_string(), Box::new(NotesCommand{}));
map.insert("new".to_string(), Box::new(NewAddressCommand{}));
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{}));
map.insert("fixbip39bug".to_string(), Box::new(FixBip39BugCommand{}));
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("rescan".to_string(), Box::new(RescanCommand{}));
map.insert("help".to_string(), Box::new(HelpCommand{}));
map.insert("balance".to_string(), Box::new(BalanceCommand{}));
map.insert("addresses".to_string(), Box::new(AddressCommand{}));
map.insert("height".to_string(), Box::new(HeightCommand{}));
map.insert("export".to_string(), Box::new(ExportCommand{}));
map.insert("info".to_string(), Box::new(InfoCommand{}));
map.insert("send".to_string(), Box::new(SendCommand{}));
map.insert("save".to_string(), Box::new(SaveCommand{}));
map.insert("quit".to_string(), Box::new(QuitCommand{}));
map.insert("list".to_string(), Box::new(TransactionsCommand{}));
map.insert("notes".to_string(), Box::new(NotesCommand{}));
map.insert("new".to_string(), Box::new(NewAddressCommand{}));
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{}));
map.insert("fixbip39bug".to_string(), Box::new(FixBip39BugCommand{}));
Box::new(map)
}

8
lib/src/lightclient.rs

@ -639,6 +639,14 @@ impl LightClient {
res
}
pub fn do_encryption_status(&self) -> JsonValue {
let wallet = self.wallet.read().unwrap();
object!{
"encrypted" => wallet.is_encrypted(),
"locked" => !wallet.is_unlocked_for_spending()
}
}
pub fn do_list_transactions(&self) -> JsonValue {
let wallet = self.wallet.read().unwrap();

4
lib/src/lightwallet.rs

@ -769,7 +769,7 @@ impl LightWallet {
None => true
}
})
.map(|nd| if nd.spent.is_none() && nd.unconfirmed_spent.is_none() { nd.note.value } else { 0 })
.map(|nd| if nd.spent.is_none() { nd.note.value } else { 0 })
.sum::<u64>()
})
.sum::<u64>() as u64
@ -1471,7 +1471,7 @@ impl LightWallet {
if selected_value < u64::from(target_value) {
let e = format!(
"Insufficient verified funds (have {}, need {:?}). NOTE: funds need {} confirmations before they can be spent.",
selected_value, target_value, self.config.anchor_offset
selected_value, target_value, self.config.anchor_offset + 1
);
error!("{}", e);
return Err(e);

13
lib/src/lightwallet/tests.rs

@ -706,6 +706,12 @@ fn test_z_spend_to_z() {
let branch_id = u32::from_str_radix("76b809bb", 16).unwrap();
let (ss, so) = get_sapling_params().unwrap();
// Make sure that the balance exists
{
assert_eq!(wallet.zbalance(None), AMOUNT1);
assert_eq!(wallet.verified_zbalance(None), AMOUNT1);
}
// Create a tx and send to address
let raw_tx = wallet.send_to_address(branch_id, &ss, &so,
vec![(&ext_address, AMOUNT_SENT, Some(outgoing_memo.clone()))]).unwrap();
@ -736,6 +742,12 @@ fn test_z_spend_to_z() {
assert_eq!(mem[&sent_txid].outgoing_metadata[0].memo.to_utf8().unwrap().unwrap(), outgoing_memo);
}
{
// The wallet should deduct this from the verified balance. The zbalance still includes it
assert_eq!(wallet.zbalance(None), AMOUNT1);
assert_eq!(wallet.verified_zbalance(None), 0);
}
let mut cb3 = FakeCompactBlock::new(2, block_hash);
cb3.add_tx(&sent_tx);
wallet.scan_block(&cb3.as_bytes()).unwrap();
@ -751,6 +763,7 @@ fn test_z_spend_to_z() {
// The sent tx should generate change
assert_eq!(txs[&sent_txid].notes.len(), 1);
assert_eq!(txs[&sent_txid].notes[0].note.value, AMOUNT1 - AMOUNT_SENT - fee);
assert_eq!(wallet.zbalance(None), AMOUNT1 - AMOUNT_SENT - fee);
assert_eq!(txs[&sent_txid].notes[0].is_change, true);
assert_eq!(txs[&sent_txid].notes[0].spent, None);
assert_eq!(txs[&sent_txid].notes[0].unconfirmed_spent, None);

Loading…
Cancel
Save