@@ -62,10 +62,10 @@ use crate::ln::channel::{
6262 self, hold_time_since, Channel, ChannelError, ChannelUpdateStatus, DisconnectResult,
6363 FundedChannel, FundingTxSigned, InboundV1Channel, OutboundV1Channel, PendingV2Channel,
6464 ReconnectionMsg, ShutdownResult, SpliceFundingFailed, StfuResponse, UpdateFulfillCommitFetch,
65- WithChannelContext,
65+ WithChannelContext, TOTAL_BITCOIN_SUPPLY_SATOSHIS,
6666};
6767use crate::ln::channel_state::ChannelDetails;
68- use crate::ln::funding::SpliceContribution;
68+ use crate::ln::funding::{FundingTxInput, SpliceContribution} ;
6969use crate::ln::inbound_payment;
7070use crate::ln::interactivetxs::InteractiveTxMessageSend;
7171use crate::ln::msgs;
@@ -9814,6 +9814,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
98149814 false,
98159815 user_channel_id,
98169816 config_overrides,
9817+ 0,
9818+ vec![],
98179819 )
98189820 }
98199821
@@ -9845,15 +9847,71 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
98459847 true,
98469848 user_channel_id,
98479849 config_overrides,
9850+ 0,
9851+ vec![],
9852+ )
9853+ }
9854+
9855+ /// Accepts a request to open a dual-funded channel with a contribution provided by us after an
9856+ /// [`Event::OpenChannelRequest`].
9857+ ///
9858+ /// The [`Event::OpenChannelRequest::channel_negotiation_type`] field will indicate the open channel
9859+ /// request is for a dual-funded channel when the variant is `InboundChannelFunds::DualFunded`.
9860+ ///
9861+ /// The `temporary_channel_id` parameter indicates which inbound channel should be accepted,
9862+ /// and the `counterparty_node_id` parameter is the id of the peer which has requested to open
9863+ /// the channel.
9864+ ///
9865+ /// The `user_channel_id` parameter will be provided back in
9866+ /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
9867+ /// with which `accept_inbound_channel_*` call.
9868+ ///
9869+ /// The `funding_inputs` parameter provides the `txin`s along with their previous transactions, and
9870+ /// a corresponding witness weight for each input that will be used to contribute towards our
9871+ /// portion of the channel value. Our contribution will be calculated as the total value of these
9872+ /// inputs minus the fees we need to cover for the interactive funding transaction. The witness
9873+ /// weights must correspond to the witnesses you will provide through [`ChannelManager::funding_transaction_signed`]
9874+ /// after receiving [`Event::FundingTransactionReadyForSigning`].
9875+ ///
9876+ /// Note that this method will return an error and reject the channel if it requires support for
9877+ /// zero confirmations.
9878+ // TODO(dual_funding): Discussion on complications with 0conf dual-funded channels where "locking"
9879+ // of UTXOs used for funding would be required and other issues.
9880+ // See https://diyhpl.us/~bryan/irc/bitcoin/bitcoin-dev/linuxfoundation-pipermail/lightning-dev/2023-May/003922.txt
9881+ ///
9882+ /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
9883+ /// [`Event::OpenChannelRequest::channel_negotiation_type`]: events::Event::OpenChannelRequest::channel_negotiation_type
9884+ /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
9885+ /// [`Event::FundingTransactionReadyForSigning`]: events::Event::FundingTransactionReadyForSigning
9886+ /// [`ChannelManager::funding_transaction_signed`]: ChannelManager::funding_transaction_signed
9887+ pub fn accept_inbound_channel_with_contribution(
9888+ &self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey,
9889+ user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>,
9890+ our_funding_satoshis: u64, funding_inputs: Vec<FundingTxInput>,
9891+ ) -> Result<(), APIError> {
9892+ self.do_accept_inbound_channel(
9893+ temporary_channel_id,
9894+ counterparty_node_id,
9895+ false,
9896+ user_channel_id,
9897+ config_overrides,
9898+ our_funding_satoshis,
9899+ funding_inputs,
98489900 )
98499901 }
98509902
98519903 /// TODO(dual_funding): Allow contributions, pass intended amount and inputs
98529904 #[rustfmt::skip]
98539905 fn do_accept_inbound_channel(
98549906 &self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, accept_0conf: bool,
9855- user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>
9907+ user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>, our_funding_satoshis: u64,
9908+ funding_inputs: Vec<FundingTxInput>
98569909 ) -> Result<(), APIError> {
9910+ // We do this check early as we will cast this to i64 for the NegotiationContext, and this is the
9911+ // actual upper bound which is less than i64::MAX.
9912+ if our_funding_satoshis >= TOTAL_BITCOIN_SUPPLY_SATOSHIS {
9913+ return Err(APIError::APIMisuseError{err: format!("the funding contribution must be smaller than the total bitcoin supply, it was {} satoshis", our_funding_satoshis)});
9914+ }
98579915
98589916 let mut config = self.config.read().unwrap().clone();
98599917
@@ -9911,7 +9969,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
99119969 &self.channel_type_features(), &peer_state.latest_features,
99129970 &open_channel_msg,
99139971 user_channel_id, &config, best_block_height,
9914- &self.logger,
9972+ &self.logger, our_funding_satoshis, funding_inputs,
99159973 ).map_err(|e| {
99169974 let channel_id = open_channel_msg.common_fields.temporary_channel_id;
99179975 MsgHandleErrInternal::from_chan_no_close(e, channel_id)
@@ -10197,7 +10255,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1019710255 &self.fee_estimator, &self.entropy_source, &self.signer_provider,
1019810256 self.get_our_node_id(), *counterparty_node_id, &self.channel_type_features(),
1019910257 &peer_state.latest_features, msg, user_channel_id,
10200- &self.config.read().unwrap(), best_block_height, &self.logger,
10258+ &self.config.read().unwrap(), best_block_height, &self.logger, 0, vec![],
1020110259 ).map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.common_fields.temporary_channel_id))?;
1020210260 let message_send_event = MessageSendEvent::SendAcceptChannelV2 {
1020310261 node_id: *counterparty_node_id,
0 commit comments