@@ -193,13 +193,16 @@ pub(crate) struct HTLCPreviousHopData {
193
193
// Note that this may be an outbound SCID alias for the associated channel.
194
194
short_channel_id: u64,
195
195
user_channel_id: Option<u128>,
196
- htlc_id: u64,
196
+ pub(crate) htlc_id: u64,
197
197
incoming_packet_shared_secret: [u8; 32],
198
198
phantom_shared_secret: Option<[u8; 32]>,
199
199
200
200
// This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
201
201
// channel with a preimage provided by the forward channel.
202
202
outpoint: OutPoint,
203
+ /// Used to preserve our backwards channel by failing back in case an HTLC claim in the forward
204
+ /// channel remains unconfirmed for too long.
205
+ pub(crate) cltv_expiry: Option<u32>,
203
206
}
204
207
205
208
enum OnionPayload {
@@ -3821,14 +3824,15 @@ where
3821
3824
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
3822
3825
})?;
3823
3826
3824
- if let PendingHTLCRouting::Forward { short_channel_id, .. } = payment.forward_info.routing {
3827
+ if let PendingHTLCRouting::Forward { short_channel_id, incoming_cltv_expiry, .. } = payment.forward_info.routing {
3825
3828
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
3826
3829
short_channel_id: payment.prev_short_channel_id,
3827
3830
user_channel_id: Some(payment.prev_user_channel_id),
3828
3831
outpoint: payment.prev_funding_outpoint,
3829
3832
htlc_id: payment.prev_htlc_id,
3830
3833
incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
3831
3834
phantom_shared_secret: None,
3835
+ cltv_expiry: incoming_cltv_expiry,
3832
3836
});
3833
3837
3834
3838
let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -3866,6 +3870,7 @@ where
3866
3870
outgoing_cltv_value, ..
3867
3871
}
3868
3872
}) => {
3873
+ let cltv_expiry = routing.incoming_cltv_expiry();
3869
3874
macro_rules! failure_handler {
3870
3875
($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr, $next_hop_unknown: expr) => {
3871
3876
log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
@@ -3877,6 +3882,7 @@ where
3877
3882
htlc_id: prev_htlc_id,
3878
3883
incoming_packet_shared_secret: incoming_shared_secret,
3879
3884
phantom_shared_secret: $phantom_ss,
3885
+ cltv_expiry,
3880
3886
});
3881
3887
3882
3888
let reason = if $next_hop_unknown {
@@ -3980,7 +3986,7 @@ where
3980
3986
prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
3981
3987
forward_info: PendingHTLCInfo {
3982
3988
incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value,
3983
- routing: PendingHTLCRouting::Forward { onion_packet, .. },
3989
+ routing: PendingHTLCRouting::Forward { onion_packet, incoming_cltv_expiry, .. },
3984
3990
skimmed_fee_msat, ..
3985
3991
},
3986
3992
}) => {
@@ -3993,6 +3999,7 @@ where
3993
3999
incoming_packet_shared_secret: incoming_shared_secret,
3994
4000
// Phantom payments are only PendingHTLCRouting::Receive.
3995
4001
phantom_shared_secret: None,
4002
+ cltv_expiry: incoming_cltv_expiry,
3996
4003
});
3997
4004
if let Err(e) = chan.get_mut().queue_add_htlc(outgoing_amt_msat,
3998
4005
payment_hash, outgoing_cltv_value, htlc_source.clone(),
@@ -4074,6 +4081,7 @@ where
4074
4081
htlc_id: prev_htlc_id,
4075
4082
incoming_packet_shared_secret: incoming_shared_secret,
4076
4083
phantom_shared_secret,
4084
+ cltv_expiry: Some(cltv_expiry),
4077
4085
},
4078
4086
// We differentiate the received value from the sender intended value
4079
4087
// if possible so that we don't prematurely mark MPP payments complete
@@ -4104,6 +4112,7 @@ where
4104
4112
htlc_id: $htlc.prev_hop.htlc_id,
4105
4113
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
4106
4114
phantom_shared_secret,
4115
+ cltv_expiry: Some(cltv_expiry),
4107
4116
}), payment_hash,
4108
4117
HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
4109
4118
HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -6113,6 +6122,7 @@ where
6113
6122
htlc_id: prev_htlc_id,
6114
6123
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
6115
6124
phantom_shared_secret: None,
6125
+ cltv_expiry: forward_info.routing.incoming_cltv_expiry(),
6116
6126
});
6117
6127
6118
6128
failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -7242,6 +7252,7 @@ where
7242
7252
incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
7243
7253
phantom_shared_secret: None,
7244
7254
outpoint: htlc.prev_funding_outpoint,
7255
+ cltv_expiry: htlc.forward_info.routing.incoming_cltv_expiry(),
7245
7256
});
7246
7257
7247
7258
let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -8053,6 +8064,7 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
8053
8064
(0, short_channel_id, required),
8054
8065
(1, phantom_shared_secret, option),
8055
8066
(2, outpoint, required),
8067
+ (3, cltv_expiry, option),
8056
8068
(4, htlc_id, required),
8057
8069
(6, incoming_packet_shared_secret, required),
8058
8070
(7, user_channel_id, option),
0 commit comments