diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index 1b33952df..fce615430 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -62,7 +62,7 @@ interface LDKNode { [Throws=NodeError] void close_channel([ByRef]ChannelId channel_id, PublicKey counterparty_node_id); [Throws=NodeError] - void update_channel_config([ByRef]ChannelId channel_id, PublicKey counterparty_node_id, [ByRef]ChannelConfig channel_config); + void update_channel_config([ByRef]ChannelId channel_id, PublicKey counterparty_node_id, ChannelConfig channel_config); [Throws=NodeError] void sync_wallets(); [Throws=NodeError] @@ -203,11 +203,18 @@ dictionary ChannelConfig { u32 forwarding_fee_proportional_millionths = 0; u32 forwarding_fee_base_msat = 1000; u16 cltv_expiry_delta = 72; - u64 max_dust_htlc_exposure_msat = 5000000; + MaxDustHTLCExposure max_dust_htlc_exposure; u64 force_close_avoidance_max_fee_satoshis = 1000; boolean accept_underpaying_htlcs = false; }; +interface MaxDustHTLCExposure { + [Name=from_fixed_limit] + constructor(u64 limit); + [Name=from_fee_multiplier] + constructor(u64 multiplier); +}; + enum LogLevel { "Gossip", "Trace", diff --git a/src/lib.rs b/src/lib.rs index 704c2bb66..3f9f7bb0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ use error::Error; pub use event::Event; pub use types::NetAddress; +pub use types::ChannelConfig; pub use io::utils::generate_entropy_mnemonic; @@ -119,7 +120,7 @@ use payment_store::PaymentStore; pub use payment_store::{PaymentDetails, PaymentDirection, PaymentStatus}; use peer_store::{PeerInfo, PeerStore}; use types::{ChainMonitor, ChannelManager, KeysManager, NetworkGraph, PeerManager, Scorer}; -pub use types::{ChannelDetails, ChannelId, PeerDetails, UserChannelId}; +pub use types::{ChannelDetails, ChannelId, PeerDetails, UserChannelId, MaxDustHTLCExposure}; use wallet::Wallet; use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger}; @@ -129,7 +130,7 @@ use lightning::ln::channelmanager::{self, PaymentId, RecipientOnionFields, Retry use lightning::ln::{PaymentHash, PaymentPreimage}; use lightning::sign::EntropySource; -use lightning::util::config::{ChannelConfig, ChannelHandshakeConfig, UserConfig}; +use lightning::util::config::{ChannelHandshakeConfig, UserConfig}; pub use lightning::util::logger::Level as LogLevel; use lightning_background_processor::process_events_async; @@ -924,7 +925,7 @@ impl Node { announced_channel: announce_channel, ..Default::default() }, - channel_config: channel_config.unwrap_or_default(), + channel_config: channel_config.unwrap_or_default().into(), ..Default::default() }; @@ -1028,10 +1029,10 @@ impl Node { /// Update the config for a previously opened channel. pub fn update_channel_config( &self, channel_id: &ChannelId, counterparty_node_id: PublicKey, - channel_config: &ChannelConfig, + channel_config: ChannelConfig, ) -> Result<(), Error> { self.channel_manager - .update_channel_config(&counterparty_node_id, &[channel_id.0], channel_config) + .update_channel_config(&counterparty_node_id, &[channel_id.0], &channel_config.into()) .map_err(|_| Error::ChannelConfigUpdateFailed) } diff --git a/src/test/functional_tests.rs b/src/test/functional_tests.rs index c59a0d33f..cbb847e5d 100644 --- a/src/test/functional_tests.rs +++ b/src/test/functional_tests.rs @@ -137,7 +137,7 @@ fn do_channel_full_cycle( }; println!("\nB receive_payment"); - let invoice_amount_1_msat = 1000000; + let invoice_amount_1_msat = 2500_000; let invoice = node_b.receive_payment(invoice_amount_1_msat, &"asdf", 9217).unwrap(); println!("\nA send_payment"); @@ -181,7 +181,7 @@ fn do_channel_full_cycle( assert_eq!(node_b.payment(&payment_hash).unwrap().amount_msat, Some(invoice_amount_1_msat)); // Test under-/overpayment - let invoice_amount_2_msat = 1000_000; + let invoice_amount_2_msat = 2500_000; let invoice = node_b.receive_payment(invoice_amount_2_msat, &"asdf", 9217).unwrap(); let underpaid_amount = invoice_amount_2_msat - 1; @@ -214,7 +214,7 @@ fn do_channel_full_cycle( // Test "zero-amount" invoice payment let variable_amount_invoice = node_b.receive_variable_amount_payment(&"asdf", 9217).unwrap(); - let determined_amount_msat = 1234_567; + let determined_amount_msat = 2345_678; assert_eq!(Err(Error::InvalidInvoice), node_a.send_payment(&variable_amount_invoice)); let payment_hash = node_a.send_payment_using_amount(&variable_amount_invoice, determined_amount_msat).unwrap(); diff --git a/src/types.rs b/src/types.rs index 298c9421e..e5df1a45b 100644 --- a/src/types.rs +++ b/src/types.rs @@ -11,8 +11,9 @@ use lightning::routing::router::DefaultRouter; use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters}; use lightning::sign::InMemorySigner; use lightning::util::ser::{Hostname, Readable, Writeable, Writer}; -use lightning_net_tokio::SocketDescriptor; -use lightning_transaction_sync::EsploraSyncClient; +use lightning::util::config::ChannelConfig as LdkChannelConfig; +use lightning::util::config::MaxDustHTLCExposure as LdkMaxDustHTLCExposure; +use lightning_net_tokio::SocketDescriptor; use lightning_transaction_sync::EsploraSyncClient; use bitcoin::secp256k1::PublicKey; use bitcoin::OutPoint; @@ -393,3 +394,68 @@ impl Readable for NetAddress { Ok(Self(addr)) } } + +/// Options which apply on a per-channel basis. +pub struct ChannelConfig { + /// See documentation of [`LdkChannelConfig::forwarding_fee_proportional_millionths`]. + pub forwarding_fee_proportional_millionths: u32, + /// See documentation of [`LdkChannelConfig::forwarding_fee_base_msat`]. + pub forwarding_fee_base_msat: u32, + /// See documentation of [`LdkChannelConfig::cltv_expiry_delta`]. + pub cltv_expiry_delta: u16, + /// See documentation of [`LdkChannelConfig::max_dust_htlc_exposure`]. + pub max_dust_htlc_exposure: Arc, + /// See documentation of [`LdkChannelConfig::force_close_avoidance_max_fee_satoshis`]. + pub force_close_avoidance_max_fee_satoshis: u64, + /// See documentation of [`LdkChannelConfig::accept_underpaying_htlcs`]. + pub accept_underpaying_htlcs: bool, +} + +impl From for ChannelConfig { + fn from(value: LdkChannelConfig) -> Self { + Self { + forwarding_fee_proportional_millionths: value.forwarding_fee_proportional_millionths, + forwarding_fee_base_msat: value.forwarding_fee_base_msat, + cltv_expiry_delta: value.cltv_expiry_delta, + max_dust_htlc_exposure: Arc::new(MaxDustHTLCExposure(value.max_dust_htlc_exposure)), + force_close_avoidance_max_fee_satoshis: value.force_close_avoidance_max_fee_satoshis, + accept_underpaying_htlcs: value.accept_underpaying_htlcs, + } + } +} + +impl From for LdkChannelConfig { + fn from(value: ChannelConfig) -> Self { + Self { + forwarding_fee_proportional_millionths: value.forwarding_fee_proportional_millionths, + forwarding_fee_base_msat: value.forwarding_fee_base_msat, + cltv_expiry_delta: value.cltv_expiry_delta, + max_dust_htlc_exposure: value.max_dust_htlc_exposure.0.clone(), + force_close_avoidance_max_fee_satoshis: value.force_close_avoidance_max_fee_satoshis, + accept_underpaying_htlcs: value.accept_underpaying_htlcs, + } + } +} + +impl Default for ChannelConfig { + fn default() -> Self { + LdkChannelConfig::default().into() + } +} + +/// Options for how to set the max dust HTLC exposure allowed on a channel. +/// +/// See documentation of [`LdkMaxDustHTLCExposure`] for details. +pub struct MaxDustHTLCExposure (pub LdkMaxDustHTLCExposure); + +impl MaxDustHTLCExposure { + /// See documentation of [`LdkMaxDustHTLCExposure::FixedLimitMsat`] for details. + pub fn from_fixed_limit(limit_msat: u64) -> Self { + Self ( LdkMaxDustHTLCExposure::FixedLimitMsat(limit_msat) ) + } + + /// See documentation of [`LdkMaxDustHTLCExposure::FeeRateMultiplier`] for details. + pub fn from_fee_multiplier(multiplier: u64) -> Self { + Self ( LdkMaxDustHTLCExposure::FeeRateMultiplier(multiplier) ) + } +}