@@ -4674,7 +4674,7 @@ mod tests {
46744674 assert_eq ! ( channel_state. short_to_id. len( ) , 0 ) ;
46754675 }
46764676
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 ) ) {
46784678 let reestablish_1 = node_a. node . peer_connected ( & node_b. node . get_our_node_id ( ) ) ;
46794679 let reestablish_2 = node_b. node . peer_connected ( & node_a. node . get_our_node_id ( ) ) ;
46804680
@@ -4703,26 +4703,47 @@ mod tests {
47034703
47044704 for chan_msgs in resp_1. drain ( ..) {
47054705 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 ( ) ;
47074708 //TODO: Test announcement_sigs re-sending when we've implemented it
47084709 } else {
47094710 assert ! ( chan_msgs. 0 . is_none( ) ) ;
47104711 }
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 {
47134719 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+ }
47154725 assert_eq ! ( commitment_update. update_fulfill_htlcs. len( ) , pending_htlc_claims. 0 ) ;
47164726 assert_eq ! ( commitment_update. update_fail_htlcs. len( ) , pending_htlc_fails. 0 ) ;
47174727 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+ }
47184731 for update_fulfill in commitment_update. update_fulfill_htlcs {
47194732 node_a. node . handle_update_fulfill_htlc ( & node_b. node . get_our_node_id ( ) , & update_fulfill) . unwrap ( ) ;
47204733 }
47214734 for update_fail in commitment_update. update_fail_htlcs {
47224735 node_a. node . handle_update_fail_htlc ( & node_b. node . get_our_node_id ( ) , & update_fail) . unwrap ( ) ;
47234736 }
47244737
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+ }
47264747 } else {
47274748 assert ! ( chan_msgs. 2 . is_none( ) ) ;
47284749 }
@@ -4735,13 +4756,23 @@ mod tests {
47354756 } else {
47364757 assert ! ( chan_msgs. 0 . is_none( ) ) ;
47374758 }
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 {
47404766 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+ }
47424770 assert_eq ! ( commitment_update. update_fulfill_htlcs. len( ) , pending_htlc_claims. 0 ) ;
47434771 assert_eq ! ( commitment_update. update_fail_htlcs. len( ) , pending_htlc_fails. 0 ) ;
47444772 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+ }
47454776 for update_fulfill in commitment_update. update_fulfill_htlcs {
47464777 node_b. node . handle_update_fulfill_htlc ( & node_a. node . get_our_node_id ( ) , & update_fulfill) . unwrap ( ) ;
47474778 }
@@ -4765,7 +4796,7 @@ mod tests {
47654796
47664797 nodes[ 0 ] . node . peer_disconnected ( & nodes[ 1 ] . node . get_our_node_id ( ) , false ) ;
47674798 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 ) ) ;
47694800
47704801 let payment_preimage_1 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 0 ;
47714802 let payment_hash_2 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 1 ;
@@ -4774,7 +4805,7 @@ mod tests {
47744805
47754806 nodes[ 0 ] . node . peer_disconnected ( & nodes[ 1 ] . node . get_our_node_id ( ) , false ) ;
47764807 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 ) ) ;
47784809
47794810 let payment_preimage_3 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 0 ;
47804811 let payment_preimage_4 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 1000000 ) . 0 ;
@@ -4787,7 +4818,7 @@ mod tests {
47874818 claim_payment_along_route ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) , true , payment_preimage_3) ;
47884819 fail_payment_along_route ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , true , payment_hash_5) ;
47894820
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 ) ) ;
47914822 {
47924823 let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
47934824 assert_eq ! ( events. len( ) , 2 ) ;
@@ -4809,6 +4840,128 @@ mod tests {
48094840 fail_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) , payment_hash_6) ;
48104841 }
48114842
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+
48124965 #[ test]
48134966 fn test_invalid_channel_announcement ( ) {
48144967 //Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs
0 commit comments