@@ -1331,14 +1331,63 @@ pub fn create_payment_onion<T: secp256k1::Signing>(
13311331 recipient_onion : RecipientOnionFields , cur_block_height : u32 , payment_hash : & PaymentHash ,
13321332 keysend_preimage : & Option < PaymentPreimage > , prng_seed : [ u8 ; 32 ] ,
13331333) -> Result < ( msgs:: OnionPacket , u64 , u32 ) , APIError > {
1334- let onion_keys = construct_onion_keys ( & secp_ctx, & path, & session_priv) . map_err ( |_| {
1334+ let mut outer_private_key = session_priv;
1335+ let mut outer_recipient_onion = RecipientOnion :: Final ( recipient_onion) ;
1336+ let mut outer_destinatation_msat = total_msat;
1337+ let mut outer_cltv = cur_block_height;
1338+
1339+ if !path. trampoline_hops . is_empty ( ) {
1340+ // TODO: replace outer_private_key to NOT be session_priv (pass in an entropy source?)
1341+
1342+ // unwrap the previously wrapped recipient onion
1343+ // TODO: find a way to make this less awkward
1344+ let RecipientOnion :: Final ( recipient_onion) = outer_recipient_onion else {
1345+ unreachable ! ( )
1346+ } ;
1347+
1348+ let trampoline_keys =
1349+ construct_trampoline_keys ( & secp_ctx, & path. trampoline_hops , & session_priv) . unwrap ( ) ;
1350+ let inner_recipient_onion = recipient_onion. clone ( ) ;
1351+ // ensure that there is no value inside the payment secret option
1352+ let ( trampoline_payloads, htlc_msat, htlc_cltv) = build_trampoline_payloads (
1353+ path,
1354+ total_msat,
1355+ inner_recipient_onion,
1356+ cur_block_height,
1357+ keysend_preimage,
1358+ ) ?;
1359+
1360+ // TODO: allow error conversion with ?
1361+ // TODO: calculate trampoline packet size (currently 650) dynamically
1362+ let trampoline_packet = construct_variable_length_onion_packet (
1363+ trampoline_payloads,
1364+ trampoline_keys,
1365+ prng_seed,
1366+ payment_hash,
1367+ 650 ,
1368+ )
1369+ . unwrap ( ) ;
1370+
1371+ let trampoline_onion = TrampolineEntryOnionFields {
1372+ trampoline_packet,
1373+ payment_metadata : recipient_onion. payment_metadata ,
1374+ custom_tlvs : recipient_onion. custom_tlvs ,
1375+ } ;
1376+ outer_recipient_onion = RecipientOnion :: TrampolineEntry ( trampoline_onion) ;
1377+
1378+ // TODO: introduce additional padding here?
1379+ outer_destinatation_msat = htlc_msat;
1380+ outer_cltv = htlc_cltv;
1381+ }
1382+
1383+ let onion_keys = construct_onion_keys ( & secp_ctx, & path, & outer_private_key) . map_err ( |_| {
13351384 APIError :: InvalidRoute { err : "Pubkey along hop was maliciously selected" . to_owned ( ) }
13361385 } ) ?;
13371386 let ( onion_payloads, htlc_msat, htlc_cltv) = build_onion_payloads (
13381387 & path,
1339- total_msat ,
1340- recipient_onion . into ( ) ,
1341- cur_block_height ,
1388+ outer_destinatation_msat ,
1389+ outer_recipient_onion ,
1390+ outer_cltv ,
13421391 keysend_preimage,
13431392 ) ?;
13441393 let onion_packet = construct_onion_packet ( onion_payloads, onion_keys, prng_seed, payment_hash)
0 commit comments