diff --git a/Cargo.toml b/Cargo.toml index edc41ed31..d2837975c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,13 +32,13 @@ panic = 'abort' # Abort on panic default = [] [dependencies] -lightning = { version = "0.0.117", features = ["max_level_trace", "std"] } -lightning-invoice = { version = "0.25.0" } -lightning-net-tokio = { version = "0.0.117" } -lightning-persister = { version = "0.0.117" } -lightning-background-processor = { version = "0.0.117", features = ["futures"] } -lightning-rapid-gossip-sync = { version = "0.0.117" } -lightning-transaction-sync = { version = "0.0.117", features = ["esplora-async-https"] } +lightning = { version = "0.0.118", features = ["max_level_trace", "std"] } +lightning-invoice = { version = "0.26.0" } +lightning-net-tokio = { version = "0.0.118" } +lightning-persister = { version = "0.0.118" } +lightning-background-processor = { version = "0.0.118", features = ["futures"] } +lightning-rapid-gossip-sync = { version = "0.0.118" } +lightning-transaction-sync = { version = "0.0.118", features = ["esplora-async-https"] } # lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["max_level_trace", "std"] } # lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main" } @@ -75,7 +75,7 @@ uniffi = { version = "0.23.0", features = ["build"], optional = true } winapi = { version = "0.3", features = ["winbase"] } [dev-dependencies] -lightning = { version = "0.0.117", features = ["max_level_trace", "std", "_test_utils"] } +lightning = { version = "0.0.118", features = ["max_level_trace", "std", "_test_utils"] } #lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["max_level_trace", "std", "_test_utils"] } electrsd = { version = "0.22.0", features = ["legacy", "esplora_a33e97e1", "bitcoind_23_0"] } electrum-client = "0.12.0" diff --git a/README.md b/README.md index ef5ffe5aa..1877168a0 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ LDK Node is a self-custodial Lightning node in library form. Its central goal is The primary abstraction of the library is the [`Node`][api_docs_node], which can be retrieved by setting up and configuring a [`Builder`][api_docs_builder] to your liking and calling one of the `build` methods. `Node` can then be controlled via commands such as `start`, `stop`, `connect_open_channel`, `send_payment`, etc. ```rust -use ldk_node::{Builder, SocketAddress}; +use ldk_node::Builder; use ldk_node::lightning_invoice::Invoice; +use ldk_node::lightning::ln::msgs::SocketAddress; use ldk_node::bitcoin::secp256k1::PublicKey; use ldk_node::bitcoin::Network; use std::str::FromStr; diff --git a/src/builder.rs b/src/builder.rs index c0645a7f6..3a6b1e6b4 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -7,7 +7,7 @@ use crate::payment_store::PaymentStore; use crate::peer_store::PeerStore; use crate::types::{ ChainMonitor, ChannelManager, FakeMessageRouter, GossipSync, KeysManager, NetworkGraph, - OnionMessenger, PeerManager, SocketAddress, + OnionMessenger, PeerManager, }; use crate::wallet::Wallet; use crate::LogLevel; @@ -18,7 +18,7 @@ use crate::{ use lightning::chain::{chainmonitor, BestBlock, Watch}; use lightning::ln::channelmanager::{self, ChainParameters, ChannelManagerReadArgs}; -use lightning::ln::msgs::RoutingMessageHandler; +use lightning::ln::msgs::{RoutingMessageHandler, SocketAddress}; use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler}; use lightning::routing::router::DefaultRouter; use lightning::routing::scoring::{ diff --git a/src/event.rs b/src/event.rs index 6bc052f9b..ce75d673e 100644 --- a/src/event.rs +++ b/src/event.rs @@ -287,7 +287,7 @@ where } => { // Construct the raw transaction with the output that is paid the amount of the // channel. - let confirmation_target = ConfirmationTarget::Normal; + let confirmation_target = ConfirmationTarget::NonAnchorChannelFee; // We set nLockTime to the current height to discourage fee sniping. let cur_height = self.channel_manager.current_best_block().height(); @@ -581,8 +581,9 @@ where }); let output_descriptors = &outputs.iter().collect::>(); - let tx_feerate = - self.wallet.get_est_sat_per_1000_weight(ConfirmationTarget::Normal); + let tx_feerate = self + .wallet + .get_est_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee); // We set nLockTime to the current height to discourage fee sniping. let cur_height = self.channel_manager.current_best_block().height(); @@ -781,6 +782,7 @@ where LdkEvent::DiscardFunding { .. } => {} LdkEvent::HTLCIntercepted { .. } => {} LdkEvent::BumpTransaction(_) => {} + LdkEvent::InvoiceRequestFailed { .. } => {} } } } diff --git a/src/lib.rs b/src/lib.rs index 52b93ddfb..6598b13bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,8 +26,9 @@ //! [`send_payment`], etc.: //! //! ```no_run -//! use ldk_node::{Builder, SocketAddress}; +//! use ldk_node::Builder; //! use ldk_node::lightning_invoice::Bolt11Invoice; +//! use ldk_node::lightning::ln::msgs::SocketAddress; //! use ldk_node::bitcoin::secp256k1::PublicKey; //! use ldk_node::bitcoin::Network; //! use std::str::FromStr; @@ -100,7 +101,6 @@ use error::Error; pub use event::Event; pub use types::ChannelConfig; -pub use types::SocketAddress; pub use io::utils::generate_entropy_mnemonic; @@ -126,6 +126,7 @@ use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger}; use lightning::chain::Confirm; use lightning::ln::channelmanager::{self, PaymentId, RecipientOnionFields, Retry}; +use lightning::ln::msgs::SocketAddress; use lightning::ln::{ChannelId, PaymentHash, PaymentPreimage}; use lightning::sign::EntropySource; @@ -631,7 +632,7 @@ impl Node { } let addresses = - bcast_config.listening_address.iter().cloned().map(|a| a.0).collect(); + bcast_config.listening_address.iter().cloned().collect(); bcast_pm.broadcast_node_announcement([0; 3], [0; 32], addresses); let unix_time_secs = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); @@ -1516,7 +1517,7 @@ impl Node { let stored_peer = self.peer_store.get_peer(&node_id); let stored_addr_opt = stored_peer.as_ref().map(|p| p.address.clone()); let address = match (con_addr_opt, stored_addr_opt) { - (Some(con_addr), _) => SocketAddress(con_addr), + (Some(con_addr), _) => con_addr, (None, Some(stored_addr)) => stored_addr, (None, None) => continue, }; diff --git a/src/types.rs b/src/types.rs index fc99cb207..d4b8f6054 100644 --- a/src/types.rs +++ b/src/types.rs @@ -4,7 +4,7 @@ use crate::wallet::{Wallet, WalletKeysManager}; use lightning::chain::chainmonitor; use lightning::ln::channelmanager::ChannelDetails as LdkChannelDetails; use lightning::ln::msgs::RoutingMessageHandler; -use lightning::ln::msgs::SocketAddress as LdkSocketAddress; +use lightning::ln::msgs::SocketAddress; use lightning::ln::peer_handler::IgnoringMessageHandler; use lightning::ln::ChannelId; use lightning::routing::gossip; @@ -20,9 +20,6 @@ use lightning_transaction_sync::EsploraSyncClient; use bitcoin::secp256k1::PublicKey; use bitcoin::OutPoint; -use std::fmt::Display; -use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; -use std::str::FromStr; use std::sync::{Arc, Mutex, RwLock}; pub(crate) type ChainMonitor = chainmonitor::ChainMonitor< @@ -320,106 +317,6 @@ pub struct PeerDetails { pub is_connected: bool, } -/// The network address of a Lightning node. -/// -/// Currently only IPv4, IPv6, and DNS hostnames are supported. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct SocketAddress(pub LdkSocketAddress); - -impl Display for SocketAddress { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.0 { - LdkSocketAddress::TcpIpV4 { addr, port } => { - let ip_addr = Ipv4Addr::from(addr); - write!(f, "{}:{}", ip_addr, port) - } - LdkSocketAddress::TcpIpV6 { addr, port } => { - let ip_addr = Ipv6Addr::from(addr); - write!(f, "[{}]:{}", ip_addr, port) - } - LdkSocketAddress::Hostname { ref hostname, port } => { - write!(f, "{}:{}", hostname.as_str(), port) - } - LdkSocketAddress::OnionV2(o) => { - write!(f, "OnionV2 (unsupported): {:?}", o) - } - LdkSocketAddress::OnionV3 { ed25519_pubkey, checksum, version, port } => write!( - f, - "OnionV3 (unsupported): {:?}/{:?}/{:?}/{:?}", - ed25519_pubkey, checksum, version, port - ), - } - } -} - -impl FromStr for SocketAddress { - type Err = (); - - fn from_str(s: &str) -> Result { - Ok(Self(LdkSocketAddress::from_str(s).map_err(|_| ())?)) - } -} - -impl From for SocketAddress { - fn from(value: SocketAddr) -> Self { - match value { - SocketAddr::V4(v4addr) => SocketAddress::from(v4addr), - SocketAddr::V6(v6addr) => SocketAddress::from(v6addr), - } - } -} - -impl From for SocketAddress { - fn from(value: SocketAddrV4) -> Self { - Self(LdkSocketAddress::TcpIpV4 { addr: value.ip().octets(), port: value.port() }) - } -} - -impl From for SocketAddress { - fn from(value: SocketAddrV6) -> Self { - Self(LdkSocketAddress::TcpIpV6 { addr: value.ip().octets(), port: value.port() }) - } -} - -impl ToSocketAddrs for SocketAddress { - type Iter = std::option::IntoIter; - - fn to_socket_addrs(&self) -> std::io::Result { - match self.0 { - LdkSocketAddress::TcpIpV4 { addr, port } => { - let ip_addr = Ipv4Addr::from(addr); - (ip_addr, port).to_socket_addrs() - } - LdkSocketAddress::TcpIpV6 { addr, port } => { - let ip_addr = Ipv6Addr::from(addr); - (ip_addr, port).to_socket_addrs() - } - LdkSocketAddress::Hostname { ref hostname, port } => { - Ok((hostname.as_str(), port).to_socket_addrs()?.next().into_iter()) - } - LdkSocketAddress::OnionV2(..) => { - Err(std::io::Error::from(std::io::ErrorKind::Unsupported)) - } - LdkSocketAddress::OnionV3 { .. } => { - Err(std::io::Error::from(std::io::ErrorKind::Unsupported)) - } - } - } -} - -impl Writeable for SocketAddress { - fn write(&self, writer: &mut W) -> Result<(), std::io::Error> { - self.0.write(writer) - } -} - -impl Readable for SocketAddress { - fn read(reader: &mut R) -> Result { - let addr: LdkSocketAddress = Readable::read(reader)?; - Ok(Self(addr)) - } -} - /// Options which apply on a per-channel basis. /// /// See documentation of [`LdkChannelConfig`] for details. diff --git a/src/wallet.rs b/src/wallet.rs index 561e92dab..4221dc084 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -116,29 +116,48 @@ where let mut locked_fee_rate_cache = self.fee_rate_cache.write().unwrap(); let confirmation_targets = vec![ - ConfirmationTarget::MempoolMinimum, - ConfirmationTarget::Background, - ConfirmationTarget::Normal, - ConfirmationTarget::HighPriority, + ConfirmationTarget::OnChainSweep, + ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee, + ConfirmationTarget::MinAllowedAnchorChannelRemoteFee, + ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee, + ConfirmationTarget::AnchorChannelFee, + ConfirmationTarget::NonAnchorChannelFee, + ConfirmationTarget::ChannelCloseMinimum, ]; for target in confirmation_targets { let num_blocks = match target { - ConfirmationTarget::MempoolMinimum => 1008, - ConfirmationTarget::Background => 12, - ConfirmationTarget::Normal => 6, - ConfirmationTarget::HighPriority => 3, + ConfirmationTarget::OnChainSweep => 6, + ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee => 1, + ConfirmationTarget::MinAllowedAnchorChannelRemoteFee => 1008, + ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee => 144, + ConfirmationTarget::AnchorChannelFee => 1008, + ConfirmationTarget::NonAnchorChannelFee => 12, + ConfirmationTarget::ChannelCloseMinimum => 144, }; let est_fee_rate = self.blockchain.estimate_fee(num_blocks).await; match est_fee_rate { Ok(rate) => { - locked_fee_rate_cache.insert(target, rate); + // LDK 0.0.118 introduced changes to the `ConfirmationTarget` semantics that + // require some post-estimation adjustments to the fee rates, which we do here. + let adjusted_fee_rate = match target { + ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee => { + let really_high_prio = rate.as_sat_per_vb() * 10.0; + FeeRate::from_sat_per_vb(really_high_prio) + } + ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee => { + let slightly_less_than_background = rate.fee_wu(1000) - 250; + FeeRate::from_sat_per_kwu(slightly_less_than_background as f32) + } + _ => rate, + }; + locked_fee_rate_cache.insert(target, adjusted_fee_rate); log_trace!( self.logger, "Fee rate estimation updated for {:?}: {} sats/kwu", target, - rate.fee_wu(1000) + adjusted_fee_rate.fee_wu(1000) ); } Err(e) => { @@ -211,7 +230,7 @@ where pub(crate) fn send_to_address( &self, address: &bitcoin::Address, amount_msat_or_drain: Option, ) -> Result { - let confirmation_target = ConfirmationTarget::Normal; + let confirmation_target = ConfirmationTarget::NonAnchorChannelFee; let fee_rate = self.estimate_fee_rate(confirmation_target); let tx = { @@ -284,10 +303,13 @@ where let locked_fee_rate_cache = self.fee_rate_cache.read().unwrap(); let fallback_sats_kwu = match confirmation_target { - ConfirmationTarget::MempoolMinimum => FEERATE_FLOOR_SATS_PER_KW, - ConfirmationTarget::Background => 500, - ConfirmationTarget::Normal => 2000, - ConfirmationTarget::HighPriority => 5000, + ConfirmationTarget::OnChainSweep => 5000, + ConfirmationTarget::MaxAllowedNonAnchorChannelRemoteFee => 25 * 250, + ConfirmationTarget::MinAllowedAnchorChannelRemoteFee => FEERATE_FLOOR_SATS_PER_KW, + ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee => FEERATE_FLOOR_SATS_PER_KW, + ConfirmationTarget::AnchorChannelFee => 500, + ConfirmationTarget::NonAnchorChannelFee => 1000, + ConfirmationTarget::ChannelCloseMinimum => 500, }; // We'll fall back on this, if we really don't have any other information.