@@ -223,6 +223,36 @@ impl From<&InboundHTLCState> for Option<InboundHTLCStateDetails> {
223
223
}
224
224
}
225
225
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
+
226
256
struct InboundHTLCOutput {
227
257
htlc_id: u64,
228
258
amount_msat: u64,
@@ -231,6 +261,26 @@ struct InboundHTLCOutput {
231
261
state: InboundHTLCState,
232
262
}
233
263
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
+
234
284
#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
235
285
enum OutboundHTLCState {
236
286
/// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we
@@ -287,6 +337,38 @@ impl From<&OutboundHTLCState> for OutboundHTLCStateDetails {
287
337
}
288
338
}
289
339
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
+
290
372
#[derive(Clone)]
291
373
#[cfg_attr(test, derive(Debug, PartialEq))]
292
374
enum OutboundHTLCOutcome {
@@ -325,6 +407,26 @@ struct OutboundHTLCOutput {
325
407
skimmed_fee_msat: Option<u64>,
326
408
}
327
409
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
+
328
430
/// See AwaitingRemoteRevoke ChannelState for more info
329
431
#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
330
432
enum HTLCUpdateAwaitingACK {
@@ -3639,40 +3741,22 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3639
3741
if local { "us" } else { "remote" }, if generated_by_local { "us" } else { "remote" }, feerate_per_kw);
3640
3742
3641
3743
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);
3655
3747
non_dust_htlc_count += 1;
3656
3748
} 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);
3658
3750
}
3659
3751
}
3660
3752
}
3661
3753
3662
3754
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);
3673
3757
remote_htlc_total_msat += htlc.amount_msat;
3674
3758
} 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() );
3676
3760
match &htlc.state {
3677
3761
&InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(_preimage)) => {
3678
3762
value_to_self_msat_offset += htlc.amount_msat as i64;
@@ -3683,19 +3767,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3683
3767
}
3684
3768
3685
3769
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);
3696
3772
local_htlc_total_msat += htlc.amount_msat;
3697
3773
} 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() );
3699
3775
match htlc.state {
3700
3776
OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) |
3701
3777
OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) |
@@ -3797,23 +3873,13 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3797
3873
}
3798
3874
3799
3875
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);
3814
3880
included_non_dust_htlcs.push((htlc_in_tx, $source));
3815
3881
} 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);
3817
3883
included_dust_htlcs.push((htlc_in_tx, $source));
3818
3884
}
3819
3885
}
@@ -3822,53 +3888,26 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3822
3888
let mut inbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3823
3889
3824
3890
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);
3835
3893
} 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);
3842
3897
}
3843
3898
}
3844
3899
}
3845
3900
3846
3901
let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3847
3902
3848
3903
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() {
3865
3905
outbound_htlc_preimages.push(preimage);
3866
3906
}
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));
3870
3909
} 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() );
3872
3911
}
3873
3912
}
3874
3913
0 commit comments