Skip to content

Commit 18ef702

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 030a784 commit 18ef702

File tree

2 files changed

+13
-26
lines changed

2 files changed

+13
-26
lines changed

lightning/src/chain/channelmonitor.rs

+3
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

+10-26
Original file line numberDiff line numberDiff line change
@@ -3541,24 +3541,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
35413541
return Err(ChannelError::close(format!("Got wrong number of HTLC signatures ({}) from remote. It must be {}", msg.htlc_signatures.len(), commitment_data.stats.tx.htlcs().len())));
35423542
}
35433543

3544-
// Up to LDK 0.0.115, HTLC information was required to be duplicated in the
3545-
// `htlcs_and_sigs` vec and in the `holder_commitment_tx` itself, both of which were passed
3546-
// in the `ChannelMonitorUpdate`. In 0.0.115, support for having a separate set of
3547-
// outbound-non-dust-HTLCSources in the `ChannelMonitorUpdate` was added, however for
3548-
// backwards compatibility, we never use it in production. To provide test coverage, here,
3549-
// we randomly decide (in test/fuzzing builds) to use the new vec sometimes.
3550-
#[allow(unused_assignments, unused_mut)]
3551-
let mut separate_nondust_htlc_sources = false;
3552-
#[cfg(all(feature = "std", any(test, fuzzing)))] {
3553-
use core::hash::{BuildHasher, Hasher};
3554-
// Get a random value using the only std API to do so - the DefaultHasher
3555-
let rand_val = std::collections::hash_map::RandomState::new().build_hasher().finish();
3556-
separate_nondust_htlc_sources = rand_val % 2 == 0;
3557-
}
3558-
3559-
let mut nondust_htlc_sources = Vec::with_capacity(htlcs_cloned.len());
3560-
let mut htlcs_and_sigs = Vec::with_capacity(htlcs_cloned.len());
35613544
let holder_keys = commitment_data.stats.tx.trust().keys();
3545+
let mut nondust_htlc_sources = Vec::with_capacity(commitment_data.stats.tx.htlcs().len());
3546+
let mut dust_htlcs = Vec::with_capacity(htlcs_cloned.len() - commitment_data.stats.tx.htlcs().len());
35623547
for (idx, (htlc, mut source_opt)) in htlcs_cloned.drain(..).enumerate() {
35633548
if let Some(_) = htlc.transaction_output_index {
35643549
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_data.stats.tx.feerate_per_kw(),
@@ -3574,16 +3559,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
35743559
if let Err(_) = self.secp_ctx.verify_ecdsa(&htlc_sighash, &msg.htlc_signatures[idx], &holder_keys.countersignatory_htlc_key.to_public_key()) {
35753560
return Err(ChannelError::close("Invalid HTLC tx signature from peer".to_owned()));
35763561
}
3577-
if !separate_nondust_htlc_sources {
3578-
htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source_opt.take()));
3562+
if htlc.offered {
3563+
if let Some(source) = source_opt.take() {
3564+
nondust_htlc_sources.push(source);
3565+
} else {
3566+
panic!("Missing outbound HTLC source");
3567+
}
35793568
}
35803569
} else {
3581-
htlcs_and_sigs.push((htlc, None, source_opt.take()));
3582-
}
3583-
if separate_nondust_htlc_sources {
3584-
if let Some(source) = source_opt.take() {
3585-
nondust_htlc_sources.push(source);
3586-
}
3570+
dust_htlcs.push((htlc, None, source_opt.take()));
35873571
}
35883572
debug_assert!(source_opt.is_none(), "HTLCSource should have been put somewhere");
35893573
}
@@ -3601,7 +3585,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36013585

36023586
Ok(LatestHolderCommitmentTXInfo {
36033587
commitment_tx: holder_commitment_tx,
3604-
htlc_outputs: htlcs_and_sigs,
3588+
htlc_outputs: dust_htlcs,
36053589
nondust_htlc_sources,
36063590
})
36073591
}

0 commit comments

Comments
 (0)