Skip to content

Commit 5956bc1

Browse files
committed
Provide non-dust HTLC sources separately for holder commitment updates
Currently, non-dust HTLCs are duplicated across the commitment transaction itself, and the full set of HTLCs (dust & non-dust) along with their `HTLCSource` considered in the commitment transaction. As of v0.0.15, we've had support for providing non-dust HTLC sources separately such that we no longer track duplicate non-dust HTLC data, but only enabled it under testing environments. This commit enables it such that it always happens. Note that we still need to support reading `ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo` updates that did not separate the non-dust HTLC sources in case they were written in an older version and they've yet to be processed.
1 parent 8b47754 commit 5956bc1

File tree

2 files changed

+13
-26
lines changed

2 files changed

+13
-26
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,9 @@ pub(crate) enum ChannelMonitorUpdateStep {
531531
/// Note that LDK after 0.0.115 supports this only containing dust HTLCs (implying the
532532
/// `Signature` field is never filled in). At that point, non-dust HTLCs are implied by the
533533
/// HTLC fields in `commitment_tx` and the sources passed via `nondust_htlc_sources`.
534+
/// Starting with 0.2, the non-dust HTLC sources will always be provided separately, and
535+
/// `htlc_outputs` will only include dust HTLCs. We still have to track the
536+
/// `Option<Signature>` for backwards compatibility.
534537
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
535538
claimed_htlcs: Vec<(SentHTLCId, PaymentPreimage)>,
536539
nondust_htlc_sources: Vec<HTLCSource>,

lightning/src/ln/channel.rs

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3531,23 +3531,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
35313531
return Err(ChannelError::close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), commitment_stats.num_nondust_htlcs)));
35323532
}
35333533

3534-
// Up to LDK 0.0.115, HTLC information was required to be duplicated in the
3535-
// `htlcs_and_sigs` vec and in the `holder_commitment_tx` itself, both of which were passed
3536-
// in the `ChannelMonitorUpdate`. In 0.0.115, support for having a separate set of
3537-
// outbound-non-dust-HTLCSources in the `ChannelMonitorUpdate` was added, however for
3538-
// backwards compatibility, we never use it in production. To provide test coverage, here,
3539-
// we randomly decide (in test/fuzzing builds) to use the new vec sometimes.
3540-
#[allow(unused_assignments, unused_mut)]
3541-
let mut separate_nondust_htlc_sources = false;
3542-
#[cfg(all(feature = "std", any(test, fuzzing)))] {
3543-
use core::hash::{BuildHasher, Hasher};
3544-
// Get a random value using the only std API to do so - the DefaultHasher
3545-
let rand_val = std::collections::hash_map::RandomState::new().build_hasher().finish();
3546-
separate_nondust_htlc_sources = rand_val % 2 == 0;
3547-
}
3548-
3549-
let mut nondust_htlc_sources = Vec::with_capacity(htlcs_cloned.len());
3550-
let mut htlcs_and_sigs = Vec::with_capacity(htlcs_cloned.len());
3534+
let mut nondust_htlc_sources = Vec::with_capacity(commitment_stats.num_nondust_htlcs);
3535+
let mut dust_htlcs = Vec::with_capacity(htlcs_cloned.len() - commitment_stats.num_nondust_htlcs);
35513536
for (idx, (htlc, mut source_opt)) in htlcs_cloned.drain(..).enumerate() {
35523537
if let Some(_) = htlc.transaction_output_index {
35533538
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_stats.feerate_per_kw,
@@ -3563,16 +3548,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
35633548
if let Err(_) = self.secp_ctx.verify_ecdsa(&htlc_sighash, &msg.htlc_signatures[idx], &keys.countersignatory_htlc_key.to_public_key()) {
35643549
return Err(ChannelError::close("Invalid HTLC tx signature from peer".to_owned()));
35653550
}
3566-
if !separate_nondust_htlc_sources {
3567-
htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source_opt.take()));
3551+
if htlc.offered {
3552+
if let Some(source) = source_opt.take() {
3553+
nondust_htlc_sources.push(source);
3554+
} else {
3555+
debug_assert!(false, "Missing outbound HTLC source");
3556+
}
35683557
}
35693558
} else {
3570-
htlcs_and_sigs.push((htlc, None, source_opt.take()));
3571-
}
3572-
if separate_nondust_htlc_sources {
3573-
if let Some(source) = source_opt.take() {
3574-
nondust_htlc_sources.push(source);
3575-
}
3559+
dust_htlcs.push((htlc, None, source_opt.take()));
35763560
}
35773561
debug_assert!(source_opt.is_none(), "HTLCSource should have been put somewhere");
35783562
}
@@ -3590,7 +3574,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
35903574

35913575
Ok(LatestHolderCommitmentTXInfo {
35923576
commitment_tx: holder_commitment_tx,
3593-
htlc_outputs: htlcs_and_sigs,
3577+
htlc_outputs: dust_htlcs,
35943578
nondust_htlc_sources,
35953579
})
35963580
}

0 commit comments

Comments
 (0)