From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Tue, 11 Jan 2022 18:44:36 +0000 (+0000) Subject: Merge pull request #43 from TheBlueMatt/2021-12-0.0.104 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=86a474d8acb1d8495307a38517dfc53b805d3b9b;hp=e3d528d2cfe5ec239571c70f71a9f0f9307862f2;p=ldk-sample Merge pull request #43 from TheBlueMatt/2021-12-0.0.104 LDK 0.0.104 --- diff --git a/Cargo.lock b/Cargo.lock index f2bdbc7..5c5b67e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" [[package]] name = "bitcoin" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a427b27dae305157520d86673f2393b3eb08d880609abfcffc6e3c3c820e764" +checksum = "9a41df6ad9642c5c15ae312dd3d074de38fd3eb7cc87ad4ce10f90292a83fe4d" dependencies = [ "bech32", "bitcoin_hashes", @@ -48,15 +48,15 @@ checksum = "006cc91e1a1d99819bc5b8214be3555c1f0611b169f527a1fdc54ed1f2b745b0" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" @@ -91,9 +91,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" dependencies = [ "futures-channel", "futures-core", @@ -106,9 +106,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" dependencies = [ "futures-core", "futures-sink", @@ -116,15 +116,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" dependencies = [ "futures-core", "futures-task", @@ -133,18 +133,16 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -152,23 +150,22 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -178,8 +175,6 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -200,9 +195,9 @@ checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "ldk-tutorial-node" @@ -228,15 +223,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.99" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "lightning" -version = "0.0.103" +version = "0.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f4cc6a6bc500226fe2716b8557fe66b57fd8d86348e4478b57de13a4dd6b8f0" +checksum = "0113e6b5a55b7ead30fb0a992b787e69a0551fa15b7eed93c99490eb018ab793" dependencies = [ "bitcoin", "secp256k1", @@ -244,9 +239,9 @@ dependencies = [ [[package]] name = "lightning-background-processor" -version = "0.0.103" +version = "0.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0cded269444c0b1d19d92b79a60b1d9188f377c2e7ddd6d0c8860b80f3ea4a" +checksum = "8fe8419b773e4f212faa21bf7fe493746aeb69284d396a263215c3a4131a0a5f" dependencies = [ "bitcoin", "lightning", @@ -255,9 +250,9 @@ dependencies = [ [[package]] name = "lightning-block-sync" -version = "0.0.103" +version = "0.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0af7169b0f238dd5c845ee1d95201fbb69acb2b93d9aea5a75b6d593abcd674f" +checksum = "54d54f17ce6a62b118fb4ebcbd81da267e6dc76c6fe7af2cdc9e47d8d99ef28a" dependencies = [ "bitcoin", "chunked_transfer", @@ -268,9 +263,9 @@ dependencies = [ [[package]] name = "lightning-invoice" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f7cc25650f634e074b0b64a793ac535f7ad2ae418dd7f0ac88972832d2f22bc" +checksum = "2531e38818b3872b9acbcc3ff499f93962d2ff23ee0d05fc386ef70b993a38a0" dependencies = [ "bech32", "bitcoin_hashes", @@ -281,9 +276,9 @@ dependencies = [ [[package]] name = "lightning-net-tokio" -version = "0.0.103" +version = "0.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4ba9c57851bfaa872a9fbea41065812d03da30bf24680e08c074b972cb3e8d" +checksum = "1851ab90c2739929526c56e06d6b07def4508bfce70f190757fde2de648d1d9c" dependencies = [ "bitcoin", "lightning", @@ -292,9 +287,9 @@ dependencies = [ [[package]] name = "lightning-persister" -version = "0.0.103" +version = "0.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea68c7b0a8b0bc01103d189206bd09c8501bd0fad721229d1e36743a80ed010" +checksum = "4cf5f42ec139dd1c878b5dc66a055a0e7d805b2db83de2a4645af3fe59e4b6af" dependencies = [ "bitcoin", "libc", @@ -313,15 +308,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "mio" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -389,32 +384,20 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -458,9 +441,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "secp256k1" @@ -482,18 +465,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.127" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", @@ -502,9 +485,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ "itoa", "ryu", @@ -513,15 +496,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "syn" -version = "1.0.74" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -541,11 +524,10 @@ dependencies = [ [[package]] name = "tokio" -version = "1.10.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "autocfg", "bytes", "libc", "memchr", @@ -558,9 +540,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.3.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 32f6cf4..6a1546a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,12 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lightning = { version = "0.0.103" } -lightning-block-sync = { version = "0.0.103", features = [ "rpc-client" ] } -lightning-invoice = { version = "0.11.0" } -lightning-net-tokio = { version = "0.0.103" } -lightning-persister = { version = "0.0.103" } -lightning-background-processor = { version = "0.0.103" } +lightning = { version = "0.0.104", features = ["max_level_trace"] } +lightning-block-sync = { version = "0.0.104", features = [ "rpc-client" ] } +lightning-invoice = { version = "0.12.0" } +lightning-net-tokio = { version = "0.0.104" } +lightning-persister = { version = "0.0.104" } +lightning-background-processor = { version = "0.0.104" } base64 = "0.13.0" bitcoin = "0.27" diff --git a/src/cli.rs b/src/cli.rs index 42696c6..a167027 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,19 +1,16 @@ use crate::disk; use crate::hex_utils; use crate::{ - ChannelManager, FilesystemLogger, HTLCStatus, InvoicePayer, MillisatAmount, PaymentInfo, - PaymentInfoStorage, PeerManager, + ChannelManager, HTLCStatus, InvoicePayer, MillisatAmount, PaymentInfo, PaymentInfoStorage, + PeerManager, }; +use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; use bitcoin::network::constants::Network; use bitcoin::secp256k1::key::PublicKey; use lightning::chain::keysinterface::{KeysInterface, KeysManager}; use lightning::ln::msgs::NetAddress; -use lightning::ln::PaymentHash; -use lightning::routing::network_graph::NetworkGraph; -use lightning::routing::router; -use lightning::routing::router::{Payee, RouteParameters}; -use lightning::routing::scorer::Scorer; +use lightning::ln::{PaymentHash, PaymentPreimage}; use lightning::util::config::{ChannelConfig, ChannelHandshakeLimits, UserConfig}; use lightning::util::events::EventHandler; use lightning_invoice::payment::PaymentError; @@ -25,7 +22,7 @@ use std::net::{IpAddr, SocketAddr, ToSocketAddrs}; use std::ops::Deref; use std::path::Path; use std::str::FromStr; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::time::Duration; pub(crate) struct LdkUserInfo { @@ -144,18 +141,21 @@ pub(crate) fn parse_startup_args() -> Result { pub(crate) async fn poll_for_user_input( invoice_payer: Arc>, peer_manager: Arc, channel_manager: Arc, keys_manager: Arc, - network_graph: Arc, scorer: Arc>, inbound_payments: PaymentInfoStorage, outbound_payments: PaymentInfoStorage, - ldk_data_dir: String, logger: Arc, network: Network, + ldk_data_dir: String, network: Network, ) { println!("LDK startup successful. To view available commands: \"help\"."); 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 { @@ -165,8 +165,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(); @@ -175,8 +173,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; } }; @@ -184,8 +180,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; } @@ -193,8 +187,6 @@ pub(crate) async fn poll_for_user_input( .await .is_err() { - print!("> "); - io::stdout().flush().unwrap(); continue; }; @@ -203,8 +195,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, @@ -229,8 +219,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; } @@ -238,8 +226,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; } }; @@ -252,15 +238,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,9 +250,6 @@ pub(crate) async fn poll_for_user_input( Some(amt) => amt, None => { println!("ERROR: keysend requires an amount in millisatoshis: `keysend `"); - - print!("> "); - io::stdout().flush().unwrap(); continue; } }; @@ -278,35 +257,27 @@ 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; } }; keysend( + &*invoice_payer, dest_pubkey, amt_msat, - network_graph.clone(), - channel_manager.clone(), + &*keys_manager, outbound_payments.clone(), - logger.clone(), - scorer.clone(), ); } "getinvoice" => { 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( @@ -321,8 +292,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) = @@ -330,8 +299,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; } }; @@ -350,15 +317,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]; @@ -369,15 +332,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]; @@ -387,11 +346,9 @@ pub(crate) async fn poll_for_user_input( "nodeinfo" => node_info(channel_manager.clone(), peer_manager.clone()), "listpeers" => list_peers(peer_manager.clone()), "signmessage" => { - const MSG_STARTPOS: usize = "signmsg".len() + 1; + const MSG_STARTPOS: usize = "signmessage".len() + 1; if line.as_bytes().len() <= MSG_STARTPOS { println!("ERROR: signmsg requires a message"); - print!("> "); - io::stdout().flush().unwrap(); continue; } println!( @@ -401,14 +358,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(); } } @@ -429,8 +382,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}},"); } @@ -527,6 +486,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) => { @@ -534,24 +503,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( @@ -622,40 +586,47 @@ fn send_payment( ); } -fn keysend( - payee_pubkey: PublicKey, amt_msat: u64, network_graph: Arc, - channel_manager: Arc, payment_storage: PaymentInfoStorage, - logger: Arc, scorer: Arc>, +fn keysend( + invoice_payer: &InvoicePayer, payee_pubkey: PublicKey, amt_msat: u64, keys: &K, + payment_storage: PaymentInfoStorage, ) { - let first_hops = channel_manager.list_usable_channels(); - let payer_pubkey = channel_manager.get_our_node_id(); - - let payee = Payee::for_keysend(payee_pubkey); - let params = RouteParameters { payee, final_value_msat: amt_msat, final_cltv_expiry_delta: 40 }; - - let route = match router::find_route( - &payer_pubkey, - ¶ms, - &network_graph, - Some(&first_hops.iter().collect::>()), - logger, - &scorer.lock().unwrap(), + let payment_preimage = keys.get_secure_random_bytes(); + + let status = match invoice_payer.pay_pubkey( + payee_pubkey, + PaymentPreimage(payment_preimage), + amt_msat, + 40, ) { - Ok(r) => r, - Err(e) => { + Ok(_payment_id) => { + println!("EVENT: initiated sending {} msats to {}", amt_msat, payee_pubkey); + print!("> "); + HTLCStatus::Pending + } + Err(PaymentError::Invoice(e)) => { + println!("ERROR: invalid payee: {}", e); + print!("> "); + return; + } + Err(PaymentError::Routing(e)) => { println!("ERROR: failed to find route: {}", e.err); + print!("> "); return; } + Err(PaymentError::Sending(e)) => { + println!("ERROR: failed to send payment: {:?}", e); + print!("> "); + HTLCStatus::Failed + } }; let mut payments = payment_storage.lock().unwrap(); - let payment_hash = channel_manager.send_spontaneous_payment(&route, None).unwrap().0; payments.insert( - payment_hash, + PaymentHash(Sha256::hash(&payment_preimage).into_inner()), PaymentInfo { preimage: None, secret: None, - status: HTLCStatus::Pending, + status, amt_msat: MillisatAmount(Some(amt_msat)), }, ); diff --git a/src/disk.rs b/src/disk.rs index 7be070c..b019626 100644 --- a/src/disk.rs +++ b/src/disk.rs @@ -3,7 +3,7 @@ use bitcoin::secp256k1::key::PublicKey; use bitcoin::BlockHash; use chrono::Utc; use lightning::routing::network_graph::NetworkGraph; -use lightning::routing::scorer::Scorer; +use lightning::routing::scoring::Scorer; use lightning::util::logger::{Logger, Record}; use lightning::util::ser::{Readable, Writeable, Writer}; use std::collections::HashMap; diff --git a/src/main.rs b/src/main.rs index 389ff05..0e18bc0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ use lightning::ln::channelmanager::{ use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler, SimpleArcPeerManager}; use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use lightning::routing::network_graph::{NetGraphMsgHandler, NetworkGraph}; -use lightning::routing::scorer::Scorer; +use lightning::routing::scoring::Scorer; use lightning::util::config::UserConfig; use lightning::util::events::{Event, PaymentPurpose}; use lightning::util::ser::ReadableArgs; @@ -195,16 +195,21 @@ async fn handle_ldk_events( } } } - Event::PaymentSent { payment_preimage, payment_hash, .. } => { + Event::PaymentSent { payment_preimage, payment_hash, fee_paid_msat, .. } => { let mut payments = outbound_payments.lock().unwrap(); for (hash, payment) in payments.iter_mut() { if *hash == *payment_hash { payment.preimage = Some(*payment_preimage); payment.status = HTLCStatus::Succeeded; println!( - "\nEVENT: successfully sent payment of {} millisatoshis from \ + "\nEVENT: successfully sent payment of {} millisatoshis{} from \ payment hash {:?} with preimage {:?}", payment.amt_msat, + if let Some(fee) = fee_paid_msat { + format!(" (fee {} msat)", fee) + } else { + "".to_string() + }, hex_utils::hex_str(&payment_hash.0), hex_utils::hex_str(&payment_preimage.0) ); @@ -213,26 +218,13 @@ async fn handle_ldk_events( } } } - Event::PaymentPathFailed { - payment_hash, - rejected_by_dest, - all_paths_failed, - short_channel_id, - .. - } => { + Event::PaymentPathSuccessful { .. } => {} + Event::PaymentPathFailed { .. } => {} + Event::PaymentFailed { payment_hash, .. } => { print!( - "\nEVENT: Failed to send payment{} to payment hash {:?}", - if *all_paths_failed { "" } else { " along MPP path" }, + "\nEVENT: Failed to send payment to payment hash {:?}: exhausted payment retry attempts", hex_utils::hex_str(&payment_hash.0) ); - if let Some(scid) = short_channel_id { - print!(" because of failure at channel {}", scid); - } - if *rejected_by_dest { - println!(": re-attempting the payment will not succeed"); - } else { - println!(": exhausted payment retry attempts"); - } print!("> "); io::stdout().flush().unwrap(); @@ -641,22 +633,39 @@ async fn start_ldk() { logger.clone(), ); - // Reconnect to channel peers if possible. + // Regularly reconnect to channel peers. + let connect_cm = Arc::clone(&channel_manager); + let connect_pm = Arc::clone(&peer_manager); let peer_data_path = format!("{}/channel_peer_data", ldk_data_dir.clone()); - match disk::read_channel_peer_data(Path::new(&peer_data_path)) { - Ok(mut info) => { - for (pubkey, peer_addr) in info.drain() { - for chan_info in channel_manager.list_channels() { - if pubkey == chan_info.counterparty.node_id { - let _ = - cli::connect_peer_if_necessary(pubkey, peer_addr, peer_manager.clone()) + tokio::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(1)); + loop { + interval.tick().await; + match disk::read_channel_peer_data(Path::new(&peer_data_path)) { + Ok(info) => { + let peers = connect_pm.get_peer_node_ids(); + for node_id in connect_cm + .list_channels() + .iter() + .map(|chan| chan.counterparty.node_id) + .filter(|id| !peers.contains(id)) + { + for (pubkey, peer_addr) in info.iter() { + if *pubkey == node_id { + let _ = cli::do_connect_peer( + *pubkey, + peer_addr.clone(), + Arc::clone(&connect_pm), + ) .await; + } + } } } + Err(e) => println!("ERROR: errored reading channel peer info from disk: {:?}", e), } } - 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. @@ -684,12 +693,9 @@ async fn start_ldk() { peer_manager.clone(), channel_manager.clone(), keys_manager.clone(), - network_graph.clone(), - scorer.clone(), inbound_payments, outbound_payments, ldk_data_dir.clone(), - logger.clone(), network, ) .await;