@@ -4674,7 +4674,7 @@ mod tests {
4674
4674
assert_eq ! ( channel_state. short_to_id. len( ) , 0 ) ;
4675
4675
}
4676
4676
4677
- fn reconnect_nodes ( node_a : & Node , node_b : & Node , pre_all_htlcs : bool , pending_htlc_claims : ( usize , usize ) , pending_htlc_fails : ( usize , usize ) ) {
4677
+ fn reconnect_nodes ( node_a : & Node , node_b : & Node , pre_all_htlcs : bool , pending_htlc_adds : ( i64 , i64 ) , pending_htlc_claims : ( usize , usize ) , pending_htlc_fails : ( usize , usize ) , pending_raa : ( bool , bool ) ) {
4678
4678
let reestablish_1 = node_a. node . peer_connected ( & node_b. node . get_our_node_id ( ) ) ;
4679
4679
let reestablish_2 = node_b. node . peer_connected ( & node_a. node . get_our_node_id ( ) ) ;
4680
4680
@@ -4703,26 +4703,47 @@ mod tests {
4703
4703
4704
4704
for chan_msgs in resp_1. drain ( ..) {
4705
4705
if pre_all_htlcs {
4706
- let _announcement_sigs_opt = node_a. node . handle_funding_locked ( & node_b. node . get_our_node_id ( ) , & chan_msgs. 0 . unwrap ( ) ) . unwrap ( ) ;
4706
+ let a = node_a. node . handle_funding_locked ( & node_b. node . get_our_node_id ( ) , & chan_msgs. 0 . unwrap ( ) ) ;
4707
+ let _announcement_sigs_opt = a. unwrap ( ) ;
4707
4708
//TODO: Test announcement_sigs re-sending when we've implemented it
4708
4709
} else {
4709
4710
assert ! ( chan_msgs. 0 . is_none( ) ) ;
4710
4711
}
4711
- assert ! ( chan_msgs. 1 . is_none( ) ) ;
4712
- if pending_htlc_claims. 0 != 0 || pending_htlc_fails. 0 != 0 {
4712
+ if pending_raa. 0 {
4713
+ assert ! ( node_a. node. handle_revoke_and_ack( & node_b. node. get_our_node_id( ) , & chan_msgs. 1 . unwrap( ) ) . unwrap( ) . is_none( ) ) ;
4714
+ check_added_monitors ! ( node_a, 1 ) ;
4715
+ } else {
4716
+ assert ! ( chan_msgs. 1 . is_none( ) ) ;
4717
+ }
4718
+ if pending_htlc_adds. 0 != 0 || pending_htlc_claims. 0 != 0 || pending_htlc_fails. 0 != 0 {
4713
4719
let commitment_update = chan_msgs. 2 . unwrap ( ) ;
4714
- assert ! ( commitment_update. update_add_htlcs. is_empty( ) ) ; // We can't relay while disconnected
4720
+ if pending_htlc_adds. 0 != -1 { // We use -1 to denote a response commitment_signed
4721
+ assert_eq ! ( commitment_update. update_add_htlcs. len( ) , pending_htlc_adds. 0 as usize ) ;
4722
+ } else {
4723
+ assert ! ( commitment_update. update_add_htlcs. is_empty( ) ) ;
4724
+ }
4715
4725
assert_eq ! ( commitment_update. update_fulfill_htlcs. len( ) , pending_htlc_claims. 0 ) ;
4716
4726
assert_eq ! ( commitment_update. update_fail_htlcs. len( ) , pending_htlc_fails. 0 ) ;
4717
4727
assert ! ( commitment_update. update_fail_malformed_htlcs. is_empty( ) ) ;
4728
+ for update_add in commitment_update. update_add_htlcs {
4729
+ node_a. node . handle_update_add_htlc ( & node_b. node . get_our_node_id ( ) , & update_add) . unwrap ( ) ;
4730
+ }
4718
4731
for update_fulfill in commitment_update. update_fulfill_htlcs {
4719
4732
node_a. node . handle_update_fulfill_htlc ( & node_b. node . get_our_node_id ( ) , & update_fulfill) . unwrap ( ) ;
4720
4733
}
4721
4734
for update_fail in commitment_update. update_fail_htlcs {
4722
4735
node_a. node . handle_update_fail_htlc ( & node_b. node . get_our_node_id ( ) , & update_fail) . unwrap ( ) ;
4723
4736
}
4724
4737
4725
- commitment_signed_dance ! ( node_a, node_b, commitment_update. commitment_signed, false ) ;
4738
+ if pending_htlc_adds. 0 != -1 { // We use -1 to denote a response commitment_signed
4739
+ commitment_signed_dance ! ( node_a, node_b, commitment_update. commitment_signed, false ) ;
4740
+ } else {
4741
+ let ( as_revoke_and_ack, as_commitment_signed) = node_a. node . handle_commitment_signed ( & node_b. node . get_our_node_id ( ) , & commitment_update. commitment_signed ) . unwrap ( ) ;
4742
+ check_added_monitors ! ( node_a, 1 ) ;
4743
+ assert ! ( as_commitment_signed. is_none( ) ) ;
4744
+ assert ! ( node_b. node. handle_revoke_and_ack( & node_a. node. get_our_node_id( ) , & as_revoke_and_ack) . unwrap( ) . is_none( ) ) ;
4745
+ check_added_monitors ! ( node_b, 1 ) ;
4746
+ }
4726
4747
} else {
4727
4748
assert ! ( chan_msgs. 2 . is_none( ) ) ;
4728
4749
}
@@ -4735,13 +4756,23 @@ mod tests {
4735
4756
} else {
4736
4757
assert ! ( chan_msgs. 0 . is_none( ) ) ;
4737
4758
}
4738
- assert ! ( chan_msgs. 1 . is_none( ) ) ;
4739
- if pending_htlc_claims. 1 != 0 || pending_htlc_fails. 1 != 0 {
4759
+ if pending_raa. 1 {
4760
+ assert ! ( node_b. node. handle_revoke_and_ack( & node_a. node. get_our_node_id( ) , & chan_msgs. 1 . unwrap( ) ) . unwrap( ) . is_none( ) ) ;
4761
+ check_added_monitors ! ( node_b, 1 ) ;
4762
+ } else {
4763
+ assert ! ( chan_msgs. 1 . is_none( ) ) ;
4764
+ }
4765
+ if pending_htlc_adds. 1 != 0 || pending_htlc_claims. 1 != 0 || pending_htlc_fails. 1 != 0 {
4740
4766
let commitment_update = chan_msgs. 2 . unwrap ( ) ;
4741
- assert ! ( commitment_update. update_add_htlcs. is_empty( ) ) ; // We can't relay while disconnected
4767
+ if pending_htlc_adds. 1 != -1 { // We use -1 to denote a response commitment_signed
4768
+ assert_eq ! ( commitment_update. update_add_htlcs. len( ) , pending_htlc_adds. 1 as usize ) ;
4769
+ }
4742
4770
assert_eq ! ( commitment_update. update_fulfill_htlcs. len( ) , pending_htlc_claims. 0 ) ;
4743
4771
assert_eq ! ( commitment_update. update_fail_htlcs. len( ) , pending_htlc_fails. 0 ) ;
4744
4772
assert ! ( commitment_update. update_fail_malformed_htlcs. is_empty( ) ) ;
4773
+ for update_add in commitment_update. update_add_htlcs {
4774
+ node_b. node . handle_update_add_htlc ( & node_a. node . get_our_node_id ( ) , & update_add) . unwrap ( ) ;
4775
+ }
4745
4776
for update_fulfill in commitment_update. update_fulfill_htlcs {
4746
4777
node_b. node . handle_update_fulfill_htlc ( & node_a. node . get_our_node_id ( ) , & update_fulfill) . unwrap ( ) ;
4747
4778
}
@@ -4765,7 +4796,7 @@ mod tests {
4765
4796
4766
4797
nodes[ 0 ] . node . peer_disconnected ( & nodes[ 1 ] . node . get_our_node_id ( ) , false ) ;
4767
4798
nodes[ 1 ] . node . peer_disconnected ( & nodes[ 0 ] . node . get_our_node_id ( ) , false ) ;
4768
- reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , true , ( 0 , 0 ) , ( 0 , 0 ) ) ;
4799
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , true , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , false ) ) ;
4769
4800
4770
4801
let payment_preimage_1 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 0 ;
4771
4802
let payment_hash_2 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 1 ;
@@ -4774,7 +4805,7 @@ mod tests {
4774
4805
4775
4806
nodes[ 0 ] . node . peer_disconnected ( & nodes[ 1 ] . node . get_our_node_id ( ) , false ) ;
4776
4807
nodes[ 1 ] . node . peer_disconnected ( & nodes[ 0 ] . node . get_our_node_id ( ) , false ) ;
4777
- reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( 0 , 0 ) , ( 0 , 0 ) ) ;
4808
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , false ) ) ;
4778
4809
4779
4810
let payment_preimage_3 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 0 ;
4780
4811
let payment_preimage_4 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 0 ;
@@ -4787,7 +4818,7 @@ mod tests {
4787
4818
claim_payment_along_route ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) , true , payment_preimage_3) ;
4788
4819
fail_payment_along_route ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , true , payment_hash_5) ;
4789
4820
4790
- reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( 1 , 0 ) , ( 1 , 0 ) ) ;
4821
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( 0 , 0 ) , ( 1 , 0 ) , ( 1 , 0 ) , ( false , false ) ) ;
4791
4822
{
4792
4823
let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
4793
4824
assert_eq ! ( events. len( ) , 2 ) ;
@@ -4809,6 +4840,128 @@ mod tests {
4809
4840
fail_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) , payment_hash_6) ;
4810
4841
}
4811
4842
4843
+ fn do_test_drop_messages_peer_disconnect ( messages_delivered : u8 ) {
4844
+ // Test that we can reconnect when in-flight HTLC updates get dropped
4845
+ let mut nodes = create_network ( 3 ) ;
4846
+ create_announced_chan_between_nodes ( & nodes, 1 , 2 ) ;
4847
+ if messages_delivered == 0 {
4848
+ create_chan_between_nodes_with_value_a ( & nodes[ 0 ] , & nodes[ 1 ] , 100000 , 10001 ) ;
4849
+ // nodes[1] doesn't receive the funding_locked message (it'll be re-sent on reconnect)
4850
+ } else {
4851
+ create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
4852
+ }
4853
+
4854
+ let route = nodes[ 0 ] . router . get_route ( & nodes[ 2 ] . node . get_our_node_id ( ) , Some ( & nodes[ 0 ] . node . list_usable_channels ( ) ) , & Vec :: new ( ) , 1000000 , TEST_FINAL_CLTV ) . unwrap ( ) ;
4855
+ let ( our_payment_preimage, our_payment_hash) = get_payment_preimage_hash ! ( nodes[ 0 ] ) ;
4856
+
4857
+ let mut payment_event = {
4858
+ nodes[ 0 ] . node . send_payment ( route, our_payment_hash) . unwrap ( ) ;
4859
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
4860
+
4861
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
4862
+ assert_eq ! ( events. len( ) , 1 ) ;
4863
+ SendEvent :: from_event ( events. remove ( 0 ) )
4864
+ } ;
4865
+ assert_eq ! ( nodes[ 1 ] . node. get_our_node_id( ) , payment_event. node_id) ;
4866
+
4867
+ if messages_delivered < 2 {
4868
+ // Drop the payment_event messages, and let them get re-generated in reconnect_nodes!
4869
+ } else {
4870
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) . unwrap ( ) ;
4871
+ let ( bs_revoke_and_ack, bs_commitment_signed) = nodes[ 1 ] . node . handle_commitment_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) , & payment_event. commitment_msg ) . unwrap ( ) ;
4872
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
4873
+ if messages_delivered >= 3 {
4874
+ assert ! ( nodes[ 0 ] . node. handle_revoke_and_ack( & nodes[ 1 ] . node. get_our_node_id( ) , & bs_revoke_and_ack) . unwrap( ) . is_none( ) ) ;
4875
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
4876
+ if messages_delivered >= 4 {
4877
+ let ( as_revoke_and_ack, as_commitment_signed) = nodes[ 0 ] . node . handle_commitment_signed ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_commitment_signed. unwrap ( ) ) . unwrap ( ) ;
4878
+ assert ! ( as_commitment_signed. is_none( ) ) ;
4879
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
4880
+ if messages_delivered >= 5 {
4881
+ assert ! ( nodes[ 1 ] . node. handle_revoke_and_ack( & nodes[ 0 ] . node. get_our_node_id( ) , & as_revoke_and_ack) . unwrap( ) . is_none( ) ) ;
4882
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
4883
+ }
4884
+ }
4885
+ }
4886
+ }
4887
+
4888
+ nodes[ 0 ] . node . peer_disconnected ( & nodes[ 1 ] . node . get_our_node_id ( ) , false ) ;
4889
+ nodes[ 1 ] . node . peer_disconnected ( & nodes[ 0 ] . node . get_our_node_id ( ) , false ) ;
4890
+ if messages_delivered < 2 {
4891
+ // Even if the funding_locked messages get exchanged, as long as nothing further was
4892
+ // received on either side, both sides will need to resend them.
4893
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , true , ( 0 , 1 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , false ) ) ;
4894
+ } else if messages_delivered == 2 {
4895
+ // nodes[0] still wants its RAA + commitment_signed
4896
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( -1 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( true , false ) ) ;
4897
+ } else if messages_delivered == 3 {
4898
+ // nodes[0] still wants its commitment_signed
4899
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( -1 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , false ) ) ;
4900
+ } else if messages_delivered == 4 {
4901
+ // nodes[1] still wants its final RAA
4902
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , true ) ) ;
4903
+ } else if messages_delivered == 5 {
4904
+ // Everything was delivered...
4905
+ reconnect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] , false , ( 0 , 0 ) , ( 0 , 0 ) , ( 0 , 0 ) , ( false , false ) ) ;
4906
+ }
4907
+
4908
+ let events_1 = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
4909
+ assert_eq ! ( events_1. len( ) , 1 ) ;
4910
+ match events_1[ 0 ] {
4911
+ Event :: PendingHTLCsForwardable { .. } => { } ,
4912
+ _ => panic ! ( "Unexpected event" ) ,
4913
+ } ;
4914
+
4915
+ nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . next_forward = Instant :: now ( ) ;
4916
+ nodes[ 1 ] . node . process_pending_htlc_forwards ( ) ;
4917
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
4918
+
4919
+ let mut events_2 = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
4920
+ payment_event = SendEvent :: from_event ( events_2. remove ( 0 ) ) ;
4921
+ assert_eq ! ( payment_event. msgs. len( ) , 1 ) ;
4922
+ assert_eq ! ( nodes[ 2 ] . node. get_our_node_id( ) , payment_event. node_id) ;
4923
+
4924
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) . unwrap ( ) ;
4925
+ check_added_monitors ! ( nodes[ 2 ] , 0 ) ;
4926
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 1 ] , payment_event. commitment_msg, false ) ;
4927
+
4928
+ let events_2 = nodes[ 2 ] . node . get_and_clear_pending_events ( ) ;
4929
+ assert_eq ! ( events_2. len( ) , 1 ) ;
4930
+ match events_2[ 0 ] {
4931
+ Event :: PendingHTLCsForwardable { .. } => { } ,
4932
+ _ => panic ! ( "Unexpected event" ) ,
4933
+ } ;
4934
+
4935
+ nodes[ 2 ] . node . channel_state . lock ( ) . unwrap ( ) . next_forward = Instant :: now ( ) ;
4936
+ nodes[ 2 ] . node . process_pending_htlc_forwards ( ) ;
4937
+
4938
+ let events_3 = nodes[ 2 ] . node . get_and_clear_pending_events ( ) ;
4939
+ assert_eq ! ( events_3. len( ) , 1 ) ;
4940
+ match events_3[ 0 ] {
4941
+ Event :: PaymentReceived { ref payment_hash, amt } => {
4942
+ assert_eq ! ( our_payment_hash, * payment_hash) ;
4943
+ assert_eq ! ( amt, 1000000 ) ;
4944
+ } ,
4945
+ _ => panic ! ( "Unexpected event" ) ,
4946
+ }
4947
+
4948
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) , our_payment_preimage) ;
4949
+ }
4950
+
4951
+ #[ test]
4952
+ fn test_drop_messages_peer_disconnect_a ( ) {
4953
+ do_test_drop_messages_peer_disconnect ( 0 ) ;
4954
+ do_test_drop_messages_peer_disconnect ( 1 ) ;
4955
+ do_test_drop_messages_peer_disconnect ( 2 ) ;
4956
+ }
4957
+
4958
+ #[ test]
4959
+ fn test_drop_messages_peer_disconnect_b ( ) {
4960
+ do_test_drop_messages_peer_disconnect ( 3 ) ;
4961
+ do_test_drop_messages_peer_disconnect ( 4 ) ;
4962
+ do_test_drop_messages_peer_disconnect ( 5 ) ;
4963
+ }
4964
+
4812
4965
#[ test]
4813
4966
fn test_invalid_channel_announcement ( ) {
4814
4967
//Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs
0 commit comments