@@ -314,6 +314,62 @@ pub(super) fn build_onion_payloads(
314
314
Ok ( ( res, cur_value_msat, cur_cltv) )
315
315
}
316
316
317
+ /// returns the hop data, as well as the first-hop value_msat and CLTV value we should send.
318
+ pub ( super ) fn build_trampoline_payloads (
319
+ path : & [ TrampolineHop ] , total_msat : u64 , mut recipient_onion : RecipientOnionFields ,
320
+ starting_htlc_offset : u32 , keysend_preimage : & Option < PaymentPreimage > ,
321
+ ) -> Result < ( Vec < msgs:: OutboundOnionPayload > , u64 , u32 ) , APIError > {
322
+ let mut cur_value_msat = 0u64 ;
323
+ let mut cur_cltv = starting_htlc_offset;
324
+ let mut res: Vec < msgs:: OutboundOnionPayload > = Vec :: with_capacity ( path. len ( ) ) ;
325
+ let mut last_node_id = None ;
326
+
327
+ for ( idx, hop) in path. iter ( ) . rev ( ) . enumerate ( ) {
328
+ // First hop gets special values so that it can check, on receipt, that everything is
329
+ // exactly as it should be (and the next hop isn't trying to probe to find out if we're
330
+ // the intended recipient).
331
+ let value_msat = if cur_value_msat == 0 { hop. fee_msat } else { cur_value_msat } ;
332
+ let cltv = if cur_cltv == starting_htlc_offset {
333
+ hop. cltv_expiry_delta + starting_htlc_offset
334
+ } else {
335
+ cur_cltv
336
+ } ;
337
+ if idx == 0 {
338
+ res. push ( msgs:: OutboundOnionPayload :: Receive {
339
+ payment_data : if let Some ( secret) = recipient_onion. payment_secret . take ( ) {
340
+ Some ( msgs:: FinalOnionHopData { payment_secret : secret, total_msat } )
341
+ } else {
342
+ None
343
+ } ,
344
+ payment_metadata : recipient_onion. payment_metadata . take ( ) ,
345
+ keysend_preimage : * keysend_preimage,
346
+ custom_tlvs : recipient_onion. custom_tlvs . clone ( ) ,
347
+ sender_intended_htlc_amt_msat : value_msat,
348
+ cltv_expiry_height : cltv,
349
+ } ) ;
350
+ } else {
351
+ res. insert (
352
+ 0 ,
353
+ msgs:: OutboundOnionPayload :: TrampolineForward {
354
+ amt_to_forward : value_msat,
355
+ outgoing_cltv_value : cltv,
356
+ outgoing_node_id : last_node_id. unwrap ( ) ,
357
+ } ,
358
+ ) ;
359
+ }
360
+ cur_value_msat += hop. fee_msat ;
361
+ if cur_value_msat >= 21000000 * 100000000 * 1000 {
362
+ return Err ( APIError :: InvalidRoute { err : "Channel fees overflowed?" . to_owned ( ) } ) ;
363
+ }
364
+ cur_cltv += hop. cltv_expiry_delta as u32 ;
365
+ if cur_cltv >= 500000000 {
366
+ return Err ( APIError :: InvalidRoute { err : "Channel CLTV overflowed?" . to_owned ( ) } ) ;
367
+ }
368
+ last_node_id = Some ( hop. pubkey ) ;
369
+ }
370
+ Ok ( ( res, cur_value_msat, cur_cltv) )
371
+ }
372
+
317
373
/// Length of the onion data packet. Before TLV-based onions this was 20 65-byte hops, though now
318
374
/// the hops can be of variable length.
319
375
pub ( crate ) const ONION_DATA_LEN : usize = 20 * 65 ;
0 commit comments