@@ -22,6 +22,7 @@ use crate::sign::{NodeSigner, Recipient};
22
22
use crate :: types:: features:: BlindedHopFeatures ;
23
23
use crate :: types:: payment:: PaymentHash ;
24
24
use crate :: util:: logger:: Logger ;
25
+ use crate :: util:: ser:: Writeable ;
25
26
26
27
#[ allow( unused_imports) ]
27
28
use crate :: prelude:: * ;
@@ -74,6 +75,24 @@ fn check_blinded_forward(
74
75
Ok ( ( amt_to_forward, outgoing_cltv_value) )
75
76
}
76
77
78
+ fn check_trampoline_onion_constraints (
79
+ outer_hop_data : & msgs:: InboundTrampolineEntrypointPayload , trampoline_cltv_value : u32 ,
80
+ trampoline_amount : u64 ,
81
+ ) -> Result < ( ) , LocalHTLCFailureReason > {
82
+ if outer_hop_data. outgoing_cltv_value < trampoline_cltv_value {
83
+ return Err ( LocalHTLCFailureReason :: FinalIncorrectCLTVExpiry ) ;
84
+ }
85
+ let outgoing_amount = outer_hop_data
86
+ . multipath_trampoline_data
87
+ . as_ref ( )
88
+ . map_or ( outer_hop_data. amt_to_forward , |mtd| mtd. total_msat ) ;
89
+ if outgoing_amount < trampoline_amount {
90
+ return Err ( LocalHTLCFailureReason :: FinalIncorrectHTLCAmount ) ;
91
+ }
92
+
93
+ Ok ( ( ) )
94
+ }
95
+
77
96
enum RoutingInfo {
78
97
Direct {
79
98
short_channel_id : u64 ,
@@ -135,7 +154,25 @@ pub(super) fn create_fwd_pending_htlc_info(
135
154
reason : LocalHTLCFailureReason :: InvalidOnionPayload ,
136
155
err_data : Vec :: new ( ) ,
137
156
} ) ,
138
- onion_utils:: Hop :: TrampolineForward { next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
157
+ onion_utils:: Hop :: TrampolineForward { ref outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
158
+ check_trampoline_onion_constraints ( outer_hop_data, next_trampoline_hop_data. outgoing_cltv_value , next_trampoline_hop_data. amt_to_forward ) . map_err ( |reason| {
159
+ let mut err_data = Vec :: new ( ) ;
160
+ match reason {
161
+ LocalHTLCFailureReason :: FinalIncorrectCLTVExpiry => {
162
+ outer_hop_data. outgoing_cltv_value . write ( & mut err_data) . unwrap ( ) ;
163
+ }
164
+ LocalHTLCFailureReason :: FinalIncorrectHTLCAmount => {
165
+ outer_hop_data. amt_to_forward . write ( & mut err_data) . unwrap ( ) ;
166
+ }
167
+ _ => unreachable ! ( )
168
+ }
169
+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's
170
+ InboundHTLCErr {
171
+ reason,
172
+ err_data,
173
+ msg : "Underflow calculating outbound amount or CLTV value for Trampoline forward" ,
174
+ }
175
+ } ) ?;
139
176
(
140
177
RoutingInfo :: Trampoline {
141
178
next_trampoline : next_trampoline_hop_data. next_trampoline ,
@@ -150,7 +187,7 @@ pub(super) fn create_fwd_pending_htlc_info(
150
187
None
151
188
)
152
189
} ,
153
- onion_utils:: Hop :: TrampolineBlindedForward { outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
190
+ onion_utils:: Hop :: TrampolineBlindedForward { ref outer_hop_data, next_trampoline_hop_data, next_trampoline_hop_hmac, new_trampoline_packet_bytes, trampoline_shared_secret, .. } => {
154
191
let ( amt_to_forward, outgoing_cltv_value) = check_blinded_forward (
155
192
msg. amount_msat , msg. cltv_expiry , & next_trampoline_hop_data. payment_relay , & next_trampoline_hop_data. payment_constraints , & next_trampoline_hop_data. features
156
193
) . map_err ( |( ) | {
@@ -162,6 +199,15 @@ pub(super) fn create_fwd_pending_htlc_info(
162
199
err_data : vec ! [ 0 ; 32 ] ,
163
200
}
164
201
} ) ?;
202
+ check_trampoline_onion_constraints ( outer_hop_data, outgoing_cltv_value, amt_to_forward) . map_err ( |_| {
203
+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's, but
204
+ // we're inside a blinded path
205
+ InboundHTLCErr {
206
+ reason : LocalHTLCFailureReason :: InvalidOnionBlinding ,
207
+ err_data : vec ! [ 0 ; 32 ] ,
208
+ msg : "Underflow calculating outbound amount or CLTV value for Trampoline forward" ,
209
+ }
210
+ } ) ?;
165
211
(
166
212
RoutingInfo :: Trampoline {
167
213
next_trampoline : next_trampoline_hop_data. next_trampoline ,
@@ -281,14 +327,35 @@ pub(super) fn create_recv_pending_htlc_info(
281
327
intro_node_blinding_point. is_none ( ) , true , invoice_request)
282
328
}
283
329
onion_utils:: Hop :: TrampolineReceive {
330
+ ref outer_hop_data,
284
331
trampoline_hop_data : msgs:: InboundOnionReceivePayload {
285
332
payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
286
333
cltv_expiry_height, payment_metadata, ..
287
334
} , ..
288
- } =>
335
+ } => {
336
+ check_trampoline_onion_constraints ( outer_hop_data, cltv_expiry_height, sender_intended_htlc_amt_msat) . map_err ( |reason| {
337
+ let mut err_data = Vec :: new ( ) ;
338
+ match reason {
339
+ LocalHTLCFailureReason :: FinalIncorrectCLTVExpiry => {
340
+ outer_hop_data. outgoing_cltv_value . write ( & mut err_data) . unwrap ( ) ;
341
+ }
342
+ LocalHTLCFailureReason :: FinalIncorrectHTLCAmount => {
343
+ outer_hop_data. amt_to_forward . write ( & mut err_data) . unwrap ( ) ;
344
+ }
345
+ _ => unreachable ! ( )
346
+ }
347
+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's
348
+ InboundHTLCErr {
349
+ reason,
350
+ err_data,
351
+ msg : "Underflow calculating skimmable amount or CLTV value for Trampoline receive" ,
352
+ }
353
+ } ) ?;
289
354
( payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
290
- cltv_expiry_height, payment_metadata, None , false , keysend_preimage. is_none ( ) , None ) ,
355
+ cltv_expiry_height, payment_metadata, None , false , keysend_preimage. is_none ( ) , None )
356
+ }
291
357
onion_utils:: Hop :: TrampolineBlindedReceive {
358
+ ref outer_hop_data,
292
359
trampoline_hop_data : msgs:: InboundOnionBlindedReceivePayload {
293
360
sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
294
361
intro_node_blinding_point, payment_constraints, payment_context, keysend_preimage,
@@ -306,6 +373,15 @@ pub(super) fn create_recv_pending_htlc_info(
306
373
}
307
374
} ) ?;
308
375
let payment_data = msgs:: FinalOnionHopData { payment_secret, total_msat } ;
376
+ check_trampoline_onion_constraints ( outer_hop_data, cltv_expiry_height, sender_intended_htlc_amt_msat) . map_err ( |_| {
377
+ // The Trampoline onion's amt and CLTV values cannot exceed the outer onion's, but
378
+ // we're inside a blinded path
379
+ InboundHTLCErr {
380
+ reason : LocalHTLCFailureReason :: InvalidOnionBlinding ,
381
+ err_data : vec ! [ 0 ; 32 ] ,
382
+ msg : "Underflow calculating skimmable amount or CLTV value for Trampoline receive" ,
383
+ }
384
+ } ) ?;
309
385
( Some ( payment_data) , keysend_preimage, custom_tlvs,
310
386
sender_intended_htlc_amt_msat, cltv_expiry_height, None , Some ( payment_context) ,
311
387
intro_node_blinding_point. is_none ( ) , true , invoice_request)
@@ -602,6 +678,25 @@ where
602
678
outgoing_cltv_value,
603
679
} )
604
680
}
681
+ onion_utils:: Hop :: TrampolineBlindedForward { next_trampoline_hop_data : msgs:: InboundTrampolineBlindedForwardPayload { next_trampoline, ref payment_relay, ref payment_constraints, ref features, .. } , outer_shared_secret, trampoline_shared_secret, incoming_trampoline_public_key, .. } => {
682
+ let ( amt_to_forward, outgoing_cltv_value) = match check_blinded_forward (
683
+ msg. amount_msat , msg. cltv_expiry , & payment_relay, & payment_constraints, & features
684
+ ) {
685
+ Ok ( ( amt, cltv) ) => ( amt, cltv) ,
686
+ Err ( ( ) ) => {
687
+ return encode_relay_error ( "Underflow calculating outbound amount or cltv value for blinded forward" ,
688
+ LocalHTLCFailureReason :: InvalidOnionBlinding , outer_shared_secret. secret_bytes ( ) , Some ( trampoline_shared_secret. secret_bytes ( ) ) , & [ 0 ; 32 ] ) ;
689
+ }
690
+ } ;
691
+ let next_trampoline_packet_pubkey = onion_utils:: next_hop_pubkey ( secp_ctx,
692
+ incoming_trampoline_public_key, & trampoline_shared_secret. secret_bytes ( ) ) ;
693
+ Some ( NextPacketDetails {
694
+ next_packet_pubkey : next_trampoline_packet_pubkey,
695
+ outgoing_connector : HopConnector :: Trampoline ( next_trampoline) ,
696
+ outgoing_amt_msat : amt_to_forward,
697
+ outgoing_cltv_value,
698
+ } )
699
+ }
605
700
_ => None
606
701
} ;
607
702
0 commit comments