@@ -142,7 +142,7 @@ use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger};
142142
143143use lightning:: chain:: { BestBlock , Confirm } ;
144144use lightning:: events:: bump_transaction:: Wallet as LdkWallet ;
145- use lightning:: ln:: channelmanager:: PaymentId ;
145+ use lightning:: ln:: channelmanager:: { ChannelShutdownState , PaymentId } ;
146146use lightning:: ln:: msgs:: SocketAddress ;
147147
148148use lightning:: util:: config:: { ChannelHandshakeConfig , UserConfig } ;
@@ -916,6 +916,8 @@ impl Node {
916916 OnchainPayment :: new (
917917 Arc :: clone ( & self . runtime ) ,
918918 Arc :: clone ( & self . wallet ) ,
919+ Arc :: clone ( & self . channel_manager ) ,
920+ Arc :: clone ( & self . config ) ,
919921 Arc :: clone ( & self . logger ) ,
920922 )
921923 }
@@ -926,6 +928,8 @@ impl Node {
926928 Arc :: new ( OnchainPayment :: new (
927929 Arc :: clone ( & self . runtime ) ,
928930 Arc :: clone ( & self . wallet ) ,
931+ Arc :: clone ( & self . channel_manager ) ,
932+ Arc :: clone ( & self . config ) ,
929933 Arc :: clone ( & self . logger ) ,
930934 ) )
931935 }
@@ -1001,6 +1005,10 @@ impl Node {
10011005 /// channel counterparty on channel open. This can be useful to start out with the balance not
10021006 /// entirely shifted to one side, therefore allowing to receive payments from the getgo.
10031007 ///
1008+ /// If Anchor channels are enabled, this will ensure the configured
1009+ /// [`AnchorChannelsConfig::per_channel_reserve_sats`] is available and will be retained before
1010+ /// opening the channel.
1011+ ///
10041012 /// Returns a [`UserChannelId`] allowing to locally keep track of the channel.
10051013 pub fn connect_open_channel (
10061014 & self , node_id : PublicKey , address : SocketAddress , channel_amount_sats : u64 ,
@@ -1013,18 +1021,26 @@ impl Node {
10131021 }
10141022 let runtime = rt_lock. as_ref ( ) . unwrap ( ) ;
10151023
1016- let cur_balance = self . wallet . get_balance ( ) ?;
1017- if cur_balance. get_spendable ( ) < channel_amount_sats {
1018- log_error ! ( self . logger, "Unable to create channel due to insufficient funds." ) ;
1019- return Err ( Error :: InsufficientFunds ) ;
1020- }
1021-
10221024 let peer_info = PeerInfo { node_id, address } ;
10231025
10241026 let con_node_id = peer_info. node_id ;
10251027 let con_addr = peer_info. address . clone ( ) ;
10261028 let con_cm = Arc :: clone ( & self . connection_manager ) ;
10271029
1030+ let cur_anchor_reserve_sats =
1031+ total_anchor_channels_reserve_sats ( & self . channel_manager , & self . config ) ;
1032+ let spendable_amount_sats =
1033+ self . wallet . get_spendable_amount_sats ( cur_anchor_reserve_sats) . unwrap_or ( 0 ) ;
1034+
1035+ // Fail early if we have less than the channel value available.
1036+ if spendable_amount_sats < channel_amount_sats {
1037+ log_error ! ( self . logger,
1038+ "Unable to create channel due to insufficient funds. Available: {}sats, Required: {}sats" ,
1039+ spendable_amount_sats, channel_amount_sats
1040+ ) ;
1041+ return Err ( Error :: InsufficientFunds ) ;
1042+ }
1043+
10281044 // We need to use our main runtime here as a local runtime might not be around to poll
10291045 // connection futures going forward.
10301046 tokio:: task:: block_in_place ( move || {
@@ -1033,11 +1049,37 @@ impl Node {
10331049 } )
10341050 } ) ?;
10351051
1052+ // Fail if we have less than the channel value + anchor reserve available (if applicable).
1053+ let init_features = self
1054+ . peer_manager
1055+ . peer_by_node_id ( & node_id)
1056+ . ok_or ( Error :: ConnectionFailed ) ?
1057+ . init_features ;
1058+ let required_funds_sats = channel_amount_sats
1059+ + self . config . anchor_channels_config . as_ref ( ) . map_or ( 0 , |c| {
1060+ if init_features. requires_anchors_zero_fee_htlc_tx ( )
1061+ && !c. trusted_peers_no_reserve . contains ( & node_id)
1062+ {
1063+ c. per_channel_reserve_sats
1064+ } else {
1065+ 0
1066+ }
1067+ } ) ;
1068+
1069+ if spendable_amount_sats < required_funds_sats {
1070+ log_error ! ( self . logger,
1071+ "Unable to create channel due to insufficient funds. Available: {}sats, Required: {}sats" ,
1072+ spendable_amount_sats, required_funds_sats
1073+ ) ;
1074+ return Err ( Error :: InsufficientFunds ) ;
1075+ }
1076+
10361077 let channel_config = ( * ( channel_config. unwrap_or_default ( ) ) ) . clone ( ) . into ( ) ;
10371078 let user_config = UserConfig {
10381079 channel_handshake_limits : Default :: default ( ) ,
10391080 channel_handshake_config : ChannelHandshakeConfig {
10401081 announced_channel : announce_channel,
1082+ negotiate_anchors_zero_fee_htlc_tx : self . config . anchor_channels_config . is_some ( ) ,
10411083 ..Default :: default ( )
10421084 } ,
10431085 channel_config,
@@ -1196,11 +1238,13 @@ impl Node {
11961238
11971239 /// Retrieves an overview of all known balances.
11981240 pub fn list_balances ( & self ) -> BalanceDetails {
1199- let ( total_onchain_balance_sats, spendable_onchain_balance_sats) = self
1200- . wallet
1201- . get_balance ( )
1202- . map ( |bal| ( bal. get_total ( ) , bal. get_spendable ( ) ) )
1203- . unwrap_or ( ( 0 , 0 ) ) ;
1241+ let cur_anchor_reserve_sats =
1242+ total_anchor_channels_reserve_sats ( & self . channel_manager , & self . config ) ;
1243+ let ( total_onchain_balance_sats, spendable_onchain_balance_sats) =
1244+ self . wallet . get_balances ( cur_anchor_reserve_sats) . unwrap_or ( ( 0 , 0 ) ) ;
1245+
1246+ let total_anchor_channels_reserve_sats =
1247+ std:: cmp:: min ( cur_anchor_reserve_sats, total_onchain_balance_sats) ;
12041248
12051249 let mut total_lightning_balance_sats = 0 ;
12061250 let mut lightning_balances = Vec :: new ( ) ;
@@ -1235,6 +1279,7 @@ impl Node {
12351279 BalanceDetails {
12361280 total_onchain_balance_sats,
12371281 spendable_onchain_balance_sats,
1282+ total_anchor_channels_reserve_sats,
12381283 total_lightning_balance_sats,
12391284 lightning_balances,
12401285 pending_balances_from_channel_closures,
@@ -1367,3 +1412,23 @@ pub struct NodeStatus {
13671412 /// Will be `None` if we have no public channels or we haven't broadcasted since the [`Node`] was initialized.
13681413 pub latest_node_announcement_broadcast_timestamp : Option < u64 > ,
13691414}
1415+
1416+ pub ( crate ) fn total_anchor_channels_reserve_sats (
1417+ channel_manager : & ChannelManager , config : & Config ,
1418+ ) -> u64 {
1419+ config. anchor_channels_config . as_ref ( ) . map_or ( 0 , |anchor_channels_config| {
1420+ channel_manager
1421+ . list_channels ( )
1422+ . into_iter ( )
1423+ . filter ( |c| {
1424+ !anchor_channels_config. trusted_peers_no_reserve . contains ( & c. counterparty . node_id )
1425+ && c. channel_shutdown_state
1426+ . map_or ( true , |s| s != ChannelShutdownState :: ShutdownComplete )
1427+ && c. channel_type
1428+ . as_ref ( )
1429+ . map_or ( false , |t| t. requires_anchors_zero_fee_htlc_tx ( ) )
1430+ } )
1431+ . count ( ) as u64
1432+ * anchor_channels_config. per_channel_reserve_sats
1433+ } )
1434+ }
0 commit comments