@@ -260,6 +260,13 @@ pub fn get_supportable_anchor_channels(
260260 num_whole_utxos + total_fractional_amount. to_sat ( ) / reserve_per_channel. to_sat ( ) / 2
261261}
262262
263+ /// Returns whether a channel of the given type requires an on-chain anchor reserve, i.e. uses
264+ /// either the `anchors_zero_fee_htlc_tx` or `anchor_zero_fee_commitments` (TRUC / 0FC) variant.
265+ fn is_anchor_channel_type ( channel_type : & ChannelTypeFeatures ) -> bool {
266+ channel_type. supports_anchors_zero_fee_htlc_tx ( )
267+ || channel_type. supports_anchor_zero_fee_commitments ( )
268+ }
269+
263270/// Verifies whether the anchor channel reserve provided by `utxos` is sufficient to support
264271/// an additional anchor channel.
265272///
@@ -296,7 +303,7 @@ where
296303 } else {
297304 continue ;
298305 } ;
299- if channel_monitor. channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( )
306+ if is_anchor_channel_type ( & channel_monitor. channel_type_features ( ) )
300307 && !channel_monitor. get_claimable_balances ( ) . is_empty ( )
301308 {
302309 anchor_channels. insert ( channel_id) ;
@@ -305,7 +312,7 @@ where
305312 // Also include channels that are in the middle of negotiation or anchor channels that don't have
306313 // a ChannelMonitor yet.
307314 for channel in a_channel_manager. get_cm ( ) . list_channels ( ) {
308- if channel. channel_type . map_or ( true , |ct| ct . supports_anchors_zero_fee_htlc_tx ( ) ) {
315+ if channel. channel_type . map_or ( true , |ct| is_anchor_channel_type ( & ct ) ) {
309316 anchor_channels. insert ( channel. channel_id ) ;
310317 }
311318 }
@@ -315,6 +322,7 @@ where
315322#[ cfg( test) ]
316323mod test {
317324 use super :: * ;
325+ use crate :: ln:: functional_test_utils:: * ;
318326 use bitcoin:: { OutPoint , ScriptBuf , Sequence , TxOut , Txid } ;
319327 use std:: str:: FromStr ;
320328
@@ -425,4 +433,48 @@ mod test {
425433 1068
426434 ) ;
427435 }
436+
437+ #[ test]
438+ fn test_can_support_additional_anchor_channel_zero_fee_commitments ( ) {
439+ // Regression test: a channel that uses the `anchor_zero_fee_commitments`
440+ // (option 41) variant is just as much an anchor channel — and requires
441+ // the same on-chain reserve — as one using `anchors_zero_fee_htlc_tx`.
442+ // The reserve check must therefore count it as an existing anchor
443+ // channel when deciding whether the wallet can safely support an
444+ // additional one. Currently `can_support_additional_anchor_channel`
445+ // only counts channels whose features set `anchors_zero_fee_htlc_tx`,
446+ // so a node whose reserves are exhausted by zero-fee-commitment
447+ // channels is incorrectly told it can open another anchor channel.
448+ let mut cfg = test_default_channel_config ( ) ;
449+ cfg. channel_handshake_config . negotiate_anchor_zero_fee_commitments = true ;
450+
451+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
452+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
453+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( cfg. clone ( ) ) , Some ( cfg) ] ) ;
454+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
455+
456+ create_chan_between_nodes ( & nodes[ 0 ] , & nodes[ 1 ] ) ;
457+
458+ let channels = nodes[ 0 ] . node . list_channels ( ) ;
459+ assert_eq ! ( channels. len( ) , 1 ) ;
460+ let channel_type = channels[ 0 ] . channel_type . as_ref ( ) . unwrap ( ) ;
461+ assert ! ( channel_type. supports_anchor_zero_fee_commitments( ) ) ;
462+ // Sanity check: a zero-fee-commitments channel does not also set the
463+ // older anchors_zero_fee_htlc_tx feature.
464+ assert ! ( !channel_type. supports_anchors_zero_fee_htlc_tx( ) ) ;
465+
466+ let context = AnchorChannelReserveContext :: default ( ) ;
467+ let reserve = get_reserve_per_channel ( & context) ;
468+ // Provide a single UTXO with enough value to cover one channel reserve.
469+ let utxos = vec ! [ make_p2wpkh_utxo( reserve * 2 ) ] ;
470+
471+ // We already have one TRUC anchor channel and only enough reserve for
472+ // a single channel; we must not authorize an additional one.
473+ assert ! ( !can_support_additional_anchor_channel(
474+ & context,
475+ & utxos,
476+ nodes[ 0 ] . node,
477+ & nodes[ 0 ] . chain_monitor. chain_monitor,
478+ ) ) ;
479+ }
428480}
0 commit comments