@@ -28,7 +28,7 @@ use bitcoin::hash_types::{BlockHash, Txid};
2828
2929use bitcoin:: secp256k1:: { SecretKey , PublicKey } ;
3030use bitcoin:: secp256k1:: Secp256k1 ;
31- use bitcoin:: { LockTime , secp256k1, Sequence } ;
31+ use bitcoin:: { LockTime , secp256k1, Sequence , Script } ;
3232
3333use crate :: chain;
3434use crate :: chain:: { Confirm , ChannelMonitorUpdateStatus , Watch , BestBlock } ;
@@ -40,7 +40,7 @@ use crate::events::{Event, EventHandler, EventsProvider, MessageSendEvent, Messa
4040// Since this struct is returned in `list_channels` methods, expose it here in case users want to
4141// construct one themselves.
4242use crate :: ln:: { inbound_payment, PaymentHash , PaymentPreimage , PaymentSecret } ;
43- use crate :: ln:: channel:: { Channel , OutboundV1Channel , InboundV1Channel , ChannelInterface , ChannelError , ChannelUpdateStatus , UpdateFulfillCommitFetch } ;
43+ use crate :: ln:: channel:: { Channel , OutboundV1Channel , InboundV1Channel , OutboundV2Channel , InboundV2Channel , ChannelInterface , ChannelError , ChannelUpdateStatus , UpdateFulfillCommitFetch } ;
4444use crate :: ln:: features:: { ChannelFeatures , ChannelTypeFeatures , InitFeatures , NodeFeatures } ;
4545#[ cfg( any( feature = "_test_utils" , test) ) ]
4646use crate :: ln:: features:: InvoiceFeatures ;
@@ -80,6 +80,8 @@ use core::ops::Deref;
8080pub use crate :: ln:: outbound_payment:: { PaymentSendFailure , Retry , RetryableSendFailure , RecipientOnionFields } ;
8181use crate :: ln:: script:: ShutdownScript ;
8282
83+ use super :: channel:: DualFundingUtxo ;
84+
8385// We hold various information about HTLC relay in the HTLC objects in Channel itself:
8486//
8587// Upon receipt of an HTLC from a peer, we'll give it a PendingHTLCStatus indicating if it should
@@ -556,6 +558,27 @@ pub(super) struct PeerState<Signer: ChannelSigner> {
556558 /// been assigned a `channel_id`, the entry in this map is removed and one is created in
557559 /// `channel_by_id`.
558560 pub ( super ) inbound_v1_channel_by_id : HashMap < [ u8 ; 32 ] , InboundV1Channel < Signer > > ,
561+ /// `(temporary_)channel_id` -> `OutboundV2Channel`.
562+ ///
563+ /// Holds all outbound V2 channels where the peer is the counterparty. V2 channels are assigned
564+ /// a `channel_id` before a funding transaction is created interactively as it's derived from
565+ /// both parties' revocation basepoints once these are known. Hence, this map's keys are either
566+ /// temporary channel IDs or channel IDs.
567+ ///
568+ /// The entries in this map are only moved to `channel_by_id` once interactive transaction
569+ /// construction completes successfully.
570+ pub ( super ) outbound_v2_channel_by_id : HashMap < [ u8 ; 32 ] , OutboundV2Channel < Signer > > ,
571+ /// `channel_id` -> `InboundV2Channel`.
572+ ///
573+ /// Holds all inbound V2 channels where the peer is the counterparty. V2 channels are assigned
574+ /// a `channel_id` before a funding transaction is created interactively as it's derived from
575+ /// both parties' revocation basepoints once these are known. At the stage of receiving an
576+ /// `open_channel2` request, we have enough information to derive the `channel_id`. Hence, this
577+ /// map's keys are always `channel_id`s.
578+ ///
579+ /// The entries in this map are only moved to `channel_by_id` once interactive transaction
580+ /// construction completes successfully.
581+ pub ( super ) inbound_v2_channel_by_id : HashMap < [ u8 ; 32 ] , InboundV2Channel < Signer > > ,
559582 /// The latest `InitFeatures` we heard from the peer.
560583 latest_features : InitFeatures ,
561584 /// Messages to send to the peer - pushed to in the same lock that they are generated in (except
@@ -1913,6 +1936,102 @@ where
19131936 Ok ( temporary_channel_id)
19141937 }
19151938
1939+
1940+ /// Creates a new outbound dual-funded channel to the given remote node and with the given value
1941+ /// contributed by us.
1942+ ///
1943+ /// `user_channel_id` will be provided back as in
1944+ /// [`Event::FundingGenerationReady::user_channel_id`] to allow tracking of which events
1945+ /// correspond with which `create_channel` call. Note that the `user_channel_id` defaults to a
1946+ /// randomized value for inbound channels. `user_channel_id` has no meaning inside of LDK, it
1947+ /// is simply copied to events and otherwise ignored.
1948+ ///
1949+ /// `funnding_satoshis` is the amount we are contributing to the channel.
1950+ /// Raises [`APIError::APIMisuseError`] when `funding_satoshis` > 2**24.
1951+ ///
1952+ /// The `funding_inputs` parameter accepts UTXOs in the form of [`DualFundingUtxo`] which will
1953+ /// be used to contribute `funding_satoshis` towards the channel (minus any mining fees due).
1954+ /// Raises [`APIError::APIMisuseError`] if the total value of the provided `funding_inputs` is
1955+ /// less than `funding_satoshis`.
1956+ // TODO(dual_funding): Describe error relating to inputs not being able to cover fees payable by us.
1957+ ///
1958+ /// The `change_script_pubkey` parameter provides a destination for the change output if any value
1959+ /// is remaining (greater than dust) after `funding_satoshis` and fees payable are satisfied by
1960+ /// `funding_inputs`
1961+ // TODO(dual_funding): We could allow a list of such outputs to be provided so that the user may
1962+ /// be able to do some more interesting things at the same time as funding a channel, like making
1963+ /// some low priority on-chain payment.
1964+ ///
1965+ /// Raises [`APIError::ChannelUnavailable`] if the channel cannot be opened due to failing to
1966+ /// generate a shutdown scriptpubkey or destination script set by
1967+ /// [`SignerProvider::get_shutdown_scriptpubkey`] or [`SignerProvider::get_destination_script`].
1968+ ///
1969+ /// Note that we do not check if you are currently connected to the given peer. If no
1970+ /// connection is available, the outbound `open_channel` message may fail to send, resulting in
1971+ /// the channel eventually being silently forgotten (dropped on reload).
1972+ ///
1973+ /// Returns the new Channel's temporary `channel_id`. This ID will appear as
1974+ /// [`Event::FundingGenerationReady::temporary_channel_id`] and in
1975+ /// [`ChannelDetails::channel_id`] until after
1976+ /// [`ChannelManager::funding_transaction_generated`] is called, swapping the Channel's ID for
1977+ /// one derived from the funding transaction's TXID. If the counterparty rejects the channel
1978+ /// immediately, this temporary ID will appear in [`Event::ChannelClosed::channel_id`].
1979+ ///
1980+ /// [`Event::FundingGenerationReady::user_channel_id`]: events::Event::FundingGenerationReady::user_channel_id
1981+ /// [`Event::FundingGenerationReady::temporary_channel_id`]: events::Event::FundingGenerationReady::temporary_channel_id
1982+ /// [`Event::ChannelClosed::channel_id`]: events::Event::ChannelClosed::channel_id
1983+ pub fn create_dual_funded_channel ( & self , their_network_key : PublicKey , funding_satoshis : u64 ,
1984+ funding_inputs : Vec < DualFundingUtxo > , change_script_pubkey : Script ,
1985+ user_channel_id : u128 , override_config : Option < UserConfig > ) -> Result < [ u8 ; 32 ] , APIError >
1986+ {
1987+ Self :: dual_funding_amount_checks ( funding_satoshis, & funding_inputs) ;
1988+
1989+ let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
1990+ // We want to make sure the lock is actually acquired by PersistenceNotifierGuard.
1991+ debug_assert ! ( & self . total_consistency_lock. try_write( ) . is_err( ) ) ;
1992+
1993+ let per_peer_state = self . per_peer_state . read ( ) . unwrap ( ) ;
1994+
1995+ let peer_state_mutex = per_peer_state. get ( & their_network_key)
1996+ . ok_or_else ( || APIError :: APIMisuseError { err : format ! ( "Not connected to node: {}" , their_network_key) } ) ?;
1997+
1998+ let mut peer_state = peer_state_mutex. lock ( ) . unwrap ( ) ;
1999+ let channel = {
2000+ let outbound_scid_alias = self . create_and_insert_outbound_scid_alias ( ) ;
2001+ let their_features = & peer_state. latest_features ;
2002+ let config = if override_config. is_some ( ) { override_config. as_ref ( ) . unwrap ( ) } else { & self . default_configuration } ;
2003+ match OutboundV2Channel :: new ( & self . fee_estimator , & self . entropy_source , & self . signer_provider , their_network_key,
2004+ their_features, funding_satoshis, funding_inputs, change_script_pubkey, user_channel_id, config,
2005+ self . best_block . read ( ) . unwrap ( ) . height ( ) , outbound_scid_alias, true )
2006+ {
2007+ Ok ( res) => res,
2008+ Err ( e) => {
2009+ self . outbound_scid_aliases . lock ( ) . unwrap ( ) . remove ( & outbound_scid_alias) ;
2010+ return Err ( e) ;
2011+ } ,
2012+ }
2013+ } ;
2014+ let res = channel. get_open_channel_v2 ( self . genesis_hash . clone ( ) ) ;
2015+
2016+ let temporary_channel_id = channel. channel_id ( ) ;
2017+ match peer_state. outbound_v2_channel_by_id . entry ( temporary_channel_id) {
2018+ hash_map:: Entry :: Occupied ( _) => {
2019+ if cfg ! ( fuzzing) {
2020+ return Err ( APIError :: APIMisuseError { err : "Fuzzy bad RNG" . to_owned ( ) } ) ;
2021+ } else {
2022+ panic ! ( "RNG is bad???" ) ;
2023+ }
2024+ } ,
2025+ hash_map:: Entry :: Vacant ( entry) => { entry. insert ( channel) ; }
2026+ }
2027+
2028+ peer_state. pending_msg_events . push ( events:: MessageSendEvent :: SendOpenChannelV2 {
2029+ node_id : their_network_key,
2030+ msg : res,
2031+ } ) ;
2032+ Ok ( temporary_channel_id)
2033+ }
2034+
19162035 fn list_funded_channels_with_filter < Fn : FnMut ( & ( & [ u8 ; 32 ] , & Channel < <SP :: Target as SignerProvider >:: Signer > ) ) -> bool + Copy > ( & self , f : Fn ) -> Vec < ChannelDetails > {
19172036 // Allocate our best estimate of the number of channels we have in the `res`
19182037 // Vec. Sadly the `short_to_chan_info` map doesn't cover channels without
@@ -4687,6 +4806,128 @@ where
46874806 Ok ( ( ) )
46884807 }
46894808
4809+ /// Accepts a request to open a dual-funded channel after an [`Event::OpenChannelV2Request`].
4810+ ///
4811+ /// The `temporary_channel_id` parameter indicates which inbound channel should be accepted,
4812+ /// and the `counterparty_node_id` parameter is the id of the peer which has requested to open
4813+ /// the channel.
4814+ ///
4815+ /// The `user_channel_id` parameter will be provided back in
4816+ /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
4817+ /// with which `accept_inbound_dual_funded_channel`/`accept_inbound_dual_funded_channel_from_trusted_peer_0conf` call.
4818+ ///
4819+ /// `funnding_satoshis` is the amount we are contributing to the channel.
4820+ /// Raises [`APIError::APIMisuseError`] when `funding_satoshis` > 2**24.
4821+ ///
4822+ /// The `funding_inputs` parameter accepts UTXOs in the form of [`DualFundingUtxo`] which will
4823+ /// be used to contribute `funding_satoshis` towards the channel (minus any mining fees due).
4824+ /// Raises [`APIError::APIMisuseError`] if the total value of the provided `funding_inputs` is
4825+ /// less than `funding_satoshis`.
4826+ // TODO(dual_funding): Describe error relating to inputs not being able to cover fees payable by us.
4827+ ///
4828+ /// The `change_script_pubkey` parameter provides a destination for the change output if any value
4829+ /// is remaining (greater than dust) after `funding_satoshis` and fees payable are satisfied by
4830+ /// `funding_inputs`
4831+ // TODO(dual_funding): We could allow a list of such outputs to be provided so that the user may
4832+ /// be able to do some more interesting things at the same time as funding.
4833+ ///
4834+ /// Note that this method will return an error and reject the channel, if it requires support
4835+ /// for zero confirmations.
4836+ // TODO(dual_funding): Discussion on complications with 0conf dual-funded channels where "locking"
4837+ // of UTXOs used for funding would be required and other issues.
4838+ // See: https://lists.linuxfoundation.org/pipermail/lightning-dev/2023-May/003920.html
4839+ ///
4840+ ///
4841+ /// [`Event::OpenChannelV2Request`]: events::Event::OpenChannelV2Request
4842+ /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
4843+ pub fn accept_inbound_dual_funded_channel ( & self , temporary_channel_id : & [ u8 ; 32 ] ,
4844+ counterparty_node_id : & PublicKey , user_channel_id : u128 , funding_satoshis : u64 ,
4845+ funding_inputs : Vec < DualFundingUtxo > , change_script_pubkey : Script ) -> Result < ( ) , APIError > {
4846+ self . do_accept_inbound_dual_funded_channel ( temporary_channel_id, counterparty_node_id, false ,
4847+ user_channel_id, funding_satoshis, funding_inputs, change_script_pubkey)
4848+ }
4849+
4850+ fn do_accept_inbound_dual_funded_channel ( & self , temporary_channel_id : & [ u8 ; 32 ] ,
4851+ counterparty_node_id : & PublicKey , accept_0conf : bool , user_channel_id : u128 ,
4852+ funding_satoshis : u64 , funding_inputs : Vec < DualFundingUtxo > , change_script_pubkey : Script ,
4853+ ) -> Result < ( ) , APIError > {
4854+ Self :: dual_funding_amount_checks ( funding_satoshis, & funding_inputs) ?;
4855+
4856+ let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
4857+
4858+ let peers_without_funded_channels =
4859+ self . peers_without_funded_channels ( |peer| { peer. total_channel_count ( ) > 0 } ) ;
4860+ let per_peer_state = self . per_peer_state . read ( ) . unwrap ( ) ;
4861+ let peer_state_mutex = per_peer_state. get ( counterparty_node_id)
4862+ . ok_or_else ( || APIError :: ChannelUnavailable { err : format ! ( "Can't find a peer matching the passed counterparty node_id {}" , counterparty_node_id) } ) ?;
4863+ let mut peer_state_lock = peer_state_mutex. lock ( ) . unwrap ( ) ;
4864+ let peer_state = & mut * peer_state_lock;
4865+ let is_only_peer_channel = peer_state. total_channel_count ( ) == 1 ;
4866+ match peer_state. inbound_v2_channel_by_id . entry ( temporary_channel_id. clone ( ) ) {
4867+ hash_map:: Entry :: Occupied ( mut channel) => {
4868+ if !channel. get ( ) . inbound_is_awaiting_accept ( ) {
4869+ return Err ( APIError :: APIMisuseError { err : "The channel isn't currently awaiting to be accepted." . to_owned ( ) } ) ;
4870+ }
4871+ if accept_0conf {
4872+ channel. get_mut ( ) . set_0conf ( ) ;
4873+ } else if channel. get ( ) . get_channel_type ( ) . requires_zero_conf ( ) {
4874+ let send_msg_err_event = events:: MessageSendEvent :: HandleError {
4875+ node_id : channel. get ( ) . get_counterparty_node_id ( ) ,
4876+ action : msgs:: ErrorAction :: SendErrorMessage {
4877+ msg : msgs:: ErrorMessage { channel_id : temporary_channel_id. clone ( ) , data : "No zero confirmation channels accepted" . to_owned ( ) , }
4878+ }
4879+ } ;
4880+ peer_state. pending_msg_events . push ( send_msg_err_event) ;
4881+ let _ = remove_channel ! ( self , channel) ;
4882+ return Err ( APIError :: APIMisuseError { err : "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations." . to_owned ( ) } ) ;
4883+ } else {
4884+ // If this peer already has some channels, a new channel won't increase our number of peers
4885+ // with unfunded channels, so as long as we aren't over the maximum number of unfunded
4886+ // channels per-peer we can accept channels from a peer with existing ones.
4887+ if is_only_peer_channel && peers_without_funded_channels >= MAX_UNFUNDED_CHANNEL_PEERS {
4888+ let send_msg_err_event = events:: MessageSendEvent :: HandleError {
4889+ node_id : channel. get ( ) . get_counterparty_node_id ( ) ,
4890+ action : msgs:: ErrorAction :: SendErrorMessage {
4891+ msg : msgs:: ErrorMessage { channel_id : temporary_channel_id. clone ( ) , data : "Have too many peers with unfunded channels, not accepting new ones" . to_owned ( ) , }
4892+ }
4893+ } ;
4894+ peer_state. pending_msg_events . push ( send_msg_err_event) ;
4895+ let _ = remove_channel ! ( self , channel) ;
4896+ return Err ( APIError :: APIMisuseError { err : "Too many peers with unfunded channels, refusing to accept new ones" . to_owned ( ) } ) ;
4897+ }
4898+ }
4899+
4900+ peer_state. pending_msg_events . push ( events:: MessageSendEvent :: SendAcceptChannel {
4901+ node_id : channel. get ( ) . get_counterparty_node_id ( ) ,
4902+ msg : channel. get_mut ( ) . accept_inbound_channel ( user_channel_id) ,
4903+ } ) ;
4904+ }
4905+ hash_map:: Entry :: Vacant ( _) => {
4906+ return Err ( APIError :: ChannelUnavailable { err : format ! ( "Channel with id {} not found for the passed counterparty node_id {}" , log_bytes!( * temporary_channel_id) , counterparty_node_id) } ) ;
4907+ }
4908+ }
4909+ Ok ( ( ) )
4910+ }
4911+
4912+ /// Checks related to inputs and their amounts related to establishing dual-funded channels.
4913+ fn dual_funding_amount_checks ( funding_satoshis : u64 , funding_inputs : & Vec < DualFundingUtxo > )
4914+ -> Result < ( ) , APIError > {
4915+ if funding_satoshis < 1000 {
4916+ return Err ( APIError :: APIMisuseError {
4917+ err : format ! ( "Funding amount must be at least 1000 satoshis. It was {} sats" , funding_satoshis) ,
4918+ } ) ;
4919+ }
4920+
4921+ let total_input_satoshis: u64 = funding_inputs. iter ( ) . map ( |input| input. output . value ) . sum ( ) ;
4922+ if total_input_satoshis < funding_satoshis {
4923+ Err ( APIError :: APIMisuseError {
4924+ err : format ! ( "Total value of funding inputs must be at least funding amount. It was {} sats" ,
4925+ total_input_satoshis) } )
4926+ } else {
4927+ Ok ( ( ) )
4928+ }
4929+ }
4930+
46904931 /// Gets the number of peers which match the given filter and do not have any funded, outbound,
46914932 /// or 0-conf channels.
46924933 ///
@@ -4726,6 +4967,11 @@ where
47264967 num_unfunded_channels += 1 ;
47274968 }
47284969 }
4970+ for ( _, chan) in peer. inbound_v2_channel_by_id . iter ( ) {
4971+ if chan. minimum_depth ( ) . unwrap_or ( 1 ) != 0 {
4972+ num_unfunded_channels += 1 ;
4973+ }
4974+ }
47294975 num_unfunded_channels
47304976 }
47314977
@@ -6820,6 +7066,8 @@ where
68207066 channel_by_id : HashMap :: new ( ) ,
68217067 outbound_v1_channel_by_id : HashMap :: new ( ) ,
68227068 inbound_v1_channel_by_id : HashMap :: new ( ) ,
7069+ outbound_v2_channel_by_id : HashMap :: new ( ) ,
7070+ inbound_v2_channel_by_id : HashMap :: new ( ) ,
68237071 latest_features : init_msg. features . clone ( ) ,
68247072 pending_msg_events : Vec :: new ( ) ,
68257073 monitor_update_blocked_actions : BTreeMap :: new ( ) ,
@@ -8013,6 +8261,8 @@ where
80138261 channel_by_id : peer_channels. remove ( & peer_pubkey) . unwrap_or ( HashMap :: new ( ) ) ,
80148262 outbound_v1_channel_by_id : HashMap :: new ( ) ,
80158263 inbound_v1_channel_by_id : HashMap :: new ( ) ,
8264+ outbound_v2_channel_by_id : HashMap :: new ( ) ,
8265+ inbound_v2_channel_by_id : HashMap :: new ( ) ,
80168266 latest_features : Readable :: read ( reader) ?,
80178267 pending_msg_events : Vec :: new ( ) ,
80188268 monitor_update_blocked_actions : BTreeMap :: new ( ) ,
0 commit comments