merge T4 into master
This commit is contained in:
+76
-38
@@ -19,8 +19,8 @@ use std::path::PathBuf;
|
||||
/// Wallet commands processing
|
||||
use std::process::exit;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use std::{process, thread};
|
||||
|
||||
use clap::ArgMatches;
|
||||
|
||||
@@ -28,7 +28,9 @@ use api::TLSConfig;
|
||||
use config::GlobalWalletConfig;
|
||||
use core::{core, global};
|
||||
use grin_wallet::{self, controller, display, libwallet};
|
||||
use grin_wallet::{HTTPWalletClient, LMDBBackend, WalletConfig, WalletInst, WalletSeed};
|
||||
use grin_wallet::{
|
||||
HTTPWalletClient, LMDBBackend, WalletBackend, WalletConfig, WalletInst, WalletSeed,
|
||||
};
|
||||
use keychain;
|
||||
use servers::start_webwallet_server;
|
||||
use util::file::get_first_line;
|
||||
@@ -53,29 +55,23 @@ pub fn seed_exists(wallet_config: WalletConfig) -> bool {
|
||||
pub fn instantiate_wallet(
|
||||
wallet_config: WalletConfig,
|
||||
passphrase: &str,
|
||||
account: &str,
|
||||
node_api_secret: Option<String>,
|
||||
) -> Box<WalletInst<HTTPWalletClient, keychain::ExtKeychain>> {
|
||||
if grin_wallet::needs_migrate(&wallet_config.data_file_dir) {
|
||||
// Migrate wallet automatically
|
||||
warn!(LOGGER, "Migrating legacy File-Based wallet to LMDB Format");
|
||||
if let Err(e) = grin_wallet::migrate(&wallet_config.data_file_dir, passphrase) {
|
||||
error!(LOGGER, "Error while trying to migrate wallet: {:?}", e);
|
||||
error!(LOGGER, "Please ensure your file wallet files exist and are not corrupted, and that your password is correct");
|
||||
panic!();
|
||||
} else {
|
||||
warn!(LOGGER, "Migration successful. Using LMDB Wallet backend");
|
||||
}
|
||||
warn!(LOGGER, "Please check the results of the migration process using `grin wallet info` and `grin wallet outputs`");
|
||||
warn!(LOGGER, "If anything went wrong, you can try again by deleting the `db` directory and running a wallet command");
|
||||
warn!(LOGGER, "If all is okay, you can move/backup/delete all files in the wallet directory EXCEPT FOR wallet.seed");
|
||||
}
|
||||
let client = HTTPWalletClient::new(&wallet_config.check_node_api_http_addr, node_api_secret);
|
||||
let db_wallet = LMDBBackend::new(wallet_config.clone(), "", client).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error creating DB wallet: {} Config: {:?}",
|
||||
e, wallet_config
|
||||
);
|
||||
});
|
||||
let mut db_wallet =
|
||||
LMDBBackend::new(wallet_config.clone(), passphrase, client).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error creating DB wallet: {} Config: {:?}",
|
||||
e, wallet_config
|
||||
);
|
||||
});
|
||||
db_wallet
|
||||
.set_parent_key_id_by_name(account)
|
||||
.unwrap_or_else(|e| {
|
||||
println!("Error starting wallet: {}", e);
|
||||
process::exit(0);
|
||||
});
|
||||
info!(LOGGER, "Using LMDB Backend for wallet");
|
||||
Box::new(db_wallet)
|
||||
}
|
||||
@@ -130,9 +126,19 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
|
||||
let passphrase = wallet_args
|
||||
.value_of("pass")
|
||||
.expect("Failed to read passphrase.");
|
||||
|
||||
let account = wallet_args
|
||||
.value_of("account")
|
||||
.expect("Failed to read account.");
|
||||
|
||||
// Handle listener startup commands
|
||||
{
|
||||
let wallet = instantiate_wallet(wallet_config.clone(), passphrase, node_api_secret.clone());
|
||||
let wallet = instantiate_wallet(
|
||||
wallet_config.clone(),
|
||||
passphrase,
|
||||
account,
|
||||
node_api_secret.clone(),
|
||||
);
|
||||
let api_secret = get_first_line(wallet_config.api_secret_path.clone());
|
||||
|
||||
let tls_conf = match wallet_config.tls_certificate_file.clone() {
|
||||
@@ -187,10 +193,40 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
|
||||
let wallet = Arc::new(Mutex::new(instantiate_wallet(
|
||||
wallet_config.clone(),
|
||||
passphrase,
|
||||
account,
|
||||
node_api_secret,
|
||||
)));
|
||||
let res = controller::owner_single_use(wallet.clone(), |api| {
|
||||
match wallet_args.subcommand() {
|
||||
("account", Some(acct_args)) => {
|
||||
let create = acct_args.value_of("create");
|
||||
if create.is_none() {
|
||||
let res = controller::owner_single_use(wallet, |api| {
|
||||
let acct_mappings = api.accounts()?;
|
||||
// give logging thread a moment to catch up
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
display::accounts(acct_mappings);
|
||||
Ok(())
|
||||
});
|
||||
if res.is_err() {
|
||||
panic!("Error listing accounts: {}", res.unwrap_err());
|
||||
}
|
||||
} else {
|
||||
let label = create.unwrap();
|
||||
let res = controller::owner_single_use(wallet, |api| {
|
||||
api.new_account_path(label)?;
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
println!("Account: '{}' Created!", label);
|
||||
Ok(())
|
||||
});
|
||||
if res.is_err() {
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
println!("Error creating account '{}': {}", label, res.unwrap_err());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
("send", Some(send_args)) => {
|
||||
let amount = send_args
|
||||
.value_of("amount")
|
||||
@@ -352,18 +388,19 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
|
||||
e, wallet_config
|
||||
)
|
||||
});
|
||||
display::info(&wallet_info, validated);
|
||||
display::info(account, &wallet_info, validated);
|
||||
Ok(())
|
||||
}
|
||||
("outputs", Some(_)) => {
|
||||
let (height, _) = api.node_height()?;
|
||||
let (validated, outputs) = api.retrieve_outputs(show_spent, true, None)?;
|
||||
let _res = display::outputs(height, validated, outputs).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error getting wallet outputs: {:?} Config: {:?}",
|
||||
e, wallet_config
|
||||
)
|
||||
});
|
||||
let _res =
|
||||
display::outputs(account, height, validated, outputs).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error getting wallet outputs: {:?} Config: {:?}",
|
||||
e, wallet_config
|
||||
)
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
("txs", Some(txs_args)) => {
|
||||
@@ -377,8 +414,8 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
|
||||
let (height, _) = api.node_height()?;
|
||||
let (validated, txs) = api.retrieve_txs(true, tx_id)?;
|
||||
let include_status = !tx_id.is_some();
|
||||
let _res =
|
||||
display::txs(height, validated, txs, include_status).unwrap_or_else(|e| {
|
||||
let _res = display::txs(account, height, validated, txs, include_status)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error getting wallet outputs: {} Config: {:?}",
|
||||
e, wallet_config
|
||||
@@ -388,12 +425,13 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) {
|
||||
// inputs/outputs
|
||||
if tx_id.is_some() {
|
||||
let (_, outputs) = api.retrieve_outputs(true, false, tx_id)?;
|
||||
let _res = display::outputs(height, validated, outputs).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error getting wallet outputs: {} Config: {:?}",
|
||||
e, wallet_config
|
||||
)
|
||||
});
|
||||
let _res = display::outputs(account, height, validated, outputs)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error getting wallet outputs: {} Config: {:?}",
|
||||
e, wallet_config
|
||||
)
|
||||
});
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+16
-2
@@ -97,7 +97,7 @@ fn main() {
|
||||
.help("Port to start the P2P server on")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("api_port")
|
||||
.short("a")
|
||||
.short("api")
|
||||
.long("api_port")
|
||||
.help("Port on which to start the api server (e.g. transaction pool api)")
|
||||
.takes_value(true))
|
||||
@@ -154,6 +154,12 @@ fn main() {
|
||||
.help("Wallet passphrase used to generate the private key seed")
|
||||
.takes_value(true)
|
||||
.default_value(""))
|
||||
.arg(Arg::with_name("account")
|
||||
.short("a")
|
||||
.long("account")
|
||||
.help("Wallet account to use for this operation")
|
||||
.takes_value(true)
|
||||
.default_value("default"))
|
||||
.arg(Arg::with_name("data_dir")
|
||||
.short("dd")
|
||||
.long("data_dir")
|
||||
@@ -171,11 +177,19 @@ fn main() {
|
||||
.help("Show spent outputs on wallet output command")
|
||||
.takes_value(false))
|
||||
.arg(Arg::with_name("api_server_address")
|
||||
.short("a")
|
||||
.short("r")
|
||||
.long("api_server_address")
|
||||
.help("Api address of running node on which to check inputs and post transactions")
|
||||
.takes_value(true))
|
||||
|
||||
.subcommand(SubCommand::with_name("account")
|
||||
.about("List wallet accounts or create a new account")
|
||||
.arg(Arg::with_name("create")
|
||||
.short("c")
|
||||
.long("create")
|
||||
.help("Name of new wallet account")
|
||||
.takes_value(true)))
|
||||
|
||||
.subcommand(SubCommand::with_name("listen")
|
||||
.about("Runs the wallet in listening mode waiting for transactions.")
|
||||
.arg(Arg::with_name("port")
|
||||
|
||||
+4
-2
@@ -63,11 +63,13 @@ pub fn create() -> Box<View> {
|
||||
let mut s: ViewRef<SelectView<&str>> = c.find_id(MAIN_MENU).unwrap();
|
||||
s.select_down(1)(c);
|
||||
Some(EventResult::Consumed(None));
|
||||
}).on_pre_event('k', move |c| {
|
||||
})
|
||||
.on_pre_event('k', move |c| {
|
||||
let mut s: ViewRef<SelectView<&str>> = c.find_id(MAIN_MENU).unwrap();
|
||||
s.select_up(1)(c);
|
||||
Some(EventResult::Consumed(None));
|
||||
}).on_pre_event(Key::Tab, move |c| {
|
||||
})
|
||||
.on_pre_event(Key::Tab, move |c| {
|
||||
let mut s: ViewRef<SelectView<&str>> = c.find_id(MAIN_MENU).unwrap();
|
||||
if s.selected_id().unwrap() == s.len() - 1 {
|
||||
s.set_selection(0)(c);
|
||||
|
||||
+22
-7
@@ -100,7 +100,9 @@ impl TableViewItem<StratumWorkerColumn> for WorkerStats {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
enum DiffColumn {
|
||||
BlockNumber,
|
||||
PoWType,
|
||||
Difficulty,
|
||||
SecondaryScaling,
|
||||
Time,
|
||||
Duration,
|
||||
}
|
||||
@@ -109,7 +111,9 @@ impl DiffColumn {
|
||||
fn _as_str(&self) -> &str {
|
||||
match *self {
|
||||
DiffColumn::BlockNumber => "Block Number",
|
||||
DiffColumn::PoWType => "Type",
|
||||
DiffColumn::Difficulty => "Network Difficulty",
|
||||
DiffColumn::SecondaryScaling => "Sec. Scaling",
|
||||
DiffColumn::Time => "Block Time",
|
||||
DiffColumn::Duration => "Duration",
|
||||
}
|
||||
@@ -120,10 +124,16 @@ impl TableViewItem<DiffColumn> for DiffBlock {
|
||||
fn to_column(&self, column: DiffColumn) -> String {
|
||||
let naive_datetime = NaiveDateTime::from_timestamp(self.time as i64, 0);
|
||||
let datetime: DateTime<Utc> = DateTime::from_utc(naive_datetime, Utc);
|
||||
let pow_type = match self.is_secondary {
|
||||
true => String::from("Secondary"),
|
||||
false => String::from("Primary"),
|
||||
};
|
||||
|
||||
match column {
|
||||
DiffColumn::BlockNumber => self.block_number.to_string(),
|
||||
DiffColumn::PoWType => pow_type,
|
||||
DiffColumn::Difficulty => self.difficulty.to_string(),
|
||||
DiffColumn::SecondaryScaling => self.secondary_scaling.to_string(),
|
||||
DiffColumn::Time => format!("{}", datetime).to_string(),
|
||||
DiffColumn::Duration => format!("{}s", self.duration).to_string(),
|
||||
}
|
||||
@@ -135,7 +145,9 @@ impl TableViewItem<DiffColumn> for DiffBlock {
|
||||
{
|
||||
match column {
|
||||
DiffColumn::BlockNumber => Ordering::Equal,
|
||||
DiffColumn::PoWType => Ordering::Equal,
|
||||
DiffColumn::Difficulty => Ordering::Equal,
|
||||
DiffColumn::SecondaryScaling => Ordering::Equal,
|
||||
DiffColumn::Time => Ordering::Equal,
|
||||
DiffColumn::Duration => Ordering::Equal,
|
||||
}
|
||||
@@ -205,7 +217,7 @@ impl TUIStatusListener for TUIMiningView {
|
||||
.child(TextView::new(" ").with_id("stratum_network_hashrate")),
|
||||
).child(
|
||||
LinearLayout::new(Orientation::Horizontal)
|
||||
.child(TextView::new(" ").with_id("stratum_cuckoo_size_status")),
|
||||
.child(TextView::new(" ").with_id("stratum_edge_bits_status")),
|
||||
);
|
||||
|
||||
let mining_device_view = LinearLayout::new(Orientation::Vertical)
|
||||
@@ -236,9 +248,12 @@ impl TUIStatusListener for TUIMiningView {
|
||||
|
||||
let diff_table_view = TableView::<DiffBlock, DiffColumn>::new()
|
||||
.column(DiffColumn::BlockNumber, "Block Number", |c| {
|
||||
c.width_percent(25)
|
||||
}).column(DiffColumn::Difficulty, "Network Difficulty", |c| {
|
||||
c.width_percent(25)
|
||||
c.width_percent(15)
|
||||
}).column(DiffColumn::PoWType, "Type", |c| c.width_percent(10))
|
||||
.column(DiffColumn::Difficulty, "Network Difficulty", |c| {
|
||||
c.width_percent(15)
|
||||
}).column(DiffColumn::SecondaryScaling, "Sec. Scaling", |c| {
|
||||
c.width_percent(10)
|
||||
}).column(DiffColumn::Time, "Block Time", |c| c.width_percent(25))
|
||||
.column(DiffColumn::Duration, "Duration", |c| c.width_percent(25));
|
||||
|
||||
@@ -301,7 +316,7 @@ impl TUIStatusListener for TUIMiningView {
|
||||
let stratum_block_height = format!("Solving Block Height: {}", stratum_stats.block_height);
|
||||
let stratum_network_difficulty =
|
||||
format!("Network Difficulty: {}", stratum_stats.network_difficulty);
|
||||
let stratum_cuckoo_size = format!("Cuckoo Size: {}", stratum_stats.cuckoo_size);
|
||||
let stratum_edge_bits = format!("Cuckoo Size: {}", stratum_stats.edge_bits);
|
||||
|
||||
c.call_on_id("stratum_config_status", |t: &mut TextView| {
|
||||
t.set_content(stratum_enabled);
|
||||
@@ -321,8 +336,8 @@ impl TUIStatusListener for TUIMiningView {
|
||||
c.call_on_id("stratum_network_hashrate", |t: &mut TextView| {
|
||||
t.set_content(stratum_network_hashrate);
|
||||
});
|
||||
c.call_on_id("stratum_cuckoo_size_status", |t: &mut TextView| {
|
||||
t.set_content(stratum_cuckoo_size);
|
||||
c.call_on_id("stratum_edge_bits_status", |t: &mut TextView| {
|
||||
t.set_content(stratum_edge_bits);
|
||||
});
|
||||
let _ = c.call_on_id(
|
||||
TABLE_MINING_STATUS,
|
||||
|
||||
@@ -201,7 +201,7 @@ impl TUIStatusListener for TUIStatusView {
|
||||
),
|
||||
format!(
|
||||
"Cuckoo {} - Network Difficulty {}",
|
||||
stats.mining_stats.cuckoo_size,
|
||||
stats.mining_stats.edge_bits,
|
||||
stats.mining_stats.network_difficulty.to_string()
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user