4 ChannelManager, FilesystemLogger, HTLCStatus, MillisatAmount, PaymentInfo, PaymentInfoStorage,
7 use bitcoin::hashes::sha256::Hash as Sha256Hash;
8 use bitcoin::hashes::Hash;
9 use bitcoin::network::constants::Network;
10 use bitcoin::secp256k1::key::{PublicKey, SecretKey};
11 use bitcoin::secp256k1::Secp256k1;
13 use lightning::ln::channelmanager::{PaymentHash, PaymentPreimage, PaymentSecret};
14 use lightning::ln::features::InvoiceFeatures;
15 use lightning::routing::network_graph::{NetGraphMsgHandler, RoutingFees};
16 use lightning::routing::router;
17 use lightning::routing::router::RouteHint;
18 use lightning::util::config::UserConfig;
19 use lightning_invoice::{Currency, Invoice, InvoiceBuilder, Route, RouteHop};
24 use std::io::{BufRead, Write};
25 use std::net::{SocketAddr, TcpStream};
28 use std::str::FromStr;
30 use std::time::Duration;
31 use tokio::sync::mpsc;
33 pub(crate) struct LdkUserInfo {
34 pub(crate) bitcoind_rpc_username: String,
35 pub(crate) bitcoind_rpc_password: String,
36 pub(crate) bitcoind_rpc_port: u16,
37 pub(crate) bitcoind_rpc_host: String,
38 pub(crate) ldk_storage_dir_path: String,
39 pub(crate) ldk_peer_listening_port: u16,
40 pub(crate) network: Network,
43 pub(crate) fn parse_startup_args() -> Result<LdkUserInfo, ()> {
44 if env::args().len() < 4 {
45 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]`");
48 let bitcoind_rpc_info = env::args().skip(1).next().unwrap();
49 let bitcoind_rpc_info_parts: Vec<&str> = bitcoind_rpc_info.split("@").collect();
50 if bitcoind_rpc_info_parts.len() != 2 {
51 println!("ERROR: bad bitcoind RPC URL provided");
54 let rpc_user_and_password: Vec<&str> = bitcoind_rpc_info_parts[0].split(":").collect();
55 if rpc_user_and_password.len() != 2 {
56 println!("ERROR: bad bitcoind RPC username/password combo provided");
59 let bitcoind_rpc_username = rpc_user_and_password[0].to_string();
60 let bitcoind_rpc_password = rpc_user_and_password[1].to_string();
61 let bitcoind_rpc_path: Vec<&str> = bitcoind_rpc_info_parts[1].split(":").collect();
62 if bitcoind_rpc_path.len() != 2 {
63 println!("ERROR: bad bitcoind RPC path provided");
66 let bitcoind_rpc_host = bitcoind_rpc_path[0].to_string();
67 let bitcoind_rpc_port = bitcoind_rpc_path[1].parse::<u16>().unwrap();
69 let ldk_storage_dir_path = env::args().skip(2).next().unwrap();
71 let mut ldk_peer_port_set = true;
72 let ldk_peer_listening_port: u16 = match env::args().skip(3).next().map(|p| p.parse()) {
74 Some(Err(e)) => panic!(e),
76 ldk_peer_port_set = false;
81 let arg_idx = match ldk_peer_port_set {
85 let network: Network = match env::args().skip(arg_idx).next().as_ref().map(String::as_str) {
86 Some("testnet") => Network::Testnet,
87 Some("regtest") => Network::Regtest,
88 Some(_) => panic!("Unsupported network provided. Options are: `regtest`, `testnet`"),
89 None => Network::Testnet,
92 bitcoind_rpc_username,
93 bitcoind_rpc_password,
97 ldk_peer_listening_port,
102 pub(crate) async fn poll_for_user_input(
103 peer_manager: Arc<PeerManager>, channel_manager: Arc<ChannelManager>,
104 router: Arc<NetGraphMsgHandler<Arc<dyn chain::Access>, Arc<FilesystemLogger>>>,
105 inbound_payments: PaymentInfoStorage, outbound_payments: PaymentInfoStorage,
106 node_privkey: SecretKey, event_notifier: mpsc::Sender<()>, ldk_data_dir: String,
107 logger: Arc<FilesystemLogger>, network: Network,
109 println!("LDK startup successful. To view available commands: \"help\".\nLDK logs are available at <your-supplied-ldk-data-dir-path>/.ldk/logs");
110 let stdin = io::stdin();
112 io::stdout().flush().unwrap(); // Without flushing, the `>` doesn't print
113 for line in stdin.lock().lines() {
114 let _ = event_notifier.try_send(());
115 let line = line.unwrap();
116 let mut words = line.split_whitespace();
117 if let Some(word) = words.next() {
121 let peer_pubkey_and_ip_addr = words.next();
122 let channel_value_sat = words.next();
123 if peer_pubkey_and_ip_addr.is_none() || channel_value_sat.is_none() {
124 println!("ERROR: openchannel has 2 required arguments: `openchannel pubkey@host:port channel_amt_satoshis` [--public]");
126 io::stdout().flush().unwrap();
129 let peer_pubkey_and_ip_addr = peer_pubkey_and_ip_addr.unwrap();
130 let (pubkey, peer_addr) =
131 match parse_peer_info(peer_pubkey_and_ip_addr.to_string()) {
134 println!("{:?}", e.into_inner().unwrap());
136 io::stdout().flush().unwrap();
141 let chan_amt_sat: Result<u64, _> = channel_value_sat.unwrap().parse();
142 if chan_amt_sat.is_err() {
143 println!("ERROR: channel amount must be a number");
145 io::stdout().flush().unwrap();
149 if connect_peer_if_necessary(
152 peer_manager.clone(),
153 event_notifier.clone(),
158 io::stdout().flush().unwrap();
162 let announce_channel = match words.next() {
163 Some("--public") | Some("--public=true") => true,
164 Some("--public=false") => false,
166 println!("ERROR: invalid `--public` command format. Valid formats: `--public`, `--public=true` `--public=false`");
168 io::stdout().flush().unwrap();
176 chan_amt_sat.unwrap(),
178 channel_manager.clone(),
182 let peer_data_path = format!("{}/channel_peer_data", ldk_data_dir.clone());
183 let _ = disk::persist_channel_peer(
184 Path::new(&peer_data_path),
185 peer_pubkey_and_ip_addr,
190 let invoice_str = words.next();
191 if invoice_str.is_none() {
192 println!("ERROR: sendpayment requires an invoice: `sendpayment <invoice>`");
194 io::stdout().flush().unwrap();
198 let invoice_res = Invoice::from_str(invoice_str.unwrap());
199 if invoice_res.is_err() {
200 println!("ERROR: invalid invoice: {:?}", invoice_res.unwrap_err());
202 io::stdout().flush().unwrap();
205 let invoice = invoice_res.unwrap();
206 let route_hints: Vec<Route> =
207 invoice.routes().iter().map(|&route| route.clone()).collect();
209 let amt_pico_btc = invoice.amount_pico_btc();
210 if amt_pico_btc.is_none() {
211 println!("ERROR: invalid invoice: must contain amount to pay");
213 io::stdout().flush().unwrap();
216 let amt_msat = amt_pico_btc.unwrap() / 10;
218 let payee_pubkey = invoice.recover_payee_pub_key();
219 let final_cltv = *invoice.min_final_cltv_expiry().unwrap_or(&9) as u32;
221 let mut payment_hash = PaymentHash([0; 32]);
222 payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]);
224 let payment_secret = match invoice.payment_secret() {
226 let mut payment_secret = PaymentSecret([0; 32]);
227 payment_secret.0.copy_from_slice(&secret.0);
233 // rust-lightning-invoice doesn't currently support features, so we parse features
234 // manually from the invoice.
235 let mut invoice_features = InvoiceFeatures::empty();
236 for field in &invoice.into_signed_raw().raw_invoice().data.tagged_fields {
238 lightning_invoice::RawTaggedField::UnknownSemantics(vec) => {
239 if vec[0] == bech32::u5::try_from_u8(5).unwrap() {
240 if vec.len() >= 6 && vec[5].to_u8() & 0b10000 != 0 {
242 invoice_features.set_variable_length_onion_optional();
244 if vec.len() >= 6 && vec[5].to_u8() & 0b01000 != 0 {
246 invoice_features.set_variable_length_onion_required();
248 if vec.len() >= 4 && vec[3].to_u8() & 0b00001 != 0 {
250 invoice_features.set_payment_secret_optional();
252 if vec.len() >= 5 && vec[4].to_u8() & 0b10000 != 0 {
254 invoice_features.set_payment_secret_required();
256 if vec.len() >= 4 && vec[3].to_u8() & 0b00100 != 0 {
258 invoice_features.set_basic_mpp_optional();
260 if vec.len() >= 4 && vec[3].to_u8() & 0b00010 != 0 {
262 invoice_features.set_basic_mpp_required();
269 let invoice_features_opt = match invoice_features == InvoiceFeatures::empty() {
271 false => Some(invoice_features),
279 invoice_features_opt,
282 channel_manager.clone(),
283 outbound_payments.clone(),
288 let amt_str = words.next();
289 if amt_str.is_none() {
290 println!("ERROR: getinvoice requires an amount in millisatoshis");
292 io::stdout().flush().unwrap();
296 let amt_msat: Result<u64, _> = amt_str.unwrap().parse();
297 if amt_msat.is_err() {
298 println!("ERROR: getinvoice provided payment amount was not a number");
300 io::stdout().flush().unwrap();
305 inbound_payments.clone(),
306 node_privkey.clone(),
307 channel_manager.clone(),
312 let peer_pubkey_and_ip_addr = words.next();
313 if peer_pubkey_and_ip_addr.is_none() {
314 println!("ERROR: connectpeer requires peer connection info: `connectpeer pubkey@host:port`");
316 io::stdout().flush().unwrap();
319 let (pubkey, peer_addr) =
320 match parse_peer_info(peer_pubkey_and_ip_addr.unwrap().to_string()) {
323 println!("{:?}", e.into_inner().unwrap());
325 io::stdout().flush().unwrap();
329 if connect_peer_if_necessary(
332 peer_manager.clone(),
333 event_notifier.clone(),
337 println!("SUCCESS: connected to peer {}", pubkey);
340 "listchannels" => list_channels(channel_manager.clone()),
342 list_payments(inbound_payments.clone(), outbound_payments.clone())
345 let channel_id_str = words.next();
346 if channel_id_str.is_none() {
347 println!("ERROR: closechannel requires a channel ID: `closechannel <channel_id>`");
349 io::stdout().flush().unwrap();
352 let channel_id_vec = hex_utils::to_vec(channel_id_str.unwrap());
353 if channel_id_vec.is_none() {
354 println!("ERROR: couldn't parse channel_id as hex");
356 io::stdout().flush().unwrap();
359 let mut channel_id = [0; 32];
360 channel_id.copy_from_slice(&channel_id_vec.unwrap());
361 close_channel(channel_id, channel_manager.clone());
363 "forceclosechannel" => {
364 let channel_id_str = words.next();
365 if channel_id_str.is_none() {
366 println!("ERROR: forceclosechannel requires a channel ID: `forceclosechannel <channel_id>`");
368 io::stdout().flush().unwrap();
371 let channel_id_vec = hex_utils::to_vec(channel_id_str.unwrap());
372 if channel_id_vec.is_none() {
373 println!("ERROR: couldn't parse channel_id as hex");
375 io::stdout().flush().unwrap();
378 let mut channel_id = [0; 32];
379 channel_id.copy_from_slice(&channel_id_vec.unwrap());
380 force_close_channel(channel_id, channel_manager.clone());
382 _ => println!("Unknown command. See `\"help\" for available commands."),
386 io::stdout().flush().unwrap();
391 println!("openchannel pubkey@host:port <channel_amt_satoshis>");
392 println!("sendpayment <invoice>");
393 println!("getinvoice <amt_in_millisatoshis>");
394 println!("connectpeer pubkey@host:port");
395 println!("listchannels");
396 println!("listpayments");
397 println!("closechannel <channel_id>");
398 println!("forceclosechannel <channel_id>");
401 fn list_channels(channel_manager: Arc<ChannelManager>) {
403 for chan_info in channel_manager.list_channels() {
406 println!("\t\tchannel_id: {},", hex_utils::hex_str(&chan_info.channel_id[..]));
408 "\t\tpeer_pubkey: {},",
409 hex_utils::hex_str(&chan_info.remote_network_id.serialize())
411 let mut pending_channel = false;
412 match chan_info.short_channel_id {
413 Some(id) => println!("\t\tshort_channel_id: {},", id),
415 pending_channel = true;
418 println!("\t\tpending_open: {},", pending_channel);
419 println!("\t\tchannel_value_satoshis: {},", chan_info.channel_value_satoshis);
420 println!("\t\tchannel_can_send_payments: {},", chan_info.is_live);
426 fn list_payments(inbound_payments: PaymentInfoStorage, outbound_payments: PaymentInfoStorage) {
427 let inbound = inbound_payments.lock().unwrap();
428 let outbound = outbound_payments.lock().unwrap();
430 for (payment_hash, payment_info) in inbound.deref() {
433 println!("\t\tamount_millisatoshis: {},", payment_info.amt_msat);
434 println!("\t\tpayment_hash: {},", hex_utils::hex_str(&payment_hash.0));
435 println!("\t\thtlc_direction: inbound,");
437 "\t\thtlc_status: {},",
438 match payment_info.status {
439 HTLCStatus::Pending => "pending",
440 HTLCStatus::Succeeded => "succeeded",
441 HTLCStatus::Failed => "failed",
448 for (payment_hash, payment_info) in outbound.deref() {
451 println!("\t\tamount_millisatoshis: {},", payment_info.amt_msat);
452 println!("\t\tpayment_hash: {},", hex_utils::hex_str(&payment_hash.0));
453 println!("\t\thtlc_direction: outbound,");
455 "\t\thtlc_status: {},",
456 match payment_info.status {
457 HTLCStatus::Pending => "pending",
458 HTLCStatus::Succeeded => "succeeded",
459 HTLCStatus::Failed => "failed",
468 pub(crate) fn connect_peer_if_necessary(
469 pubkey: PublicKey, peer_addr: SocketAddr, peer_manager: Arc<PeerManager>,
470 event_notifier: mpsc::Sender<()>,
471 ) -> Result<(), ()> {
472 for node_pubkey in peer_manager.get_peer_node_ids() {
473 if node_pubkey == pubkey {
477 match TcpStream::connect_timeout(&peer_addr, Duration::from_secs(10)) {
479 let peer_mgr = peer_manager.clone();
480 let event_ntfns = event_notifier.clone();
481 tokio::spawn(async move {
482 lightning_net_tokio::setup_outbound(peer_mgr, event_ntfns, pubkey, stream).await;
484 let mut peer_connected = false;
485 while !peer_connected {
486 for node_pubkey in peer_manager.get_peer_node_ids() {
487 if node_pubkey == pubkey {
488 peer_connected = true;
494 println!("ERROR: failed to connect to peer: {:?}", e);
502 peer_pubkey: PublicKey, channel_amt_sat: u64, announce_channel: bool,
503 channel_manager: Arc<ChannelManager>,
504 ) -> Result<(), ()> {
505 let mut config = UserConfig::default();
506 if announce_channel {
507 config.channel_options.announced_channel = true;
509 // lnd's max to_self_delay is 2016, so we want to be compatible.
510 config.peer_channel_config_limits.their_to_self_delay = 2016;
511 match channel_manager.create_channel(peer_pubkey, channel_amt_sat, 0, 0, None) {
513 println!("EVENT: initiated channel with peer {}. ", peer_pubkey);
517 println!("ERROR: failed to open channel: {:?}", e);
524 payee: PublicKey, amt_msat: u64, final_cltv: u32, payment_hash: PaymentHash,
525 payment_secret: Option<PaymentSecret>, payee_features: Option<InvoiceFeatures>,
526 mut route_hints: Vec<Route>,
527 router: Arc<NetGraphMsgHandler<Arc<dyn chain::Access>, Arc<FilesystemLogger>>>,
528 channel_manager: Arc<ChannelManager>, payment_storage: PaymentInfoStorage,
529 logger: Arc<FilesystemLogger>,
531 let network_graph = router.network_graph.read().unwrap();
532 let first_hops = channel_manager.list_usable_channels();
533 let payer_pubkey = channel_manager.get_our_node_id();
535 let mut hints: Vec<RouteHint> = Vec::new();
536 for route in route_hints.drain(..) {
537 let route_hops = route.into_inner();
538 let last_hop = &route_hops[route_hops.len() - 1];
539 hints.push(RouteHint {
540 src_node_id: last_hop.pubkey,
541 short_channel_id: u64::from_be_bytes(last_hop.short_channel_id),
543 base_msat: last_hop.fee_base_msat,
544 proportional_millionths: last_hop.fee_proportional_millionths,
546 cltv_expiry_delta: last_hop.cltv_expiry_delta,
547 htlc_minimum_msat: None,
548 htlc_maximum_msat: None,
551 let route = router::get_route(
556 Some(&first_hops.iter().collect::<Vec<_>>()),
557 &hints.iter().collect::<Vec<_>>(),
562 if let Err(e) = route {
563 println!("ERROR: failed to find route: {}", e.err);
566 let status = match channel_manager.send_payment(&route.unwrap(), payment_hash, &payment_secret)
569 println!("EVENT: initiated sending {} msats to {}", amt_msat, payee);
573 println!("ERROR: failed to send payment: {:?}", e);
577 let mut payments = payment_storage.lock().unwrap();
582 secret: payment_secret,
584 amt_msat: MillisatAmount(Some(amt_msat)),
590 amt_msat: u64, payment_storage: PaymentInfoStorage, our_node_privkey: SecretKey,
591 channel_manager: Arc<ChannelManager>, network: Network,
593 let mut payments = payment_storage.lock().unwrap();
594 let secp_ctx = Secp256k1::new();
596 let mut preimage = [0; 32];
597 rand::thread_rng().fill_bytes(&mut preimage);
598 let payment_hash = Sha256Hash::hash(&preimage);
600 let our_node_pubkey = channel_manager.get_our_node_id();
601 let mut invoice = InvoiceBuilder::new(match network {
602 Network::Bitcoin => Currency::Bitcoin,
603 Network::Testnet => Currency::BitcoinTestnet,
604 Network::Regtest => Currency::Regtest,
605 Network::Signet => panic!("Signet invoices not supported"),
607 .payment_hash(payment_hash)
608 .description("rust-lightning-bitcoinrpc invoice".to_string())
609 .amount_pico_btc(amt_msat * 10)
611 .payee_pub_key(our_node_pubkey);
613 // Add route hints to the invoice.
614 let our_channels = channel_manager.list_usable_channels();
615 let mut min_final_cltv_expiry = 9;
616 for channel in our_channels {
617 let short_channel_id = match channel.short_channel_id {
618 Some(id) => id.to_be_bytes(),
621 let forwarding_info = match channel.counterparty_forwarding_info {
625 if forwarding_info.cltv_expiry_delta > min_final_cltv_expiry {
626 min_final_cltv_expiry = forwarding_info.cltv_expiry_delta;
628 invoice = invoice.route(vec![RouteHop {
629 pubkey: channel.remote_network_id,
631 fee_base_msat: forwarding_info.fee_base_msat,
632 fee_proportional_millionths: forwarding_info.fee_proportional_millionths,
633 cltv_expiry_delta: forwarding_info.cltv_expiry_delta,
636 invoice = invoice.min_final_cltv_expiry(min_final_cltv_expiry.into());
640 invoice.build_signed(|msg_hash| secp_ctx.sign_recoverable(msg_hash, &our_node_privkey));
643 Ok(invoice) => println!("SUCCESS: generated invoice: {}", invoice),
644 Err(e) => println!("ERROR: failed to create invoice: {:?}", e),
648 PaymentHash(payment_hash.into_inner()),
650 preimage: Some(PaymentPreimage(preimage)),
651 // We can't add payment secrets to invoices until we support features in invoices.
652 // Otherwise lnd errors with "destination hop doesn't understand payment addresses"
653 // (for context, lnd calls payment secrets "payment addresses").
655 status: HTLCStatus::Pending,
656 amt_msat: MillisatAmount(Some(amt_msat)),
661 fn close_channel(channel_id: [u8; 32], channel_manager: Arc<ChannelManager>) {
662 match channel_manager.close_channel(&channel_id) {
663 Ok(()) => println!("EVENT: initiating channel close"),
664 Err(e) => println!("ERROR: failed to close channel: {:?}", e),
668 fn force_close_channel(channel_id: [u8; 32], channel_manager: Arc<ChannelManager>) {
669 match channel_manager.force_close_channel(&channel_id) {
670 Ok(()) => println!("EVENT: initiating channel force-close"),
671 Err(e) => println!("ERROR: failed to force-close channel: {:?}", e),
675 pub(crate) fn parse_peer_info(
676 peer_pubkey_and_ip_addr: String,
677 ) -> Result<(PublicKey, SocketAddr), std::io::Error> {
678 let mut pubkey_and_addr = peer_pubkey_and_ip_addr.split("@");
679 let pubkey = pubkey_and_addr.next();
680 let peer_addr_str = pubkey_and_addr.next();
681 if peer_addr_str.is_none() || peer_addr_str.is_none() {
682 return Err(std::io::Error::new(
683 std::io::ErrorKind::Other,
684 "ERROR: incorrectly formatted peer
685 info. Should be formatted as: `pubkey@host:port`",
689 let peer_addr: Result<SocketAddr, _> = peer_addr_str.unwrap().parse();
690 if peer_addr.is_err() {
691 return Err(std::io::Error::new(
692 std::io::ErrorKind::Other,
693 "ERROR: couldn't parse pubkey@host:port into a socket address",
697 let pubkey = hex_utils::to_compressed_pubkey(pubkey.unwrap());
698 if pubkey.is_none() {
699 return Err(std::io::Error::new(
700 std::io::ErrorKind::Other,
701 "ERROR: unable to parse given pubkey for node",
705 Ok((pubkey.unwrap(), peer_addr.unwrap()))