@@ -125,6 +125,16 @@ pub(super) enum PendingHTLCRouting {
125
125
},
126
126
}
127
127
128
+ impl PendingHTLCRouting {
129
+ fn incoming_cltv_expiry(&self) -> Option<u32> {
130
+ match self {
131
+ Self::Forward { incoming_cltv_expiry, .. } => *incoming_cltv_expiry,
132
+ Self::Receive { incoming_cltv_expiry, .. } => Some(*incoming_cltv_expiry),
133
+ Self::ReceiveKeysend { incoming_cltv_expiry, .. } => Some(*incoming_cltv_expiry),
134
+ }
135
+ }
136
+ }
137
+
128
138
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
129
139
pub(super) struct PendingHTLCInfo {
130
140
pub(super) routing: PendingHTLCRouting,
@@ -189,6 +199,9 @@ pub(crate) struct HTLCPreviousHopData {
189
199
// This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
190
200
// channel with a preimage provided by the forward channel.
191
201
outpoint: OutPoint,
202
+ /// Used to preserve our backwards channel by failing back in case an HTLC claim in the forward
203
+ /// channel remains unconfirmed for too long.
204
+ pub(crate) cltv_expiry: Option<u32>,
192
205
}
193
206
194
207
enum OnionPayload {
@@ -3746,13 +3759,14 @@ where
3746
3759
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
3747
3760
})?;
3748
3761
3749
- if let PendingHTLCRouting::Forward { short_channel_id, .. } = payment.forward_info.routing {
3762
+ if let PendingHTLCRouting::Forward { short_channel_id, incoming_cltv_expiry, .. } = payment.forward_info.routing {
3750
3763
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
3751
3764
short_channel_id: payment.prev_short_channel_id,
3752
3765
outpoint: payment.prev_funding_outpoint,
3753
3766
htlc_id: payment.prev_htlc_id,
3754
3767
incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
3755
3768
phantom_shared_secret: None,
3769
+ cltv_expiry: incoming_cltv_expiry,
3756
3770
});
3757
3771
3758
3772
let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -3790,6 +3804,7 @@ where
3790
3804
outgoing_cltv_value, ..
3791
3805
}
3792
3806
}) => {
3807
+ let cltv_expiry = routing.incoming_cltv_expiry();
3793
3808
macro_rules! failure_handler {
3794
3809
($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr, $next_hop_unknown: expr) => {
3795
3810
log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
@@ -3800,6 +3815,7 @@ where
3800
3815
htlc_id: prev_htlc_id,
3801
3816
incoming_packet_shared_secret: incoming_shared_secret,
3802
3817
phantom_shared_secret: $phantom_ss,
3818
+ cltv_expiry,
3803
3819
});
3804
3820
3805
3821
let reason = if $next_hop_unknown {
@@ -3903,7 +3919,8 @@ where
3903
3919
prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id: _,
3904
3920
forward_info: PendingHTLCInfo {
3905
3921
incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value,
3906
- routing: PendingHTLCRouting::Forward { onion_packet, .. }, skimmed_fee_msat, ..
3922
+ routing: PendingHTLCRouting::Forward { onion_packet, incoming_cltv_expiry, .. },
3923
+ skimmed_fee_msat, ..
3907
3924
},
3908
3925
}) => {
3909
3926
log_trace!(self.logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", prev_short_channel_id, log_bytes!(payment_hash.0), short_chan_id);
@@ -3914,6 +3931,7 @@ where
3914
3931
incoming_packet_shared_secret: incoming_shared_secret,
3915
3932
// Phantom payments are only PendingHTLCRouting::Receive.
3916
3933
phantom_shared_secret: None,
3934
+ cltv_expiry: incoming_cltv_expiry,
3917
3935
});
3918
3936
if let Err(e) = chan.get_mut().queue_add_htlc(outgoing_amt_msat,
3919
3937
payment_hash, outgoing_cltv_value, htlc_source.clone(),
@@ -3994,6 +4012,7 @@ where
3994
4012
htlc_id: prev_htlc_id,
3995
4013
incoming_packet_shared_secret: incoming_shared_secret,
3996
4014
phantom_shared_secret,
4015
+ cltv_expiry: Some(cltv_expiry),
3997
4016
},
3998
4017
// We differentiate the received value from the sender intended value
3999
4018
// if possible so that we don't prematurely mark MPP payments complete
@@ -4023,6 +4042,7 @@ where
4023
4042
htlc_id: $htlc.prev_hop.htlc_id,
4024
4043
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
4025
4044
phantom_shared_secret,
4045
+ cltv_expiry: Some(cltv_expiry),
4026
4046
}), payment_hash,
4027
4047
HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
4028
4048
HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -4721,7 +4741,10 @@ where
4721
4741
&self.pending_events, &self.logger)
4722
4742
{ self.push_pending_forwards_ev(); }
4723
4743
},
4724
- HTLCSource::PreviousHopData(HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint }) => {
4744
+ HTLCSource::PreviousHopData(HTLCPreviousHopData { ref short_channel_id, ref htlc_id,
4745
+ ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint,
4746
+ cltv_expiry: _,
4747
+ }) => {
4725
4748
log_trace!(self.logger, "Failing HTLC with payment_hash {} backwards from us with {:?}", log_bytes!(payment_hash.0), onion_error);
4726
4749
let err_packet = onion_error.get_encrypted_failure_packet(incoming_packet_shared_secret, phantom_shared_secret);
4727
4750
@@ -5929,6 +5952,7 @@ where
5929
5952
htlc_id: prev_htlc_id,
5930
5953
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
5931
5954
phantom_shared_secret: None,
5955
+ cltv_expiry: forward_info.routing.incoming_cltv_expiry(),
5932
5956
});
5933
5957
5934
5958
failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -7047,6 +7071,7 @@ where
7047
7071
incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
7048
7072
phantom_shared_secret: None,
7049
7073
outpoint: htlc.prev_funding_outpoint,
7074
+ cltv_expiry: htlc.forward_info.routing.incoming_cltv_expiry(),
7050
7075
});
7051
7076
7052
7077
let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -7810,6 +7835,7 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
7810
7835
(0, short_channel_id, required),
7811
7836
(1, phantom_shared_secret, option),
7812
7837
(2, outpoint, required),
7838
+ (3, cltv_expiry, option),
7813
7839
(4, htlc_id, required),
7814
7840
(6, incoming_packet_shared_secret, required)
7815
7841
});
0 commit comments