]> git.bitcoin.ninja Git - rust-lightning/blob - lightning/src/ln/onion_payment.rs
Merge pull request #3041 from G8XSU/followup-2957
[rust-lightning] / lightning / src / ln / onion_payment.rs
1 //! Utilities to decode payment onions and do contextless validation of incoming payments.
2 //!
3 //! Primarily features [`peel_payment_onion`], which allows the decoding of an onion statelessly
4 //! and can be used to predict whether we'd accept a payment.
5
6 use bitcoin::hashes::{Hash, HashEngine};
7 use bitcoin::hashes::hmac::{Hmac, HmacEngine};
8 use bitcoin::hashes::sha256::Hash as Sha256;
9 use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1};
10
11 use crate::blinded_path;
12 use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay};
13 use crate::chain::channelmonitor::{HTLC_FAIL_BACK_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
14 use crate::ln::types::PaymentHash;
15 use crate::ln::channelmanager::{BlindedFailure, BlindedForward, CLTV_FAR_FAR_AWAY, HTLCFailureMsg, MIN_CLTV_EXPIRY_DELTA, PendingHTLCInfo, PendingHTLCRouting};
16 use crate::ln::features::BlindedHopFeatures;
17 use crate::ln::msgs;
18 use crate::ln::onion_utils;
19 use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
20 use crate::sign::{NodeSigner, Recipient};
21 use crate::util::logger::Logger;
22
23 #[allow(unused_imports)]
24 use crate::prelude::*;
25
26 use core::ops::Deref;
27
28 /// Invalid inbound onion payment.
29 #[derive(Debug)]
30 pub struct InboundHTLCErr {
31         /// BOLT 4 error code.
32         pub err_code: u16,
33         /// Data attached to this error.
34         pub err_data: Vec<u8>,
35         /// Error message text.
36         pub msg: &'static str,
37 }
38
39 fn check_blinded_payment_constraints(
40         amt_msat: u64, cltv_expiry: u32, constraints: &PaymentConstraints
41 ) -> Result<(), ()> {
42         if amt_msat < constraints.htlc_minimum_msat ||
43                 cltv_expiry > constraints.max_cltv_expiry
44         { return Err(()) }
45         Ok(())
46 }
47
48 fn check_blinded_forward(
49         inbound_amt_msat: u64, inbound_cltv_expiry: u32, payment_relay: &PaymentRelay,
50         payment_constraints: &PaymentConstraints, features: &BlindedHopFeatures
51 ) -> Result<(u64, u32), ()> {
52         let amt_to_forward = blinded_path::payment::amt_to_forward_msat(
53                 inbound_amt_msat, payment_relay
54         ).ok_or(())?;
55         let outgoing_cltv_value = inbound_cltv_expiry.checked_sub(
56                 payment_relay.cltv_expiry_delta as u32
57         ).ok_or(())?;
58         check_blinded_payment_constraints(inbound_amt_msat, outgoing_cltv_value, payment_constraints)?;
59
60         if features.requires_unknown_bits_from(&BlindedHopFeatures::empty()) { return Err(()) }
61         Ok((amt_to_forward, outgoing_cltv_value))
62 }
63
64 pub(super) fn create_fwd_pending_htlc_info(
65         msg: &msgs::UpdateAddHTLC, hop_data: msgs::InboundOnionPayload, hop_hmac: [u8; 32],
66         new_packet_bytes: [u8; onion_utils::ONION_DATA_LEN], shared_secret: [u8; 32],
67         next_packet_pubkey_opt: Option<Result<PublicKey, secp256k1::Error>>
68 ) -> Result<PendingHTLCInfo, InboundHTLCErr> {
69         debug_assert!(next_packet_pubkey_opt.is_some());
70         let outgoing_packet = msgs::OnionPacket {
71                 version: 0,
72                 public_key: next_packet_pubkey_opt.unwrap_or(Err(secp256k1::Error::InvalidPublicKey)),
73                 hop_data: new_packet_bytes,
74                 hmac: hop_hmac,
75         };
76
77         let (
78                 short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point
79         ) = match hop_data {
80                 msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } =>
81                         (short_channel_id, amt_to_forward, outgoing_cltv_value, None),
82                 msgs::InboundOnionPayload::BlindedForward {
83                         short_channel_id, payment_relay, payment_constraints, intro_node_blinding_point, features,
84                 } => {
85                         let (amt_to_forward, outgoing_cltv_value) = check_blinded_forward(
86                                 msg.amount_msat, msg.cltv_expiry, &payment_relay, &payment_constraints, &features
87                         ).map_err(|()| {
88                                 // We should be returning malformed here if `msg.blinding_point` is set, but this is
89                                 // unreachable right now since we checked it in `decode_update_add_htlc_onion`.
90                                 InboundHTLCErr {
91                                         msg: "Underflow calculating outbound amount or cltv value for blinded forward",
92                                         err_code: INVALID_ONION_BLINDING,
93                                         err_data: vec![0; 32],
94                                 }
95                         })?;
96                         (short_channel_id, amt_to_forward, outgoing_cltv_value, intro_node_blinding_point)
97                 },
98                 msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } =>
99                         return Err(InboundHTLCErr {
100                                 msg: "Final Node OnionHopData provided for us as an intermediary node",
101                                 err_code: 0x4000 | 22,
102                                 err_data: Vec::new(),
103                         }),
104         };
105
106         Ok(PendingHTLCInfo {
107                 routing: PendingHTLCRouting::Forward {
108                         onion_packet: outgoing_packet,
109                         short_channel_id,
110                         blinded: intro_node_blinding_point.or(msg.blinding_point)
111                                 .map(|bp| BlindedForward {
112                                         inbound_blinding_point: bp,
113                                         failure: intro_node_blinding_point
114                                                 .map(|_| BlindedFailure::FromIntroductionNode)
115                                                 .unwrap_or(BlindedFailure::FromBlindedNode),
116                                 }),
117                 },
118                 payment_hash: msg.payment_hash,
119                 incoming_shared_secret: shared_secret,
120                 incoming_amt_msat: Some(msg.amount_msat),
121                 outgoing_amt_msat: amt_to_forward,
122                 outgoing_cltv_value,
123                 skimmed_fee_msat: None,
124         })
125 }
126
127 pub(super) fn create_recv_pending_htlc_info(
128         hop_data: msgs::InboundOnionPayload, shared_secret: [u8; 32], payment_hash: PaymentHash,
129         amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>, allow_underpay: bool,
130         counterparty_skimmed_fee_msat: Option<u64>, current_height: u32, accept_mpp_keysend: bool,
131 ) -> Result<PendingHTLCInfo, InboundHTLCErr> {
132         let (
133                 payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, onion_cltv_expiry,
134                 payment_metadata, payment_context, requires_blinded_error
135         ) = match hop_data {
136                 msgs::InboundOnionPayload::Receive {
137                         payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
138                         cltv_expiry_height, payment_metadata, ..
139                 } =>
140                         (payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
141                          cltv_expiry_height, payment_metadata, None, false),
142                 msgs::InboundOnionPayload::BlindedReceive {
143                         sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
144                         intro_node_blinding_point, payment_constraints, payment_context, keysend_preimage,
145                         custom_tlvs
146                 } => {
147                         check_blinded_payment_constraints(
148                                 sender_intended_htlc_amt_msat, cltv_expiry, &payment_constraints
149                         )
150                                 .map_err(|()| {
151                                         InboundHTLCErr {
152                                                 err_code: INVALID_ONION_BLINDING,
153                                                 err_data: vec![0; 32],
154                                                 msg: "Amount or cltv_expiry violated blinded payment constraints",
155                                         }
156                                 })?;
157                         let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
158                         (Some(payment_data), keysend_preimage, custom_tlvs,
159                          sender_intended_htlc_amt_msat, cltv_expiry_height, None, Some(payment_context),
160                          intro_node_blinding_point.is_none())
161                 }
162                 msgs::InboundOnionPayload::Forward { .. } => {
163                         return Err(InboundHTLCErr {
164                                 err_code: 0x4000|22,
165                                 err_data: Vec::new(),
166                                 msg: "Got non final data with an HMAC of 0",
167                         })
168                 },
169                 msgs::InboundOnionPayload::BlindedForward { .. } => {
170                         return Err(InboundHTLCErr {
171                                 err_code: INVALID_ONION_BLINDING,
172                                 err_data: vec![0; 32],
173                                 msg: "Got blinded non final data with an HMAC of 0",
174                         })
175                 }
176         };
177         // final_incorrect_cltv_expiry
178         if onion_cltv_expiry > cltv_expiry {
179                 return Err(InboundHTLCErr {
180                         msg: "Upstream node set CLTV to less than the CLTV set by the sender",
181                         err_code: 18,
182                         err_data: cltv_expiry.to_be_bytes().to_vec()
183                 })
184         }
185         // final_expiry_too_soon
186         // We have to have some headroom to broadcast on chain if we have the preimage, so make sure
187         // we have at least HTLC_FAIL_BACK_BUFFER blocks to go.
188         //
189         // Also, ensure that, in the case of an unknown preimage for the received payment hash, our
190         // payment logic has enough time to fail the HTLC backward before our onchain logic triggers a
191         // channel closure (see HTLC_FAIL_BACK_BUFFER rationale).
192         if cltv_expiry <= current_height + HTLC_FAIL_BACK_BUFFER + 1 {
193                 let mut err_data = Vec::with_capacity(12);
194                 err_data.extend_from_slice(&amt_msat.to_be_bytes());
195                 err_data.extend_from_slice(&current_height.to_be_bytes());
196                 return Err(InboundHTLCErr {
197                         err_code: 0x4000 | 15, err_data,
198                         msg: "The final CLTV expiry is too soon to handle",
199                 });
200         }
201         if (!allow_underpay && onion_amt_msat > amt_msat) ||
202                 (allow_underpay && onion_amt_msat >
203                  amt_msat.saturating_add(counterparty_skimmed_fee_msat.unwrap_or(0)))
204         {
205                 return Err(InboundHTLCErr {
206                         err_code: 19,
207                         err_data: amt_msat.to_be_bytes().to_vec(),
208                         msg: "Upstream node sent less than we were supposed to receive in payment",
209                 });
210         }
211
212         let routing = if let Some(payment_preimage) = keysend_preimage {
213                 // We need to check that the sender knows the keysend preimage before processing this
214                 // payment further. Otherwise, an intermediary routing hop forwarding non-keysend-HTLC X
215                 // could discover the final destination of X, by probing the adjacent nodes on the route
216                 // with a keysend payment of identical payment hash to X and observing the processing
217                 // time discrepancies due to a hash collision with X.
218                 let hashed_preimage = PaymentHash(Sha256::hash(&payment_preimage.0).to_byte_array());
219                 if hashed_preimage != payment_hash {
220                         return Err(InboundHTLCErr {
221                                 err_code: 0x4000|22,
222                                 err_data: Vec::new(),
223                                 msg: "Payment preimage didn't match payment hash",
224                         });
225                 }
226                 if !accept_mpp_keysend && payment_data.is_some() {
227                         return Err(InboundHTLCErr {
228                                 err_code: 0x4000|22,
229                                 err_data: Vec::new(),
230                                 msg: "We don't support MPP keysend payments",
231                         });
232                 }
233                 PendingHTLCRouting::ReceiveKeysend {
234                         payment_data,
235                         payment_preimage,
236                         payment_metadata,
237                         incoming_cltv_expiry: onion_cltv_expiry,
238                         custom_tlvs,
239                         requires_blinded_error,
240                 }
241         } else if let Some(data) = payment_data {
242                 PendingHTLCRouting::Receive {
243                         payment_data: data,
244                         payment_metadata,
245                         payment_context,
246                         incoming_cltv_expiry: onion_cltv_expiry,
247                         phantom_shared_secret,
248                         custom_tlvs,
249                         requires_blinded_error,
250                 }
251         } else {
252                 return Err(InboundHTLCErr {
253                         err_code: 0x4000|0x2000|3,
254                         err_data: Vec::new(),
255                         msg: "We require payment_secrets",
256                 });
257         };
258         Ok(PendingHTLCInfo {
259                 routing,
260                 payment_hash,
261                 incoming_shared_secret: shared_secret,
262                 incoming_amt_msat: Some(amt_msat),
263                 outgoing_amt_msat: onion_amt_msat,
264                 outgoing_cltv_value: onion_cltv_expiry,
265                 skimmed_fee_msat: counterparty_skimmed_fee_msat,
266         })
267 }
268
269 /// Peel one layer off an incoming onion, returning a [`PendingHTLCInfo`] that contains information
270 /// about the intended next-hop for the HTLC.
271 ///
272 /// This does all the relevant context-free checks that LDK requires for payment relay or
273 /// acceptance. If the payment is to be received, and the amount matches the expected amount for
274 /// a given invoice, this indicates the [`msgs::UpdateAddHTLC`], once fully committed in the
275 /// channel, will generate an [`Event::PaymentClaimable`].
276 ///
277 /// [`Event::PaymentClaimable`]: crate::events::Event::PaymentClaimable
278 pub fn peel_payment_onion<NS: Deref, L: Deref, T: secp256k1::Verification>(
279         msg: &msgs::UpdateAddHTLC, node_signer: &NS, logger: &L, secp_ctx: &Secp256k1<T>,
280         cur_height: u32, accept_mpp_keysend: bool, allow_skimmed_fees: bool,
281 ) -> Result<PendingHTLCInfo, InboundHTLCErr>
282 where
283         NS::Target: NodeSigner,
284         L::Target: Logger,
285 {
286         let (hop, shared_secret, next_packet_details_opt) =
287                 decode_incoming_update_add_htlc_onion(msg, node_signer, logger, secp_ctx
288         ).map_err(|e| {
289                 let (err_code, err_data) = match e {
290                         HTLCFailureMsg::Malformed(m) => (m.failure_code, Vec::new()),
291                         HTLCFailureMsg::Relay(r) => (0x4000 | 22, r.reason.data),
292                 };
293                 let msg = "Failed to decode update add htlc onion";
294                 InboundHTLCErr { msg, err_code, err_data }
295         })?;
296         Ok(match hop {
297                 onion_utils::Hop::Forward { next_hop_data, next_hop_hmac, new_packet_bytes } => {
298                         let NextPacketDetails {
299                                 next_packet_pubkey, outgoing_amt_msat: _, outgoing_scid: _, outgoing_cltv_value
300                         } = match next_packet_details_opt {
301                                 Some(next_packet_details) => next_packet_details,
302                                 // Forward should always include the next hop details
303                                 None => return Err(InboundHTLCErr {
304                                         msg: "Failed to decode update add htlc onion",
305                                         err_code: 0x4000 | 22,
306                                         err_data: Vec::new(),
307                                 }),
308                         };
309
310                         if let Err((err_msg, code)) = check_incoming_htlc_cltv(
311                                 cur_height, outgoing_cltv_value, msg.cltv_expiry
312                         ) {
313                                 return Err(InboundHTLCErr {
314                                         msg: err_msg,
315                                         err_code: code,
316                                         err_data: Vec::new(),
317                                 });
318                         }
319
320                         // TODO: If this is potentially a phantom payment we should decode the phantom payment
321                         // onion here and check it.
322
323                         create_fwd_pending_htlc_info(
324                                 msg, next_hop_data, next_hop_hmac, new_packet_bytes, shared_secret,
325                                 Some(next_packet_pubkey)
326                         )?
327                 },
328                 onion_utils::Hop::Receive(received_data) => {
329                         create_recv_pending_htlc_info(
330                                 received_data, shared_secret, msg.payment_hash, msg.amount_msat, msg.cltv_expiry,
331                                 None, allow_skimmed_fees, msg.skimmed_fee_msat, cur_height, accept_mpp_keysend,
332                         )?
333                 }
334         })
335 }
336
337 pub(super) struct NextPacketDetails {
338         pub(super) next_packet_pubkey: Result<PublicKey, secp256k1::Error>,
339         pub(super) outgoing_scid: u64,
340         pub(super) outgoing_amt_msat: u64,
341         pub(super) outgoing_cltv_value: u32,
342 }
343
344 pub(super) fn decode_incoming_update_add_htlc_onion<NS: Deref, L: Deref, T: secp256k1::Verification>(
345         msg: &msgs::UpdateAddHTLC, node_signer: &NS, logger: &L, secp_ctx: &Secp256k1<T>,
346 ) -> Result<(onion_utils::Hop, [u8; 32], Option<NextPacketDetails>), HTLCFailureMsg>
347 where
348         NS::Target: NodeSigner,
349         L::Target: Logger,
350 {
351         macro_rules! return_malformed_err {
352                 ($msg: expr, $err_code: expr) => {
353                         {
354                                 log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
355                                 let (sha256_of_onion, failure_code) = if msg.blinding_point.is_some() {
356                                         ([0; 32], INVALID_ONION_BLINDING)
357                                 } else {
358                                         (Sha256::hash(&msg.onion_routing_packet.hop_data).to_byte_array(), $err_code)
359                                 };
360                                 return Err(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
361                                         channel_id: msg.channel_id,
362                                         htlc_id: msg.htlc_id,
363                                         sha256_of_onion,
364                                         failure_code,
365                                 }));
366                         }
367                 }
368         }
369
370         if let Err(_) = msg.onion_routing_packet.public_key {
371                 return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
372         }
373
374         let blinded_node_id_tweak = msg.blinding_point.map(|bp| {
375                 let blinded_tlvs_ss = node_signer.ecdh(Recipient::Node, &bp, None).unwrap().secret_bytes();
376                 let mut hmac = HmacEngine::<Sha256>::new(b"blinded_node_id");
377                 hmac.input(blinded_tlvs_ss.as_ref());
378                 Scalar::from_be_bytes(Hmac::from_engine(hmac).to_byte_array()).unwrap()
379         });
380         let shared_secret = node_signer.ecdh(
381                 Recipient::Node, &msg.onion_routing_packet.public_key.unwrap(), blinded_node_id_tweak.as_ref()
382         ).unwrap().secret_bytes();
383
384         if msg.onion_routing_packet.version != 0 {
385                 //TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
386                 //sha256_of_onion error data packets), or the entire onion_routing_packet. Either way,
387                 //the hash doesn't really serve any purpose - in the case of hashing all data, the
388                 //receiving node would have to brute force to figure out which version was put in the
389                 //packet by the node that send us the message, in the case of hashing the hop_data, the
390                 //node knows the HMAC matched, so they already know what is there...
391                 return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4);
392         }
393         macro_rules! return_err {
394                 ($msg: expr, $err_code: expr, $data: expr) => {
395                         {
396                                 if msg.blinding_point.is_some() {
397                                         return_malformed_err!($msg, INVALID_ONION_BLINDING)
398                                 }
399
400                                 log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
401                                 return Err(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
402                                         channel_id: msg.channel_id,
403                                         htlc_id: msg.htlc_id,
404                                         reason: HTLCFailReason::reason($err_code, $data.to_vec())
405                                                 .get_encrypted_failure_packet(&shared_secret, &None),
406                                 }));
407                         }
408                 }
409         }
410
411         let next_hop = match onion_utils::decode_next_payment_hop(
412                 shared_secret, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
413                 msg.payment_hash, msg.blinding_point, node_signer
414         ) {
415                 Ok(res) => res,
416                 Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
417                         return_malformed_err!(err_msg, err_code);
418                 },
419                 Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
420                         return_err!(err_msg, err_code, &[0; 0]);
421                 },
422         };
423
424         let next_packet_details = match next_hop {
425                 onion_utils::Hop::Forward {
426                         next_hop_data: msgs::InboundOnionPayload::Forward {
427                                 short_channel_id, amt_to_forward, outgoing_cltv_value
428                         }, ..
429                 } => {
430                         let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
431                                 msg.onion_routing_packet.public_key.unwrap(), &shared_secret);
432                         NextPacketDetails {
433                                 next_packet_pubkey, outgoing_scid: short_channel_id,
434                                 outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
435                         }
436                 },
437                 onion_utils::Hop::Forward {
438                         next_hop_data: msgs::InboundOnionPayload::BlindedForward {
439                                 short_channel_id, ref payment_relay, ref payment_constraints, ref features, ..
440                         }, ..
441                 } => {
442                         let (amt_to_forward, outgoing_cltv_value) = match check_blinded_forward(
443                                 msg.amount_msat, msg.cltv_expiry, &payment_relay, &payment_constraints, &features
444                         ) {
445                                 Ok((amt, cltv)) => (amt, cltv),
446                                 Err(()) => {
447                                         return_err!("Underflow calculating outbound amount or cltv value for blinded forward",
448                                                 INVALID_ONION_BLINDING, &[0; 32]);
449                                 }
450                         };
451                         let next_packet_pubkey = onion_utils::next_hop_pubkey(&secp_ctx,
452                                 msg.onion_routing_packet.public_key.unwrap(), &shared_secret);
453                         NextPacketDetails {
454                                 next_packet_pubkey, outgoing_scid: short_channel_id, outgoing_amt_msat: amt_to_forward,
455                                 outgoing_cltv_value
456                         }
457                 },
458                 onion_utils::Hop::Receive { .. } => return Ok((next_hop, shared_secret, None)),
459                 onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::Receive { .. }, .. } |
460                         onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::BlindedReceive { .. }, .. } =>
461                 {
462                         return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0; 0]);
463                 }
464         };
465
466         Ok((next_hop, shared_secret, Some(next_packet_details)))
467 }
468
469 pub(super) fn check_incoming_htlc_cltv(
470         cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32
471 ) -> Result<(), (&'static str, u16)> {
472         if (cltv_expiry as u64) < (outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 {
473                 return Err((
474                         "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta",
475                         0x1000 | 13, // incorrect_cltv_expiry
476                 ));
477         }
478         // Theoretically, channel counterparty shouldn't send us a HTLC expiring now,
479         // but we want to be robust wrt to counterparty packet sanitization (see
480         // HTLC_FAIL_BACK_BUFFER rationale).
481         if cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 { // expiry_too_soon
482                 return Err(("CLTV expiry is too close", 0x1000 | 14));
483         }
484         if cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 { // expiry_too_far
485                 return Err(("CLTV expiry is too far in the future", 21));
486         }
487         // If the HTLC expires ~now, don't bother trying to forward it to our
488         // counterparty. They should fail it anyway, but we don't want to bother with
489         // the round-trips or risk them deciding they definitely want the HTLC and
490         // force-closing to ensure they get it if we're offline.
491         // We previously had a much more aggressive check here which tried to ensure
492         // our counterparty receives an HTLC which has *our* risk threshold met on it,
493         // but there is no need to do that, and since we're a bit conservative with our
494         // risk threshold it just results in failing to forward payments.
495         if (outgoing_cltv_value) as u64 <= (cur_height + LATENCY_GRACE_PERIOD_BLOCKS) as u64 {
496                 return Err(("Outgoing CLTV value is too soon", 0x1000 | 14));
497         }
498
499         Ok(())
500 }
501
502 #[cfg(test)]
503 mod tests {
504         use bitcoin::hashes::Hash;
505         use bitcoin::hashes::sha256::Hash as Sha256;
506         use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
507         use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
508         use crate::ln::channelmanager::RecipientOnionFields;
509         use crate::ln::features::{ChannelFeatures, NodeFeatures};
510         use crate::ln::msgs;
511         use crate::ln::onion_utils::create_payment_onion;
512         use crate::routing::router::{Path, RouteHop};
513         use crate::util::test_utils;
514
515         #[test]
516         fn fail_construct_onion_on_too_big_payloads() {
517                 // Ensure that if we call `construct_onion_packet` and friends where payloads are too large for
518                 // the allotted packet length, we'll fail to construct. Previously, senders would happily
519                 // construct invalid packets by array-shifting the final node's HMAC out of the packet when
520                 // adding an intermediate onion layer, causing the receiver to error with "final payload
521                 // provided for us as an intermediate node."
522                 let secp_ctx = Secp256k1::new();
523                 let bob = crate::sign::KeysManager::new(&[2; 32], 42, 42);
524                 let bob_pk = PublicKey::from_secret_key(&secp_ctx, &bob.get_node_secret_key());
525                 let charlie = crate::sign::KeysManager::new(&[3; 32], 42, 42);
526                 let charlie_pk = PublicKey::from_secret_key(&secp_ctx, &charlie.get_node_secret_key());
527
528                 let (
529                         session_priv, total_amt_msat, cur_height, mut recipient_onion, keysend_preimage, payment_hash,
530                         prng_seed, hops, ..
531                 ) = payment_onion_args(bob_pk, charlie_pk);
532
533                 // Ensure the onion will not fit all the payloads by adding a large custom TLV.
534                 recipient_onion.custom_tlvs.push((13377331, vec![0; 1156]));
535
536                 let path = Path { hops, blinded_tail: None, };
537                 let onion_keys = super::onion_utils::construct_onion_keys(&secp_ctx, &path, &session_priv).unwrap();
538                 let (onion_payloads, ..) = super::onion_utils::build_onion_payloads(
539                         &path, total_amt_msat, recipient_onion, cur_height + 1, &Some(keysend_preimage)
540                 ).unwrap();
541
542                 assert!(super::onion_utils::construct_onion_packet(
543                                 onion_payloads, onion_keys, prng_seed, &payment_hash
544                 ).is_err());
545         }
546
547         #[test]
548         fn test_peel_payment_onion() {
549                 use super::*;
550                 let secp_ctx = Secp256k1::new();
551
552                 let bob = crate::sign::KeysManager::new(&[2; 32], 42, 42);
553                 let bob_pk = PublicKey::from_secret_key(&secp_ctx, &bob.get_node_secret_key());
554                 let charlie = crate::sign::KeysManager::new(&[3; 32], 42, 42);
555                 let charlie_pk = PublicKey::from_secret_key(&secp_ctx, &charlie.get_node_secret_key());
556
557                 let (session_priv, total_amt_msat, cur_height, recipient_onion, preimage, payment_hash,
558                         prng_seed, hops, recipient_amount, pay_secret) = payment_onion_args(bob_pk, charlie_pk);
559
560                 let path = Path {
561                         hops: hops,
562                         blinded_tail: None,
563                 };
564
565                 let (onion, amount_msat, cltv_expiry) = create_payment_onion(
566                         &secp_ctx, &path, &session_priv, total_amt_msat, recipient_onion, cur_height,
567                         &payment_hash, &Some(preimage), prng_seed
568                 ).unwrap();
569
570                 let msg = make_update_add_msg(amount_msat, cltv_expiry, payment_hash, onion);
571                 let logger = test_utils::TestLogger::with_id("bob".to_string());
572
573                 let peeled = peel_payment_onion(&msg, &&bob, &&logger, &secp_ctx, cur_height, true, false)
574                         .map_err(|e| e.msg).unwrap();
575
576                 let next_onion = match peeled.routing {
577                         PendingHTLCRouting::Forward { onion_packet, .. } => {
578                                 onion_packet
579                         },
580                         _ => panic!("expected a forwarded onion"),
581                 };
582
583                 let msg2 = make_update_add_msg(amount_msat, cltv_expiry, payment_hash, next_onion);
584                 let peeled2 = peel_payment_onion(&msg2, &&charlie, &&logger, &secp_ctx, cur_height, true, false)
585                         .map_err(|e| e.msg).unwrap();
586
587                 match peeled2.routing {
588                         PendingHTLCRouting::ReceiveKeysend { payment_preimage, payment_data, incoming_cltv_expiry, .. } => {
589                                 assert_eq!(payment_preimage, preimage);
590                                 assert_eq!(peeled2.outgoing_amt_msat, recipient_amount);
591                                 assert_eq!(incoming_cltv_expiry, peeled2.outgoing_cltv_value);
592                                 let msgs::FinalOnionHopData{total_msat, payment_secret} = payment_data.unwrap();
593                                 assert_eq!(total_msat, total_amt_msat);
594                                 assert_eq!(payment_secret, pay_secret);
595                         },
596                         _ => panic!("expected a received keysend"),
597                 };
598         }
599
600         fn make_update_add_msg(
601                 amount_msat: u64, cltv_expiry: u32, payment_hash: PaymentHash,
602                 onion_routing_packet: msgs::OnionPacket
603         ) -> msgs::UpdateAddHTLC {
604                 msgs::UpdateAddHTLC {
605                         channel_id: ChannelId::from_bytes([0; 32]),
606                         htlc_id: 0,
607                         amount_msat,
608                         cltv_expiry,
609                         payment_hash,
610                         onion_routing_packet,
611                         skimmed_fee_msat: None,
612                         blinding_point: None,
613                 }
614         }
615
616         fn payment_onion_args(hop_pk: PublicKey, recipient_pk: PublicKey) -> (
617                 SecretKey, u64, u32, RecipientOnionFields, PaymentPreimage, PaymentHash, [u8; 32],
618                 Vec<RouteHop>, u64, PaymentSecret,
619         ) {
620                 let session_priv_bytes = [42; 32];
621                 let session_priv = SecretKey::from_slice(&session_priv_bytes).unwrap();
622                 let total_amt_msat = 1000;
623                 let cur_height = 1000;
624                 let pay_secret = PaymentSecret([99; 32]);
625                 let recipient_onion = RecipientOnionFields::secret_only(pay_secret);
626                 let preimage_bytes = [43; 32];
627                 let preimage = PaymentPreimage(preimage_bytes);
628                 let rhash_bytes = Sha256::hash(&preimage_bytes).to_byte_array();
629                 let payment_hash = PaymentHash(rhash_bytes);
630                 let prng_seed = [44; 32];
631
632                 // make a route alice -> bob -> charlie
633                 let hop_fee = 1;
634                 let recipient_amount = total_amt_msat - hop_fee;
635                 let hops = vec![
636                         RouteHop {
637                                 pubkey: hop_pk,
638                                 fee_msat: hop_fee,
639                                 cltv_expiry_delta: 42,
640                                 short_channel_id: 1,
641                                 node_features: NodeFeatures::empty(),
642                                 channel_features: ChannelFeatures::empty(),
643                                 maybe_announced_channel: false,
644                         },
645                         RouteHop {
646                                 pubkey: recipient_pk,
647                                 fee_msat: recipient_amount,
648                                 cltv_expiry_delta: 42,
649                                 short_channel_id: 2,
650                                 node_features: NodeFeatures::empty(),
651                                 channel_features: ChannelFeatures::empty(),
652                                 maybe_announced_channel: false,
653                         }
654                 ];
655
656                 (session_priv, total_amt_msat, cur_height, recipient_onion, preimage, payment_hash,
657                         prng_seed, hops, recipient_amount, pay_secret)
658         }
659
660 }