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