@@ -223,6 +223,36 @@ impl From<&InboundHTLCState> for Option<InboundHTLCStateDetails> {
223223 }
224224}
225225
226+ impl InboundHTLCState {
227+ fn str(&self) -> &str {
228+ match self {
229+ InboundHTLCState::RemoteAnnounced(_) => "RemoteAnnounced",
230+ InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => "AwaitingRemoteRevokeToAnnounce",
231+ InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => "AwaitingAnnouncedRemoteRevoke",
232+ InboundHTLCState::Committed => "Committed",
233+ InboundHTLCState::LocalRemoved(_) => "LocalRemoved",
234+ }
235+ }
236+
237+ fn preimage(&self) -> Option<PaymentPreimage> {
238+ match self {
239+ InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(preimage)) => Some(*preimage),
240+ _ => None,
241+ }
242+ }
243+
244+ // Determines whether a HTLC is present on a commitment transaction, either as a dust or non-dust HTLC
245+ fn is_present(&self, generated_by_local: bool) -> bool {
246+ match self {
247+ InboundHTLCState::RemoteAnnounced(_) => !generated_by_local,
248+ InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => !generated_by_local,
249+ InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => true,
250+ InboundHTLCState::Committed => true,
251+ InboundHTLCState::LocalRemoved(_) => !generated_by_local,
252+ }
253+ }
254+ }
255+
226256struct InboundHTLCOutput {
227257 htlc_id: u64,
228258 amount_msat: u64,
@@ -231,6 +261,26 @@ struct InboundHTLCOutput {
231261 state: InboundHTLCState,
232262}
233263
264+ impl InboundHTLCOutput {
265+ fn is_nondust(&self, local: bool, feerate_per_kw: u32, broadcaster_dust_limit_sat: u64, features: &ChannelTypeFeatures) -> bool {
266+ let htlc_tx_fee = if features.supports_anchors_zero_fee_htlc_tx() {
267+ 0
268+ } else {
269+ feerate_per_kw as u64 * if !local {
270+ // this is an offered htlc
271+ htlc_timeout_tx_weight(features)
272+ } else {
273+ htlc_success_tx_weight(features)
274+ } / 1000
275+ };
276+ if self.amount_msat / 1000 >= broadcaster_dust_limit_sat + htlc_tx_fee {
277+ true
278+ } else {
279+ false
280+ }
281+ }
282+ }
283+
234284#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
235285enum OutboundHTLCState {
236286 /// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we
@@ -287,6 +337,38 @@ impl From<&OutboundHTLCState> for OutboundHTLCStateDetails {
287337 }
288338}
289339
340+ impl OutboundHTLCState {
341+ fn str(&self) -> &str {
342+ match self {
343+ OutboundHTLCState::LocalAnnounced(_) => "LocalAnnounced",
344+ OutboundHTLCState::Committed => "Committed",
345+ OutboundHTLCState::RemoteRemoved(_) => "RemoteRemoved",
346+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => "AwaitingRemoteRevokeToRemove",
347+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => "AwaitingRemovedRemoteRevoke",
348+ }
349+ }
350+
351+ fn preimage(&self) -> Option<PaymentPreimage> {
352+ match self {
353+ OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(p)) => p.as_ref().copied(),
354+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(p)) => p.as_ref().copied(),
355+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(p)) => p.as_ref().copied(),
356+ _ => None,
357+ }
358+ }
359+
360+ // Determines whether a HTLC is present on a commitment transaction, either as a dust or non-dust HTLC
361+ fn is_present(&self, generated_by_local: bool) -> bool {
362+ match self {
363+ OutboundHTLCState::LocalAnnounced(_) => generated_by_local,
364+ OutboundHTLCState::Committed => true,
365+ OutboundHTLCState::RemoteRemoved(_) => generated_by_local,
366+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => generated_by_local,
367+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => false,
368+ }
369+ }
370+ }
371+
290372#[derive(Clone)]
291373#[cfg_attr(test, derive(Debug, PartialEq))]
292374enum OutboundHTLCOutcome {
@@ -325,6 +407,26 @@ struct OutboundHTLCOutput {
325407 skimmed_fee_msat: Option<u64>,
326408}
327409
410+ impl OutboundHTLCOutput {
411+ fn is_nondust(&self, local: bool, feerate_per_kw: u32, broadcaster_dust_limit_sat: u64, features: &ChannelTypeFeatures) -> bool {
412+ let htlc_tx_fee = if features.supports_anchors_zero_fee_htlc_tx() {
413+ 0
414+ } else {
415+ feerate_per_kw as u64 * if local {
416+ // this is an offered htlc
417+ htlc_timeout_tx_weight(features)
418+ } else {
419+ htlc_success_tx_weight(features)
420+ } / 1000
421+ };
422+ if self.amount_msat / 1000 >= broadcaster_dust_limit_sat + htlc_tx_fee {
423+ true
424+ } else {
425+ false
426+ }
427+ }
428+ }
429+
328430/// See AwaitingRemoteRevoke ChannelState for more info
329431#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
330432enum HTLCUpdateAwaitingACK {
@@ -3639,40 +3741,22 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36393741 if local { "us" } else { "remote" }, if generated_by_local { "us" } else { "remote" }, feerate_per_kw);
36403742
36413743 macro_rules! count_nondust_htlc {
3642- ($htlc: expr, $outbound: expr, $state_name: expr) => {
3643- let offered = $outbound == local;
3644- let htlc_tx_fee = if self.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
3645- 0
3646- } else {
3647- feerate_per_kw as u64 * if offered {
3648- htlc_timeout_tx_weight(self.get_channel_type())
3649- } else {
3650- htlc_success_tx_weight(self.get_channel_type())
3651- } / 1000
3652- };
3653- if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_sat + htlc_tx_fee {
3654- log_trace!(logger, " ...counting {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
3744+ ($htlc: expr, $outbound: expr) => {
3745+ if $htlc.is_nondust(local, feerate_per_kw, broadcaster_dust_limit_sat, self.get_channel_type()) {
3746+ log_trace!(logger, " ...counting {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $htlc.state.str(), $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
36553747 non_dust_htlc_count += 1;
36563748 } else {
3657- log_trace!(logger, " ...not counting {} {} dust HTLC {} (hash {}) with value {} due to dust limit", if $outbound { "outbound" } else { "inbound" }, $state_name , $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
3749+ log_trace!(logger, " ...not counting {} {} dust HTLC {} (hash {}) with value {} due to dust limit", if $outbound { "outbound" } else { "inbound" }, $htlc.state.str() , $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
36583750 }
36593751 }
36603752 }
36613753
36623754 for ref htlc in self.pending_inbound_htlcs.iter() {
3663- let (include, state_name) = match htlc.state {
3664- InboundHTLCState::RemoteAnnounced(_) => (!generated_by_local, "RemoteAnnounced"),
3665- InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => (!generated_by_local, "AwaitingRemoteRevokeToAnnounce"),
3666- InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => (true, "AwaitingAnnouncedRemoteRevoke"),
3667- InboundHTLCState::Committed => (true, "Committed"),
3668- InboundHTLCState::LocalRemoved(_) => (!generated_by_local, "LocalRemoved"),
3669- };
3670-
3671- if include {
3672- count_nondust_htlc!(htlc, false, state_name);
3755+ if htlc.state.is_present(generated_by_local) {
3756+ count_nondust_htlc!(htlc, false);
36733757 remote_htlc_total_msat += htlc.amount_msat;
36743758 } else {
3675- log_trace!(logger, " ...not counting inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, state_name );
3759+ log_trace!(logger, " ...not counting inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, htlc.state.str() );
36763760 match &htlc.state {
36773761 &InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(_preimage)) => {
36783762 value_to_self_msat_offset += htlc.amount_msat as i64;
@@ -3683,19 +3767,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36833767 }
36843768
36853769 for ref htlc in self.pending_outbound_htlcs.iter() {
3686- let (include, state_name) = match htlc.state {
3687- OutboundHTLCState::LocalAnnounced(_) => (generated_by_local, "LocalAnnounced"),
3688- OutboundHTLCState::Committed => (true, "Committed"),
3689- OutboundHTLCState::RemoteRemoved(_) => (generated_by_local, "RemoteRemoved"),
3690- OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => (generated_by_local, "AwaitingRemoteRevokeToRemove"),
3691- OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => (false, "AwaitingRemovedRemoteRevoke"),
3692- };
3693-
3694- if include {
3695- count_nondust_htlc!(htlc, true, state_name);
3770+ if htlc.state.is_present(generated_by_local) {
3771+ count_nondust_htlc!(htlc, true);
36963772 local_htlc_total_msat += htlc.amount_msat;
36973773 } else {
3698- log_trace!(logger, " ...not counting outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, state_name );
3774+ log_trace!(logger, " ...not counting outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, htlc.state.str() );
36993775 match htlc.state {
37003776 OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) |
37013777 OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) |
@@ -3797,23 +3873,13 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
37973873 }
37983874
37993875 macro_rules! add_htlc_output {
3800- ($htlc: expr, $outbound: expr, $source: expr, $state_name: expr) => {
3801- let offered = $outbound == local;
3802- let htlc_in_tx = get_htlc_in_commitment!($htlc, offered);
3803- let htlc_tx_fee = if self.get_channel_type().supports_anchors_zero_fee_htlc_tx() {
3804- 0
3805- } else {
3806- feerate_per_kw as u64 * if offered {
3807- htlc_timeout_tx_weight(self.get_channel_type())
3808- } else {
3809- htlc_success_tx_weight(self.get_channel_type())
3810- } / 1000
3811- };
3812- if $htlc.amount_msat / 1000 >= broadcaster_dust_limit_sat + htlc_tx_fee {
3813- log_trace!(logger, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $state_name, $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
3876+ ($htlc: expr, $outbound: expr, $source: expr) => {
3877+ let htlc_in_tx = get_htlc_in_commitment!($htlc, $outbound == local);
3878+ if $htlc.is_nondust(local, feerate_per_kw, broadcaster_dust_limit_sat, self.get_channel_type()) {
3879+ log_trace!(logger, " ...including {} {} HTLC {} (hash {}) with value {}", if $outbound { "outbound" } else { "inbound" }, $htlc.state.str(), $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
38143880 included_non_dust_htlcs.push((htlc_in_tx, $source));
38153881 } else {
3816- log_trace!(logger, " ...including {} {} dust HTLC {} (hash {}) with value {} due to dust limit", if $outbound { "outbound" } else { "inbound" }, $state_name , $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
3882+ log_trace!(logger, " ...including {} {} dust HTLC {} (hash {}) with value {} due to dust limit", if $outbound { "outbound" } else { "inbound" }, $htlc.state.str() , $htlc.htlc_id, &$htlc.payment_hash, $htlc.amount_msat);
38173883 included_dust_htlcs.push((htlc_in_tx, $source));
38183884 }
38193885 }
@@ -3822,53 +3888,26 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38223888 let mut inbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
38233889
38243890 for ref htlc in self.pending_inbound_htlcs.iter() {
3825- let (include, state_name) = match htlc.state {
3826- InboundHTLCState::RemoteAnnounced(_) => (!generated_by_local, "RemoteAnnounced"),
3827- InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => (!generated_by_local, "AwaitingRemoteRevokeToAnnounce"),
3828- InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => (true, "AwaitingAnnouncedRemoteRevoke"),
3829- InboundHTLCState::Committed => (true, "Committed"),
3830- InboundHTLCState::LocalRemoved(_) => (!generated_by_local, "LocalRemoved"),
3831- };
3832-
3833- if include {
3834- add_htlc_output!(htlc, false, None, state_name);
3891+ if htlc.state.is_present(generated_by_local) {
3892+ add_htlc_output!(htlc, false, None);
38353893 } else {
3836- log_trace!(logger, " ...not including inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, state_name);
3837- match &htlc.state {
3838- &InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(preimage)) => {
3839- inbound_htlc_preimages.push(preimage);
3840- },
3841- _ => {},
3894+ log_trace!(logger, " ...not including inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, htlc.state.str());
3895+ if let Some(preimage) = htlc.state.preimage() {
3896+ inbound_htlc_preimages.push(preimage);
38423897 }
38433898 }
38443899 }
38453900
38463901 let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
38473902
38483903 for ref htlc in self.pending_outbound_htlcs.iter() {
3849- let (include, state_name) = match htlc.state {
3850- OutboundHTLCState::LocalAnnounced(_) => (generated_by_local, "LocalAnnounced"),
3851- OutboundHTLCState::Committed => (true, "Committed"),
3852- OutboundHTLCState::RemoteRemoved(_) => (generated_by_local, "RemoteRemoved"),
3853- OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => (generated_by_local, "AwaitingRemoteRevokeToRemove"),
3854- OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => (false, "AwaitingRemovedRemoteRevoke"),
3855- };
3856-
3857- let preimage_opt = match htlc.state {
3858- OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(p)) => p,
3859- OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(p)) => p,
3860- OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(p)) => p,
3861- _ => None,
3862- };
3863-
3864- if let Some(preimage) = preimage_opt {
3904+ if let Some(preimage) = htlc.state.preimage() {
38653905 outbound_htlc_preimages.push(preimage);
38663906 }
3867-
3868- if include {
3869- add_htlc_output!(htlc, true, Some(&htlc.source), state_name);
3907+ if htlc.state.is_present(generated_by_local) {
3908+ add_htlc_output!(htlc, true, Some(&htlc.source));
38703909 } else {
3871- log_trace!(logger, " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, state_name );
3910+ log_trace!(logger, " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, &htlc.payment_hash, htlc.amount_msat, htlc.state.str() );
38723911 }
38733912 }
38743913
0 commit comments