diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index 72935f153ea..c1c7c0be7a1 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -270,6 +270,8 @@ pub fn do_test(data: &[u8], out: Out) { inbound_htlc_maximum_msat: None, config: None, feerate_sat_per_1000_weight: None, + incoming_htlc_stats: None, + outgoing_htlc_stats: None, }); } Some(&first_hops_vec[..]) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 8cb73241562..c64b4bface5 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -27,7 +27,7 @@ use crate::ln::features::{ChannelTypeFeatures, InitFeatures}; use crate::ln::msgs; use crate::ln::msgs::DecodeError; use crate::ln::script::{self, ShutdownScript}; -use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, SentHTLCId, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT}; +use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCStats, SentHTLCId, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT}; use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, htlc_success_tx_weight, htlc_timeout_tx_weight, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction}; use crate::ln::chan_utils; use crate::ln::onion_utils::HTLCFailReason; @@ -347,16 +347,6 @@ enum HTLCInitiator { RemoteOffered, } -/// An enum gathering stats on pending HTLCs, either inbound or outbound side. -struct HTLCStats { - pending_htlcs: u32, - pending_htlcs_value_msat: u64, - on_counterparty_tx_dust_exposure_msat: u64, - on_holder_tx_dust_exposure_msat: u64, - holding_cell_msat: u64, - on_holder_tx_holding_cell_htlcs_count: u32, // dust HTLCs *non*-included -} - /// An enum gathering stats on commitment transaction, either local or remote. struct CommitmentStats<'a> { tx: CommitmentTransaction, // the transaction info @@ -2621,7 +2611,7 @@ impl Channel { } /// Returns a HTLCStats about inbound pending htlcs - fn get_inbound_pending_htlc_stats(&self, outbound_feerate_update: Option) -> HTLCStats { + pub(super) fn get_inbound_pending_htlc_stats(&self, outbound_feerate_update: Option) -> HTLCStats { let mut stats = HTLCStats { pending_htlcs: self.pending_inbound_htlcs.len() as u32, pending_htlcs_value_msat: 0, @@ -2653,7 +2643,7 @@ impl Channel { } /// Returns a HTLCStats about pending outbound htlcs, *including* pending adds in our holding cell. - fn get_outbound_pending_htlc_stats(&self, outbound_feerate_update: Option) -> HTLCStats { + pub(super) fn get_outbound_pending_htlc_stats(&self, outbound_feerate_update: Option) -> HTLCStats { let mut stats = HTLCStats { pending_htlcs: self.pending_outbound_htlcs.len() as u32, pending_htlcs_value_msat: 0, diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 7c065f1ba44..4bb00f6ed03 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1272,6 +1272,39 @@ pub struct ChannelCounterparty { pub outbound_htlc_maximum_msat: Option, } +/// An enum gathering stats on pending HTLCs, either inbound or outbound side. +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct HTLCStats { + /// The number of pending HTLCs. + pub pending_htlcs: u32, + /// The total value of pending HTLCs. + pub pending_htlcs_value_msat: u64, + /// The total dust exposure for the counterparty. + pub on_counterparty_tx_dust_exposure_msat: u64, + /// The total dust exposure for the local node. + pub on_holder_tx_dust_exposure_msat: u64, + /// The total value of pending, outgoing HTLCs being held. + /// + /// These HTLCs are being held temporarily after sending commitment_signed to discern them + /// from HTLCs implicitly included in the counterparty's revoke_and_ack. + pub holding_cell_msat: u64, + /// The number of pending, outgoing HTLCs being added that are being held, + /// dust HTLCS not included. + /// + /// These HTLCs are being held temporarily after sending commitment_signed to discern them + /// from HTLCs implicitly included in the counterparty's revoke_and_ack. + pub on_holder_tx_holding_cell_htlcs_count: u32, +} + +impl_writeable_tlv_based!(HTLCStats, { + (0, pending_htlcs, required), + (2, pending_htlcs_value_msat, required), + (4, on_counterparty_tx_dust_exposure_msat, required), + (6, on_holder_tx_dust_exposure_msat, required), + (8, holding_cell_msat, required), + (10, on_holder_tx_holding_cell_htlcs_count, required), +}); + /// Details of a channel, as returned by [`ChannelManager::list_channels`] and [`ChannelManager::list_usable_channels`] #[derive(Clone, Debug, PartialEq)] pub struct ChannelDetails { @@ -1443,6 +1476,14 @@ pub struct ChannelDetails { /// /// This field is only `None` for `ChannelDetails` objects serialized prior to LDK 0.0.109. pub config: Option, + /// Statistics on pending incoming HTLCs. + /// + /// This field is only `None` for `ChannelDetails` objects serialized prior to LDK 0.0.116. + pub incoming_htlc_stats: Option, + /// Statistics on pending outgoing HTLCs. + /// + /// This field is only `None` for `ChannelDetails` objects serialized prior to LDK 0.0.116. + pub outgoing_htlc_stats: Option, } impl ChannelDetails { @@ -1514,6 +1555,8 @@ impl ChannelDetails { inbound_htlc_minimum_msat: Some(channel.get_holder_htlc_minimum_msat()), inbound_htlc_maximum_msat: channel.get_holder_htlc_maximum_msat(), config: Some(channel.config()), + incoming_htlc_stats: Some(channel.get_inbound_pending_htlc_stats(None)), + outgoing_htlc_stats: Some(channel.get_outbound_pending_htlc_stats(None)), } } } @@ -7156,6 +7199,8 @@ impl Writeable for ChannelDetails { (35, self.inbound_htlc_maximum_msat, option), (37, user_channel_id_high_opt, option), (39, self.feerate_sat_per_1000_weight, option), + (41, self.incoming_htlc_stats, option), + (43, self.outgoing_htlc_stats, option), }); Ok(()) } @@ -7193,6 +7238,8 @@ impl Readable for ChannelDetails { (35, inbound_htlc_maximum_msat, option), (37, user_channel_id_high_opt, option), (39, feerate_sat_per_1000_weight, option), + (40, incoming_htlc_stats, option), + (41, outgoing_htlc_stats, option), }); // `user_channel_id` used to be a single u64 value. In order to remain backwards compatible with @@ -7228,6 +7275,8 @@ impl Readable for ChannelDetails { inbound_htlc_minimum_msat, inbound_htlc_maximum_msat, feerate_sat_per_1000_weight, + incoming_htlc_stats, + outgoing_htlc_stats, }) } } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index f7ed173b901..a4855c2b6e1 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -2512,7 +2512,9 @@ mod tests { inbound_htlc_minimum_msat: None, inbound_htlc_maximum_msat: None, config: None, - feerate_sat_per_1000_weight: None + feerate_sat_per_1000_weight: None, + incoming_htlc_stats: None, + outgoing_htlc_stats: None, } } @@ -6299,6 +6301,8 @@ pub(crate) mod bench_utils { inbound_htlc_maximum_msat: None, config: None, feerate_sat_per_1000_weight: None, + incoming_htlc_stats: None, + outgoing_htlc_stats: None, } }