@@ -61,6 +61,16 @@ fn check_blinded_forward(
6161 Ok ( ( amt_to_forward, outgoing_cltv_value) )
6262}
6363
64+ fn check_trampoline_sanity ( outer_hop_data : & msgs:: InboundTrampolineEntrypointPayload , trampoline_cltv_value : u32 , trampoline_amount : u64 ) -> Result < ( ) , ( ) > {
65+ if outer_hop_data. outgoing_cltv_value < trampoline_cltv_value {
66+ return Err ( ( ) ) ;
67+ }
68+ if outer_hop_data. amt_to_forward < trampoline_amount {
69+ return Err ( ( ) ) ;
70+ }
71+ Ok ( ( ) )
72+ }
73+
6474enum RoutingInfo {
6575 Direct {
6676 short_channel_id : u64 ,
@@ -121,7 +131,15 @@ pub(super) fn create_fwd_pending_htlc_info(
121131 err_code : 0x4000 | 22 ,
122132 err_data : Vec :: new ( ) ,
123133 } ) ,
124- onion_utils:: Hop :: TrampolineForward { next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
134+ onion_utils:: Hop :: TrampolineForward { ref outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
135+ check_trampoline_sanity ( outer_hop_data, next_trampoline_hop_data. outgoing_cltv_value , next_trampoline_hop_data. amt_to_forward ) . map_err ( |( ) | {
136+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's
137+ InboundHTLCErr {
138+ msg : "Underflow calculating outbound amount or CLTV value for Trampoline forward" ,
139+ err_code : 0x2000 | 26 ,
140+ err_data : Vec :: new ( ) ,
141+ }
142+ } ) ?;
125143 (
126144 RoutingInfo :: Trampoline {
127145 next_trampoline : next_trampoline_hop_data. next_trampoline ,
@@ -136,7 +154,7 @@ pub(super) fn create_fwd_pending_htlc_info(
136154 None
137155 )
138156 } ,
139- onion_utils:: Hop :: TrampolineBlindedForward { outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
157+ onion_utils:: Hop :: TrampolineBlindedForward { ref outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
140158 let ( amt_to_forward, outgoing_cltv_value) = check_blinded_forward (
141159 msg. amount_msat , msg. cltv_expiry , & next_trampoline_hop_data. payment_relay , & next_trampoline_hop_data. payment_constraints , & next_trampoline_hop_data. features
142160 ) . map_err ( |( ) | {
@@ -148,6 +166,15 @@ pub(super) fn create_fwd_pending_htlc_info(
148166 err_data : vec ! [ 0 ; 32 ] ,
149167 }
150168 } ) ?;
169+ check_trampoline_sanity ( outer_hop_data, outgoing_cltv_value, amt_to_forward) . map_err ( |( ) | {
170+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's, but
171+ // we're inside a blinded path
172+ InboundHTLCErr {
173+ msg : "Underflow calculating outbound amount or CLTV value for Trampoline forward" ,
174+ err_code : INVALID_ONION_BLINDING ,
175+ err_data : vec ! [ 0 ; 32 ] ,
176+ }
177+ } ) ?;
151178 (
152179 RoutingInfo :: Trampoline {
153180 next_trampoline : next_trampoline_hop_data. next_trampoline ,
@@ -266,14 +293,25 @@ pub(super) fn create_recv_pending_htlc_info(
266293 intro_node_blinding_point. is_none ( ) , true , invoice_request)
267294 }
268295 onion_utils:: Hop :: TrampolineReceive {
296+ ref outer_hop_data,
269297 trampoline_hop_data : msgs:: InboundOnionReceivePayload {
270298 payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
271299 cltv_expiry_height, payment_metadata, ..
272300 } , ..
273- } =>
301+ } => {
302+ check_trampoline_sanity ( outer_hop_data, cltv_expiry_height, sender_intended_htlc_amt_msat) . map_err ( |( ) | {
303+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's
304+ InboundHTLCErr {
305+ msg : "Underflow calculating skimmable amount or CLTV value for Trampoline receive" ,
306+ err_code : 0x2000 | 26 ,
307+ err_data : Vec :: new ( ) ,
308+ }
309+ } ) ?;
274310 ( payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
275- cltv_expiry_height, payment_metadata, None , false , keysend_preimage. is_none ( ) , None ) ,
311+ cltv_expiry_height, payment_metadata, None , false , keysend_preimage. is_none ( ) , None )
312+ } ,
276313 onion_utils:: Hop :: TrampolineBlindedReceive {
314+ ref outer_hop_data,
277315 trampoline_hop_data : msgs:: InboundOnionBlindedReceivePayload {
278316 sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
279317 intro_node_blinding_point, payment_constraints, payment_context, keysend_preimage,
@@ -290,6 +328,15 @@ pub(super) fn create_recv_pending_htlc_info(
290328 msg : "Amount or cltv_expiry violated blinded payment constraints within Trampoline onion" ,
291329 }
292330 } ) ?;
331+ check_trampoline_sanity ( outer_hop_data, cltv_expiry_height, sender_intended_htlc_amt_msat) . map_err ( |( ) | {
332+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's, but
333+ // we're inside a blinded path
334+ InboundHTLCErr {
335+ msg : "Underflow calculating skimmable amount or CLTV value for Trampoline receive" ,
336+ err_code : INVALID_ONION_BLINDING ,
337+ err_data : vec ! [ 0 ; 32 ] ,
338+ }
339+ } ) ?;
293340 let payment_data = msgs:: FinalOnionHopData { payment_secret, total_msat } ;
294341 ( Some ( payment_data) , keysend_preimage, custom_tlvs,
295342 sender_intended_htlc_amt_msat, cltv_expiry_height, None , Some ( payment_context) ,
0 commit comments