@@ -24,7 +24,8 @@ use crate::ln::channelmanager::{
2424 MAX_UNFUNDED_CHANS_PER_PEER ,
2525} ;
2626use crate :: ln:: msgs:: {
27- AcceptChannel , BaseMessageHandler , ChannelMessageHandler , ErrorAction , MessageSendEvent ,
27+ AcceptChannel , BaseMessageHandler , ChannelMessageHandler , ErrorAction , ErrorMessage ,
28+ MessageSendEvent ,
2829} ;
2930use crate :: ln:: types:: ChannelId ;
3031use crate :: ln:: { functional_test_utils:: * , msgs} ;
@@ -48,6 +49,7 @@ use bitcoin::{Amount, Sequence, Transaction, TxIn, TxOut, Witness};
4849use lightning_macros:: xtest;
4950
5051use lightning_types:: features:: ChannelTypeFeatures ;
52+ use types:: string:: UntrustedString ;
5153
5254#[ test]
5355fn test_outbound_chans_unlimited ( ) {
@@ -2496,3 +2498,189 @@ fn test_fund_pending_channel() {
24962498 } ;
24972499 check_closed_event ( & nodes[ 0 ] , 1 , reason, & [ node_b_id] , 100_000 ) ;
24982500}
2501+
2502+ #[ xtest( feature = "_externalize_tests" ) ]
2503+ fn test_holder_selected_0reserve_on_legacy_channel_is_not_allowed ( ) {
2504+ {
2505+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2506+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2507+ let mut channel_config = test_default_channel_config ( ) ;
2508+ assert ! ( channel_config. channel_handshake_config. negotiate_anchors_zero_fee_htlc_tx) ;
2509+ let node_chanmgrs = create_node_chanmgrs (
2510+ 2 ,
2511+ & node_cfgs,
2512+ & [ Some ( channel_config. clone ( ) ) , Some ( channel_config. clone ( ) ) ] ,
2513+ ) ;
2514+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2515+
2516+ let _node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
2517+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
2518+
2519+ let mut legacy_channel_config = test_default_channel_config ( ) ;
2520+ legacy_channel_config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = false ;
2521+ legacy_channel_config. channel_handshake_config . negotiate_anchor_zero_fee_commitments =
2522+ false ;
2523+
2524+ // User tries to open a legacy 0-reserve channel with a config override, we fail
2525+ assert_eq ! (
2526+ nodes[ 0 ]
2527+ . node
2528+ . create_channel_to_trusted_peer_0reserve(
2529+ node_b_id,
2530+ 100_000 ,
2531+ 0 ,
2532+ 42 ,
2533+ None ,
2534+ Some ( legacy_channel_config)
2535+ )
2536+ . unwrap_err( ) ,
2537+ APIError :: APIMisuseError {
2538+ err: "0-reserve is not allowed on legacy channels" . to_owned( )
2539+ }
2540+ ) ;
2541+ }
2542+ {
2543+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2544+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2545+ let mut channel_config = test_default_channel_config ( ) ;
2546+ channel_config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = false ;
2547+ channel_config. channel_handshake_config . negotiate_anchor_zero_fee_commitments = false ;
2548+ let node_chanmgrs = create_node_chanmgrs (
2549+ 2 ,
2550+ & node_cfgs,
2551+ & [ Some ( channel_config. clone ( ) ) , Some ( channel_config. clone ( ) ) ] ,
2552+ ) ;
2553+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2554+
2555+ let _node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
2556+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
2557+
2558+ // User tries to open a legacy 0-reserve channel from the default config, we fail
2559+ assert_eq ! (
2560+ nodes[ 0 ]
2561+ . node
2562+ . create_channel_to_trusted_peer_0reserve( node_b_id, 100_000 , 0 , 42 , None , None )
2563+ . unwrap_err( ) ,
2564+ APIError :: APIMisuseError {
2565+ err: "0-reserve is not allowed on legacy channels" . to_owned( )
2566+ }
2567+ ) ;
2568+ }
2569+
2570+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2571+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2572+ let mut channel_config = test_default_channel_config ( ) ;
2573+ channel_config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = false ;
2574+ channel_config. channel_handshake_config . negotiate_anchor_zero_fee_commitments = false ;
2575+ let node_chanmgrs = create_node_chanmgrs (
2576+ 2 ,
2577+ & node_cfgs,
2578+ & [ Some ( channel_config. clone ( ) ) , Some ( channel_config. clone ( ) ) ] ,
2579+ ) ;
2580+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2581+
2582+ let node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
2583+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
2584+
2585+ nodes[ 0 ] . node . create_channel ( node_b_id, 100_000 , 0 , 42 , None , None ) . unwrap ( ) ;
2586+ let mut open_channel_msg_0reserve =
2587+ get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendOpenChannel , node_b_id) ;
2588+ open_channel_msg_0reserve. channel_reserve_satoshis = 0 ;
2589+ assert_eq ! (
2590+ open_channel_msg_0reserve. common_fields. channel_type,
2591+ Some ( ChannelTypeFeatures :: only_static_remote_key( ) )
2592+ ) ;
2593+
2594+ // User accepts a legacy channel, and sets 0-reserve for the counterparty, we fail
2595+ nodes[ 1 ] . node . handle_open_channel ( node_a_id, & open_channel_msg_0reserve) ;
2596+ let events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
2597+ match events[ 0 ] {
2598+ Event :: OpenChannelRequest { temporary_channel_id, .. } => {
2599+ let error = nodes[ 1 ]
2600+ . node
2601+ . accept_inbound_channel_from_trusted_peer (
2602+ & temporary_channel_id,
2603+ & node_a_id,
2604+ 42 ,
2605+ TrustedChannelFeatures :: ZeroReserve ,
2606+ None ,
2607+ )
2608+ . unwrap_err ( ) ;
2609+ assert_eq ! (
2610+ error,
2611+ APIError :: ChannelUnavailable {
2612+ err: "0-reserve is not allowed on legacy channels" . to_owned( )
2613+ }
2614+ ) ;
2615+ } ,
2616+ _ => panic ! ( "Unexpected event" ) ,
2617+ }
2618+ let err_msg = get_err_msg ( & nodes[ 1 ] , & node_a_id) ;
2619+ assert_eq ! (
2620+ err_msg,
2621+ ErrorMessage {
2622+ channel_id: open_channel_msg_0reserve. common_fields. temporary_channel_id,
2623+ data: "0-reserve is not allowed on legacy channels" . to_string( )
2624+ }
2625+ ) ;
2626+
2627+ // But legacy channels where only the counterparty sets 0-reserve are ok!
2628+ // Here node 1 accepts 0-reserve from node 0, and node 1 sets some non-zero reserve...
2629+ handle_and_accept_open_channel ( & nodes[ 1 ] , node_a_id, & open_channel_msg_0reserve) ;
2630+ let mut accept_channel_msg =
2631+ get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendAcceptChannel , node_a_id) ;
2632+ // Override the reserve selected by node 1, make sure node 0 accepts too
2633+ accept_channel_msg. channel_reserve_satoshis = 0 ;
2634+
2635+ nodes[ 0 ] . node . handle_accept_channel ( node_b_id, & accept_channel_msg) ;
2636+
2637+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
2638+ assert_eq ! ( events. len( ) , 1 ) ;
2639+ assert ! (
2640+ matches!( events[ 0 ] , Event :: FundingGenerationReady { channel_value_satoshis: 100_000 , user_channel_id: 42 , counterparty_node_id, .. } if counterparty_node_id == node_b_id)
2641+ ) ;
2642+ }
2643+
2644+ #[ xtest( feature = "_externalize_tests" ) ]
2645+ fn test_error_if_0reserve_negotiates_down_to_legacy ( ) {
2646+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2647+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2648+ let channel_config = test_default_channel_config ( ) ;
2649+ assert ! ( channel_config. channel_handshake_config. negotiate_anchors_zero_fee_htlc_tx) ;
2650+ let node_chanmgrs = create_node_chanmgrs (
2651+ 2 ,
2652+ & node_cfgs,
2653+ & [ Some ( channel_config. clone ( ) ) , Some ( channel_config. clone ( ) ) ] ,
2654+ ) ;
2655+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2656+
2657+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
2658+
2659+ nodes[ 0 ]
2660+ . node
2661+ . create_channel_to_trusted_peer_0reserve ( node_b_id, 100_000 , 0 , 42 , None , None )
2662+ . unwrap ( ) ;
2663+ let open_channel_msg = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendOpenChannel , node_b_id) ;
2664+ assert_eq ! (
2665+ open_channel_msg. common_fields. channel_type,
2666+ Some ( ChannelTypeFeatures :: anchors_zero_htlc_fee_and_dependencies( ) )
2667+ ) ;
2668+ assert_eq ! ( open_channel_msg. channel_reserve_satoshis, 0 ) ;
2669+
2670+ let reason = "Don't like your channel" . to_owned ( ) ;
2671+ nodes[ 0 ] . node . handle_error (
2672+ node_b_id,
2673+ & ErrorMessage {
2674+ channel_id : open_channel_msg. common_fields . temporary_channel_id ,
2675+ data : reason. clone ( ) ,
2676+ } ,
2677+ ) ;
2678+
2679+ let reason = ClosureReason :: CounterpartyForceClosed { peer_msg : UntrustedString ( reason) } ;
2680+ let expected_closing = ExpectedCloseEvent :: from_id_reason (
2681+ open_channel_msg. common_fields . temporary_channel_id ,
2682+ false ,
2683+ reason,
2684+ ) ;
2685+ check_closed_events ( & nodes[ 0 ] , & [ expected_closing] ) ;
2686+ }
0 commit comments