99
1010use bitcoin:: secp256k1:: Secp256k1 ;
1111use crate :: blinded_path:: BlindedPath ;
12- use crate :: blinded_path:: payment:: { PaymentConstraints , ReceiveTlvs } ;
13- use crate :: ln:: channelmanager:: { PaymentId , RecipientOnionFields } ;
12+ use crate :: blinded_path:: payment:: { ForwardTlvs , PaymentConstraints , PaymentRelay , ReceiveTlvs } ;
13+ use crate :: events:: MessageSendEventsProvider ;
14+ use crate :: ln:: channelmanager:: { PaymentId , RecipientOnionFields , RetryableSendFailure } ;
15+ use crate :: ln:: features:: BlindedHopFeatures ;
1416use crate :: ln:: functional_test_utils:: * ;
17+ use crate :: ln:: msgs:: ChannelMessageHandler ;
1518use crate :: ln:: outbound_payment:: Retry ;
1619use crate :: prelude:: * ;
1720use crate :: routing:: router:: { PaymentParameters , RouteParameters } ;
1821
22+ #[ test]
23+ fn simple_blinded_payment ( ) {
24+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
25+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
26+ let mut cfg = test_default_channel_config ( ) ;
27+ // Test the fee_proportional_millionths specified in the blinded path's payment constraints.
28+ cfg. channel_config . forwarding_fee_proportional_millionths = 100 ;
29+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , Some ( cfg) , None ] ) ;
30+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
31+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
32+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) ;
33+ let chan_upd = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) . 0 . contents ;
34+
35+ let amt_msat = 5000 ;
36+ let ( payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 3 ] , Some ( amt_msat) , None ) ;
37+ let intermediate_nodes = vec ! [ ( nodes[ 2 ] . node. get_our_node_id( ) , ForwardTlvs {
38+ short_channel_id: chan_upd. short_channel_id,
39+ payment_relay: PaymentRelay {
40+ cltv_expiry_delta: chan_upd. cltv_expiry_delta,
41+ fee_proportional_millionths: chan_upd. fee_proportional_millionths,
42+ fee_base_msat: chan_upd. fee_base_msat,
43+ } ,
44+ payment_constraints: PaymentConstraints {
45+ max_cltv_expiry: u32 :: max_value( ) ,
46+ htlc_minimum_msat: chan_upd. htlc_minimum_msat,
47+ } ,
48+ features: BlindedHopFeatures :: empty( ) ,
49+ } ) ] ;
50+ let payee_tlvs = ReceiveTlvs {
51+ payment_secret,
52+ payment_constraints : PaymentConstraints {
53+ max_cltv_expiry : u32:: max_value ( ) ,
54+ htlc_minimum_msat : chan_upd. htlc_minimum_msat ,
55+ } ,
56+ } ;
57+ let mut secp_ctx = Secp256k1 :: new ( ) ;
58+ let blinded_path = BlindedPath :: new_for_payment (
59+ & intermediate_nodes[ ..] , nodes[ 3 ] . node . get_our_node_id ( ) , payee_tlvs,
60+ chan_upd. htlc_maximum_msat , & chanmon_cfgs[ 3 ] . keys_manager , & secp_ctx
61+ ) . unwrap ( ) ;
62+
63+ let route_params = RouteParameters {
64+ payment_params : PaymentParameters :: blinded ( vec ! [ blinded_path] ) ,
65+ final_value_msat : amt_msat
66+ } ;
67+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) , PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
68+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
69+ pass_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ] ] , amt_msat, payment_hash, payment_secret) ;
70+ claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ] , payment_preimage) ;
71+ }
72+
73+ #[ test]
74+ fn blinded_intercept_payment ( ) {
75+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
76+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
77+ let mut intercept_forwards_config = test_default_channel_config ( ) ;
78+ intercept_forwards_config. accept_intercept_htlcs = true ;
79+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , Some ( intercept_forwards_config) , None ] ) ;
80+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
81+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
82+ let chan = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) ;
83+ let ( channel_id, chan_upd) = ( chan. 2 , chan. 0 . contents ) ;
84+
85+ let amt_msat = 5000 ;
86+ let ( payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 2 ] , Some ( amt_msat) , None ) ;
87+ let intercept_scid = nodes[ 1 ] . node . get_intercept_scid ( ) ;
88+ let intermediate_nodes = vec ! [ ( nodes[ 1 ] . node. get_our_node_id( ) , ForwardTlvs {
89+ short_channel_id: intercept_scid,
90+ payment_relay: PaymentRelay {
91+ cltv_expiry_delta: chan_upd. cltv_expiry_delta,
92+ fee_proportional_millionths: chan_upd. fee_proportional_millionths,
93+ fee_base_msat: chan_upd. fee_base_msat,
94+ } ,
95+ payment_constraints: PaymentConstraints {
96+ max_cltv_expiry: u32 :: max_value( ) ,
97+ htlc_minimum_msat: chan_upd. htlc_minimum_msat,
98+ } ,
99+ features: BlindedHopFeatures :: empty( ) ,
100+ } ) ] ;
101+ let payee_tlvs = ReceiveTlvs {
102+ payment_secret,
103+ payment_constraints : PaymentConstraints {
104+ max_cltv_expiry : u32:: max_value ( ) ,
105+ htlc_minimum_msat : chan_upd. htlc_minimum_msat ,
106+ } ,
107+ } ;
108+ let mut secp_ctx = Secp256k1 :: new ( ) ;
109+ let blinded_path = BlindedPath :: new_for_payment (
110+ & intermediate_nodes[ ..] , nodes[ 2 ] . node . get_our_node_id ( ) , payee_tlvs,
111+ chan_upd. htlc_maximum_msat , & chanmon_cfgs[ 2 ] . keys_manager , & secp_ctx
112+ ) . unwrap ( ) ;
113+
114+ let route_params = RouteParameters {
115+ payment_params : PaymentParameters :: blinded ( vec ! [ blinded_path] ) ,
116+ final_value_msat : amt_msat
117+ } ;
118+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) ,
119+ PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
120+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
121+ let payment_event = {
122+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
123+ assert_eq ! ( events. len( ) , 1 ) ;
124+ SendEvent :: from_event ( events. remove ( 0 ) )
125+ } ;
126+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
127+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , & payment_event. commitment_msg, false , true ) ;
128+
129+ let events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
130+ assert_eq ! ( events. len( ) , 1 ) ;
131+ let ( intercept_id, expected_outbound_amount_msat) = match events[ 0 ] {
132+ crate :: events:: Event :: HTLCIntercepted {
133+ intercept_id, expected_outbound_amount_msat, payment_hash : pmt_hash,
134+ requested_next_hop_scid : short_channel_id, ..
135+ } => {
136+ assert_eq ! ( pmt_hash, payment_hash) ;
137+ assert_eq ! ( short_channel_id, intercept_scid) ;
138+ ( intercept_id, expected_outbound_amount_msat)
139+ } ,
140+ _ => panic ! ( )
141+ } ;
142+
143+ nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, & channel_id, nodes[ 2 ] . node . get_our_node_id ( ) ,
144+ expected_outbound_amount_msat) . unwrap ( ) ;
145+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
146+
147+ let payment_event = {
148+ {
149+ let mut added_monitors = nodes[ 1 ] . chain_monitor . added_monitors . lock ( ) . unwrap ( ) ;
150+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
151+ added_monitors. clear ( ) ;
152+ }
153+ let mut events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
154+ assert_eq ! ( events. len( ) , 1 ) ;
155+ SendEvent :: from_event ( events. remove ( 0 ) )
156+ } ;
157+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
158+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 1 ] , & payment_event. commitment_msg, false , true ) ;
159+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
160+
161+ expect_payment_claimable ! ( & nodes[ 2 ] , payment_hash, payment_secret, amt_msat, None ,
162+ nodes[ 2 ] . node. get_our_node_id( ) ) ;
163+ do_claim_payment_along_route ( & nodes[ 0 ] , & vec ! ( & vec!( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] ) , false , payment_preimage) ;
164+ expect_payment_sent ( & nodes[ 0 ] , payment_preimage, Some ( Some ( 1000 ) ) , true , true ) ;
165+ }
166+
19167#[ test]
20168fn one_hop_blinded_path ( ) {
21169 do_one_hop_blinded_path ( true ) ;
@@ -49,7 +197,7 @@ fn do_one_hop_blinded_path(success: bool) {
49197 final_value_msat : amt_msat
50198 } ;
51199 nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) ,
52- PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
200+ PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
53201 check_added_monitors ( & nodes[ 0 ] , 1 ) ;
54202 pass_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] ] ] , amt_msat, payment_hash, payment_secret) ;
55203 if success {
@@ -58,3 +206,86 @@ fn do_one_hop_blinded_path(success: bool) {
58206 fail_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , payment_hash) ;
59207 }
60208}
209+
210+ #[ test]
211+ fn min_htlc ( ) {
212+ // The min htlc of a blinded path is the max (htlc_min - following_fees) along the path. Make sure
213+ // the payment succeeds when we calculate the min htlc this way.
214+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
215+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
216+ let mut node_0_cfg = test_default_channel_config ( ) ;
217+ let mut node_1_cfg = test_default_channel_config ( ) ;
218+ node_1_cfg. channel_handshake_config . our_htlc_minimum_msat = 2000 ;
219+ node_1_cfg. channel_config . forwarding_fee_base_msat = 1000 ;
220+ let mut node_2_cfg = test_default_channel_config ( ) ;
221+ node_2_cfg. channel_handshake_config . our_htlc_minimum_msat = 5000 ;
222+ node_2_cfg. channel_config . forwarding_fee_base_msat = 200 ;
223+ let mut node_3_cfg = test_default_channel_config ( ) ;
224+ node_3_cfg. channel_handshake_config . our_htlc_minimum_msat = 2000 ;
225+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ Some ( node_0_cfg) , Some ( node_1_cfg) , Some ( node_2_cfg) , Some ( node_3_cfg) ] ) ;
226+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
227+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) . 0 . contents ;
228+ let chan_1_2 = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) ;
229+ let chan_2_3 = create_announced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) ;
230+ let chan_upd_1_2 = chan_1_2. 0 . contents ;
231+ let chan_upd_2_3 = chan_2_3. 0 . contents ;
232+
233+ let min_htlc_msat = 4800 ; // the resulting htlc min
234+ let ( payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 3 ] , Some ( min_htlc_msat) , None ) ;
235+ let intermediate_nodes = vec ! [ ( nodes[ 1 ] . node. get_our_node_id( ) , ForwardTlvs {
236+ short_channel_id: chan_upd_1_2. short_channel_id,
237+ payment_relay: PaymentRelay {
238+ cltv_expiry_delta: chan_upd_1_2. cltv_expiry_delta,
239+ fee_proportional_millionths: chan_upd_1_2. fee_proportional_millionths,
240+ fee_base_msat: chan_upd_1_2. fee_base_msat,
241+ } ,
242+ payment_constraints: PaymentConstraints {
243+ max_cltv_expiry: u32 :: max_value( ) ,
244+ htlc_minimum_msat: chan_upd_1_2. htlc_minimum_msat,
245+ } ,
246+ features: BlindedHopFeatures :: empty( ) ,
247+ } ) , ( nodes[ 2 ] . node. get_our_node_id( ) , ForwardTlvs {
248+ short_channel_id: chan_upd_2_3. short_channel_id,
249+ payment_relay: PaymentRelay {
250+ cltv_expiry_delta: chan_upd_2_3. cltv_expiry_delta,
251+ fee_proportional_millionths: chan_upd_2_3. fee_proportional_millionths,
252+ fee_base_msat: chan_upd_2_3. fee_base_msat,
253+ } ,
254+ payment_constraints: PaymentConstraints {
255+ max_cltv_expiry: u32 :: max_value( ) ,
256+ htlc_minimum_msat: chan_upd_2_3. htlc_minimum_msat,
257+ } ,
258+ features: BlindedHopFeatures :: empty( ) ,
259+ } ) ] ;
260+ let payee_tlvs = ReceiveTlvs {
261+ payment_secret,
262+ payment_constraints : PaymentConstraints {
263+ max_cltv_expiry : u32:: max_value ( ) ,
264+ htlc_minimum_msat : 1 ,
265+ } ,
266+ } ;
267+ let mut secp_ctx = Secp256k1 :: new ( ) ;
268+ let blinded_path = BlindedPath :: new_for_payment (
269+ & intermediate_nodes[ ..] , nodes[ 3 ] . node . get_our_node_id ( ) , payee_tlvs,
270+ chan_upd_2_3. htlc_maximum_msat , & chanmon_cfgs[ 3 ] . keys_manager , & secp_ctx
271+ ) . unwrap ( ) ;
272+ assert_eq ! ( min_htlc_msat, blinded_path. 0 . htlc_minimum_msat) ;
273+
274+ let route_params = RouteParameters {
275+ payment_params : PaymentParameters :: blinded ( vec ! [ blinded_path. clone( ) ] ) ,
276+ final_value_msat : min_htlc_msat,
277+ } ;
278+ nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) , PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) . unwrap ( ) ;
279+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
280+ pass_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ] ] , min_htlc_msat, payment_hash, payment_secret) ;
281+ claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] , & nodes[ 3 ] ] , payment_preimage) ;
282+
283+ // Paying 1 less than the min fails.
284+ let route_params = RouteParameters {
285+ payment_params : PaymentParameters :: blinded ( vec ! [ blinded_path] ) ,
286+ final_value_msat : min_htlc_msat - 1 ,
287+ } ;
288+ if let Err ( e) = nodes[ 0 ] . node . send_payment ( payment_hash, RecipientOnionFields :: spontaneous_empty ( ) , PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 0 ) ) {
289+ assert_eq ! ( e, RetryableSendFailure :: RouteNotFound ) ;
290+ } else { panic ! ( ) }
291+ }
0 commit comments