@@ -2676,6 +2676,100 @@ fn test_splice_locked_waits_for_channel_reestablish() {
26762676 send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1_000_000 ) ;
26772677}
26782678
2679+ #[ test]
2680+ fn test_promoted_splice_locked_sent_after_channel_reestablish ( ) {
2681+ // Test that a splice gets promoted for both nodes if one of the nodes sees the splice lock
2682+ // before reestablishment and the other after.
2683+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2684+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2685+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
2686+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2687+
2688+ let node_id_0 = nodes[ 0 ] . node . get_our_node_id ( ) ;
2689+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
2690+
2691+ let initial_channel_value_sat = 100_000 ;
2692+ let ( _, _, channel_id, _) =
2693+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , initial_channel_value_sat, 0 ) ;
2694+ let prev_funding_txo = get_monitor ! ( nodes[ 0 ] , channel_id) . get_funding_txo ( ) ;
2695+
2696+ send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1_000_000 ) ;
2697+
2698+ let outputs = vec ! [
2699+ TxOut {
2700+ value: Amount :: from_sat( initial_channel_value_sat / 4 ) ,
2701+ script_pubkey: nodes[ 0 ] . wallet_source. get_change_script( ) . unwrap( ) ,
2702+ } ,
2703+ TxOut {
2704+ value: Amount :: from_sat( initial_channel_value_sat / 4 ) ,
2705+ script_pubkey: nodes[ 1 ] . wallet_source. get_change_script( ) . unwrap( ) ,
2706+ } ,
2707+ ] ;
2708+ let funding_contribution =
2709+ initiate_splice_out ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, outputs) . unwrap ( ) ;
2710+ let ( splice_tx, _) = splice_channel ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, funding_contribution) ;
2711+
2712+ // Confirm the splice for node 0 first. This should result in them sending `splice_locked`, but
2713+ // node 1 should not send it back yet as it hasn't seen the confirmation.
2714+ confirm_transaction ( & nodes[ 0 ] , & splice_tx) ;
2715+ let splice_locked_0 = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendSpliceLocked , node_id_1) ;
2716+ nodes[ 1 ] . node . handle_splice_locked ( node_id_0, & splice_locked_0) ;
2717+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
2718+
2719+ // Reconnect the peers.
2720+ nodes[ 0 ] . node . peer_disconnected ( node_id_1) ;
2721+ nodes[ 1 ] . node . peer_disconnected ( node_id_0) ;
2722+ connect_nodes ( & nodes[ 0 ] , & nodes[ 1 ] ) ;
2723+ let reestablish_0 =
2724+ get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendChannelReestablish , node_id_1) ;
2725+ let reestablish_1 =
2726+ get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendChannelReestablish , node_id_0) ;
2727+
2728+ // Before delivering the reestablish message to each other, confirm the splice for node 1. We
2729+ // should see a `ChannelReady` event for node 1 as the pending splice should have been promoted,
2730+ // but `splice_locked` should not be sent until it receives node 0's reestablish.
2731+ confirm_transaction ( & nodes[ 1 ] , & splice_tx) ;
2732+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
2733+ let new_funding_txo =
2734+ get_monitor ! ( nodes[ 1 ] , channel_id) . get_funding_txo ( ) . into_bitcoin_outpoint ( ) ;
2735+ let channel_ready_1 = get_event ! ( & nodes[ 1 ] , Event :: ChannelReady ) ;
2736+ assert ! ( matches!(
2737+ channel_ready_1, Event :: ChannelReady { funding_txo, .. }
2738+ if funding_txo == Some ( new_funding_txo)
2739+ ) ) ;
2740+
2741+ nodes[ 1 ] . node . handle_channel_reestablish ( node_id_0, & reestablish_0) ;
2742+ let msg_events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2743+ assert_eq ! ( msg_events. len( ) , 3 , "{msg_events:?}" ) ;
2744+ assert ! ( matches!( & msg_events[ 0 ] , MessageSendEvent :: SendAnnouncementSignatures { .. } ) ) ;
2745+ let splice_locked_1 = if let MessageSendEvent :: SendSpliceLocked { msg, .. } = & msg_events[ 1 ] {
2746+ msg
2747+ } else {
2748+ panic ! ( "Unexpected event {:?}" , msg_events[ 0 ] ) ;
2749+ } ;
2750+ assert ! ( matches!( & msg_events[ 2 ] , MessageSendEvent :: SendChannelUpdate { .. } ) ) ;
2751+
2752+ // Deliver node 1's reestablish to node 0. Since it was generated prior to the splice
2753+ // confirmation, it should not promote the splice for node 0 yet.
2754+ nodes[ 0 ] . node . handle_channel_reestablish ( node_id_1, & reestablish_1) ;
2755+ let _ = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendChannelUpdate , node_id_1) ;
2756+
2757+ // Deliver node 1's splice locked to node 0, allowing the splice to be promoted on node 0's side
2758+ // as well.
2759+ nodes[ 0 ] . node . handle_splice_locked ( node_id_1, splice_locked_1) ;
2760+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
2761+ let _ = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendAnnouncementSignatures , node_id_1) ;
2762+ let channel_ready_0 = get_event ! ( & nodes[ 0 ] , Event :: ChannelReady ) ;
2763+ assert ! ( matches!(
2764+ channel_ready_0, Event :: ChannelReady { funding_txo, .. }
2765+ if funding_txo == Some ( new_funding_txo)
2766+ ) ) ;
2767+
2768+ for node in [ & nodes[ 0 ] , & nodes[ 1 ] ] {
2769+ node. chain_source . remove_watched_by_txid ( prev_funding_txo. txid ) ;
2770+ }
2771+ }
2772+
26792773#[ test]
26802774fn test_splice_reestablish_waits_for_holder_tx_signatures_before_commitment_signed ( ) {
26812775 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
0 commit comments