Skip to content

Commit 2fcbcf7

Browse files
committed
Add cltv expiry to PendingHTLCRouting::Forward
1 parent ccbaba9 commit 2fcbcf7

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ pub(super) enum PendingHTLCRouting {
104104
/// The SCID from the onion that we should forward to. This could be a real SCID or a fake one
105105
/// generated using `get_fake_scid` from the scid_utils::fake_scid module.
106106
short_channel_id: u64, // This should be NonZero<u64> eventually when we bump MSRV
107+
incoming_cltv_expiry: Option<u32>,
107108
},
108109
Receive {
109110
payment_data: msgs::FinalOnionHopData,
@@ -124,6 +125,16 @@ pub(super) enum PendingHTLCRouting {
124125
},
125126
}
126127

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+
127138
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
128139
pub(super) struct PendingHTLCInfo {
129140
pub(super) routing: PendingHTLCRouting,
@@ -182,13 +193,16 @@ pub(crate) struct HTLCPreviousHopData {
182193
// Note that this may be an outbound SCID alias for the associated channel.
183194
short_channel_id: u64,
184195
user_channel_id: Option<u128>,
185-
htlc_id: u64,
196+
pub(crate) htlc_id: u64,
186197
incoming_packet_shared_secret: [u8; 32],
187198
phantom_shared_secret: Option<[u8; 32]>,
188199

189200
// This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards
190201
// channel with a preimage provided by the forward channel.
191202
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>,
192206
}
193207

194208
enum OnionPayload {
@@ -2742,6 +2756,7 @@ where
27422756
routing: PendingHTLCRouting::Forward {
27432757
onion_packet: outgoing_packet,
27442758
short_channel_id,
2759+
incoming_cltv_expiry: Some(msg.cltv_expiry),
27452760
},
27462761
payment_hash: msg.payment_hash,
27472762
incoming_shared_secret: shared_secret,
@@ -3771,8 +3786,9 @@ where
37713786
})?;
37723787

37733788
let routing = match payment.forward_info.routing {
3774-
PendingHTLCRouting::Forward { onion_packet, .. } => {
3775-
PendingHTLCRouting::Forward { onion_packet, short_channel_id: next_hop_scid }
3789+
PendingHTLCRouting::Forward { onion_packet, incoming_cltv_expiry, .. } => {
3790+
PendingHTLCRouting::Forward { onion_packet, short_channel_id: next_hop_scid,
3791+
incoming_cltv_expiry }
37763792
},
37773793
_ => unreachable!() // Only `PendingHTLCRouting::Forward`s are intercepted
37783794
};
@@ -3808,14 +3824,15 @@ where
38083824
err: format!("Payment with intercept id {} not found", log_bytes!(intercept_id.0))
38093825
})?;
38103826

3811-
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 {
38123828
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
38133829
short_channel_id: payment.prev_short_channel_id,
38143830
user_channel_id: Some(payment.prev_user_channel_id),
38153831
outpoint: payment.prev_funding_outpoint,
38163832
htlc_id: payment.prev_htlc_id,
38173833
incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
38183834
phantom_shared_secret: None,
3835+
cltv_expiry: incoming_cltv_expiry,
38193836
});
38203837

38213838
let failure_reason = HTLCFailReason::from_failure_code(0x4000 | 10);
@@ -3853,6 +3870,7 @@ where
38533870
outgoing_cltv_value, ..
38543871
}
38553872
}) => {
3873+
let cltv_expiry = routing.incoming_cltv_expiry();
38563874
macro_rules! failure_handler {
38573875
($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr, $next_hop_unknown: expr) => {
38583876
log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
@@ -3864,6 +3882,7 @@ where
38643882
htlc_id: prev_htlc_id,
38653883
incoming_packet_shared_secret: incoming_shared_secret,
38663884
phantom_shared_secret: $phantom_ss,
3885+
cltv_expiry,
38673886
});
38683887

38693888
let reason = if $next_hop_unknown {
@@ -3967,7 +3986,8 @@ where
39673986
prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
39683987
forward_info: PendingHTLCInfo {
39693988
incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value,
3970-
routing: PendingHTLCRouting::Forward { onion_packet, .. }, skimmed_fee_msat, ..
3989+
routing: PendingHTLCRouting::Forward { onion_packet, incoming_cltv_expiry, .. },
3990+
skimmed_fee_msat, ..
39713991
},
39723992
}) => {
39733993
log_trace!(self.logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", prev_short_channel_id, &payment_hash, short_chan_id);
@@ -3979,6 +3999,7 @@ where
39793999
incoming_packet_shared_secret: incoming_shared_secret,
39804000
// Phantom payments are only PendingHTLCRouting::Receive.
39814001
phantom_shared_secret: None,
4002+
cltv_expiry: incoming_cltv_expiry,
39824003
});
39834004
if let Err(e) = chan.get_mut().queue_add_htlc(outgoing_amt_msat,
39844005
payment_hash, outgoing_cltv_value, htlc_source.clone(),
@@ -4060,6 +4081,7 @@ where
40604081
htlc_id: prev_htlc_id,
40614082
incoming_packet_shared_secret: incoming_shared_secret,
40624083
phantom_shared_secret,
4084+
cltv_expiry: Some(cltv_expiry),
40634085
},
40644086
// We differentiate the received value from the sender intended value
40654087
// if possible so that we don't prematurely mark MPP payments complete
@@ -4090,6 +4112,7 @@ where
40904112
htlc_id: $htlc.prev_hop.htlc_id,
40914113
incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
40924114
phantom_shared_secret,
4115+
cltv_expiry: Some(cltv_expiry),
40934116
}), payment_hash,
40944117
HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data),
40954118
HTLCDestination::FailedPayment { payment_hash: $payment_hash },
@@ -6099,6 +6122,7 @@ where
60996122
htlc_id: prev_htlc_id,
61006123
incoming_packet_shared_secret: forward_info.incoming_shared_secret,
61016124
phantom_shared_secret: None,
6125+
cltv_expiry: forward_info.routing.incoming_cltv_expiry(),
61026126
});
61036127

61046128
failed_intercept_forwards.push((htlc_source, forward_info.payment_hash,
@@ -7228,6 +7252,7 @@ where
72287252
incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
72297253
phantom_shared_secret: None,
72307254
outpoint: htlc.prev_funding_outpoint,
7255+
cltv_expiry: htlc.forward_info.routing.incoming_cltv_expiry(),
72317256
});
72327257

72337258
let requested_forward_scid /* intercept scid */ = match htlc.forward_info.routing {
@@ -7933,6 +7958,7 @@ impl_writeable_tlv_based!(PhantomRouteHints, {
79337958
impl_writeable_tlv_based_enum!(PendingHTLCRouting,
79347959
(0, Forward) => {
79357960
(0, onion_packet, required),
7961+
(1, incoming_cltv_expiry, option),
79367962
(2, short_channel_id, required),
79377963
},
79387964
(1, Receive) => {
@@ -8038,6 +8064,7 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
80388064
(0, short_channel_id, required),
80398065
(1, phantom_shared_secret, option),
80408066
(2, outpoint, required),
8067+
(3, cltv_expiry, option),
80418068
(4, htlc_id, required),
80428069
(6, incoming_packet_shared_secret, required),
80438070
(7, user_channel_id, option),

0 commit comments

Comments
 (0)