merge T4 into master

This commit is contained in:
yeastplume
2018-10-18 11:23:04 +01:00
109 changed files with 3081 additions and 2420 deletions
+76 -38
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
+1 -1
View File
@@ -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()
),
)