From f067e142f7d0557d4fd8347590e4b25d384427e9 Mon Sep 17 00:00:00 2001 From: Quentin Le Sceller Date: Mon, 15 Jan 2018 20:44:03 -0500 Subject: [PATCH] Add ban/unban in grin client (#620) * Added ban/unban in grin client --- src/bin/client.rs | 34 +++++++++++- src/bin/grin.rs | 128 ++++++++++++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 51 deletions(-) diff --git a/src/bin/client.rs b/src/bin/client.rs index e16f212cb..d804d8c71 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -14,12 +14,13 @@ extern crate term; +use std::net::SocketAddr; use api; use grin::ServerConfig; pub fn show_status(config: &ServerConfig) { println!(); - let title = format!("Grin Server Status "); + let title = format!("Grin Server Status"); let mut t = term::stdout().unwrap(); let mut e = term::stdout().unwrap(); t.fg(term::color::MAGENTA).unwrap(); @@ -29,7 +30,7 @@ pub fn show_status(config: &ServerConfig) { match get_status_from_node(config) { Ok(status) => { writeln!(e, "Protocol version: {}", status.protocol_version).unwrap(); - writeln!(e, "User agent: {}", status.user_agent).unwrap(); + writeln!(e, "User agent: {}", status.user_agent).unwrap(); writeln!(e, "Connections: {}", status.connections).unwrap(); writeln!(e, "Chain height: {}", status.tip.height).unwrap(); writeln!(e, "Last block hash: {}", status.tip.last_block_pushed).unwrap(); @@ -45,6 +46,35 @@ pub fn show_status(config: &ServerConfig) { println!(); } +pub fn ban_peer(config: &ServerConfig, peer_addr: &SocketAddr) { + let params = ""; + let mut e = term::stdout().unwrap(); + let url = format!( + "http://{}/v1/peers/{}/ban", + config.api_http_addr, + peer_addr.to_string() + ); + match api::client::post(url.as_str(), ¶ms).map_err(|e| Error::API(e)) { + Ok(_) => writeln!(e, "Successfully banned peer {}", peer_addr.to_string()).unwrap(), + Err(_) => writeln!(e, "Failed to ban peer {}", peer_addr).unwrap(), + }; + e.reset().unwrap(); +} + +pub fn unban_peer(config: &ServerConfig, peer_addr: &SocketAddr) { + let params = ""; + let mut e = term::stdout().unwrap(); + let url = format!( + "http://{}/v1/peers/{}/unban", + config.api_http_addr, + peer_addr.to_string() + ); + match api::client::post(url.as_str(), ¶ms).map_err(|e| Error::API(e)) { + Ok(_) => writeln!(e, "Successfully unbanned peer {}", peer_addr).unwrap(), + Err(_) => writeln!(e, "Failed to unban peer {}", peer_addr).unwrap(), + }; +} + fn get_status_from_node(config: &ServerConfig) -> Result { let url = format!("http://{}/v1/status", config.api_http_addr); api::client::get::(url.as_str()).map_err(|e| Error::API(e)) diff --git a/src/bin/grin.rs b/src/bin/grin.rs index 8c39284bc..0914894b8 100644 --- a/src/bin/grin.rs +++ b/src/bin/grin.rs @@ -139,7 +139,7 @@ fn main() { .short("w") .long("wallet_url") .help("The wallet listener to which mining rewards will be sent") - .takes_value(true)) + .takes_value(true)) .subcommand(SubCommand::with_name("start") .about("Start the Grin server as a daemon")) .subcommand(SubCommand::with_name("stop") @@ -151,7 +151,22 @@ fn main() { .subcommand(SubCommand::with_name("client") .about("Communicates with the Grin server") .subcommand(SubCommand::with_name("status") - .about("current status of the Grin chain"))) + .about("current status of the Grin chain")) + .subcommand(SubCommand::with_name("ban") + .about("Ban peer") + .arg(Arg::with_name("peer") + .short("p") + .long("peer") + .help("Peer ip and port (e.g. 10.12.12.13:13414)") + .takes_value(true))) + .subcommand(SubCommand::with_name("unban") + .about("Unban peer") + .arg(Arg::with_name("peer") + .short("p") + .long("peer") + .help("Peer ip and port (e.g. 10.12.12.13:13414)") + .takes_value(true)))) + // specification of the wallet commands and options .subcommand(SubCommand::with_name("wallet") @@ -370,6 +385,24 @@ fn client_command(client_args: &ArgMatches, global_config: GlobalConfig) { ("status", Some(_)) => { client::show_status(&server_config); } + ("ban", Some(peer_args)) => { + if let Some(peer) = peer_args.value_of("peer") { + if let Ok(addr) = peer.parse() { + client::ban_peer(&server_config, &addr); + } else { + panic!("Invalid peer address format"); + } + } + } + ("unban", Some(peer_args)) => { + if let Some(peer) = peer_args.value_of("peer") { + if let Ok(addr) = peer.parse() { + client::unban_peer(&server_config, &addr); + } else { + panic!("Invalid peer address format"); + } + } + } _ => panic!("Unknown client command, use 'grin help client' for details"), } } @@ -411,12 +444,12 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { let wallet_seed = wallet::WalletSeed::from_file(&wallet_config).expect("Failed to read wallet seed file."); - let passphrase = wallet_args.value_of("pass").expect( - "Failed to read passphrase.", - ); - let mut keychain = wallet_seed.derive_keychain(&passphrase).expect( - "Failed to derive keychain from seed file and passphrase.", - ); + let passphrase = wallet_args + .value_of("pass") + .expect("Failed to read passphrase."); + let mut keychain = wallet_seed + .derive_keychain(&passphrase) + .expect("Failed to derive keychain from seed file and passphrase."); match wallet_args.subcommand() { ("listen", Some(listen_args)) => { @@ -445,24 +478,22 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { } }*/ ("send", Some(send_args)) => { - let amount = send_args.value_of("amount").expect( - "Amount to send required", - ); - let amount = core::core::amount_from_hr_string(amount).expect( - "Could not parse amount as a number with optional decimal point.", - ); - let minimum_confirmations: u64 = - send_args - .value_of("minimum_confirmations") - .unwrap() - .parse() - .expect("Could not parse minimum_confirmations as a whole number."); - let selection_strategy = send_args.value_of("selection_strategy").expect( - "Selection strategy required", - ); - let dest = send_args.value_of("dest").expect( - "Destination wallet address required", - ); + let amount = send_args + .value_of("amount") + .expect("Amount to send required"); + let amount = core::core::amount_from_hr_string(amount) + .expect("Could not parse amount as a number with optional decimal point."); + let minimum_confirmations: u64 = send_args + .value_of("minimum_confirmations") + .unwrap() + .parse() + .expect("Could not parse minimum_confirmations as a whole number."); + let selection_strategy = send_args + .value_of("selection_strategy") + .expect("Selection strategy required"); + let dest = send_args + .value_of("dest") + .expect("Destination wallet address required"); let max_outputs = 500; let result = wallet::issue_send_tx( &wallet_config, @@ -474,15 +505,13 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { (selection_strategy == "all"), ); match result { - Ok(_) => { - info!( - LOGGER, - "Tx sent: {} grin to {} (strategy '{}')", - amount_to_hr_string(amount), - dest, - selection_strategy, - ) - } + Ok(_) => info!( + LOGGER, + "Tx sent: {} grin to {} (strategy '{}')", + amount_to_hr_string(amount), + dest, + selection_strategy, + ), Err(wallet::Error::NotEnoughFunds(available)) => { error!( LOGGER, @@ -490,9 +519,12 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { amount_to_hr_string(available), ); } - Err(wallet::Error::FeeExceedsAmount {sender_amount, recipient_fee}) => { + Err(wallet::Error::FeeExceedsAmount { + sender_amount, + recipient_fee, + }) => { error!( - LOGGER, + LOGGER, "Recipient rejected the transfer because transaction fee ({}) exceeded amount ({}).", amount_to_hr_string(recipient_fee), amount_to_hr_string(sender_amount) @@ -504,18 +536,16 @@ fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { }; } ("burn", Some(send_args)) => { - let amount = send_args.value_of("amount").expect( - "Amount to burn required", - ); - let amount = core::core::amount_from_hr_string(amount).expect( - "Could not parse amount as number with optional decimal point.", - ); - let minimum_confirmations: u64 = - send_args - .value_of("minimum_confirmations") - .unwrap() - .parse() - .expect("Could not parse minimum_confirmations as a whole number."); + let amount = send_args + .value_of("amount") + .expect("Amount to burn required"); + let amount = core::core::amount_from_hr_string(amount) + .expect("Could not parse amount as number with optional decimal point."); + let minimum_confirmations: u64 = send_args + .value_of("minimum_confirmations") + .unwrap() + .parse() + .expect("Could not parse minimum_confirmations as a whole number."); let max_outputs = 500; wallet::issue_burn_tx( &wallet_config,