@@ -756,6 +756,9 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
756
756
}
757
757
758
758
/// Send an on-chain payment to the given address.
759
+ ///
760
+ /// This will respect any on-chain reserve we need to keep, i.e., won't allow to cut into
761
+ /// [`BalanceDetails::total_anchor_channels_reserve_sats`].
759
762
pub fn send_to_onchain_address (
760
763
& self , address : & bitcoin:: Address , amount_sats : u64 ,
761
764
) -> Result < Txid , Error > {
@@ -764,15 +767,29 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
764
767
return Err ( Error :: NotRunning ) ;
765
768
}
766
769
767
- let cur_balance = self . wallet . get_balance ( ) ?;
768
- if cur_balance. get_spendable ( ) < amount_sats {
769
- log_error ! ( self . logger, "Unable to send payment due to insufficient funds." ) ;
770
+ let cur_anchor_reserve_sats =
771
+ total_anchor_channels_reserve_sats ( & self . channel_manager , & self . config ) ;
772
+ let spendable_amount_sats =
773
+ self . wallet . get_balances ( cur_anchor_reserve_sats) . map ( |( _, s) | s) . unwrap_or ( 0 ) ;
774
+
775
+ if spendable_amount_sats < amount_sats {
776
+ log_error ! ( self . logger,
777
+ "Unable to send payment due to insufficient funds. Available: {}sats, Required: {}sats" ,
778
+ spendable_amount_sats, amount_sats
779
+ ) ;
770
780
return Err ( Error :: InsufficientFunds ) ;
771
781
}
772
782
self . wallet . send_to_address ( address, Some ( amount_sats) )
773
783
}
774
784
775
785
/// Send an on-chain payment to the given address, draining all the available funds.
786
+ ///
787
+ /// This is useful if you have closed all channels and want to migrate funds to another
788
+ /// on-chain wallet.
789
+ ///
790
+ /// Please note that this will **not** retain any on-chain reserves, which might be potentially
791
+ /// dangerous if you have open Anchor channels for which you can't trust the counterparty to
792
+ /// spend the Anchor output after channel closure.
776
793
pub fn send_all_to_onchain_address ( & self , address : & bitcoin:: Address ) -> Result < Txid , Error > {
777
794
let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
778
795
if rt_lock. is_none ( ) {
@@ -854,6 +871,10 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
854
871
/// channel counterparty on channel open. This can be useful to start out with the balance not
855
872
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
856
873
///
874
+ /// If Anchor channels are enabled, this will ensure the configured
875
+ /// [`AnchorChannelsConfig::per_channel_reserve_sats`] is available and will be retained before
876
+ /// opening the channel.
877
+ ///
857
878
/// Returns a temporary channel id.
858
879
pub fn connect_open_channel (
859
880
& self , node_id : PublicKey , address : SocketAddress , channel_amount_sats : u64 ,
@@ -866,9 +887,25 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
866
887
}
867
888
let runtime = rt_lock. as_ref ( ) . unwrap ( ) ;
868
889
869
- let cur_balance = self . wallet . get_balance ( ) ?;
870
- if cur_balance. get_spendable ( ) < channel_amount_sats {
871
- log_error ! ( self . logger, "Unable to create channel due to insufficient funds." ) ;
890
+ let required_funds_sats = channel_amount_sats
891
+ + self . config . anchor_channels_config . as_ref ( ) . map_or ( 0 , |c| {
892
+ if c. trusted_peers_no_reserve . contains ( & node_id) {
893
+ 0
894
+ } else {
895
+ c. per_channel_reserve_sats
896
+ }
897
+ } ) ;
898
+
899
+ let cur_anchor_reserve_sats =
900
+ total_anchor_channels_reserve_sats ( & self . channel_manager , & self . config ) ;
901
+ let spendable_amount_sats =
902
+ self . wallet . get_balances ( cur_anchor_reserve_sats) . map ( |( _, s) | s) . unwrap_or ( 0 ) ;
903
+
904
+ if spendable_amount_sats < required_funds_sats {
905
+ log_error ! ( self . logger,
906
+ "Unable to create channel due to insufficient funds. Available: {}sats, Required: {}sats" ,
907
+ spendable_amount_sats, required_funds_sats
908
+ ) ;
872
909
return Err ( Error :: InsufficientFunds ) ;
873
910
}
874
911
@@ -892,6 +929,7 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
892
929
channel_handshake_limits : Default :: default ( ) ,
893
930
channel_handshake_config : ChannelHandshakeConfig {
894
931
announced_channel : announce_channel,
932
+ negotiate_anchors_zero_fee_htlc_tx : self . config . anchor_channels_config . is_some ( ) ,
895
933
..Default :: default ( )
896
934
} ,
897
935
channel_config,
@@ -1450,11 +1488,13 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
1450
1488
1451
1489
/// Retrieves an overview of all known balances.
1452
1490
pub fn list_balances ( & self ) -> BalanceDetails {
1453
- let ( total_onchain_balance_sats, spendable_onchain_balance_sats) = self
1454
- . wallet
1455
- . get_balance ( )
1456
- . map ( |bal| ( bal. get_total ( ) , bal. get_spendable ( ) ) )
1457
- . unwrap_or ( ( 0 , 0 ) ) ;
1491
+ let cur_anchor_reserve_sats =
1492
+ total_anchor_channels_reserve_sats ( & self . channel_manager , & self . config ) ;
1493
+ let ( total_onchain_balance_sats, spendable_onchain_balance_sats) =
1494
+ self . wallet . get_balances ( cur_anchor_reserve_sats) . unwrap_or ( ( 0 , 0 ) ) ;
1495
+
1496
+ let total_anchor_channels_reserve_sats =
1497
+ std:: cmp:: min ( cur_anchor_reserve_sats, total_onchain_balance_sats) ;
1458
1498
1459
1499
let mut total_lightning_balance_sats = 0 ;
1460
1500
let mut lightning_balances = Vec :: new ( ) ;
@@ -1487,6 +1527,7 @@ impl<K: KVStore + Sync + Send + 'static> Node<K> {
1487
1527
BalanceDetails {
1488
1528
total_onchain_balance_sats,
1489
1529
spendable_onchain_balance_sats,
1530
+ total_anchor_channels_reserve_sats,
1490
1531
total_lightning_balance_sats,
1491
1532
lightning_balances,
1492
1533
pending_balances_from_channel_closures,
@@ -1635,3 +1676,21 @@ async fn do_connect_peer<K: KVStore + Sync + Send + 'static>(
1635
1676
}
1636
1677
}
1637
1678
}
1679
+
1680
+ pub ( crate ) fn total_anchor_channels_reserve_sats < K : KVStore + Sync + Send + ' static > (
1681
+ channel_manager : & ChannelManager < K > , config : & Config ,
1682
+ ) -> u64 {
1683
+ config. anchor_channels_config . as_ref ( ) . map_or ( 0 , |anchor_channels_config| {
1684
+ channel_manager
1685
+ . list_channels ( )
1686
+ . into_iter ( )
1687
+ . filter ( |c| {
1688
+ !anchor_channels_config. trusted_peers_no_reserve . contains ( & c. counterparty . node_id )
1689
+ && c. channel_type
1690
+ . as_ref ( )
1691
+ . map_or ( false , |t| t. supports_anchors_zero_fee_htlc_tx ( ) )
1692
+ } )
1693
+ . count ( ) as u64
1694
+ * anchor_channels_config. per_channel_reserve_sats
1695
+ } )
1696
+ }
0 commit comments