Automatically load and save wallet

This commit is contained in:
Aditya Kulkarni
2019-09-06 14:09:12 -07:00
parent c2e26fbbca
commit 48d305c406
4 changed files with 59 additions and 30 deletions

View File

@@ -7,7 +7,7 @@ pub trait Command {
fn short_help(&self) -> String; fn short_help(&self) -> String;
fn exec(&self, args: &[String], lightclient: &mut LightClient); fn exec(&self, _args: &[String], lightclient: &mut LightClient);
} }
struct SyncCommand {} struct SyncCommand {}
@@ -21,7 +21,7 @@ impl Command for SyncCommand {
"Download CompactBlocks and sync to the server".to_string() "Download CompactBlocks and sync to the server".to_string()
} }
fn exec(&self, args: &[String], lightclient: &mut LightClient) { fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_sync(); lightclient.do_sync();
} }
} }
@@ -37,7 +37,7 @@ impl Command for HelpCommand {
"Lists all available commands".to_string() "Lists all available commands".to_string()
} }
fn exec(&self, args: &[String], _: &mut LightClient) { fn exec(&self, _args: &[String], _: &mut LightClient) {
// Print a list of all commands // Print a list of all commands
get_commands().iter().for_each(| (cmd, obj) | { get_commands().iter().for_each(| (cmd, obj) | {
println!("{} - {}", cmd, obj.short_help()); println!("{} - {}", cmd, obj.short_help());
@@ -55,7 +55,7 @@ impl Command for InfoCommand {
"Get the lightwalletd server's info".to_string() "Get the lightwalletd server's info".to_string()
} }
fn exec(&self, args: &[String], lightclient: &mut LightClient) { fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_info(); lightclient.do_info();
} }
} }
@@ -70,7 +70,7 @@ impl Command for AddressCommand {
"List all current addresses".to_string() "List all current addresses".to_string()
} }
fn exec(&self, args: &[String], lightclient: &mut LightClient) { fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_address(); lightclient.do_address();
} }
} }
@@ -85,7 +85,7 @@ impl Command for SendCommand {
"Send ZEC to the given address".to_string() "Send ZEC to the given address".to_string()
} }
fn exec(&self, args: &[String], lightclient: &mut LightClient) { fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_send( lightclient.do_send(
"ztestsapling1x65nq4dgp0qfywgxcwk9n0fvm4fysmapgr2q00p85ju252h6l7mmxu2jg9cqqhtvzd69jwhgv8d".to_string(), "ztestsapling1x65nq4dgp0qfywgxcwk9n0fvm4fysmapgr2q00p85ju252h6l7mmxu2jg9cqqhtvzd69jwhgv8d".to_string(),
1500000, 1500000,
@@ -103,7 +103,7 @@ impl Command for SaveCommand {
"Save wallet file to disk".to_string() "Save wallet file to disk".to_string()
} }
fn exec(&self, args: &[String], lightclient: &mut LightClient) { fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_save(); lightclient.do_save();
} }
} }
@@ -118,11 +118,27 @@ impl Command for ReadCommand {
"Read wallet file from disk".to_string() "Read wallet file from disk".to_string()
} }
fn exec(&self, args: &[String], lightclient: &mut LightClient) { fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_read(); lightclient.do_read();
} }
} }
struct QuitCommand {}
impl Command for QuitCommand {
fn help(&self) {
println!("Quit");
}
fn short_help(&self) -> String {
"Quit the lightwallet, saving state to disk".to_string()
}
fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_save();
}
}
pub fn get_commands() -> Box<HashMap<String, Box<dyn Command>>> { pub fn get_commands() -> Box<HashMap<String, Box<dyn Command>>> {
let mut map: HashMap<String, Box<dyn Command>> = HashMap::new(); let mut map: HashMap<String, Box<dyn Command>> = HashMap::new();
@@ -133,12 +149,13 @@ pub fn get_commands() -> Box<HashMap<String, Box<dyn Command>>> {
map.insert("send".to_string(), Box::new(SendCommand{})); map.insert("send".to_string(), Box::new(SendCommand{}));
map.insert("save".to_string(), Box::new(SaveCommand{})); map.insert("save".to_string(), Box::new(SaveCommand{}));
map.insert("read".to_string(), Box::new(ReadCommand{})); map.insert("read".to_string(), Box::new(ReadCommand{}));
map.insert("quit".to_string(), Box::new(QuitCommand{}));
Box::new(map) Box::new(map)
} }
pub fn do_user_command(cmd: String, lightclient: &mut LightClient) { pub fn do_user_command(cmd: &String, lightclient: &mut LightClient) {
match get_commands().get(&cmd) { match get_commands().get(cmd) {
Some(cmd) => cmd.exec(&[], lightclient), Some(cmd) => cmd.exec(&[], lightclient),
None => { None => {
println!("Unknown command : {}. Type 'help' for a list of commands", cmd); println!("Unknown command : {}. Type 'help' for a list of commands", cmd);

View File

@@ -1,6 +1,7 @@
use crate::lightwallet::LightWallet; use crate::lightwallet::LightWallet;
use std::fs::File; use std::fs::File;
use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::sync::Arc; use std::sync::Arc;
@@ -62,16 +63,22 @@ impl LightClient {
} }
pub fn do_read(&mut self) { pub fn do_read(&mut self) {
print!("Reading wallet...");
io::stdout().flush().ok().expect("Could not flush stdout");
let mut file_buffer = File::open("wallet.dat").unwrap(); let mut file_buffer = File::open("wallet.dat").unwrap();
let lw = LightWallet::read(&mut file_buffer).unwrap(); let lw = LightWallet::read(&mut file_buffer).unwrap();
self.wallet = Arc::new(lw); self.wallet = Arc::new(lw);
println!("[OK]");
} }
pub fn do_save(&self) { pub fn do_save(&self) {
print!("Saving wallet...");
io::stdout().flush().ok().expect("Could not flush stdout");
let mut file_buffer = File::create("wallet.dat").unwrap(); let mut file_buffer = File::create("wallet.dat").unwrap();
self.wallet.write(&mut file_buffer).unwrap(); self.wallet.write(&mut file_buffer).unwrap();
println!("[OK]");
} }

View File

@@ -1,22 +1,22 @@
pub extern crate ff; pub extern crate ff;
use std::time::SystemTime; use std::time::SystemTime;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use pairing::bls12_381::{Bls12};
use zcash_primitives::primitives::{Diversifier, Note, PaymentAddress, /*read_note */ };
use std::cmp; use std::cmp;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use protobuf::*; use protobuf::*;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use pairing::bls12_381::{Bls12};
use ff::{PrimeField, PrimeFieldRepr};
use zcash_client_backend::{ use zcash_client_backend::{
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS, encoding::encode_payment_address, constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS, encoding::encode_payment_address,
proto::compact_formats::CompactBlock, welding_rig::scan_block, proto::compact_formats::CompactBlock, welding_rig::scan_block,
}; };
use ff::{PrimeField, PrimeFieldRepr};
use zcash_primitives::{ use zcash_primitives::{
block::BlockHash, block::BlockHash,
merkle_tree::{CommitmentTree, IncrementalWitness}, merkle_tree::{CommitmentTree, IncrementalWitness},
@@ -30,21 +30,16 @@ use zcash_primitives::{
note_encryption::{Memo, try_sapling_note_decryption}, note_encryption::{Memo, try_sapling_note_decryption},
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, zip32::{ExtendedFullViewingKey, ExtendedSpendingKey},
JUBJUB, JUBJUB,
}; primitives::{Diversifier, Note, PaymentAddress},
use zcash_primitives::jubjub::{ jubjub::{
JubjubEngine, JubjubEngine,
fs::{Fs, FsRepr}, fs::{Fs, FsRepr},
}
}; };
use crate::address; use crate::address;
use crate::prover; use crate::prover;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
const ANCHOR_OFFSET: u32 = 10; const ANCHOR_OFFSET: u32 = 10;
const SAPLING_ACTIVATION_HEIGHT: i32 = 280_000; const SAPLING_ACTIVATION_HEIGHT: i32 = 280_000;

View File

@@ -16,7 +16,10 @@ pub mod grpc_client {
pub fn main() { pub fn main() {
let mut light_client = LightClient::new(); let mut lightclient = LightClient::new();
// At startup, read the wallet.dat
commands::do_user_command(&"read".to_string(), &mut lightclient);
// `()` can be used when no completer is required // `()` can be used when no completer is required
let mut rl = Editor::<()>::new(); let mut rl = Editor::<()>::new();
@@ -24,18 +27,25 @@ pub fn main() {
println!("No previous history."); println!("No previous history.");
} }
loop { loop {
let readline = rl.readline(&format!("Block:{} (h for help) >> ", light_client.last_scanned_height())); let readline = rl.readline(&format!("Block:{} (h for help) >> ", lightclient.last_scanned_height()));
match readline { match readline {
Ok(line) => { Ok(line) => {
rl.add_history_entry(line.as_str()); rl.add_history_entry(line.as_str());
commands::do_user_command(line, &mut light_client); commands::do_user_command(&line, &mut lightclient);
// Special check for Quit command.
if line == "quit" {
break;
}
}, },
Err(ReadlineError::Interrupted) => { Err(ReadlineError::Interrupted) => {
println!("CTRL-C"); println!("CTRL-C");
lightclient.do_save();
break break
}, },
Err(ReadlineError::Eof) => { Err(ReadlineError::Eof) => {
println!("CTRL-D"); println!("CTRL-D");
lightclient.do_save();
break break
}, },
Err(err) => { Err(err) => {