X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fcli.rs;h=d34512c56e3dc31b52b9e95f7d8bccb99d7583ce;hb=7d0af178ba9a79008af7b3ea89e563749f8f7252;hp=54b2eab7c5f46fda4ba7f60c39ee85a09c3fc6fb;hpb=f44c400f2a98f0f19eb89d0f870af84027561b54;p=ldk-sample diff --git a/src/cli.rs b/src/cli.rs index 54b2eab..d34512c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -151,10 +151,14 @@ pub(crate) async fn poll_for_user_input( println!("LDK logs are available at /.ldk/logs"); println!("Local Node ID is {}.", channel_manager.get_our_node_id()); let stdin = io::stdin(); - print!("> "); - io::stdout().flush().unwrap(); // Without flushing, the `>` doesn't print - for line in stdin.lock().lines() { - let line = line.unwrap(); + let mut line_reader = stdin.lock().lines(); + loop { + print!("> "); + io::stdout().flush().unwrap(); // Without flushing, the `>` doesn't print + let line = match line_reader.next() { + Some(l) => l.unwrap(), + None => break, + }; let mut words = line.split_whitespace(); if let Some(word) = words.next() { match word { @@ -164,8 +168,6 @@ pub(crate) async fn poll_for_user_input( let channel_value_sat = words.next(); if peer_pubkey_and_ip_addr.is_none() || channel_value_sat.is_none() { println!("ERROR: openchannel has 2 required arguments: `openchannel pubkey@host:port channel_amt_satoshis` [--public]"); - print!("> "); - io::stdout().flush().unwrap(); continue; } let peer_pubkey_and_ip_addr = peer_pubkey_and_ip_addr.unwrap(); @@ -174,8 +176,6 @@ pub(crate) async fn poll_for_user_input( Ok(info) => info, Err(e) => { println!("{:?}", e.into_inner().unwrap()); - print!("> "); - io::stdout().flush().unwrap(); continue; } }; @@ -183,8 +183,6 @@ pub(crate) async fn poll_for_user_input( let chan_amt_sat: Result = channel_value_sat.unwrap().parse(); if chan_amt_sat.is_err() { println!("ERROR: channel amount must be a number"); - print!("> "); - io::stdout().flush().unwrap(); continue; } @@ -192,8 +190,6 @@ pub(crate) async fn poll_for_user_input( .await .is_err() { - print!("> "); - io::stdout().flush().unwrap(); continue; }; @@ -202,8 +198,6 @@ pub(crate) async fn poll_for_user_input( Some("--public=false") => false, Some(_) => { println!("ERROR: invalid `--public` command format. Valid formats: `--public`, `--public=true` `--public=false`"); - print!("> "); - io::stdout().flush().unwrap(); continue; } None => false, @@ -228,8 +222,6 @@ pub(crate) async fn poll_for_user_input( let invoice_str = words.next(); if invoice_str.is_none() { println!("ERROR: sendpayment requires an invoice: `sendpayment `"); - print!("> "); - io::stdout().flush().unwrap(); continue; } @@ -237,8 +229,6 @@ pub(crate) async fn poll_for_user_input( Ok(inv) => inv, Err(e) => { println!("ERROR: invalid invoice: {:?}", e); - print!("> "); - io::stdout().flush().unwrap(); continue; } }; @@ -251,15 +241,11 @@ pub(crate) async fn poll_for_user_input( Some(pk) => pk, None => { println!("ERROR: couldn't parse destination pubkey"); - print!("> "); - io::stdout().flush().unwrap(); continue; } }, None => { println!("ERROR: keysend requires a destination pubkey: `keysend `"); - print!("> "); - io::stdout().flush().unwrap(); continue; } }; @@ -268,8 +254,6 @@ pub(crate) async fn poll_for_user_input( None => { println!("ERROR: keysend requires an amount in millisatoshis: `keysend `"); - print!("> "); - io::stdout().flush().unwrap(); continue; } }; @@ -277,8 +261,6 @@ pub(crate) async fn poll_for_user_input( Ok(amt) => amt, Err(e) => { println!("ERROR: couldn't parse amount_msat: {}", e); - print!("> "); - io::stdout().flush().unwrap(); continue; } }; @@ -296,16 +278,12 @@ pub(crate) async fn poll_for_user_input( let amt_str = words.next(); if amt_str.is_none() { println!("ERROR: getinvoice requires an amount in millisatoshis"); - print!("> "); - io::stdout().flush().unwrap(); continue; } let amt_msat: Result = amt_str.unwrap().parse(); if amt_msat.is_err() { println!("ERROR: getinvoice provided payment amount was not a number"); - print!("> "); - io::stdout().flush().unwrap(); continue; } get_invoice( @@ -320,8 +298,6 @@ pub(crate) async fn poll_for_user_input( let peer_pubkey_and_ip_addr = words.next(); if peer_pubkey_and_ip_addr.is_none() { println!("ERROR: connectpeer requires peer connection info: `connectpeer pubkey@host:port`"); - print!("> "); - io::stdout().flush().unwrap(); continue; } let (pubkey, peer_addr) = @@ -329,8 +305,6 @@ pub(crate) async fn poll_for_user_input( Ok(info) => info, Err(e) => { println!("{:?}", e.into_inner().unwrap()); - print!("> "); - io::stdout().flush().unwrap(); continue; } }; @@ -349,15 +323,11 @@ pub(crate) async fn poll_for_user_input( let channel_id_str = words.next(); if channel_id_str.is_none() { println!("ERROR: closechannel requires a channel ID: `closechannel `"); - print!("> "); - io::stdout().flush().unwrap(); continue; } let channel_id_vec = hex_utils::to_vec(channel_id_str.unwrap()); if channel_id_vec.is_none() { println!("ERROR: couldn't parse channel_id as hex"); - print!("> "); - io::stdout().flush().unwrap(); continue; } let mut channel_id = [0; 32]; @@ -368,15 +338,11 @@ pub(crate) async fn poll_for_user_input( let channel_id_str = words.next(); if channel_id_str.is_none() { println!("ERROR: forceclosechannel requires a channel ID: `forceclosechannel `"); - print!("> "); - io::stdout().flush().unwrap(); continue; } let channel_id_vec = hex_utils::to_vec(channel_id_str.unwrap()); if channel_id_vec.is_none() { println!("ERROR: couldn't parse channel_id as hex"); - print!("> "); - io::stdout().flush().unwrap(); continue; } let mut channel_id = [0; 32]; @@ -389,8 +355,6 @@ pub(crate) async fn poll_for_user_input( const MSG_STARTPOS: usize = "signmsg".len() + 1; if line.as_bytes().len() <= MSG_STARTPOS { println!("ERROR: signmsg requires a message"); - print!("> "); - io::stdout().flush().unwrap(); continue; } println!( @@ -400,14 +364,10 @@ pub(crate) async fn poll_for_user_input( &keys_manager.get_node_secret() ) ); - print!("> "); - io::stdout().flush().unwrap(); } _ => println!("Unknown command. See `\"help\" for available commands."), } } - print!("> "); - io::stdout().flush().unwrap(); } } @@ -428,8 +388,14 @@ fn help() { fn node_info(channel_manager: Arc, peer_manager: Arc) { println!("\t{{"); println!("\t\t node_pubkey: {}", channel_manager.get_our_node_id()); - println!("\t\t num_channels: {}", channel_manager.list_channels().len()); - println!("\t\t num_usable_channels: {}", channel_manager.list_usable_channels().len()); + let chans = channel_manager.list_channels(); + println!("\t\t num_channels: {}", chans.len()); + println!("\t\t num_usable_channels: {}", chans.iter().filter(|c| c.is_usable).count()); + let local_balance_msat = chans + .iter() + .map(|c| c.unspendable_punishment_reserve.unwrap_or(0) * 1000 + c.outbound_capacity_msat) + .sum::(); + println!("\t\t local_balance_msat: {}", local_balance_msat); println!("\t\t num_peers: {}", peer_manager.get_peer_node_ids().len()); println!("\t}},"); } @@ -526,6 +492,16 @@ pub(crate) async fn connect_peer_if_necessary( return Ok(()); } } + let res = do_connect_peer(pubkey, peer_addr, peer_manager).await; + if res.is_err() { + println!("ERROR: failed to connect to peer"); + } + res +} + +pub(crate) async fn do_connect_peer( + pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc, +) -> Result<(), ()> { match lightning_net_tokio::connect_outbound(Arc::clone(&peer_manager), pubkey, peer_addr).await { Some(connection_closed_future) => { @@ -533,24 +509,19 @@ pub(crate) async fn connect_peer_if_necessary( loop { match futures::poll!(&mut connection_closed_future) { std::task::Poll::Ready(_) => { - println!("ERROR: Peer disconnected before we finished the handshake"); return Err(()); } std::task::Poll::Pending => {} } // Avoid blocking the tokio context by sleeping a bit match peer_manager.get_peer_node_ids().iter().find(|id| **id == pubkey) { - Some(_) => break, + Some(_) => return Ok(()), None => tokio::time::sleep(Duration::from_millis(10)).await, } } } - None => { - println!("ERROR: failed to connect to peer"); - return Err(()); - } + None => Err(()), } - Ok(()) } fn open_channel(