@@ -2709,6 +2709,23 @@ fn test_promoted_splice_locked_sent_after_channel_reestablish() {
27092709 initiate_splice_out ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, outputs) . unwrap ( ) ;
27102710 let ( splice_tx, _) = splice_channel ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, funding_contribution) ;
27112711
2712+ // Send a payment from node 0 to node 1 but don't fully commit it to make sure node 1
2713+ // sends `splice_locked` first when it responds.
2714+ let payment_amount = 1_000_000 ;
2715+ let ( route, payment_hash, _payment_preimage, payment_secret) =
2716+ get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 1 ] , payment_amount) ;
2717+ let onion = RecipientOnionFields :: secret_only ( payment_secret, payment_amount) ;
2718+ let payment_id = PaymentId ( payment_hash. 0 ) ;
2719+ nodes[ 0 ] . node . send_payment_with_route ( route, payment_hash, onion, payment_id) . unwrap ( ) ;
2720+ let update = get_htlc_update_msgs ( & nodes[ 0 ] , & node_id_1) ;
2721+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
2722+
2723+ nodes[ 1 ] . node . handle_update_add_htlc ( node_id_0, & update. update_add_htlcs [ 0 ] ) ;
2724+ nodes[ 1 ] . node . handle_commitment_signed_batch_test ( node_id_0, & update. commitment_signed ) ;
2725+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
2726+ let ( _dropped_raa, dropped_commitment_signed) = get_revoke_commit_msgs ( & nodes[ 1 ] , & node_id_0) ;
2727+ assert ! ( dropped_commitment_signed. len( ) > 1 , "{dropped_commitment_signed:?}" ) ;
2728+
27122729 // Confirm the splice for node 0 first. This should result in them sending `splice_locked`, but
27132730 // node 1 should not send it back yet as it hasn't seen the confirmation.
27142731 confirm_transaction ( & nodes[ 0 ] , & splice_tx) ;
@@ -2740,14 +2757,25 @@ fn test_promoted_splice_locked_sent_after_channel_reestablish() {
27402757
27412758 nodes[ 1 ] . node . handle_channel_reestablish ( node_id_0, & reestablish_0) ;
27422759 let msg_events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2743- assert_eq ! ( msg_events. len( ) , 3 , "{msg_events:?}" ) ;
2760+ assert_eq ! ( msg_events. len( ) , 5 , "{msg_events:?}" ) ;
27442761 assert ! ( matches!( & msg_events[ 0 ] , MessageSendEvent :: SendAnnouncementSignatures { .. } ) ) ;
27452762 let splice_locked_1 = if let MessageSendEvent :: SendSpliceLocked { msg, .. } = & msg_events[ 1 ] {
27462763 msg
27472764 } else {
2748- panic ! ( "Unexpected event {:?}" , msg_events[ 0 ] ) ;
2765+ panic ! ( "Unexpected event {:?}" , msg_events[ 1 ] ) ;
2766+ } ;
2767+ let revoke_and_ack = if let MessageSendEvent :: SendRevokeAndACK { msg, .. } = & msg_events[ 2 ] {
2768+ msg
2769+ } else {
2770+ panic ! ( "Unexpected event {:?}" , msg_events[ 2 ] ) ;
2771+ } ;
2772+ let commit_sig = if let MessageSendEvent :: UpdateHTLCs { updates, .. } = & msg_events[ 3 ] {
2773+ assert_eq ! ( updates. commitment_signed. len( ) , 1 ) ;
2774+ updates. commitment_signed . first ( ) . unwrap ( )
2775+ } else {
2776+ panic ! ( "Unexpected event {:?}" , msg_events[ 3 ] ) ;
27492777 } ;
2750- assert ! ( matches!( & msg_events[ 2 ] , MessageSendEvent :: SendChannelUpdate { .. } ) ) ;
2778+ assert ! ( matches!( & msg_events[ 4 ] , MessageSendEvent :: SendChannelUpdate { .. } ) ) ;
27512779
27522780 // Deliver node 1's reestablish to node 0. Since it was generated prior to the splice
27532781 // confirmation, it should not promote the splice for node 0 yet.
@@ -2765,6 +2793,21 @@ fn test_promoted_splice_locked_sent_after_channel_reestablish() {
27652793 if funding_txo == Some ( new_funding_txo)
27662794 ) ) ;
27672795
2796+ // And finally, deliver the remaining messages to fully commit the sent HTLC.
2797+ nodes[ 0 ] . node . handle_revoke_and_ack ( node_id_1, revoke_and_ack) ;
2798+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
2799+ nodes[ 0 ] . node . handle_commitment_signed ( node_id_1, commit_sig) ;
2800+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
2801+
2802+ let revoke_and_ack = get_event_msg ! ( & nodes[ 0 ] , MessageSendEvent :: SendRevokeAndACK , node_id_1) ;
2803+ nodes[ 1 ] . node . handle_revoke_and_ack ( node_id_0, & revoke_and_ack) ;
2804+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
2805+ nodes[ 1 ] . node . process_pending_htlc_forwards ( ) ;
2806+ expect_payment_claimable ! ( & nodes[ 1 ] , payment_hash, payment_secret, payment_amount) ;
2807+
2808+ // We should be able to send payments again now that the state is fully committed.
2809+ send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , payment_amount) ;
2810+
27682811 for node in [ & nodes[ 0 ] , & nodes[ 1 ] ] {
27692812 node. chain_source . remove_watched_by_txid ( prev_funding_txo. txid ) ;
27702813 }
@@ -2841,6 +2884,110 @@ fn test_splice_reestablish_waits_for_holder_tx_signatures_before_commitment_sign
28412884 expect_splice_pending_event ( & nodes[ 1 ] , & node_id_0) ;
28422885}
28432886
2887+ #[ test]
2888+ fn test_splice_reestablish_sends_commitment_signed_before_tx_signatures ( ) {
2889+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2890+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2891+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
2892+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2893+
2894+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
2895+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
2896+
2897+ let initial_channel_value_sat = 100_000 ;
2898+ let ( _, _, channel_id, _) =
2899+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , initial_channel_value_sat, 0 ) ;
2900+
2901+ let outputs = vec ! [ TxOut {
2902+ value: Amount :: from_sat( initial_channel_value_sat / 4 ) ,
2903+ script_pubkey: nodes[ 0 ] . wallet_source. get_change_script( ) . unwrap( ) ,
2904+ } ] ;
2905+ let initiator_contribution =
2906+ initiate_splice_out ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, outputs) . unwrap ( ) ;
2907+ negotiate_splice_tx ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, initiator_contribution) ;
2908+
2909+ let signing_event = get_event ! ( nodes[ 0 ] , Event :: FundingTransactionReadyForSigning ) ;
2910+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
2911+
2912+ // Drop node 1's initial `commitment_signed` so node 0 requests it on reconnect.
2913+ let acceptor_commit_sig = get_htlc_update_msgs ( & nodes[ 1 ] , & node_id_0) ;
2914+ assert_eq ! ( acceptor_commit_sig. commitment_signed. len( ) , 1 ) ;
2915+
2916+ let unsigned_transaction = if let Event :: FundingTransactionReadyForSigning {
2917+ unsigned_transaction,
2918+ ..
2919+ } = signing_event
2920+ {
2921+ unsigned_transaction
2922+ } else {
2923+ panic ! ( "Expected FundingTransactionReadyForSigning event" ) ;
2924+ } ;
2925+ let tx = nodes[ 0 ] . wallet_source . sign_tx ( unsigned_transaction) . unwrap ( ) ;
2926+ nodes[ 0 ] . node . funding_transaction_signed ( & channel_id, & node_id_1, tx) . unwrap ( ) ;
2927+ check_added_monitors ( & nodes[ 0 ] , 0 ) ;
2928+
2929+ let initiator_commit_sig = get_htlc_update_msgs ( & nodes[ 0 ] , & node_id_1) ;
2930+ nodes[ 1 ]
2931+ . node
2932+ . handle_commitment_signed_batch_test ( node_id_0, & initiator_commit_sig. commitment_signed ) ;
2933+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
2934+
2935+ // Drop node 1's `tx_signatures`. At this point node 0 has not received node 1's
2936+ // `commitment_signed`, while node 1 has its `tx_signatures` ready, so one
2937+ // `channel_reestablish` should trigger both retransmissions.
2938+ let _ = get_event_msg ! ( & nodes[ 1 ] , MessageSendEvent :: SendTxSignatures , node_id_0) ;
2939+
2940+ nodes[ 0 ] . node . peer_disconnected ( node_id_1) ;
2941+ nodes[ 1 ] . node . peer_disconnected ( node_id_0) ;
2942+ connect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] ) ;
2943+ let reestablish_0 =
2944+ get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendChannelReestablish , node_id_1) ;
2945+ let _reestablish_1 =
2946+ get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendChannelReestablish , node_id_0) ;
2947+ let next_funding = reestablish_0. next_funding . as_ref ( ) . expect ( "next_funding should be set" ) ;
2948+ assert ! ( next_funding. should_retransmit( msgs:: NextFundingFlag :: CommitmentSigned ) ) ;
2949+
2950+ nodes[ 1 ] . node . handle_channel_reestablish ( node_id_0, & reestablish_0) ;
2951+ let msg_events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2952+ let commitment_update_idx = msg_events
2953+ . iter ( )
2954+ . position ( |event| {
2955+ matches ! ( event, MessageSendEvent :: UpdateHTLCs { updates, .. }
2956+ if updates. commitment_signed. len( ) == 1 )
2957+ } )
2958+ . expect ( "commitment_signed should be retransmitted" ) ;
2959+ let tx_signatures_idx = msg_events
2960+ . iter ( )
2961+ . position ( |event| matches ! ( event, MessageSendEvent :: SendTxSignatures { .. } ) )
2962+ . expect ( "tx_signatures should be retransmitted" ) ;
2963+ assert ! (
2964+ commitment_update_idx < tx_signatures_idx,
2965+ "commitment_signed should be retransmitted before tx_signatures: {msg_events:?}"
2966+ ) ;
2967+
2968+ let commitment_signed =
2969+ if let MessageSendEvent :: UpdateHTLCs { updates, .. } = & msg_events[ commitment_update_idx] {
2970+ updates. commitment_signed . clone ( )
2971+ } else {
2972+ panic ! ( "Expected UpdateHTLCs" ) ;
2973+ } ;
2974+ let tx_signatures =
2975+ if let MessageSendEvent :: SendTxSignatures { msg, .. } = & msg_events[ tx_signatures_idx] {
2976+ msg. clone ( )
2977+ } else {
2978+ panic ! ( "Expected SendTxSignatures" ) ;
2979+ } ;
2980+ nodes[ 0 ] . node . handle_commitment_signed_batch_test ( node_id_1, & commitment_signed) ;
2981+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
2982+ nodes[ 0 ] . node . handle_tx_signatures ( node_id_1, & tx_signatures) ;
2983+ let initiator_tx_signatures =
2984+ get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendTxSignatures , node_id_1) ;
2985+ nodes[ 1 ] . node . handle_tx_signatures ( node_id_0, & initiator_tx_signatures) ;
2986+
2987+ expect_splice_pending_event ( & nodes[ 0 ] , & node_id_1) ;
2988+ expect_splice_pending_event ( & nodes[ 1 ] , & node_id_0) ;
2989+ }
2990+
28442991#[ test]
28452992fn test_splice_confirms_on_both_sides_while_disconnected ( ) {
28462993 // Regression test: when a splice transaction confirms on both sides while peers are
0 commit comments