use lightning::chain;
use lightning::chain::keysinterface::KeysManager;
use lightning::ln::features::InvoiceFeatures;
+use lightning::ln::msgs::NetAddress;
use lightning::ln::{PaymentHash, PaymentSecret};
use lightning::routing::network_graph::NetGraphMsgHandler;
use lightning::routing::router;
use std::env;
use std::io;
use std::io::{BufRead, Write};
-use std::net::SocketAddr;
+use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
use std::ops::Deref;
use std::path::Path;
use std::str::FromStr;
pub(crate) bitcoind_rpc_host: String,
pub(crate) ldk_storage_dir_path: String,
pub(crate) ldk_peer_listening_port: u16,
+ pub(crate) ldk_announced_listen_addr: Option<NetAddress>,
+ pub(crate) ldk_announced_node_name: [u8; 32],
pub(crate) network: Network,
}
pub(crate) fn parse_startup_args() -> Result<LdkUserInfo, ()> {
if env::args().len() < 3 {
- println!("ldk-tutorial-node requires 3 arguments: `cargo run <bitcoind-rpc-username>:<bitcoind-rpc-password>@<bitcoind-rpc-host>:<bitcoind-rpc-port> ldk_storage_directory_path [<ldk-incoming-peer-listening-port>] [bitcoin-network]`");
+ println!("ldk-tutorial-node requires 3 arguments: `cargo run <bitcoind-rpc-username>:<bitcoind-rpc-password>@<bitcoind-rpc-host>:<bitcoind-rpc-port> ldk_storage_directory_path [<ldk-incoming-peer-listening-port>] [bitcoin-network] [announced-listen-addr announced-node-name]`");
return Err(());
}
let bitcoind_rpc_info = env::args().skip(1).next().unwrap();
Some(_) => panic!("Unsupported network provided. Options are: `regtest`, `testnet`"),
None => Network::Testnet,
};
+
+ let ldk_announced_listen_addr = match env::args().skip(arg_idx + 1).next().as_ref() {
+ Some(s) => match IpAddr::from_str(s) {
+ Ok(IpAddr::V4(a)) => {
+ Some(NetAddress::IPv4 { addr: a.octets(), port: ldk_peer_listening_port })
+ }
+ Ok(IpAddr::V6(a)) => {
+ Some(NetAddress::IPv6 { addr: a.octets(), port: ldk_peer_listening_port })
+ }
+ Err(_) => panic!("Failed to parse announced-listen-addr into an IP address"),
+ },
+ None => None,
+ };
+
+ let ldk_announced_node_name = match env::args().skip(arg_idx + 2).next().as_ref() {
+ Some(s) => {
+ if s.len() > 32 {
+ panic!("Node Alias can not be longer than 32 bytes");
+ }
+ let mut bytes = [0; 32];
+ bytes[..s.len()].copy_from_slice(s.as_bytes());
+ bytes
+ }
+ None => [0; 32],
+ };
+
Ok(LdkUserInfo {
bitcoind_rpc_username,
bitcoind_rpc_password,
bitcoind_rpc_port,
ldk_storage_dir_path,
ldk_peer_listening_port,
+ ldk_announced_listen_addr,
+ ldk_announced_node_name,
network,
})
}
}
fn help() {
- println!("openchannel pubkey@host:port <channel_amt_satoshis>");
+ println!("openchannel pubkey@host:port <amt_satoshis>");
println!("sendpayment <invoice>");
- println!("getinvoice <amt_in_millisatoshis>");
+ println!("getinvoice <amt_millisatoshis>");
println!("connectpeer pubkey@host:port");
println!("listchannels");
println!("listpayments");
println!("closechannel <channel_id>");
println!("forceclosechannel <channel_id>");
+ println!("nodeinfo");
+ println!("listpeers");
}
fn node_info(channel_manager: Arc<ChannelManager>, peer_manager: Arc<PeerManager>) {
println!("");
println!("\t{{");
println!("\t\tchannel_id: {},", hex_utils::hex_str(&chan_info.channel_id[..]));
+ if let Some(funding_txo) = chan_info.funding_txo {
+ println!("\t\tfunding_txid: {},", funding_txo.txid);
+ }
println!(
"\t\tpeer_pubkey: {},",
hex_utils::hex_str(&chan_info.remote_network_id.serialize())
);
- let mut pending_channel = false;
- match chan_info.short_channel_id {
- Some(id) => println!("\t\tshort_channel_id: {},", id),
- None => {
- pending_channel = true;
- }
+ if let Some(id) = chan_info.short_channel_id {
+ println!("\t\tshort_channel_id: {},", id);
}
- println!("\t\tpending_open: {},", pending_channel);
+ println!("\t\tis_confirmed_onchain: {},", chan_info.is_funding_locked);
println!("\t\tchannel_value_satoshis: {},", chan_info.channel_value_satoshis);
- println!("\t\tchannel_can_send_payments: {},", chan_info.is_live);
+ if chan_info.is_usable {
+ println!("\t\tavailable_balance_for_send_msat: {},", chan_info.outbound_capacity_msat);
+ println!("\t\tavailable_balance_for_recv_msat: {},", chan_info.inbound_capacity_msat);
+ }
+ println!("\t\tchannel_can_send_payments: {},", chan_info.is_usable);
+ println!("\t\tpublic: {},", chan_info.is_public);
println!("\t}},");
}
println!("]");
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"ERROR: incorrectly formatted peer
- info. Should be formatted as: `pubkey@host:port`",
+ info. Should be formatted as: `pubkey@host:port`",
));
}
- let peer_addr: Result<SocketAddr, _> = peer_addr_str.unwrap().parse();
- if peer_addr.is_err() {
+ let peer_addr = peer_addr_str.unwrap().to_socket_addrs().map(|mut r| r.next());
+ if peer_addr.is_err() || peer_addr.as_ref().unwrap().is_none() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"ERROR: couldn't parse pubkey@host:port into a socket address",
));
}
- Ok((pubkey.unwrap(), peer_addr.unwrap()))
+ Ok((pubkey.unwrap(), peer_addr.unwrap().unwrap()))
}