Parse blinded forward-as-intro onion payloads
[rust-lightning] / lightning / src / ln / onion_payment.rs
1 //! Utilities for channelmanager.rs
2 //!
3 //! Includes a public [`peel_payment_onion`] function for use by external projects or libraries.
4
5 use bitcoin::hashes::Hash;
6 use bitcoin::hashes::sha256::Hash as Sha256;
7 use bitcoin::secp256k1::{self, Secp256k1, PublicKey};
8
9 use crate::chain::channelmonitor::{HTLC_FAIL_BACK_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
10 use crate::ln::PaymentHash;
11 use crate::ln::channelmanager::{CLTV_FAR_FAR_AWAY, HTLCFailureMsg, MIN_CLTV_EXPIRY_DELTA, PendingHTLCInfo, PendingHTLCRouting};
12 use crate::ln::msgs;
13 use crate::ln::onion_utils;
14 use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING};
15 use crate::sign::{NodeSigner, Recipient};
16 use crate::util::logger::Logger;
17
18 use crate::prelude::*;
19 use core::ops::Deref;
20
21 /// Invalid inbound onion payment.
22 pub struct InboundOnionErr {
23         /// BOLT 4 error code.
24         pub err_code: u16,
25         /// Data attached to this error.
26         pub err_data: Vec<u8>,
27         /// Error message text.
28         pub msg: &'static str,
29 }
30
31 pub(super) fn create_fwd_pending_htlc_info(
32         msg: &msgs::UpdateAddHTLC, hop_data: msgs::InboundOnionPayload, hop_hmac: [u8; 32],
33         new_packet_bytes: [u8; onion_utils::ONION_DATA_LEN], shared_secret: [u8; 32],
34         next_packet_pubkey_opt: Option<Result<PublicKey, secp256k1::Error>>
35 ) -> Result<PendingHTLCInfo, InboundOnionErr> {
36         debug_assert!(next_packet_pubkey_opt.is_some());
37         let outgoing_packet = msgs::OnionPacket {
38                 version: 0,
39                 public_key: next_packet_pubkey_opt.unwrap_or(Err(secp256k1::Error::InvalidPublicKey)),
40                 hop_data: new_packet_bytes,
41                 hmac: hop_hmac,
42         };
43
44         let (short_channel_id, amt_to_forward, outgoing_cltv_value) = match hop_data {
45                 msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } =>
46                         (short_channel_id, amt_to_forward, outgoing_cltv_value),
47                 msgs::InboundOnionPayload::BlindedForward { .. } => todo!(),
48                 msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } =>
49                         return Err(InboundOnionErr {
50                                 msg: "Final Node OnionHopData provided for us as an intermediary node",
51                                 err_code: 0x4000 | 22,
52                                 err_data: Vec::new(),
53                         }),
54         };
55
56         Ok(PendingHTLCInfo {
57                 routing: PendingHTLCRouting::Forward {
58                         onion_packet: outgoing_packet,
59                         short_channel_id,
60                         blinded: None,
61                 },
62                 payment_hash: msg.payment_hash,
63                 incoming_shared_secret: shared_secret,
64                 incoming_amt_msat: Some(msg.amount_msat),
65                 outgoing_amt_msat: amt_to_forward,
66                 outgoing_cltv_value,
67                 skimmed_fee_msat: None,
68         })
69 }
70
71 pub(super) fn create_recv_pending_htlc_info(
72         hop_data: msgs::InboundOnionPayload, shared_secret: [u8; 32], payment_hash: PaymentHash,
73         amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>, allow_underpay: bool,
74         counterparty_skimmed_fee_msat: Option<u64>, current_height: u32, accept_mpp_keysend: bool,
75 ) -> Result<PendingHTLCInfo, InboundOnionErr> {
76         let (payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, outgoing_cltv_value, payment_metadata) = match hop_data {
77                 msgs::InboundOnionPayload::Receive {
78                         payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata, ..
79                 } =>
80                         (payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata),
81                 msgs::InboundOnionPayload::BlindedReceive {
82                         amt_msat, total_msat, outgoing_cltv_value, payment_secret, ..
83                 } => {
84                         let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
85                         (Some(payment_data), None, Vec::new(), amt_msat, outgoing_cltv_value, None)
86                 }
87                 msgs::InboundOnionPayload::Forward { .. } => {
88                         return Err(InboundOnionErr {
89                                 err_code: 0x4000|22,
90                                 err_data: Vec::new(),
91                                 msg: "Got non final data with an HMAC of 0",
92                         })
93                 },
94                 msgs::InboundOnionPayload::BlindedForward { .. } => {
95                         return Err(InboundOnionErr {
96                                 err_code: INVALID_ONION_BLINDING,
97                                 err_data: vec![0; 32],
98                                 msg: "Got blinded non final data with an HMAC of 0",
99                         })
100                 }
101         };
102         // final_incorrect_cltv_expiry
103         if outgoing_cltv_value > cltv_expiry {
104                 return Err(InboundOnionErr {
105                         msg: "Upstream node set CLTV to less than the CLTV set by the sender",
106                         err_code: 18,
107                         err_data: cltv_expiry.to_be_bytes().to_vec()
108                 })
109         }
110         // final_expiry_too_soon
111         // We have to have some headroom to broadcast on chain if we have the preimage, so make sure
112         // we have at least HTLC_FAIL_BACK_BUFFER blocks to go.
113         //
114         // Also, ensure that, in the case of an unknown preimage for the received payment hash, our
115         // payment logic has enough time to fail the HTLC backward before our onchain logic triggers a
116         // channel closure (see HTLC_FAIL_BACK_BUFFER rationale).
117         if cltv_expiry <= current_height + HTLC_FAIL_BACK_BUFFER + 1 {
118                 let mut err_data = Vec::with_capacity(12);
119                 err_data.extend_from_slice(&amt_msat.to_be_bytes());
120                 err_data.extend_from_slice(&current_height.to_be_bytes());
121                 return Err(InboundOnionErr {
122                         err_code: 0x4000 | 15, err_data,
123                         msg: "The final CLTV expiry is too soon to handle",
124                 });
125         }
126         if (!allow_underpay && onion_amt_msat > amt_msat) ||
127                 (allow_underpay && onion_amt_msat >
128                  amt_msat.saturating_add(counterparty_skimmed_fee_msat.unwrap_or(0)))
129         {
130                 return Err(InboundOnionErr {
131                         err_code: 19,
132                         err_data: amt_msat.to_be_bytes().to_vec(),
133                         msg: "Upstream node sent less than we were supposed to receive in payment",
134                 });
135         }
136
137         let routing = if let Some(payment_preimage) = keysend_preimage {
138                 // We need to check that the sender knows the keysend preimage before processing this
139                 // payment further. Otherwise, an intermediary routing hop forwarding non-keysend-HTLC X
140                 // could discover the final destination of X, by probing the adjacent nodes on the route
141                 // with a keysend payment of identical payment hash to X and observing the processing
142                 // time discrepancies due to a hash collision with X.
143                 let hashed_preimage = PaymentHash(Sha256::hash(&payment_preimage.0).to_byte_array());
144                 if hashed_preimage != payment_hash {
145                         return Err(InboundOnionErr {
146                                 err_code: 0x4000|22,
147                                 err_data: Vec::new(),
148                                 msg: "Payment preimage didn't match payment hash",
149                         });
150                 }
151                 if !accept_mpp_keysend && payment_data.is_some() {
152                         return Err(InboundOnionErr {
153                                 err_code: 0x4000|22,
154                                 err_data: Vec::new(),
155                                 msg: "We don't support MPP keysend payments",
156                         });
157                 }
158                 PendingHTLCRouting::ReceiveKeysend {
159                         payment_data,
160                         payment_preimage,
161                         payment_metadata,
162                         incoming_cltv_expiry: outgoing_cltv_value,
163                         custom_tlvs,
164                 }
165         } else if let Some(data) = payment_data {
166                 PendingHTLCRouting::Receive {
167                         payment_data: data,
168                         payment_metadata,
169                         incoming_cltv_expiry: outgoing_cltv_value,
170                         phantom_shared_secret,
171                         custom_tlvs,
172                 }
173         } else {
174                 return Err(InboundOnionErr {
175                         err_code: 0x4000|0x2000|3,
176                         err_data: Vec::new(),
177                         msg: "We require payment_secrets",
178                 });
179         };
180         Ok(PendingHTLCInfo {
181                 routing,
182                 payment_hash,
183                 incoming_shared_secret: shared_secret,
184                 incoming_amt_msat: Some(amt_msat),
185                 outgoing_amt_msat: onion_amt_msat,
186                 outgoing_cltv_value,
187                 skimmed_fee_msat: counterparty_skimmed_fee_msat,
188         })
189 }
190
191 /// Peel one layer off an incoming onion, returning [`PendingHTLCInfo`] (either Forward or Receive).
192 /// This does all the relevant context-free checks that LDK requires for payment relay or
193 /// acceptance. If the payment is to be received, and the amount matches the expected amount for
194 /// a given invoice, this indicates the [`msgs::UpdateAddHTLC`], once fully committed in the
195 /// channel, will generate an [`Event::PaymentClaimable`].
196 ///
197 /// [`Event::PaymentClaimable`]: crate::events::Event::PaymentClaimable
198 pub fn peel_payment_onion<NS: Deref, L: Deref, T: secp256k1::Verification>(
199         msg: &msgs::UpdateAddHTLC, node_signer: &NS, logger: &L, secp_ctx: &Secp256k1<T>,
200         cur_height: u32, accept_mpp_keysend: bool,
201 ) -> Result<PendingHTLCInfo, InboundOnionErr>
202 where
203         NS::Target: NodeSigner,
204         L::Target: Logger,
205 {
206         let (hop, shared_secret, next_packet_details_opt) =
207                 decode_incoming_update_add_htlc_onion(msg, node_signer, logger, secp_ctx
208         ).map_err(|e| {
209                 let (err_code, err_data) = match e {
210                         HTLCFailureMsg::Malformed(m) => (m.failure_code, Vec::new()),
211                         HTLCFailureMsg::Relay(r) => (0x4000 | 22, r.reason.data),
212                 };
213                 let msg = "Failed to decode update add htlc onion";
214                 InboundOnionErr { msg, err_code, err_data }
215         })?;
216         Ok(match hop {
217                 onion_utils::Hop::Forward { next_hop_data, next_hop_hmac, new_packet_bytes } => {
218                         let NextPacketDetails {
219                                 next_packet_pubkey, outgoing_amt_msat: _, outgoing_scid: _, outgoing_cltv_value
220                         } = match next_packet_details_opt {
221                                 Some(next_packet_details) => next_packet_details,
222                                 // Forward should always include the next hop details
223                                 None => return Err(InboundOnionErr {
224                                         msg: "Failed to decode update add htlc onion",
225                                         err_code: 0x4000 | 22,
226                                         err_data: Vec::new(),
227                                 }),
228                         };
229
230                         if let Err((err_msg, code)) = check_incoming_htlc_cltv(
231                                 cur_height, outgoing_cltv_value, msg.cltv_expiry
232                         ) {
233                                 return Err(InboundOnionErr {
234                                         msg: err_msg,
235                                         err_code: code,
236                                         err_data: Vec::new(),
237                                 });
238                         }
239                         create_fwd_pending_htlc_info(
240                                 msg, next_hop_data, next_hop_hmac, new_packet_bytes, shared_secret,
241                                 Some(next_packet_pubkey)
242                         )?
243                 },
244                 onion_utils::Hop::Receive(received_data) => {
245                         create_recv_pending_htlc_info(
246                                 received_data, shared_secret, msg.payment_hash, msg.amount_msat, msg.cltv_expiry,
247                                 None, false, msg.skimmed_fee_msat, cur_height, accept_mpp_keysend,
248                         )?
249                 }
250         })
251 }
252
253 pub(super) struct NextPacketDetails {
254         pub(super) next_packet_pubkey: Result<PublicKey, secp256k1::Error>,
255         pub(super) outgoing_scid: u64,
256         pub(super) outgoing_amt_msat: u64,
257         pub(super) outgoing_cltv_value: u32,
258 }
259
260 pub(super) fn decode_incoming_update_add_htlc_onion<NS: Deref, L: Deref, T: secp256k1::Verification>(
261         msg: &msgs::UpdateAddHTLC, node_signer: &NS, logger: &L, secp_ctx: &Secp256k1<T>,
262 ) -> Result<(onion_utils::Hop, [u8; 32], Option<NextPacketDetails>), HTLCFailureMsg>
263 where
264         NS::Target: NodeSigner,
265         L::Target: Logger,
266 {
267         macro_rules! return_malformed_err {
268                 ($msg: expr, $err_code: expr) => {
269                         {
270                                 log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
271                                 return Err(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
272                                         channel_id: msg.channel_id,
273                                         htlc_id: msg.htlc_id,
274                                         sha256_of_onion: Sha256::hash(&msg.onion_routing_packet.hop_data).to_byte_array(),
275                                         failure_code: $err_code,
276                                 }));
277                         }
278                 }
279         }
280
281         if let Err(_) = msg.onion_routing_packet.public_key {
282                 return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
283         }
284
285         let shared_secret = node_signer.ecdh(
286                 Recipient::Node, &msg.onion_routing_packet.public_key.unwrap(), None
287         ).unwrap().secret_bytes();
288
289         if msg.onion_routing_packet.version != 0 {
290                 //TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
291                 //sha256_of_onion error data packets), or the entire onion_routing_packet. Either way,
292                 //the hash doesn't really serve any purpose - in the case of hashing all data, the
293                 //receiving node would have to brute force to figure out which version was put in the
294                 //packet by the node that send us the message, in the case of hashing the hop_data, the
295                 //node knows the HMAC matched, so they already know what is there...
296                 return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4);
297         }
298         macro_rules! return_err {
299                 ($msg: expr, $err_code: expr, $data: expr) => {
300                         {
301                                 log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
302                                 return Err(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
303                                         channel_id: msg.channel_id,
304                                         htlc_id: msg.htlc_id,
305                                         reason: HTLCFailReason::reason($err_code, $data.to_vec())
306                                                 .get_encrypted_failure_packet(&shared_secret, &None),
307                                 }));
308                         }
309                 }
310         }
311
312         let next_hop = match onion_utils::decode_next_payment_hop(
313                 shared_secret, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
314                 msg.payment_hash, node_signer
315         ) {
316                 Ok(res) => res,
317                 Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
318                         return_malformed_err!(err_msg, err_code);
319                 },
320                 Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
321                         return_err!(err_msg, err_code, &[0; 0]);
322                 },
323         };
324
325         let next_packet_details = match next_hop {
326                 onion_utils::Hop::Forward {
327                         next_hop_data: msgs::InboundOnionPayload::Forward {
328                                 short_channel_id, amt_to_forward, outgoing_cltv_value
329                         }, ..
330                 } => {
331                         let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
332                                 msg.onion_routing_packet.public_key.unwrap(), &shared_secret);
333                         NextPacketDetails {
334                                 next_packet_pubkey, outgoing_scid: short_channel_id,
335                                 outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
336                         }
337                 },
338                 onion_utils::Hop::Forward {
339                         next_hop_data: msgs::InboundOnionPayload::BlindedForward { .. }, ..
340                 } => {
341                         todo!()
342                 },
343                 onion_utils::Hop::Receive { .. } => return Ok((next_hop, shared_secret, None)),
344                 onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::Receive { .. }, .. } |
345                         onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::BlindedReceive { .. }, .. } =>
346                 {
347                         return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0; 0]);
348                 }
349         };
350
351         Ok((next_hop, shared_secret, Some(next_packet_details)))
352 }
353
354 pub(super) fn check_incoming_htlc_cltv(
355         cur_height: u32, outgoing_cltv_value: u32, cltv_expiry: u32
356 ) -> Result<(), (&'static str, u16)> {
357         if (cltv_expiry as u64) < (outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 {
358                 return Err((
359                         "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta",
360                         0x1000 | 13, // incorrect_cltv_expiry
361                 ));
362         }
363         // Theoretically, channel counterparty shouldn't send us a HTLC expiring now,
364         // but we want to be robust wrt to counterparty packet sanitization (see
365         // HTLC_FAIL_BACK_BUFFER rationale).
366         if cltv_expiry <= cur_height + HTLC_FAIL_BACK_BUFFER as u32 { // expiry_too_soon
367                 return Err(("CLTV expiry is too close", 0x1000 | 14));
368         }
369         if cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 { // expiry_too_far
370                 return Err(("CLTV expiry is too far in the future", 21));
371         }
372         // If the HTLC expires ~now, don't bother trying to forward it to our
373         // counterparty. They should fail it anyway, but we don't want to bother with
374         // the round-trips or risk them deciding they definitely want the HTLC and
375         // force-closing to ensure they get it if we're offline.
376         // We previously had a much more aggressive check here which tried to ensure
377         // our counterparty receives an HTLC which has *our* risk threshold met on it,
378         // but there is no need to do that, and since we're a bit conservative with our
379         // risk threshold it just results in failing to forward payments.
380         if (outgoing_cltv_value) as u64 <= (cur_height + LATENCY_GRACE_PERIOD_BLOCKS) as u64 {
381                 return Err(("Outgoing CLTV value is too soon", 0x1000 | 14));
382         }
383
384         Ok(())
385 }
386
387 #[cfg(test)]
388 mod tests {
389         use bitcoin::hashes::Hash;
390         use bitcoin::hashes::sha256::Hash as Sha256;
391         use bitcoin::secp256k1::{PublicKey, SecretKey};
392         use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
393         use crate::ln::ChannelId;
394         use crate::ln::channelmanager::RecipientOnionFields;
395         use crate::ln::features::{ChannelFeatures, NodeFeatures};
396         use crate::ln::msgs;
397         use crate::ln::onion_utils::create_payment_onion;
398         use crate::routing::router::{Path, RouteHop};
399         use crate::util::test_utils;
400
401         #[test]
402         fn test_peel_payment_onion() {
403                 use super::*;
404                 let secp_ctx = Secp256k1::new();
405
406                 let bob = crate::sign::KeysManager::new(&[2; 32], 42, 42);
407                 let bob_pk = PublicKey::from_secret_key(&secp_ctx, &bob.get_node_secret_key());
408                 let charlie = crate::sign::KeysManager::new(&[3; 32], 42, 42);
409                 let charlie_pk = PublicKey::from_secret_key(&secp_ctx, &charlie.get_node_secret_key());
410
411                 let (session_priv, total_amt_msat, cur_height, recipient_onion, preimage, payment_hash,
412                         prng_seed, hops, recipient_amount, pay_secret) = payment_onion_args(bob_pk, charlie_pk);
413
414                 let path = Path {
415                         hops: hops,
416                         blinded_tail: None,
417                 };
418
419                 let (onion, amount_msat, cltv_expiry) = create_payment_onion(
420                         &secp_ctx, &path, &session_priv, total_amt_msat, recipient_onion, cur_height,
421                         &payment_hash, &Some(preimage), prng_seed
422                 ).unwrap();
423
424                 let msg = make_update_add_msg(amount_msat, cltv_expiry, payment_hash, onion);
425                 let logger = test_utils::TestLogger::with_id("bob".to_string());
426
427                 let peeled = peel_payment_onion(&msg, &&bob, &&logger, &secp_ctx, cur_height, true)
428                         .map_err(|e| e.msg).unwrap();
429
430                 let next_onion = match peeled.routing {
431                         PendingHTLCRouting::Forward { onion_packet, .. } => {
432                                 onion_packet
433                         },
434                         _ => panic!("expected a forwarded onion"),
435                 };
436
437                 let msg2 = make_update_add_msg(amount_msat, cltv_expiry, payment_hash, next_onion);
438                 let peeled2 = peel_payment_onion(&msg2, &&charlie, &&logger, &secp_ctx, cur_height, true)
439                         .map_err(|e| e.msg).unwrap();
440
441                 match peeled2.routing {
442                         PendingHTLCRouting::ReceiveKeysend { payment_preimage, payment_data, incoming_cltv_expiry, .. } => {
443                                 assert_eq!(payment_preimage, preimage);
444                                 assert_eq!(peeled2.outgoing_amt_msat, recipient_amount);
445                                 assert_eq!(incoming_cltv_expiry, peeled2.outgoing_cltv_value);
446                                 let msgs::FinalOnionHopData{total_msat, payment_secret} = payment_data.unwrap();
447                                 assert_eq!(total_msat, total_amt_msat);
448                                 assert_eq!(payment_secret, pay_secret);
449                         },
450                         _ => panic!("expected a received keysend"),
451                 };
452         }
453
454         fn make_update_add_msg(
455                 amount_msat: u64, cltv_expiry: u32, payment_hash: PaymentHash,
456                 onion_routing_packet: msgs::OnionPacket
457         ) -> msgs::UpdateAddHTLC {
458                 msgs::UpdateAddHTLC {
459                         channel_id: ChannelId::from_bytes([0; 32]),
460                         htlc_id: 0,
461                         amount_msat,
462                         cltv_expiry,
463                         payment_hash,
464                         onion_routing_packet,
465                         skimmed_fee_msat: None,
466                         blinding_point: None,
467                 }
468         }
469
470         fn payment_onion_args(hop_pk: PublicKey, recipient_pk: PublicKey) -> (
471                 SecretKey, u64, u32, RecipientOnionFields, PaymentPreimage, PaymentHash, [u8; 32],
472                 Vec<RouteHop>, u64, PaymentSecret,
473         ) {
474                 let session_priv_bytes = [42; 32];
475                 let session_priv = SecretKey::from_slice(&session_priv_bytes).unwrap();
476                 let total_amt_msat = 1000;
477                 let cur_height = 1000;
478                 let pay_secret = PaymentSecret([99; 32]);
479                 let recipient_onion = RecipientOnionFields::secret_only(pay_secret);
480                 let preimage_bytes = [43; 32];
481                 let preimage = PaymentPreimage(preimage_bytes);
482                 let rhash_bytes = Sha256::hash(&preimage_bytes).to_byte_array();
483                 let payment_hash = PaymentHash(rhash_bytes);
484                 let prng_seed = [44; 32];
485
486                 // make a route alice -> bob -> charlie
487                 let hop_fee = 1;
488                 let recipient_amount = total_amt_msat - hop_fee;
489                 let hops = vec![
490                         RouteHop {
491                                 pubkey: hop_pk,
492                                 fee_msat: hop_fee,
493                                 cltv_expiry_delta: 42,
494                                 short_channel_id: 1,
495                                 node_features: NodeFeatures::empty(),
496                                 channel_features: ChannelFeatures::empty(),
497                                 maybe_announced_channel: false,
498                         },
499                         RouteHop {
500                                 pubkey: recipient_pk,
501                                 fee_msat: recipient_amount,
502                                 cltv_expiry_delta: 42,
503                                 short_channel_id: 2,
504                                 node_features: NodeFeatures::empty(),
505                                 channel_features: ChannelFeatures::empty(),
506                                 maybe_announced_channel: false,
507                         }
508                 ];
509
510                 (session_priv, total_amt_msat, cur_height, recipient_onion, preimage, payment_hash,
511                         prng_seed, hops, recipient_amount, pay_secret)
512         }
513
514 }