@@ -4357,6 +4357,70 @@ fn test_splice_rbf_acceptor_basic() {
43574357 ) ;
43584358}
43594359
4360+ #[ test]
4361+ fn test_splice_rbf_at_high_feerate ( ) {
4362+ // Test that min_rbf_feerate satisfies the spec's 25/24 rule at high feerates (above 600
4363+ // sat/kwu, where a flat +25 increment alone would be insufficient).
4364+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
4365+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
4366+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
4367+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
4368+
4369+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
4370+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
4371+
4372+ let initial_channel_value_sat = 100_000 ;
4373+ let ( _, _, channel_id, _) =
4374+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , initial_channel_value_sat, 0 ) ;
4375+
4376+ let added_value = Amount :: from_sat ( 50_000 ) ;
4377+ provide_utxo_reserves ( & nodes, 2 , added_value * 2 ) ;
4378+
4379+ // Step 1: Complete a splice-in at floor feerate.
4380+ let funding_contribution = do_initiate_splice_in ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, added_value) ;
4381+ let ( _first_splice_tx, new_funding_script) =
4382+ splice_channel ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, funding_contribution) ;
4383+
4384+ // Step 2: RBF to a high feerate (1000 sat/kwu, well above the 600 crossover point).
4385+ provide_utxo_reserves ( & nodes, 2 , added_value * 2 ) ;
4386+ let high_feerate = FeeRate :: from_sat_per_kwu ( 1000 ) ;
4387+ let contribution =
4388+ do_initiate_rbf_splice_in ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, added_value, high_feerate) ;
4389+ complete_rbf_handshake ( & nodes[ 0 ] , & nodes[ 1 ] ) ;
4390+ complete_interactive_funding_negotiation (
4391+ & nodes[ 0 ] ,
4392+ & nodes[ 1 ] ,
4393+ channel_id,
4394+ contribution,
4395+ new_funding_script. clone ( ) ,
4396+ ) ;
4397+ let ( _, splice_locked) = sign_interactive_funding_tx ( & nodes[ 0 ] , & nodes[ 1 ] , false ) ;
4398+ assert ! ( splice_locked. is_none( ) ) ;
4399+ expect_splice_pending_event ( & nodes[ 0 ] , & node_id_1) ;
4400+ expect_splice_pending_event ( & nodes[ 1 ] , & node_id_0) ;
4401+
4402+ // Step 3: RBF again using the template's min_rbf_feerate. The counterparty must accept it.
4403+ provide_utxo_reserves ( & nodes, 2 , added_value * 2 ) ;
4404+ let rbf_feerate = {
4405+ let funding_template = nodes[ 0 ] . node . splice_channel ( & channel_id, & node_id_1) . unwrap ( ) ;
4406+ funding_template. min_rbf_feerate ( ) . unwrap ( )
4407+ } ;
4408+ let contribution =
4409+ do_initiate_rbf_splice_in ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, added_value, rbf_feerate) ;
4410+ complete_rbf_handshake ( & nodes[ 0 ] , & nodes[ 1 ] ) ;
4411+ complete_interactive_funding_negotiation (
4412+ & nodes[ 0 ] ,
4413+ & nodes[ 1 ] ,
4414+ channel_id,
4415+ contribution,
4416+ new_funding_script,
4417+ ) ;
4418+ let ( _, splice_locked) = sign_interactive_funding_tx ( & nodes[ 0 ] , & nodes[ 1 ] , false ) ;
4419+ assert ! ( splice_locked. is_none( ) ) ;
4420+ expect_splice_pending_event ( & nodes[ 0 ] , & node_id_1) ;
4421+ expect_splice_pending_event ( & nodes[ 1 ] , & node_id_0) ;
4422+ }
4423+
43604424#[ test]
43614425fn test_splice_rbf_insufficient_feerate ( ) {
43624426 // Test that splice_in_sync rejects a feerate that doesn't satisfy the +25 sat/kwu rule, and that the
@@ -5984,7 +6048,8 @@ fn test_funding_contributed_rbf_adjustment_insufficient_budget() {
59846048 funding_template. splice_in_sync ( added_value, floor_feerate, FeeRate :: MAX , & wallet) . unwrap ( ) ;
59856049
59866050 // Node 1 initiates a splice at a HIGH feerate (10,000 sat/kwu). The minimum RBF feerate will be
5987- // 10,000 + 25 = 10,025 sat/kwu — far above what node 0's tight budget can handle.
6051+ // max(10,000 + 25, ceil(10,000 * 25/24)) = 10,417 sat/kwu — far above what node 0's tight
6052+ // budget can handle.
59886053 let high_feerate = FeeRate :: from_sat_per_kwu ( 10_000 ) ;
59896054 let node_1_template = nodes[ 1 ] . node . splice_channel ( & channel_id, & node_id_0) . unwrap ( ) ;
59906055 let node_1_wallet = WalletSync :: new ( Arc :: clone ( & nodes[ 1 ] . wallet_source ) , nodes[ 1 ] . logger ) ;
0 commit comments