@@ -68,6 +68,7 @@ fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>,
68
68
// 3: final node fails backward (but tamper onion payloads from node0)
69
69
// 100: trigger error in the intermediate node and tamper returning fail_htlc
70
70
// 200: trigger error in the final node and tamper returning fail_htlc
71
+ // 201: trigger error in the final node and delay
71
72
fn run_onion_failure_test_with_fail_intercept < F1 , F2 , F3 > (
72
73
_name : & str , test_case : u8 , nodes : & Vec < Node > , route : & Route , payment_hash : & PaymentHash ,
73
74
payment_secret : & PaymentSecret , mut callback_msg : F1 , mut callback_fail : F2 ,
@@ -122,10 +123,10 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(
122
123
assert ! ( update_1_0. update_fail_htlcs. len( ) +update_1_0. update_fail_malformed_htlcs. len( ) ==1 && ( update_1_0. update_fail_htlcs. len( ) ==1 || update_1_0. update_fail_malformed_htlcs. len( ) ==1 ) ) ;
123
124
update_1_0
124
125
} ,
125
- 1 |2 |3 |200 => { // final node failure; forwarding to 2
126
+ 1 |2 |3 |200 | 201 => { // final node failure; forwarding to 2
126
127
assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
127
128
// forwarding on 1
128
- if test_case != 200 {
129
+ if test_case != 200 && test_case != 201 {
129
130
callback_node ( ) ;
130
131
}
131
132
expect_htlc_forward ! ( & nodes[ 1 ] ) ;
@@ -143,23 +144,33 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(
143
144
nodes[ 2 ] . node . handle_update_add_htlc ( nodes[ 1 ] . node . get_our_node_id ( ) , & update_add_1) ;
144
145
commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 1 ] , update_1. commitment_signed, false , true ) ;
145
146
146
- if test_case == 2 || test_case == 200 {
147
- expect_htlc_forward ! ( & nodes[ 2 ] ) ;
148
- expect_event ! ( & nodes[ 2 ] , Event :: PaymentClaimable ) ;
149
- callback_node ( ) ;
150
- expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 2 ] , vec![ HTLCHandlingFailureType :: Receive { payment_hash: payment_hash. clone( ) } ] ) ;
151
- } else if test_case == 1 || test_case == 3 {
152
- expect_htlc_forward ! ( & nodes[ 2 ] ) ;
153
- expect_htlc_handling_failed_destinations ! ( nodes[ 2 ] . node. get_and_clear_pending_events( ) , vec![ expected_failure_type. clone( ) . unwrap( ) ] ) ;
147
+ match test_case {
148
+ 2 | 200 | 201 => {
149
+ expect_htlc_forward ! ( & nodes[ 2 ] ) ;
150
+ expect_event ! ( & nodes[ 2 ] , Event :: PaymentClaimable ) ;
151
+ callback_node ( ) ;
152
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 2 ] , vec![ HTLCHandlingFailureType :: Receive { payment_hash: payment_hash. clone( ) } ] ) ;
153
+ }
154
+ 1 | 3 => {
155
+ expect_htlc_forward ! ( & nodes[ 2 ] ) ;
156
+ expect_htlc_handling_failed_destinations ! ( nodes[ 2 ] . node. get_and_clear_pending_events( ) , vec![ expected_failure_type. clone( ) . unwrap( ) ] ) ;
157
+ }
158
+ _ => { }
154
159
}
155
160
check_added_monitors ! ( & nodes[ 2 ] , 1 ) ;
156
161
157
162
let update_2_1 = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
158
163
assert ! ( update_2_1. update_fail_htlcs. len( ) == 1 ) ;
159
164
160
165
let mut fail_msg = update_2_1. update_fail_htlcs [ 0 ] . clone ( ) ;
161
- if test_case == 200 {
162
- callback_fail ( & mut fail_msg) ;
166
+ match test_case {
167
+ // Trigger error in the final node and tamper returning fail_htlc.
168
+ 200 => callback_fail ( & mut fail_msg) ,
169
+ // Trigger error in the final node and delay.
170
+ 201 => {
171
+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 200 ) ) ;
172
+ } ,
173
+ _ => { }
163
174
}
164
175
165
176
// 2 => 1
@@ -189,7 +200,11 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(
189
200
190
201
let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
191
202
assert_eq ! ( events. len( ) , 2 ) ;
192
- if let & Event :: PaymentPathFailed { ref payment_failed_permanently, ref short_channel_id, ref error_code, failure : PathFailure :: OnPath { ref network_update } , .. } = & events[ 0 ] {
203
+ if let & Event :: PaymentPathFailed { ref payment_failed_permanently, ref short_channel_id, ref error_code, failure : PathFailure :: OnPath { ref network_update } , ref hold_times, ..} = & events[ 0 ] {
204
+ // When resolution is delayed, we expect that to show up in the hold times.
205
+ if test_case == 201 {
206
+ assert ! ( hold_times. iter( ) . any( |ht| * ht > 0 ) ) ;
207
+ }
193
208
assert_eq ! ( * payment_failed_permanently, !expected_retryable) ;
194
209
assert_eq ! ( error_code. is_none( ) , expected_error_reason. is_none( ) ) ;
195
210
if let Some ( expected_reason) = expected_error_reason {
@@ -778,6 +793,9 @@ fn test_onion_failure() {
778
793
is_permanent : false ,
779
794
} ) ,
780
795
Some ( channels[ 1 ] . 0 . contents . short_channel_id ) , None ) ;
796
+ run_onion_failure_test ( "delayed_fail" , 201 , & nodes, & route, & payment_hash, & payment_secret, |_| { } , || {
797
+ nodes[ 2 ] . node . fail_htlc_backwards ( & payment_hash) ;
798
+ } , false , Some ( LocalHTLCFailureReason :: IncorrectPaymentDetails ) , None , None , None ) ;
781
799
}
782
800
783
801
#[ test]
0 commit comments