Skip to content

Commit efec4b9

Browse files
committed
fix(cch): enhance outgoing payment expiry calculation using actual invoice terms
1 parent 84f9344 commit efec4b9

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

crates/fiber-lib/src/cch/actions/send_outgoing_payment.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ impl SendOutgoingPaymentDispatcher {
235235
/// The other half is reserved for the CCH to settle the incoming payment
236236
/// after receiving the preimage.
237237
///
238+
/// The final expiry delta is extracted from the stored incoming invoice when
239+
/// available, so that persisted orders use the actual inbound HTLC/TLC terms
240+
/// even if the config has changed since order creation. Falls back to the
241+
/// current config values when the invoice does not carry the setting.
242+
///
238243
/// Returns `None` if there is insufficient time remaining.
239244
fn compute_max_outgoing_expiry_seconds<S: CchOrderStore>(
240245
state: &CchState<S>,
@@ -248,9 +253,21 @@ impl SendOutgoingPaymentDispatcher {
248253

249254
// The incoming TLC/HTLC was accepted with at least this many seconds of expiry.
250255
// Using `created_at` is conservative (the TLC was accepted after order creation).
256+
//
257+
// Prefer the final expiry delta encoded in the stored incoming invoice so
258+
// that persisted orders are checked against their actual terms, not values
259+
// that may have drifted if the config was updated between restart.
251260
let incoming_expiry_seconds = match &order.incoming_invoice {
252-
CchInvoice::Fiber(_) => state.config.ckb_final_tlc_expiry_delta_seconds,
253-
CchInvoice::Lightning(_) => state.config.btc_final_tlc_expiry_delta_blocks * 600,
261+
CchInvoice::Fiber(inv) => {
262+
// CkbInvoice stores the delta in milliseconds; convert to seconds.
263+
inv.final_tlc_minimum_expiry_delta()
264+
.map(|ms| ms / 1000)
265+
.unwrap_or(state.config.ckb_final_tlc_expiry_delta_seconds)
266+
}
267+
CchInvoice::Lightning(inv) => {
268+
// Bolt11Invoice stores the delta in blocks; convert to seconds.
269+
inv.min_final_cltv_expiry_delta().saturating_mul(600)
270+
}
254271
};
255272
let remaining = incoming_expiry_seconds.checked_sub(elapsed)?;
256273

0 commit comments

Comments
 (0)