ln/refactor: pass minimum delta into check_incoming_htlc_cltv
What changed, and why it matters
This commit is a code refactor that prepares for future 'trampoline' Lightning payments. It changes an internal CLTV (timelock) check so the caller can specify a minimum time delta, instead of always using a hardcoded minimum. The commit itself does not enable trampoline payments or change live behavior; it only adds flexibility for a future feature. There is no direct evidence this fixes an active security bug.
No immediate action required. Treat as routine refactor. When the future trampoline feature is reviewed, ensure the zero-delta path does not weaken timelock protections or allow incoming HTLCs to expire too early relative to outgoing HTLCs.
Security signals we found
CLTV/timelock validation logic touched
Refactor enables future zero-delta path for trampoline payments
No change to current enforcement value at existing call sites
No vendor security disclosure or CVE referenced
Evidence from the diff
The change modifies check_incoming_htlc_cltv() in onion_payment.rs to accept a min_cltv_expiry_delta parameter rather than always adding MIN_CLTV_EXPIRY_DELTA. Both current call sites in channelmanager.rs and onion_payment.rs pass MIN_CLTV_EXPIRY_DELTA, so the runtime behavior is unchanged. The purpose stated in the commit message is to allow a zero delta for trampoline payments where the delta will be derived from an inner trampoline onion. This is a preparatory refactor, not a functional security patch.
Changed components
lightning/src/ln/onion_payment.rslightning/src/ln/channelmanager.rsInspect captured patch +9 / −5
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index 9da8e1f..a3c33b8 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -5203,8 +5203,12 @@ impl<
};
let cur_height = self.best_block.read().unwrap().height + 1;
- check_incoming_htlc_cltv(cur_height, next_hop.outgoing_cltv_value, msg.cltv_expiry)?;
-
+ check_incoming_htlc_cltv(
+ cur_height,
+ next_hop.outgoing_cltv_value,
+ msg.cltv_expiry,
+ MIN_CLTV_EXPIRY_DELTA,
+ )?;
Ok(intercept)
}
diff --git a/lightning/src/ln/onion_payment.rs b/lightning/src/ln/onion_payment.rs
index bb5b8f2..615c357 100644
--- a/lightning/src/ln/onion_payment.rs
+++ b/lightning/src/ln/onion_payment.rs
@@ -515,7 +515,7 @@ pub fn peel_payment_onion<NS: NodeSigner, L: Logger, T: secp256k1::Verification>
};
if let Err(reason) = check_incoming_htlc_cltv(
- cur_height, outgoing_cltv_value, msg.cltv_expiry,
+ cur_height, outgoing_cltv_value, msg.cltv_expiry, MIN_CLTV_EXPIRY_DELTA,
) {
return Err(InboundHTLCErr {
msg: "incoming cltv check failed",
@@ -719,9 +719,9 @@ pub(super) fn decode_incoming_update_add_htlc_onion<NS: NodeSigner, L: Logger, T
}
pub(super) fn check_incoming_htlc_cltv(
- cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32,
+ cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32, min_cltv_expiry_delta: u16,
) -> Result<(), LocalHTLCFailureReason> {
- if (cltv_expiry as u64) < (outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 {
+ if (cltv_expiry as u64) < (outgoing_cltv_value) as u64 + min_cltv_expiry_delta as u64 {
return Err(LocalHTLCFailureReason::IncorrectCLTVExpiry);
}
// Theoretically, channel counterparty shouldn't send us a HTLC expiring now,
Why this scored 29/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.