@@ -4404,33 +4404,54 @@ fn test_splice_rbf_insufficient_feerate() {
44044404 . is_ok( ) ) ;
44054405
44064406 // Acceptor-side: tx_init_rbf with an insufficient feerate is also rejected.
4407- reenter_quiescence ( & nodes[ 0 ] , & nodes[ 1 ] , & channel_id) ;
4407+ // Node 0 initiates a proper RBF but we tamper the feerate to be insufficient.
4408+ provide_utxo_reserves ( & nodes, 2 , added_value * 2 ) ;
4409+ let _funding_contribution =
4410+ do_initiate_rbf_splice_in ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, added_value, min_rbf_feerate) ;
44084411
4409- let tx_init_rbf = msgs:: TxInitRbf {
4410- channel_id,
4411- locktime : 0 ,
4412- feerate_sat_per_1000_weight : FEERATE_FLOOR_SATS_PER_KW ,
4413- funding_output_contribution : Some ( added_value. to_sat ( ) as i64 ) ,
4414- } ;
4412+ let stfu_0 = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendStfu , node_id_1) ;
4413+ nodes[ 1 ] . node . handle_stfu ( node_id_0, & stfu_0) ;
4414+ let stfu_1 = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendStfu , node_id_0) ;
4415+ nodes[ 0 ] . node . handle_stfu ( node_id_1, & stfu_1) ;
44154416
4417+ let mut tx_init_rbf = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendTxInitRbf , node_id_1) ;
4418+ tx_init_rbf. feerate_sat_per_1000_weight = FEERATE_FLOOR_SATS_PER_KW ;
44164419 nodes[ 1 ] . node . handle_tx_init_rbf ( node_id_0, & tx_init_rbf) ;
44174420
44184421 let tx_abort = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendTxAbort , node_id_0) ;
44194422 assert_eq ! ( tx_abort. channel_id, channel_id) ;
44204423
4424+ // Node 0 echoes tx_abort and exits quiescence.
4425+ nodes[ 0 ] . node . handle_tx_abort ( node_id_1, & tx_abort) ;
4426+ let tx_abort_echo = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendTxAbort , node_id_1) ;
4427+
4428+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
4429+ assert_eq ! ( events. len( ) , 2 ) ;
4430+ assert ! (
4431+ matches!( & events[ 0 ] , Event :: SpliceFailed { channel_id: cid, .. } if * cid == channel_id)
4432+ ) ;
4433+ assert ! (
4434+ matches!( & events[ 1 ] , Event :: DiscardFunding { channel_id: cid, .. } if * cid == channel_id)
4435+ ) ;
4436+
4437+ // Node 1 handles the echo (no-op since it already aborted).
4438+ nodes[ 1 ] . node . handle_tx_abort ( node_id_0, & tx_abort_echo) ;
4439+
44214440 // Acceptor-side: a counterparty feerate that satisfies the spec's 25/24 rule (264) is
44224441 // accepted, even though our own RBF floor (+25 sat/kwu = 278) is higher.
4423- // After tx_abort the channel remains quiescent, so no need to re-enter quiescence.
4424- nodes[ 0 ] . node . handle_tx_abort ( node_id_1, & tx_abort) ;
4442+ // Node 0 initiates another proper RBF but we tamper the feerate to the 25/24 value.
4443+ provide_utxo_reserves ( & nodes, 2 , added_value * 2 ) ;
4444+ let _funding_contribution =
4445+ do_initiate_rbf_splice_in ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, added_value, min_rbf_feerate) ;
44254446
4426- let rbf_feerate_25_24 = ( ( FEERATE_FLOOR_SATS_PER_KW as u64 ) * 25 ) . div_ceil ( 24 ) as u32 ;
4427- let tx_init_rbf = msgs:: TxInitRbf {
4428- channel_id,
4429- locktime : 0 ,
4430- feerate_sat_per_1000_weight : rbf_feerate_25_24,
4431- funding_output_contribution : Some ( added_value. to_sat ( ) as i64 ) ,
4432- } ;
4447+ let stfu_0 = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendStfu , node_id_1) ;
4448+ nodes[ 1 ] . node . handle_stfu ( node_id_0, & stfu_0) ;
4449+ let stfu_1 = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendStfu , node_id_0) ;
4450+ nodes[ 0 ] . node . handle_stfu ( node_id_1, & stfu_1) ;
44334451
4452+ let mut tx_init_rbf = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendTxInitRbf , node_id_1) ;
4453+ let rbf_feerate_25_24 = ( ( FEERATE_FLOOR_SATS_PER_KW as u64 ) * 25 ) . div_ceil ( 24 ) as u32 ;
4454+ tx_init_rbf. feerate_sat_per_1000_weight = rbf_feerate_25_24;
44344455 nodes[ 1 ] . node . handle_tx_init_rbf ( node_id_0, & tx_init_rbf) ;
44354456 let _tx_ack_rbf = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendTxAckRbf , node_id_0) ;
44364457}
@@ -5118,10 +5139,25 @@ fn test_splice_rbf_tiebreak_feerate_too_high_rejected() {
51185139 assert_eq ! ( tx_init_rbf. feerate_sat_per_1000_weight, high_feerate. to_sat_per_kwu( ) as u32 ) ;
51195140
51205141 // Node 1 handles tx_init_rbf — TooHigh: target (100k) >> max (3k) and fair fee > budget.
5142+ // Node 1 exits quiescence upon rejecting with tx_abort, and since it has a pending
5143+ // QuiescentAction (from its own splice RBF attempt), it immediately re-proposes quiescence.
51215144 nodes[ 1 ] . node . handle_tx_init_rbf ( node_id_0, & tx_init_rbf) ;
51225145
5123- let tx_abort = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendTxAbort , node_id_0) ;
5124- assert_eq ! ( tx_abort. channel_id, channel_id) ;
5146+ let msg_events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
5147+ assert_eq ! ( msg_events. len( ) , 2 ) ;
5148+ match & msg_events[ 0 ] {
5149+ MessageSendEvent :: SendTxAbort { node_id, msg } => {
5150+ assert_eq ! ( * node_id, node_id_0) ;
5151+ assert_eq ! ( msg. channel_id, channel_id) ;
5152+ } ,
5153+ _ => panic ! ( "Expected SendTxAbort, got {:?}" , msg_events[ 0 ] ) ,
5154+ } ;
5155+ match & msg_events[ 1 ] {
5156+ MessageSendEvent :: SendStfu { node_id, .. } => {
5157+ assert_eq ! ( * node_id, node_id_0) ;
5158+ } ,
5159+ _ => panic ! ( "Expected SendStfu, got {:?}" , msg_events[ 1 ] ) ,
5160+ } ;
51255161}
51265162
51275163#[ test]
0 commit comments