@@ -61,6 +61,7 @@ use lightning::ln::splicing_tests::*;
6161use lightning:: ln:: types:: ChannelId ;
6262use lightning:: onion_message:: packet:: Packet ;
6363use lightning:: sign:: OutputSpender ;
64+ use lightning:: util:: errors:: APIError ;
6465use lightning:: util:: ser:: { MaybeReadable , Writeable } ;
6566use lightning:: util:: wallet_utils:: WalletSourceSync ;
6667
@@ -1016,4 +1017,88 @@ fn upgrade_single_splice_from_0_2() {
10161017 assert_eq ! ( splice. candidates. len( ) , 1 ) ;
10171018 assert_eq ! ( splice. candidates[ 0 ] . contribution, None ) ;
10181019 }
1020+
1021+ // The splice cannot be RBF'd: 0.2 persisted no feerate, so splice_channel refuses it.
1022+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
1023+ let err = nodes[ 0 ] . node . splice_channel ( & channel_id, & node_id_1) . unwrap_err ( ) ;
1024+ let expected = format ! (
1025+ "Channel {} has a pending splice from a prior LDK version and cannot be spliced again" ,
1026+ channel_id,
1027+ ) ;
1028+ match err {
1029+ APIError :: APIMisuseError { err } => assert_eq ! ( err, expected) ,
1030+ _ => panic ! ( "unexpected error: {:?}" , err) ,
1031+ }
1032+ }
1033+
1034+ #[ test]
1035+ fn splice_inherited_across_0_2_cannot_be_rbfed ( ) {
1036+ // Negotiate a contributory splice on current, downgrade to LDK 0.2, then upgrade back. LDK 0.2
1037+ // persists neither our contribution nor the splice feerate and does not retain the odd TLVs that
1038+ // carry them, so the splice returns to current without either. `splice_channel` needs the prior
1039+ // feerate to derive the RBF floor, so it refuses such a channel with a clean error rather than
1040+ // operating on incomplete state (which would otherwise trip a debug assertion that a pending
1041+ // splice always has a known feerate).
1042+ let chan_id_bytes;
1043+ let ( v3_mgr, v3_mon) ;
1044+ {
1045+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
1046+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
1047+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
1048+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1049+ let ( _, _, channel_id, _) =
1050+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 100_000 , 0 ) ;
1051+ chan_id_bytes = channel_id. 0 ;
1052+
1053+ let added_value = Amount :: from_sat ( 50_000 ) ;
1054+ provide_utxo_reserves ( & nodes, 2 , added_value * 2 ) ;
1055+ let contribution = do_initiate_splice_in ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, added_value) ;
1056+ let ( splice_tx, _) = splice_channel ( & nodes[ 0 ] , & nodes[ 1 ] , channel_id, contribution) ;
1057+ mine_transaction ( & nodes[ 0 ] , & splice_tx) ;
1058+ mine_transaction ( & nodes[ 1 ] , & splice_tx) ;
1059+
1060+ v3_mgr = nodes[ 0 ] . node . encode ( ) ;
1061+ v3_mon = get_monitor ! ( nodes[ 0 ] , channel_id) . encode ( ) ;
1062+ }
1063+
1064+ // Downgrade node 0 to LDK 0.2 and re-serialize there, stripping the contribution and feerate.
1065+ let ( v2_mgr, v2_mon) ;
1066+ {
1067+ let mut chanmon_cfgs = lightning_0_2_utils:: create_chanmon_cfgs ( 2 ) ;
1068+ chanmon_cfgs[ 0 ] . keys_manager . disable_all_state_policy_checks = true ;
1069+ chanmon_cfgs[ 1 ] . keys_manager . disable_all_state_policy_checks = true ;
1070+ let node_cfgs = lightning_0_2_utils:: create_node_cfgs ( 2 , & chanmon_cfgs) ;
1071+ let node_chanmgrs = lightning_0_2_utils:: create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
1072+ let nodes = lightning_0_2_utils:: create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1073+ let mut config = lightning_0_2_utils:: test_default_channel_config ( ) ;
1074+ config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = true ;
1075+ let mgr = lightning_0_2_utils:: _reload_node ( & nodes[ 0 ] , config, & v3_mgr, & [ & v3_mon[ ..] ] ) ;
1076+ assert_eq ! ( mgr. list_channels( ) . len( ) , 1 ) ;
1077+ let v2_channel_id = lightning_0_2:: ln:: types:: ChannelId ( chan_id_bytes) ;
1078+ v2_mgr = mgr. encode ( ) ;
1079+ v2_mon = get_monitor_0_2 ! ( nodes[ 0 ] , v2_channel_id) . encode ( ) ;
1080+ }
1081+
1082+ // Upgrade back to current and attempt to RBF the inherited splice.
1083+ let mut chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
1084+ chanmon_cfgs[ 0 ] . keys_manager . disable_all_state_policy_checks = true ;
1085+ chanmon_cfgs[ 1 ] . keys_manager . disable_all_state_policy_checks = true ;
1086+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
1087+ let ( persister, chain_mon, new_node) ;
1088+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
1089+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1090+ let config = test_default_channel_config ( ) ;
1091+ reload_node ! ( nodes[ 0 ] , config, & v2_mgr, & [ & v2_mon[ ..] ] , persister, chain_mon, new_node) ;
1092+
1093+ let channel_id = ChannelId ( chan_id_bytes) ;
1094+ let node_id_1 = nodes[ 1 ] . node . get_our_node_id ( ) ;
1095+ let err = nodes[ 0 ] . node . splice_channel ( & channel_id, & node_id_1) . unwrap_err ( ) ;
1096+ let expected = format ! (
1097+ "Channel {} has a pending splice from a prior LDK version and cannot be spliced again" ,
1098+ channel_id,
1099+ ) ;
1100+ match err {
1101+ APIError :: APIMisuseError { err } => assert_eq ! ( err, expected) ,
1102+ _ => panic ! ( "unexpected error: {:?}" , err) ,
1103+ }
10191104}
0 commit comments