Skip to content

Small tweaks to logging and printing + node_announcement #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@ git clone [email protected]:lightningdevkit/ldk-sample.git
## Usage
```
cd ldk-sample
cargo run <bitcoind-rpc-username>:<bitcoind-rpc-password>@<bitcoind-rpc-host>:<bitcoind-rpc-port> <ldk_storage_directory_path> [<ldk-peer-listening-port>] [bitcoin-network]
cargo run <bitcoind-rpc-username>:<bitcoind-rpc-password>@<bitcoind-rpc-host>:<bitcoind-rpc-port> <ldk_storage_directory_path> [<ldk-peer-listening-port>] [bitcoin-network] [announced-listen-addr announced-node-name]
```
`bitcoind`'s RPC username and password likely can be found through `cat ~/.bitcoin/.cookie`.

`bitcoin-network`: defaults to `testnet`. Options: `testnet`, `regtest`.

`ldk-peer-listening-port`: defaults to 9735.

`announced-listen-addr` and `announced-node-name`: default to nothing, disabling any public announcements of this node.
`announced-listen-addr` can be set to an IPv4 or IPv6 address to announce that as a publicly-connectable address for this node.
`announced-node-name` can be any string up to 32 bytes in length, representing this node's alias.

## License

Licensed under either:
Expand Down
52 changes: 43 additions & 9 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use bitcoin::secp256k1::key::PublicKey;
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;
Expand All @@ -18,7 +19,7 @@ use lightning_invoice::{utils, Currency, Invoice};
use std::env;
use std::io;
use std::io::{BufRead, Write};
use std::net::{SocketAddr, ToSocketAddrs};
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
use std::ops::Deref;
use std::path::Path;
use std::str::FromStr;
Expand All @@ -33,12 +34,14 @@ pub(crate) struct LdkUserInfo {
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();
Expand Down Expand Up @@ -84,13 +87,41 @@ pub(crate) fn parse_startup_args() -> Result<LdkUserInfo, ()> {
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_host,
bitcoind_rpc_port,
ldk_storage_dir_path,
ldk_peer_listening_port,
ldk_announced_listen_addr,
ldk_announced_node_name,
network,
})
}
Expand Down Expand Up @@ -393,19 +424,22 @@ fn list_channels(channel_manager: Arc<ChannelManager>) {
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);
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}},");
}
Expand Down
29 changes: 25 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ async fn handle_ldk_events(
hex_utils::hex_str(&payment_hash.0)
);
if rejected_by_dest {
println!("rejected by destination node");
println!("re-attempting the payment will not succeed");
} else {
println!("route failed");
println!("payment may be retried");
}
print!("> ");
io::stdout().flush().unwrap();
Expand Down Expand Up @@ -569,14 +569,35 @@ async fn start_ldk() {
peer_addr,
peer_manager.clone(),
event_ntfn_sender.clone(),
);
)
.await;
}
}
}
}
Err(e) => println!("ERROR: errored reading channel peer info from disk: {:?}", e),
}

// Regularly broadcast our node_announcement. This is only required (or possible) if we have
// some public channels, and is only useful if we have public listen address(es) to announce.
// In a production environment, this should occur only after the announcement of new channels
// to avoid churn in the global network graph.
let chan_manager = Arc::clone(&channel_manager);
let network = args.network;
if args.ldk_announced_listen_addr.is_some() {
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(60));
loop {
interval.tick().await;
chan_manager.broadcast_node_announcement(
[0; 3],
args.ldk_announced_node_name,
vec![args.ldk_announced_listen_addr.as_ref().unwrap().clone()],
);
}
});
}

// Start the CLI.
cli::poll_for_user_input(
peer_manager.clone(),
Expand All @@ -588,7 +609,7 @@ async fn start_ldk() {
event_ntfn_sender,
ldk_data_dir.clone(),
logger.clone(),
args.network,
network,
)
.await;
}
Expand Down