@@ -3,9 +3,11 @@ use crate::events::Event;
33use crate :: events:: HTLCDestination ;
44use crate :: events:: MessageSendEvent ;
55use crate :: events:: MessageSendEventsProvider ;
6+ use crate :: ln:: channel:: DISCONNECT_PEER_AWAITING_RESPONSE_TICKS ;
67use crate :: ln:: channelmanager:: PaymentId ;
78use crate :: ln:: channelmanager:: RecipientOnionFields ;
89use crate :: ln:: functional_test_utils:: * ;
10+ use crate :: ln:: msgs;
911use crate :: ln:: msgs:: { ChannelMessageHandler , ErrorAction } ;
1012use crate :: util:: errors:: APIError ;
1113use crate :: util:: test_channel_signer:: SignerOp ;
@@ -410,3 +412,87 @@ fn quiescence_updates_go_to_holding_cell(fail_htlc: bool) {
410412 expect_payment_sent ( & nodes[ 1 ] , payment_preimage1, None , true , true ) ;
411413 }
412414}
415+
416+ #[ test]
417+ fn test_quiescence_timeout ( ) {
418+ // Test that we'll disconnect if we remain quiescent for `DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`.
419+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
420+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
421+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
422+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
423+ let chan_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) . 2 ;
424+
425+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
426+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
427+
428+ nodes[ 0 ] . node . maybe_propose_quiescence ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan_id) . unwrap ( ) ;
429+
430+ let stfu_initiator = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendStfu , node_id_1) ;
431+ nodes[ 1 ] . node . handle_stfu ( node_id_0, & stfu_initiator) ;
432+
433+ let stfu_responder = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendStfu , node_id_0) ;
434+ nodes[ 0 ] . node . handle_stfu ( node_id_1, & stfu_responder) ;
435+
436+ assert ! ( stfu_initiator. initiator && !stfu_responder. initiator) ;
437+
438+ for _ in 0 ..DISCONNECT_PEER_AWAITING_RESPONSE_TICKS {
439+ nodes[ 0 ] . node . timer_tick_occurred ( ) ;
440+ nodes[ 1 ] . node . timer_tick_occurred ( ) ;
441+ }
442+
443+ let f = |event| {
444+ if let MessageSendEvent :: HandleError { action, .. } = event {
445+ if let msgs:: ErrorAction :: DisconnectPeerWithWarning { .. } = action {
446+ Some ( ( ) )
447+ } else {
448+ None
449+ }
450+ } else {
451+ None
452+ }
453+ } ;
454+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . into_iter( ) . find_map( f) . is_some( ) ) ;
455+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . into_iter( ) . find_map( f) . is_some( ) ) ;
456+ }
457+
458+ #[ test]
459+ fn test_quiescence_timeout_while_waiting_for_counterparty_stfu ( ) {
460+ // Test that we'll disconnect if the counterparty does not send their stfu within a reasonable
461+ // time if we've already sent ours.
462+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
463+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
464+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
465+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
466+ let chan_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) . 2 ;
467+
468+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
469+
470+ nodes[ 1 ] . node . maybe_propose_quiescence ( & node_id_0, & chan_id) . unwrap ( ) ;
471+ let _ = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendStfu , node_id_0) ;
472+
473+ // Route a payment in between to ensure expecting to receive `revoke_and_ack` doesn't override
474+ // the expectation of receiving `stfu` as well.
475+ let _ = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1_000_000 ) ;
476+
477+ for _ in 0 ..DISCONNECT_PEER_AWAITING_RESPONSE_TICKS {
478+ nodes[ 0 ] . node . timer_tick_occurred ( ) ;
479+ nodes[ 1 ] . node . timer_tick_occurred ( ) ;
480+ }
481+
482+ // nodes[0] hasn't received stfu from nodes[1], so it's not enforcing any timeouts.
483+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
484+
485+ // nodes[1] didn't receive nodes[0]'s stfu within the timeout so it'll disconnect.
486+ let f = |& ref event| {
487+ if let MessageSendEvent :: HandleError { action, .. } = event {
488+ if let msgs:: ErrorAction :: DisconnectPeerWithWarning { .. } = action {
489+ Some ( ( ) )
490+ } else {
491+ None
492+ }
493+ } else {
494+ None
495+ }
496+ } ;
497+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . iter( ) . find_map( f) . is_some( ) ) ;
498+ }
0 commit comments