@@ -12,7 +12,7 @@ use crate::ln::channelmanager::{HTLCSource, RecipientOnionFields};
1212use crate :: ln:: msgs;
1313use crate :: ln:: wire:: Encode ;
1414use crate :: routing:: gossip:: NetworkUpdate ;
15- use crate :: routing:: router:: { Path , RouteHop } ;
15+ use crate :: routing:: router:: { BlindedTail , Path , RouteHop } ;
1616use crate :: util:: chacha20:: { ChaCha20 , ChaChaReader } ;
1717use crate :: util:: errors:: { self , APIError } ;
1818use crate :: util:: ser:: { Readable , ReadableArgs , Writeable , Writer , LengthCalculatingWriter } ;
@@ -169,35 +169,61 @@ pub(super) fn build_onion_payloads(path: &Path, total_msat: u64, mut recipient_o
169169 let mut cur_value_msat = 0u64 ;
170170 let mut cur_cltv = starting_htlc_offset;
171171 let mut last_short_channel_id = 0 ;
172- let mut res: Vec < msgs:: OutboundOnionPayload > = Vec :: with_capacity ( path. hops . len ( ) ) ;
172+ let mut res: Vec < msgs:: OutboundOnionPayload > = Vec :: with_capacity (
173+ path. hops . len ( ) + path. blinded_tail . as_ref ( ) . map_or ( 0 , |t| t. hops . len ( ) )
174+ ) ;
173175
174176 for ( idx, hop) in path. hops . iter ( ) . rev ( ) . enumerate ( ) {
175177 // First hop gets special values so that it can check, on receipt, that everything is
176178 // exactly as it should be (and the next hop isn't trying to probe to find out if we're
177179 // the intended recipient).
178180 let value_msat = if cur_value_msat == 0 { hop. fee_msat } else { cur_value_msat } ;
179181 let cltv = if cur_cltv == starting_htlc_offset { hop. cltv_expiry_delta + starting_htlc_offset } else { cur_cltv } ;
180- res. insert ( 0 , if idx == 0 {
181- msgs:: OutboundOnionPayload :: Receive {
182- payment_data : if let Some ( secret) = recipient_onion. payment_secret . take ( ) {
183- Some ( msgs:: FinalOnionHopData {
184- payment_secret : secret,
185- total_msat,
186- } )
187- } else { None } ,
188- payment_metadata : recipient_onion. payment_metadata . take ( ) ,
189- keysend_preimage : * keysend_preimage,
190- custom_tlvs : recipient_onion. custom_tlvs . clone ( ) ,
191- amt_msat : value_msat,
192- outgoing_cltv_value : cltv,
182+ if idx == 0 {
183+ if let Some ( BlindedTail {
184+ blinding_point, hops, final_value_msat, excess_final_cltv_expiry_delta, ..
185+ } ) = & path. blinded_tail {
186+ let mut blinding_point = Some ( * blinding_point) ;
187+ for ( i, blinded_hop) in hops. iter ( ) . enumerate ( ) {
188+ if i == hops. len ( ) - 1 {
189+ cur_value_msat += final_value_msat;
190+ cur_cltv += excess_final_cltv_expiry_delta;
191+ res. push ( msgs:: OutboundOnionPayload :: BlindedReceive {
192+ amt_msat : * final_value_msat,
193+ total_msat,
194+ outgoing_cltv_value : cltv,
195+ encrypted_tlvs : blinded_hop. encrypted_payload . clone ( ) ,
196+ intro_node_blinding_point : blinding_point. take ( ) ,
197+ } ) ;
198+ } else {
199+ res. push ( msgs:: OutboundOnionPayload :: BlindedForward {
200+ encrypted_tlvs : blinded_hop. encrypted_payload . clone ( ) ,
201+ intro_node_blinding_point : blinding_point. take ( ) ,
202+ } ) ;
203+ }
204+ }
205+ } else {
206+ res. push ( msgs:: OutboundOnionPayload :: Receive {
207+ payment_data : if let Some ( secret) = recipient_onion. payment_secret . take ( ) {
208+ Some ( msgs:: FinalOnionHopData {
209+ payment_secret : secret,
210+ total_msat,
211+ } )
212+ } else { None } ,
213+ payment_metadata : recipient_onion. payment_metadata . take ( ) ,
214+ keysend_preimage : * keysend_preimage,
215+ custom_tlvs : recipient_onion. custom_tlvs . clone ( ) ,
216+ amt_msat : value_msat,
217+ outgoing_cltv_value : cltv,
218+ } ) ;
193219 }
194220 } else {
195- msgs:: OutboundOnionPayload :: Forward {
221+ res . insert ( 0 , msgs:: OutboundOnionPayload :: Forward {
196222 short_channel_id : last_short_channel_id,
197223 amt_to_forward : value_msat,
198224 outgoing_cltv_value : cltv,
199- }
200- } ) ;
225+ } ) ;
226+ }
201227 cur_value_msat += hop. fee_msat ;
202228 if cur_value_msat >= 21000000 * 100000000 * 1000 {
203229 return Err ( APIError :: InvalidRoute { err : "Channel fees overflowed?" . to_owned ( ) } ) ;
0 commit comments