@@ -136,7 +136,7 @@ pub enum PendingHTLCRouting {
136
136
payment_data: Option<msgs::FinalOnionHopData>,
137
137
/// Preimage for this onion payment.
138
138
payment_preimage: PaymentPreimage,
139
- /// Metadata associated with this payment .
139
+ /// See [`RecipientOnionFields::payment_metadata`] for more info .
140
140
payment_metadata: Option<Vec<u8>>,
141
141
/// CLTV expiry of the incoming HTLC.
142
142
incoming_cltv_expiry: u32, // Used to track when we should expire pending HTLCs that go unclaimed
@@ -3030,10 +3030,16 @@ where
3030
3030
3031
3031
let cur_height = self.best_block.read().unwrap().height() + 1;
3032
3032
3033
- if let Err((err_msg, code, include_chan_update_opt )) = check_incoming_htlc_cltv(
3033
+ if let Err((err_msg, code)) = check_incoming_htlc_cltv(
3034
3034
cur_height, outgoing_cltv_value, msg.cltv_expiry
3035
3035
) {
3036
- let chan_update_opt = if include_chan_update_opt { chan_update_opt } else { None };
3036
+ if code & 0x1000 != 0 && chan_update_opt.is_none() {
3037
+ // We really should set `incorrect_cltv_expiry` here but as we're not
3038
+ // forwarding over a real channel we can't generate a channel_update
3039
+ // for it. Instead we just return a generic temporary_node_failure.
3040
+ break Some((err_msg, 0x2000 | 2, None))
3041
+ }
3042
+ let chan_update_opt = if code & 0x1000 != 0 { chan_update_opt } else { None };
3037
3043
break Some((err_msg, code, chan_update_opt));
3038
3044
}
3039
3045
@@ -7892,7 +7898,7 @@ where
7892
7898
}),
7893
7899
};
7894
7900
7895
- if let Err((err_msg, code, _ )) = check_incoming_htlc_cltv(
7901
+ if let Err((err_msg, code)) = check_incoming_htlc_cltv(
7896
7902
cur_height, outgoing_cltv_value, msg.cltv_expiry
7897
7903
) {
7898
7904
return Err(InboundOnionErr {
@@ -7924,9 +7930,7 @@ struct NextPacketDetails {
7924
7930
7925
7931
fn decode_incoming_update_add_htlc_onion<NS: Deref, L: Deref, T: secp256k1::Verification>(
7926
7932
msg: &msgs::UpdateAddHTLC, node_signer: &NS, logger: &L, secp_ctx: &Secp256k1<T>,
7927
- ) -> Result<(
7928
- onion_utils::Hop, [u8; 32], Option<NextPacketDetails>
7929
- ), HTLCFailureMsg>
7933
+ ) -> Result<(onion_utils::Hop, [u8; 32], Option<NextPacketDetails>), HTLCFailureMsg>
7930
7934
where
7931
7935
NS::Target: NodeSigner,
7932
7936
L::Target: Logger,
@@ -8002,6 +8006,8 @@ where
8002
8006
outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
8003
8007
}
8004
8008
},
8009
+ // We'll do receive checks in [`Self::construct_pending_htlc_info`] so we have access to the
8010
+ // inbound channel's state.
8005
8011
onion_utils::Hop::Receive { .. } => return Ok((next_hop, shared_secret, None)),
8006
8012
onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::Receive { .. }, .. } |
8007
8013
onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::BlindedReceive { .. }, .. } =>
@@ -8015,24 +8021,21 @@ where
8015
8021
8016
8022
fn check_incoming_htlc_cltv(
8017
8023
cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32
8018
- ) -> Result<(), (&'static str, u16, bool )> {
8024
+ ) -> Result<(), (&'static str, u16)> {
8019
8025
if (cltv_expiry as u64) < (outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 {
8020
- // We really should set `incorrect_cltv_expiry` here but as we're not
8021
- // forwarding over a real channel we can't generate a channel_update
8022
- // for it. Instead we just return a generic temporary_node_failure.
8023
8026
return Err((
8024
- "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta",
8025
- 0x2000 | 2, false,
8027
+ "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta",
8028
+ 0x1000 | 13, // incorrect_cltv_expiry
8026
8029
));
8027
8030
}
8028
8031
// Theoretically, channel counterparty shouldn't send us a HTLC expiring now,
8029
8032
// but we want to be robust wrt to counterparty packet sanitization (see
8030
8033
// HTLC_FAIL_BACK_BUFFER rationale).
8031
8034
if cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 { // expiry_too_soon
8032
- return Err(("CLTV expiry is too close", 0x1000 | 14, true ));
8035
+ return Err(("CLTV expiry is too close", 0x1000 | 14));
8033
8036
}
8034
8037
if cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 { // expiry_too_far
8035
- return Err(("CLTV expiry is too far in the future", 21, false ));
8038
+ return Err(("CLTV expiry is too far in the future", 21));
8036
8039
}
8037
8040
// If the HTLC expires ~now, don't bother trying to forward it to our
8038
8041
// counterparty. They should fail it anyway, but we don't want to bother with
@@ -8043,7 +8046,7 @@ fn check_incoming_htlc_cltv(
8043
8046
// but there is no need to do that, and since we're a bit conservative with our
8044
8047
// risk threshold it just results in failing to forward payments.
8045
8048
if (outgoing_cltv_value) as u64 <= (cur_height + LATENCY_GRACE_PERIOD_BLOCKS) as u64 {
8046
- return Err(("Outgoing CLTV value is too soon", 0x1000 | 14, true ));
8049
+ return Err(("Outgoing CLTV value is too soon", 0x1000 | 14));
8047
8050
}
8048
8051
8049
8052
Ok(())
@@ -12205,7 +12208,7 @@ mod tests {
12205
12208
let charlie = crate::sign::KeysManager::new(&[3; 32], 42, 42);
12206
12209
let charlie_pk = PublicKey::from_secret_key(&secp_ctx, &charlie.get_node_secret_key());
12207
12210
12208
- let (session_priv, total_amt_msat, cur_height, recipient_onion, preimage, payment_hash,
12211
+ let (session_priv, total_amt_msat, cur_height, recipient_onion, preimage, payment_hash,
12209
12212
prng_seed, hops, recipient_amount, pay_secret) = payment_onion_args(bob_pk, charlie_pk);
12210
12213
12211
12214
let path = Path {
@@ -12220,9 +12223,9 @@ mod tests {
12220
12223
12221
12224
let msg = make_update_add_msg(amount_msat, cltv_expiry, payment_hash, onion);
12222
12225
let logger = test_utils::TestLogger::with_id("bob".to_string());
12223
-
12226
+
12224
12227
let peeled = peel_payment_onion(&msg, &&bob, &&logger, &secp_ctx, cur_height, true)
12225
- .map_err(|e| e.msg).unwrap();
12228
+ .map_err(|e| e.msg).unwrap();
12226
12229
12227
12230
let next_onion = match peeled.routing {
12228
12231
PendingHTLCRouting::Forward { onion_packet, short_channel_id: _ } => {
@@ -12233,8 +12236,8 @@ mod tests {
12233
12236
12234
12237
let msg2 = make_update_add_msg(amount_msat, cltv_expiry, payment_hash, next_onion);
12235
12238
let peeled2 = peel_payment_onion(&msg2, &&charlie, &&logger, &secp_ctx, cur_height, true)
12236
- .map_err(|e| e.msg).unwrap();
12237
-
12239
+ .map_err(|e| e.msg).unwrap();
12240
+
12238
12241
match peeled2.routing {
12239
12242
PendingHTLCRouting::ReceiveKeysend { payment_preimage, payment_data, incoming_cltv_expiry, .. } => {
12240
12243
assert_eq!(payment_preimage, preimage);
@@ -12249,7 +12252,7 @@ mod tests {
12249
12252
}
12250
12253
12251
12254
fn make_update_add_msg(
12252
- amount_msat: u64, cltv_expiry: u32, payment_hash: PaymentHash,
12255
+ amount_msat: u64, cltv_expiry: u32, payment_hash: PaymentHash,
12253
12256
onion_routing_packet: msgs::OnionPacket
12254
12257
) -> msgs::UpdateAddHTLC {
12255
12258
msgs::UpdateAddHTLC {
@@ -12308,7 +12311,7 @@ mod tests {
12308
12311
}
12309
12312
12310
12313
pub fn create_payment_onion<T: bitcoin::secp256k1::Signing>(
12311
- secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey, total_msat: u64,
12314
+ secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey, total_msat: u64,
12312
12315
recipient_onion: RecipientOnionFields, best_block_height: u32, payment_hash: PaymentHash,
12313
12316
keysend_preimage: Option<PaymentPreimage>, prng_seed: [u8; 32]
12314
12317
) -> Result<(u64, u32, msgs::OnionPacket), ()> {
0 commit comments