@@ -240,17 +240,6 @@ impl InboundHTLCState {
240
240
_ => None,
241
241
}
242
242
}
243
-
244
- // Determines whether a HTLC is included in a commitment transaction, either as a dust or non-dust HTLC
245
- fn included_in_commitment(&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
243
}
255
244
256
245
struct InboundHTLCOutput {
@@ -353,17 +342,6 @@ impl OutboundHTLCState {
353
342
_ => None,
354
343
}
355
344
}
356
-
357
- // Determines whether a HTLC is included in a commitment transaction, either as a dust or non-dust HTLC
358
- fn included_in_commitment(&self, generated_by_local: bool) -> bool {
359
- match self {
360
- OutboundHTLCState::LocalAnnounced(_) => generated_by_local,
361
- OutboundHTLCState::Committed => true,
362
- OutboundHTLCState::RemoteRemoved(_) => generated_by_local,
363
- OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => generated_by_local,
364
- OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => false,
365
- }
366
- }
367
345
}
368
346
369
347
#[derive(Clone)]
@@ -974,10 +952,10 @@ struct HTLCStats {
974
952
}
975
953
976
954
/// A struct gathering data on a commitment, either local or remote.
977
- struct CommitmentData<'a> {
955
+ struct CommitmentData {
978
956
tx: CommitmentTransaction,
979
957
stats: CommitmentStats,
980
- htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
958
+ htlcs_included: Vec<(HTLCOutputInCommitment, Option<Box< HTLCSource> >)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
981
959
outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
982
960
inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
983
961
}
@@ -3604,7 +3582,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3604
3582
}
3605
3583
bitcoin_tx.txid
3606
3584
};
3607
- let mut htlcs_cloned: Vec<_> = commitment_data.htlcs_included.iter().map(|htlc| (htlc.0.clone(), htlc.1.map(|h| h.clone()))).collect();
3608
3585
3609
3586
// If our counterparty updated the channel fee in this commitment transaction, check that
3610
3587
// they can actually afford the new fee now.
@@ -3655,10 +3632,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3655
3632
separate_nondust_htlc_sources = rand_val % 2 == 0;
3656
3633
}
3657
3634
3658
- let mut nondust_htlc_sources = Vec::with_capacity(htlcs_cloned .len());
3659
- let mut htlcs_and_sigs = Vec::with_capacity(htlcs_cloned .len());
3635
+ let mut nondust_htlc_sources = Vec::with_capacity(commitment_data.htlcs_included .len());
3636
+ let mut htlcs_and_sigs = Vec::with_capacity(commitment_data.htlcs_included .len());
3660
3637
let holder_keys = commitment_data.tx.trust().keys();
3661
- for (idx, (htlc, mut source_opt)) in htlcs_cloned.drain(.. ).enumerate() {
3638
+ for (idx, (htlc, mut source_opt)) in commitment_data.htlcs_included.into_iter( ).enumerate() {
3662
3639
if let Some(_) = htlc.transaction_output_index {
3663
3640
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_data.tx.feerate_per_kw(),
3664
3641
funding.get_counterparty_selected_contest_delay().unwrap(), &htlc, &self.channel_type,
@@ -3674,14 +3651,14 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3674
3651
return Err(ChannelError::close("Invalid HTLC tx signature from peer".to_owned()));
3675
3652
}
3676
3653
if !separate_nondust_htlc_sources {
3677
- htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source_opt.take()));
3654
+ htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source_opt.take().map(|source| *source) ));
3678
3655
}
3679
3656
} else {
3680
- htlcs_and_sigs.push((htlc, None, source_opt.take()));
3657
+ htlcs_and_sigs.push((htlc, None, source_opt.take().map(|source| *source) ));
3681
3658
}
3682
3659
if separate_nondust_htlc_sources {
3683
3660
if let Some(source) = source_opt.take() {
3684
- nondust_htlc_sources.push(source);
3661
+ nondust_htlc_sources.push(* source);
3685
3662
}
3686
3663
}
3687
3664
debug_assert!(source_opt.is_none(), "HTLCSource should have been put somewhere");
@@ -3705,6 +3682,36 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3705
3682
})
3706
3683
}
3707
3684
3685
+ fn for_each_inbound<F>(&self, generated_by_local: bool, mut for_each: F)
3686
+ where F: FnMut(bool, &InboundHTLCOutput)
3687
+ {
3688
+ self.pending_inbound_htlcs.iter().for_each(|htlc| {
3689
+ let included = match htlc.state {
3690
+ InboundHTLCState::RemoteAnnounced(_) => !generated_by_local,
3691
+ InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => !generated_by_local,
3692
+ InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => true,
3693
+ InboundHTLCState::Committed => true,
3694
+ InboundHTLCState::LocalRemoved(_) => !generated_by_local,
3695
+ };
3696
+ for_each(included, htlc);
3697
+ })
3698
+ }
3699
+
3700
+ fn for_each_outbound<F>(&self, generated_by_local: bool, mut for_each: F)
3701
+ where F: FnMut(bool, &OutboundHTLCOutput),
3702
+ {
3703
+ self.pending_outbound_htlcs.iter().for_each(|htlc| {
3704
+ let included = match htlc.state {
3705
+ OutboundHTLCState::LocalAnnounced(_) => generated_by_local,
3706
+ OutboundHTLCState::Committed => true,
3707
+ OutboundHTLCState::RemoteRemoved(_) => generated_by_local,
3708
+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(_) => generated_by_local,
3709
+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => false,
3710
+ };
3711
+ for_each(included, htlc);
3712
+ })
3713
+ }
3714
+
3708
3715
/// Generates stats on a potential commitment transaction build, without actually building the
3709
3716
/// commitment transaction. See `build_commitment_transaction` for further docs.
3710
3717
#[inline]
@@ -3745,37 +3752,34 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3745
3752
}
3746
3753
}
3747
3754
3748
- for ref htlc in self.pending_inbound_htlcs.iter() {
3749
- if htlc.state.included_in_commitment(generated_by_local) {
3755
+ let for_each = |included: bool, htlc: &InboundHTLCOutput| {
3756
+ if included {
3750
3757
count_nondust_htlc!(htlc, false);
3751
3758
remote_htlc_total_msat += htlc.amount_msat;
3752
3759
} else {
3753
3760
log_trace!(logger, " ...not counting inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, htlc.payment_hash, htlc.amount_msat, htlc.state.as_str());
3754
- match htlc.state {
3755
- InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(_preimage)) => {
3756
- value_to_self_msat_offset += htlc.amount_msat as i64;
3757
- },
3758
- _ => {},
3761
+ if let InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(_preimage)) = htlc.state {
3762
+ value_to_self_msat_offset += htlc.amount_msat as i64;
3759
3763
}
3760
3764
}
3761
- }
3765
+ };
3766
+ self.for_each_inbound(generated_by_local, for_each);
3762
3767
3763
- for ref htlc in self.pending_outbound_htlcs.iter() {
3764
- if htlc.state.included_in_commitment(generated_by_local) {
3768
+ let for_each = |included: bool, htlc: &OutboundHTLCOutput| {
3769
+ if included {
3765
3770
count_nondust_htlc!(htlc, true);
3766
3771
local_htlc_total_msat += htlc.amount_msat;
3767
3772
} else {
3768
3773
log_trace!(logger, " ...not counting outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, htlc.payment_hash, htlc.amount_msat, htlc.state.as_str());
3769
- match htlc.state {
3770
- OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) |
3774
+ if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) |
3771
3775
OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) |
3772
- OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(_)) => {
3773
- value_to_self_msat_offset -= htlc.amount_msat as i64;
3774
- },
3775
- _ => {},
3776
+ OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(_))
3777
+ = htlc.state {
3778
+ value_to_self_msat_offset -= htlc.amount_msat as i64;
3776
3779
}
3777
3780
}
3778
- }
3781
+ };
3782
+ self.for_each_outbound(generated_by_local, for_each);
3779
3783
3780
3784
// # Panics
3781
3785
//
@@ -3844,9 +3848,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3844
3848
remote_balance_before_fee_anchors_msat
3845
3849
} = stats;
3846
3850
3847
- let mut included_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<& HTLCSource>)> = Vec::new();
3851
+ let mut included_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<Box< HTLCSource> >)> = Vec::new();
3848
3852
let num_htlcs = self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len();
3849
- let mut included_non_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<& HTLCSource>)> = Vec::with_capacity(num_htlcs);
3853
+ let mut included_non_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<Box< HTLCSource> >)> = Vec::with_capacity(num_htlcs);
3850
3854
3851
3855
log_trace!(logger, "Building commitment transaction number {} (really {} xor {}) for channel {} for {}, generated by {} with fee {}...",
3852
3856
commitment_number, (INITIAL_COMMITMENT_NUMBER - commitment_number),
@@ -3880,30 +3884,32 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3880
3884
}
3881
3885
3882
3886
let mut inbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3887
+ let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3883
3888
3884
- for ref htlc in self.pending_inbound_htlcs.iter() {
3885
- if htlc.state.included_in_commitment(generated_by_local) {
3889
+ let for_each = |included: bool, htlc: &InboundHTLCOutput| {
3890
+ if included {
3886
3891
add_htlc_output!(htlc, false, None);
3887
3892
} else {
3888
3893
log_trace!(logger, " ...not including inbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, htlc.payment_hash, htlc.amount_msat, htlc.state.as_str());
3889
3894
if let Some(preimage) = htlc.state.preimage() {
3890
3895
inbound_htlc_preimages.push(preimage);
3891
3896
}
3892
3897
}
3893
- }
3894
-
3895
- let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3898
+ };
3899
+ self.for_each_inbound(generated_by_local, for_each);
3896
3900
3897
- for ref htlc in self.pending_outbound_htlcs.iter() {
3901
+ let for_each = |included: bool, htlc: &OutboundHTLCOutput| {
3898
3902
if let Some(preimage) = htlc.state.preimage() {
3899
3903
outbound_htlc_preimages.push(preimage);
3900
3904
}
3901
- if htlc.state.included_in_commitment(generated_by_local) {
3902
- add_htlc_output!(htlc, true, Some(&htlc.source));
3905
+ if included {
3906
+ // We box the source here because borrowed data cannot escape a closure
3907
+ add_htlc_output!(htlc, true, Some(Box::new(htlc.source.clone())));
3903
3908
} else {
3904
3909
log_trace!(logger, " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})", htlc.htlc_id, htlc.payment_hash, htlc.amount_msat, htlc.state.as_str());
3905
3910
}
3906
- }
3911
+ };
3912
+ self.for_each_outbound(generated_by_local, for_each);
3907
3913
3908
3914
// We MUST use saturating subs here, as the funder's balance is not guaranteed to be greater
3909
3915
// than or equal to the sum of `total_fee_sat` and `total_anchors_sat`.
@@ -8814,11 +8820,9 @@ impl<SP: Deref> FundedChannel<SP> where
8814
8820
}
8815
8821
self.context.resend_order = RAACommitmentOrder::RevokeAndACKFirst;
8816
8822
8817
- let (mut htlcs_ref , counterparty_commitment_tx) =
8823
+ let (htlcs , counterparty_commitment_tx) =
8818
8824
self.build_commitment_no_state_update(logger);
8819
8825
let counterparty_commitment_txid = counterparty_commitment_tx.trust().txid();
8820
- let htlcs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)> =
8821
- htlcs_ref.drain(..).map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))).collect();
8822
8826
8823
8827
if self.context.announcement_sigs_state == AnnouncementSigsState::MessageSent {
8824
8828
self.context.announcement_sigs_state = AnnouncementSigsState::Committed;
@@ -8845,7 +8849,7 @@ impl<SP: Deref> FundedChannel<SP> where
8845
8849
}
8846
8850
8847
8851
fn build_commitment_no_state_update<L: Deref>(&self, logger: &L)
8848
- -> (Vec<(HTLCOutputInCommitment, Option<& HTLCSource>)>, CommitmentTransaction)
8852
+ -> (Vec<(HTLCOutputInCommitment, Option<Box< HTLCSource> >)>, CommitmentTransaction)
8849
8853
where L::Target: Logger
8850
8854
{
8851
8855
let commitment_data = self.context.build_commitment_transaction(&self.funding,
0 commit comments