Skip to content

Commit 5a212d8

Browse files
committed
Add ChannelContext::for_each_{inbound, outbound}
These functions sort included from excluded htlcs based on their state, and run the passed closure on each sorted htlc.
1 parent ea4eecf commit 5a212d8

File tree

1 file changed

+67
-63
lines changed

1 file changed

+67
-63
lines changed

lightning/src/ln/channel.rs

+67-63
Original file line numberDiff line numberDiff line change
@@ -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

256245
struct 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,34 @@ 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+
let for_each = |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+
};
3766+
self.for_each_inbound(generated_by_local, for_each);
37623767

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 {
37653770
count_nondust_htlc!(htlc, true);
37663771
local_htlc_total_msat += htlc.amount_msat;
37673772
} else {
37683773
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(_)) |
37713775
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;
37763779
}
37773780
}
3778-
}
3781+
};
3782+
self.for_each_outbound(generated_by_local, for_each);
37793783

37803784
// # Panics
37813785
//
@@ -3844,9 +3848,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38443848
remote_balance_before_fee_anchors_msat
38453849
} = stats;
38463850

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();
38483852
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);
38503854

38513855
log_trace!(logger, "Building commitment transaction number {} (really {} xor {}) for channel {} for {}, generated by {} with fee {}...",
38523856
commitment_number, (INITIAL_COMMITMENT_NUMBER - commitment_number),
@@ -3880,30 +3884,32 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38803884
}
38813885

38823886
let mut inbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3887+
let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
38833888

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 {
38863891
add_htlc_output!(htlc, false, None);
38873892
} else {
38883893
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());
38893894
if let Some(preimage) = htlc.state.preimage() {
38903895
inbound_htlc_preimages.push(preimage);
38913896
}
38923897
}
3893-
}
3894-
3895-
let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
3898+
};
3899+
self.for_each_inbound(generated_by_local, for_each);
38963900

3897-
for ref htlc in self.pending_outbound_htlcs.iter() {
3901+
let for_each = |included: bool, htlc: &OutboundHTLCOutput| {
38983902
if let Some(preimage) = htlc.state.preimage() {
38993903
outbound_htlc_preimages.push(preimage);
39003904
}
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())));
39033908
} else {
39043909
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());
39053910
}
3906-
}
3911+
};
3912+
self.for_each_outbound(generated_by_local, for_each);
39073913

39083914
// We MUST use saturating subs here, as the funder's balance is not guaranteed to be greater
39093915
// than or equal to the sum of `total_fee_sat` and `total_anchors_sat`.
@@ -8814,11 +8820,9 @@ impl<SP: Deref> FundedChannel<SP> where
88148820
}
88158821
self.context.resend_order = RAACommitmentOrder::RevokeAndACKFirst;
88168822

8817-
let (mut htlcs_ref, counterparty_commitment_tx) =
8823+
let (htlcs, counterparty_commitment_tx) =
88188824
self.build_commitment_no_state_update(logger);
88198825
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();
88228826

88238827
if self.context.announcement_sigs_state == AnnouncementSigsState::MessageSent {
88248828
self.context.announcement_sigs_state = AnnouncementSigsState::Committed;
@@ -8845,7 +8849,7 @@ impl<SP: Deref> FundedChannel<SP> where
88458849
}
88468850

88478851
fn build_commitment_no_state_update<L: Deref>(&self, logger: &L)
8848-
-> (Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>, CommitmentTransaction)
8852+
-> (Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>, CommitmentTransaction)
88498853
where L::Target: Logger
88508854
{
88518855
let commitment_data = self.context.build_commitment_transaction(&self.funding,

0 commit comments

Comments
 (0)