@@ -240,17 +240,6 @@ impl InboundHTLCState {
240240 _ => None,
241241 }
242242 }
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- }
254243}
255244
256245struct InboundHTLCOutput {
@@ -353,17 +342,6 @@ impl OutboundHTLCState {
353342 _ => None,
354343 }
355344 }
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- }
367345}
368346
369347#[derive(Clone)]
@@ -974,10 +952,10 @@ struct HTLCStats {
974952}
975953
976954/// A struct gathering data on a commitment, either local or remote.
977- struct CommitmentData<'a> {
955+ struct CommitmentData {
978956 tx: CommitmentTransaction,
979957 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
981959 outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
982960 inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
983961}
@@ -3604,7 +3582,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36043582 }
36053583 bitcoin_tx.txid
36063584 };
3607- let mut htlcs_cloned: Vec<_> = commitment_data.htlcs_included.iter().map(|htlc| (htlc.0.clone(), htlc.1.map(|h| h.clone()))).collect();
36083585
36093586 // If our counterparty updated the channel fee in this commitment transaction, check that
36103587 // they can actually afford the new fee now.
@@ -3655,10 +3632,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36553632 separate_nondust_htlc_sources = rand_val % 2 == 0;
36563633 }
36573634
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());
36603637 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() {
36623639 if let Some(_) = htlc.transaction_output_index {
36633640 let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_data.tx.feerate_per_kw(),
36643641 funding.get_counterparty_selected_contest_delay().unwrap(), &htlc, &self.channel_type,
@@ -3674,14 +3651,14 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36743651 return Err(ChannelError::close("Invalid HTLC tx signature from peer".to_owned()));
36753652 }
36763653 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) ));
36783655 }
36793656 } else {
3680- htlcs_and_sigs.push((htlc, None, source_opt.take()));
3657+ htlcs_and_sigs.push((htlc, None, source_opt.take().map(|source| *source) ));
36813658 }
36823659 if separate_nondust_htlc_sources {
36833660 if let Some(source) = source_opt.take() {
3684- nondust_htlc_sources.push(source);
3661+ nondust_htlc_sources.push(* source);
36853662 }
36863663 }
36873664 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 {
37053682 })
37063683 }
37073684
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+
37083715 /// Generates stats on a potential commitment transaction build, without actually building the
37093716 /// commitment transaction. See `build_commitment_transaction` for further docs.
37103717 #[inline]
@@ -3745,37 +3752,32 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
37453752 }
37463753 }
37473754
3748- for ref htlc in self.pending_inbound_htlcs.iter() {
3749- if htlc.state.included_in_commitment(generated_by_local) {
3755+ self.for_each_inbound(generated_by_local, |included: bool, htlc: &InboundHTLCOutput| {
3756+ if included {
37503757 count_nondust_htlc!(htlc, false);
37513758 remote_htlc_total_msat += htlc.amount_msat;
37523759 } else {
37533760 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;
37593763 }
37603764 }
3761- }
3765+ });
37623766
3763- for ref htlc in self.pending_outbound_htlcs.iter() {
3764- if htlc.state.included_in_commitment(generated_by_local) {
3767+ self.for_each_outbound(generated_by_local, |included: bool, htlc: &OutboundHTLCOutput| {
3768+ if included {
37653769 count_nondust_htlc!(htlc, true);
37663770 local_htlc_total_msat += htlc.amount_msat;
37673771 } else {
37683772 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(_)) |
3773+ if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) |
37713774 OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) |
3772- OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(_)) => {
3773- value_to_self_msat_offset -= htlc.amount_msat as i64;
3774- },
3775- _ => {},
3775+ OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(_))
3776+ = htlc.state {
3777+ value_to_self_msat_offset -= htlc.amount_msat as i64;
37763778 }
37773779 }
3778- }
3780+ });
37793781
37803782 // # Panics
37813783 //
@@ -3844,9 +3846,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38443846 remote_balance_before_fee_anchors_msat
38453847 } = stats;
38463848
3847- let mut included_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<& HTLCSource>)> = Vec::new();
3849+ let mut included_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<Box< HTLCSource> >)> = Vec::new();
38483850 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);
3851+ let mut included_non_dust_htlcs: Vec<(HTLCOutputInCommitment, Option<Box< HTLCSource> >)> = Vec::with_capacity(num_htlcs);
38503852
38513853 log_trace!(logger, "Building commitment transaction number {} (really {} xor {}) for channel {} for {}, generated by {} with fee {}...",
38523854 commitment_number, (INITIAL_COMMITMENT_NUMBER - commitment_number),
@@ -3880,30 +3882,30 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38803882 }
38813883
38823884 let mut inbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3885+ let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
38833886
3884- for ref htlc in self.pending_inbound_htlcs.iter() {
3885- if htlc.state.included_in_commitment(generated_by_local) {
3887+ self.for_each_inbound(generated_by_local, |included: bool, htlc: &InboundHTLCOutput| {
3888+ if included {
38863889 add_htlc_output!(htlc, false, None);
38873890 } else {
38883891 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());
38893892 if let Some(preimage) = htlc.state.preimage() {
38903893 inbound_htlc_preimages.push(preimage);
38913894 }
38923895 }
3893- }
3894-
3895- let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3896+ });
38963897
3897- for ref htlc in self.pending_outbound_htlcs.iter() {
3898+ self.for_each_outbound(generated_by_local, |included: bool, htlc: &OutboundHTLCOutput| {
38983899 if let Some(preimage) = htlc.state.preimage() {
38993900 outbound_htlc_preimages.push(preimage);
39003901 }
3901- if htlc.state.included_in_commitment(generated_by_local) {
3902- add_htlc_output!(htlc, true, Some(&htlc.source));
3902+ if included {
3903+ // We box the source here because borrowed data cannot escape a closure
3904+ add_htlc_output!(htlc, true, Some(Box::new(htlc.source.clone())));
39033905 } else {
39043906 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());
39053907 }
3906- }
3908+ });
39073909
39083910 // We MUST use saturating subs here, as the funder's balance is not guaranteed to be greater
39093911 // than or equal to the sum of `total_fee_sat` and `total_anchors_sat`.
@@ -8814,11 +8816,9 @@ impl<SP: Deref> FundedChannel<SP> where
88148816 }
88158817 self.context.resend_order = RAACommitmentOrder::RevokeAndACKFirst;
88168818
8817- let (mut htlcs_ref , counterparty_commitment_tx) =
8819+ let (htlcs , counterparty_commitment_tx) =
88188820 self.build_commitment_no_state_update(logger);
88198821 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();
88228822
88238823 if self.context.announcement_sigs_state == AnnouncementSigsState::MessageSent {
88248824 self.context.announcement_sigs_state = AnnouncementSigsState::Committed;
@@ -8845,7 +8845,7 @@ impl<SP: Deref> FundedChannel<SP> where
88458845 }
88468846
88478847 fn build_commitment_no_state_update<L: Deref>(&self, logger: &L)
8848- -> (Vec<(HTLCOutputInCommitment, Option<& HTLCSource>)>, CommitmentTransaction)
8848+ -> (Vec<(HTLCOutputInCommitment, Option<Box< HTLCSource> >)>, CommitmentTransaction)
88498849 where L::Target: Logger
88508850 {
88518851 let commitment_data = self.context.build_commitment_transaction(&self.funding,
0 commit comments