@@ -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 ;
1113
@@ -373,3 +375,88 @@ fn quiescence_updates_go_to_holding_cell(fail_htlc: bool) {
373375 expect_payment_sent ( & nodes[ 1 ] , payment_preimage1, None , true , true ) ;
374376 }
375377}
378+
379+ #[ test]
380+ fn test_quiescence_timeout ( ) {
381+ // Test that we'll disconnect if we remain quiescent for `DISCONNECT_PEER_AWAITING_RESPONSE_TICKS`.
382+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
383+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
384+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
385+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
386+ let chan_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) . 2 ;
387+
388+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
389+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
390+
391+ nodes[ 0 ] . node . maybe_propose_quiescence ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan_id) . unwrap ( ) ;
392+
393+ let stfu_initiator = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendStfu , node_id_1) ;
394+ nodes[ 1 ] . node . handle_stfu ( node_id_0, & stfu_initiator) ;
395+
396+ let stfu_responder = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendStfu , node_id_0) ;
397+ nodes[ 0 ] . node . handle_stfu ( node_id_1, & stfu_responder) ;
398+
399+ assert ! ( stfu_initiator. initiator && !stfu_responder. initiator) ;
400+
401+ for _ in 0 ..DISCONNECT_PEER_AWAITING_RESPONSE_TICKS {
402+ nodes[ 0 ] . node . timer_tick_occurred ( ) ;
403+ nodes[ 1 ] . node . timer_tick_occurred ( ) ;
404+ }
405+
406+ let f = |event| {
407+ if let MessageSendEvent :: HandleError { action, .. } = event {
408+ if let msgs:: ErrorAction :: DisconnectPeerWithWarning { .. } = action {
409+ Some ( ( ) )
410+ } else {
411+ None
412+ }
413+ } else {
414+ None
415+ }
416+ } ;
417+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . into_iter( ) . find_map( f) . is_some( ) ) ;
418+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . into_iter( ) . find_map( f) . is_some( ) ) ;
419+ }
420+
421+ #[ test]
422+ fn test_quiescence_timeout_while_waiting_for_counterparty_stfu ( ) {
423+ // Test that we'll disconnect if the counterparty does not send their stfu within a reasonable
424+ // time if we've already sent ours.
425+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
426+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
427+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
428+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
429+ let chan_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) . 2 ;
430+
431+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
432+
433+ nodes[ 1 ] . node . maybe_propose_quiescence ( & node_id_0, & chan_id) . unwrap ( ) ;
434+ let _ = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendStfu , node_id_0) ;
435+
436+ // Route a payment in between to ensure expecting to receive `revoke_and_ack` doesn't override
437+ // the expectation of receiving `stfu` as well.
438+ let _ = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1_000_000 ) ;
439+
440+ for _ in 0 ..DISCONNECT_PEER_AWAITING_RESPONSE_TICKS {
441+ nodes[ 0 ] . node . timer_tick_occurred ( ) ;
442+ nodes[ 1 ] . node . timer_tick_occurred ( ) ;
443+ }
444+
445+ // nodes[0] hasn't received stfu from nodes[1], so it's not enforcing any timeouts.
446+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
447+
448+ // nodes[1] didn't receive nodes[0]'s stfu within the timeout so it'll disconnect.
449+ let f = |& ref event| {
450+ if let MessageSendEvent :: HandleError { action, .. } = event {
451+ if let msgs:: ErrorAction :: DisconnectPeerWithWarning { .. } = action {
452+ Some ( ( ) )
453+ } else {
454+ None
455+ }
456+ } else {
457+ None
458+ }
459+ } ;
460+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . iter( ) . find_map( f) . is_some( ) ) ;
461+ }
462+
0 commit comments