@@ -7841,6 +7841,53 @@ fn test_funding_contributed_rbf_adjustment_exceeds_max_feerate() {
78417841 assert_eq ! ( splice_init. funding_feerate_per_kw, FEERATE_FLOOR_SATS_PER_KW ) ;
78427842}
78437843
7844+ #[ test]
7845+ fn test_peer_initiated_stfu_skips_local_rbf_feerate_check ( ) {
7846+ // Test that a local low-fee splice RBF attempt does not prevent us from responding to a
7847+ // counterparty-initiated quiescence attempt.
7848+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
7849+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
7850+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
7851+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
7852+
7853+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
7854+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
7855+
7856+ let initial_channel_value_sat = 100_000 ;
7857+ let ( _, _, channel_id, _) =
7858+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , initial_channel_value_sat, 0 ) ;
7859+
7860+ let added_value = Amount :: from_sat ( 50_000 ) ;
7861+ provide_utxo_reserves ( & nodes, 4 , added_value * 2 ) ;
7862+
7863+ let floor_feerate = FeeRate :: from_sat_per_kwu ( FEERATE_FLOOR_SATS_PER_KW as u64 ) ;
7864+ let node_0_template = nodes[ 0 ] . node . splice_channel ( & channel_id, & node_id_1) . unwrap ( ) ;
7865+ let wallet = WalletSync :: new ( Arc :: clone ( & nodes[ 0 ] . wallet_source ) , nodes[ 0 ] . logger ) ;
7866+ let node_0_contribution =
7867+ node_0_template. splice_in_sync ( added_value, floor_feerate, floor_feerate, & wallet) . unwrap ( ) ;
7868+
7869+ // Node 1 creates a pending splice before node 0 submits its contribution. Node 0's
7870+ // contribution cannot be adjusted up to the pending splice's minimum RBF feerate, so it must
7871+ // not send its own stfu yet.
7872+ let node_1_contribution = do_initiate_splice_in ( & nodes[ 1 ] , & nodes[ 0 ] , channel_id, added_value) ;
7873+ let ( _first_splice_tx, _) =
7874+ splice_channel ( & nodes[ 1 ] , & nodes[ 0 ] , channel_id, node_1_contribution) ;
7875+ nodes[ 0 ] . node . funding_contributed ( & channel_id, & node_id_1, node_0_contribution, None ) . unwrap ( ) ;
7876+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
7877+
7878+ // Node 1 can still initiate quiescence for its own RBF attempt. Node 0 should reply as the
7879+ // non-initiator instead of applying its local splice RBF feerate check to the response.
7880+ let min_rbf_feerate = FeeRate :: from_sat_per_kwu ( FEERATE_FLOOR_SATS_PER_KW as u64 + 25 ) ;
7881+ let _node_1_rbf_contribution =
7882+ do_initiate_rbf_splice_in ( & nodes[ 1 ] , & nodes[ 0 ] , channel_id, min_rbf_feerate) ;
7883+ let stfu_init = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendStfu , node_id_0) ;
7884+ assert ! ( stfu_init. initiator) ;
7885+
7886+ nodes[ 0 ] . node . handle_stfu ( node_id_1, & stfu_init) ;
7887+ let stfu_response = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendStfu , node_id_1) ;
7888+ assert ! ( !stfu_response. initiator) ;
7889+ }
7890+
78447891#[ test]
78457892fn test_funding_contributed_rbf_adjustment_insufficient_budget ( ) {
78467893 // Test that when the change output can't absorb the fee increase needed for the minimum RBF feerate
0 commit comments