@@ -94,6 +94,7 @@ fn run_onion_failure_test<F1, F2>(
94
94
// 3: final node fails backward (but tamper onion payloads from node0)
95
95
// 100: trigger error in the intermediate node and tamper returning fail_htlc
96
96
// 200: trigger error in the final node and tamper returning fail_htlc
97
+ // 201: trigger error in the final node and delay
97
98
fn run_onion_failure_test_with_fail_intercept < F1 , F2 , F3 > (
98
99
_name : & str , test_case : u8 , nodes : & Vec < Node > , route : & Route , payment_hash : & PaymentHash ,
99
100
payment_secret : & PaymentSecret , mut callback_msg : F1 , mut callback_fail : F2 ,
@@ -164,11 +165,11 @@ fn run_onion_failure_test_with_fail_intercept<F1, F2, F3>(
164
165
) ;
165
166
update_1_0
166
167
} ,
167
- 1 | 2 | 3 | 200 => {
168
+ 1 | 2 | 3 | 200 | 201 => {
168
169
// final node failure; forwarding to 2
169
170
assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
170
171
// forwarding on 1
171
- if test_case != 200 {
172
+ if test_case != 200 && test_case != 201 {
172
173
callback_node ( ) ;
173
174
}
174
175
expect_htlc_forward ! ( & nodes[ 1 ] ) ;
@@ -186,29 +187,41 @@ fn run_onion_failure_test_with_fail_intercept<F1, F2, F3>(
186
187
nodes[ 2 ] . node . handle_update_add_htlc ( nodes[ 1 ] . node . get_our_node_id ( ) , & update_add_1) ;
187
188
commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 1 ] , update_1. commitment_signed, false , true ) ;
188
189
189
- if test_case == 2 || test_case == 200 {
190
- expect_htlc_forward ! ( & nodes[ 2 ] ) ;
191
- expect_event ! ( & nodes[ 2 ] , Event :: PaymentClaimable ) ;
192
- callback_node ( ) ;
193
- expect_pending_htlcs_forwardable_and_htlc_handling_failed ! (
194
- nodes[ 2 ] ,
195
- vec![ HTLCHandlingFailureType :: Receive { payment_hash: payment_hash. clone( ) } ]
196
- ) ;
197
- } else if test_case == 1 || test_case == 3 {
198
- expect_htlc_forward ! ( & nodes[ 2 ] ) ;
199
- expect_htlc_handling_failed_destinations ! (
200
- nodes[ 2 ] . node. get_and_clear_pending_events( ) ,
201
- vec![ expected_failure_type. clone( ) . unwrap( ) ]
202
- ) ;
190
+ match test_case {
191
+ 2 | 200 | 201 => {
192
+ expect_htlc_forward ! ( & nodes[ 2 ] ) ;
193
+ expect_event ! ( & nodes[ 2 ] , Event :: PaymentClaimable ) ;
194
+ callback_node ( ) ;
195
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! (
196
+ nodes[ 2 ] ,
197
+ vec![ HTLCHandlingFailureType :: Receive {
198
+ payment_hash: payment_hash. clone( )
199
+ } ]
200
+ ) ;
201
+ } ,
202
+ 1 | 3 => {
203
+ expect_htlc_forward ! ( & nodes[ 2 ] ) ;
204
+ expect_htlc_handling_failed_destinations ! (
205
+ nodes[ 2 ] . node. get_and_clear_pending_events( ) ,
206
+ vec![ expected_failure_type. clone( ) . unwrap( ) ]
207
+ ) ;
208
+ } ,
209
+ _ => { } ,
203
210
}
204
211
check_added_monitors ! ( & nodes[ 2 ] , 1 ) ;
205
212
206
213
let update_2_1 = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
207
214
assert ! ( update_2_1. update_fail_htlcs. len( ) == 1 ) ;
208
215
209
216
let mut fail_msg = update_2_1. update_fail_htlcs [ 0 ] . clone ( ) ;
210
- if test_case == 200 {
211
- callback_fail ( & mut fail_msg) ;
217
+ match test_case {
218
+ // Trigger error in the final node and tamper returning fail_htlc.
219
+ 200 => callback_fail ( & mut fail_msg) ,
220
+ // Trigger error in the final node and delay.
221
+ 201 => {
222
+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 200 ) ) ;
223
+ } ,
224
+ _ => { } ,
212
225
}
213
226
214
227
// 2 => 1
@@ -246,9 +259,15 @@ fn run_onion_failure_test_with_fail_intercept<F1, F2, F3>(
246
259
ref short_channel_id,
247
260
ref error_code,
248
261
failure : PathFailure :: OnPath { ref network_update } ,
262
+ ref hold_times,
249
263
..
250
264
} = & events[ 0 ]
251
265
{
266
+ // When resolution is delayed, we expect that to show up in the hold times. Hold times are only reported in std.
267
+ #[ cfg( feature = "std" ) ]
268
+ if test_case == 201 {
269
+ assert ! ( hold_times. iter( ) . any( |ht| * ht > 0 ) ) ;
270
+ }
252
271
assert_eq ! ( * payment_failed_permanently, !expected_retryable) ;
253
272
assert_eq ! ( error_code. is_none( ) , expected_error_reason. is_none( ) ) ;
254
273
if let Some ( expected_reason) = expected_error_reason {
@@ -1581,6 +1600,23 @@ fn test_onion_failure() {
1581
1600
Some ( channels[ 1 ] . 0 . contents . short_channel_id ) ,
1582
1601
None ,
1583
1602
) ;
1603
+ run_onion_failure_test (
1604
+ "delayed_fail" ,
1605
+ 201 ,
1606
+ & nodes,
1607
+ & route,
1608
+ & payment_hash,
1609
+ & payment_secret,
1610
+ |_| { } ,
1611
+ || {
1612
+ nodes[ 2 ] . node . fail_htlc_backwards ( & payment_hash) ;
1613
+ } ,
1614
+ false ,
1615
+ Some ( LocalHTLCFailureReason :: IncorrectPaymentDetails ) ,
1616
+ None ,
1617
+ None ,
1618
+ None ,
1619
+ ) ;
1584
1620
}
1585
1621
1586
1622
#[ test]
0 commit comments