@@ -139,13 +139,14 @@ use graph::NetworkGraph;
139139use io:: utils:: write_node_metrics;
140140use lightning:: chain:: BestBlock ;
141141use lightning:: impl_writeable_tlv_based;
142+ use lightning:: ln:: chan_utils:: FUNDING_TRANSACTION_WITNESS_WEIGHT ;
142143use lightning:: ln:: channel_state:: { ChannelDetails as LdkChannelDetails , ChannelShutdownState } ;
143144use lightning:: ln:: channelmanager:: PaymentId ;
144145use lightning:: ln:: msgs:: SocketAddress ;
145146use lightning:: routing:: gossip:: NodeAlias ;
146147use lightning:: sign:: EntropySource ;
147148use lightning:: util:: persist:: KVStoreSync ;
148- use lightning:: util:: wallet_utils:: Wallet as LdkWallet ;
149+ use lightning:: util:: wallet_utils:: { Input , Wallet as LdkWallet } ;
149150use lightning_background_processor:: process_events_async;
150151use liquidity:: { LSPS1Liquidity , LiquiditySource } ;
151152use logger:: { log_debug, log_error, log_info, log_trace, LdkLogger , Logger } ;
@@ -1374,29 +1375,73 @@ impl Node {
13741375 )
13751376 }
13761377
1377- /// Add funds from the on-chain wallet into an existing channel.
1378- ///
1379- /// This provides for increasing a channel's outbound liquidity without re-balancing or closing
1380- /// it. Once negotiation with the counterparty is complete, the channel remains operational
1381- /// while waiting for a new funding transaction to confirm.
1382- ///
1383- /// # Experimental API
1384- ///
1385- /// This API is experimental. Currently, a splice-in will be marked as an outbound payment, but
1386- /// this classification may change in the future.
1387- pub fn splice_in (
1378+ fn splice_in_inner (
13881379 & self , user_channel_id : & UserChannelId , counterparty_node_id : PublicKey ,
1389- splice_amount_sats : u64 ,
1380+ splice_amount_sats : FundingAmount ,
13901381 ) -> Result < ( ) , Error > {
13911382 let open_channels =
13921383 self . channel_manager . list_channels_with_counterparty ( & counterparty_node_id) ;
13931384 if let Some ( channel_details) =
13941385 open_channels. iter ( ) . find ( |c| c. user_channel_id == user_channel_id. 0 )
13951386 {
1396- self . check_sufficient_funds_for_channel ( splice_amount_sats, & counterparty_node_id) ?;
1397-
13981387 let fee_rate = self . fee_estimator . estimate_fee_rate ( ConfirmationTarget :: ChannelFunding ) ;
13991388
1389+ let splice_amount_sats = match splice_amount_sats {
1390+ FundingAmount :: Exact { amount_sats } => amount_sats,
1391+ FundingAmount :: Max => {
1392+ let cur_anchor_reserve_sats =
1393+ total_anchor_channels_reserve_sats ( & self . channel_manager , & self . config ) ;
1394+
1395+ const EMPTY_SCRIPT_SIG_WEIGHT : u64 =
1396+ 1 /* empty script_sig */ * bitcoin:: constants:: WITNESS_SCALE_FACTOR as u64 ;
1397+
1398+ let funding_txo = channel_details. funding_txo . ok_or_else ( || {
1399+ log_error ! ( self . logger, "Failed to splice channel: channel not yet ready" , ) ;
1400+ Error :: ChannelSplicingFailed
1401+ } ) ?;
1402+
1403+ let funding_output = channel_details. get_funding_output ( ) . ok_or_else ( || {
1404+ log_error ! ( self . logger, "Failed to splice channel: channel not yet ready" ) ;
1405+ Error :: ChannelSplicingFailed
1406+ } ) ?;
1407+
1408+ let shared_input = Input {
1409+ outpoint : funding_txo. into_bitcoin_outpoint ( ) ,
1410+ previous_utxo : funding_output. clone ( ) ,
1411+ satisfaction_weight : EMPTY_SCRIPT_SIG_WEIGHT
1412+ + FUNDING_TRANSACTION_WITNESS_WEIGHT ,
1413+ } ;
1414+
1415+ let amount = self
1416+ . wallet
1417+ . get_max_splice_in_amount (
1418+ shared_input,
1419+ funding_output. script_pubkey . clone ( ) ,
1420+ cur_anchor_reserve_sats,
1421+ fee_rate,
1422+ )
1423+ . map_err ( |e| {
1424+ log_error ! (
1425+ self . logger,
1426+ "Failed to determine max splice-in amount: {e:?}"
1427+ ) ;
1428+ e
1429+ } ) ?;
1430+
1431+ log_info ! (
1432+ self . logger,
1433+ "Splicing in with all balance: {}sats (fee rate: {} sat/kw, anchor reserve: {}sats)" ,
1434+ amount,
1435+ fee_rate. to_sat_per_kwu( ) ,
1436+ cur_anchor_reserve_sats,
1437+ ) ;
1438+
1439+ amount
1440+ } ,
1441+ } ;
1442+
1443+ self . check_sufficient_funds_for_channel ( splice_amount_sats, & counterparty_node_id) ?;
1444+
14001445 let funding_template = self
14011446 . channel_manager
14021447 . splice_channel ( & channel_details. channel_id , & counterparty_node_id, fee_rate)
@@ -1438,6 +1483,46 @@ impl Node {
14381483 }
14391484 }
14401485
1486+ /// Add funds to an existing channel from a transaction output you control.
1487+ ///
1488+ /// This provides for increasing a channel's outbound liquidity without re-balancing or closing
1489+ /// it. Once negotiation with the counterparty is complete, the channel remains operational
1490+ /// while waiting for a new funding transaction to confirm.
1491+ ///
1492+ /// # Experimental API
1493+ ///
1494+ /// This API is experimental. Currently, a splice-in will be marked as an outbound payment, but
1495+ /// this classification may change in the future.
1496+ pub fn splice_in (
1497+ & self , user_channel_id : & UserChannelId , counterparty_node_id : PublicKey ,
1498+ splice_amount_sats : u64 ,
1499+ ) -> Result < ( ) , Error > {
1500+ self . splice_in_inner (
1501+ user_channel_id,
1502+ counterparty_node_id,
1503+ FundingAmount :: Exact { amount_sats : splice_amount_sats } ,
1504+ )
1505+ }
1506+
1507+ /// Add all available on-chain funds into an existing channel.
1508+ ///
1509+ /// This is similar to [`Node::splice_in`] but uses all available confirmed on-chain funds
1510+ /// instead of requiring a specific amount.
1511+ ///
1512+ /// This provides for increasing a channel's outbound liquidity without re-balancing or closing
1513+ /// it. Once negotiation with the counterparty is complete, the channel remains operational
1514+ /// while waiting for a new funding transaction to confirm.
1515+ ///
1516+ /// # Experimental API
1517+ ///
1518+ /// This API is experimental. Currently, a splice-in will be marked as an outbound payment, but
1519+ /// this classification may change in the future.
1520+ pub fn splice_in_with_all (
1521+ & self , user_channel_id : & UserChannelId , counterparty_node_id : PublicKey ,
1522+ ) -> Result < ( ) , Error > {
1523+ self . splice_in_inner ( user_channel_id, counterparty_node_id, FundingAmount :: Max )
1524+ }
1525+
14411526 /// Remove funds from an existing channel, sending them to an on-chain address.
14421527 ///
14431528 /// This provides for decreasing a channel's outbound liquidity without re-balancing or closing
0 commit comments