From 6099dbf16839b1d4882d5eba903d7d5e5ac1ba1b Mon Sep 17 00:00:00 2001 From: Duncan Dean Date: Mon, 22 May 2023 16:46:40 +0200 Subject: [PATCH] wip: Add channelmanager dual-funding support --- lightning/src/events/mod.rs | 59 +++++ lightning/src/ln/channel.rs | 365 ++++++++++++++++++----------- lightning/src/ln/channelmanager.rs | 313 +++++++++++++++++++++++-- lightning/src/util/config.rs | 16 ++ 4 files changed, 590 insertions(+), 163 deletions(-) diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs index e099b2241e8..fc614de66e2 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -837,6 +837,59 @@ pub enum Event { /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager channel_type: ChannelTypeFeatures, }, + /// Indicates a request to open a new dual-funded channel by a peer. + /// + /// To accept the request, call [`ChannelManager::accept_inbound_dual_funded_channel`]. + /// To reject the request, call [`ChannelManager::force_close_without_broadcasting_txn`]. + /// + /// The event is always triggered when a new open channel request is received for a dual-funded + /// channel, regardless of the value of the [`UserConfig::manually_accept_inbound_channels`] + /// config flag. This is so that funding inputs can be manually provided to contribute to the + /// overall channel capacity on the acceptor side. + /// + /// [`ChannelManager::accept_inbound_dual_funded_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_dual_funded_channel + /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn + /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels + OpenChannelV2Request { + /// The temporary channel ID of the channel requested to be opened. + /// + /// When responding to the request, the `temporary_channel_id` should be passed + /// back to the ChannelManager through [`ChannelManager::accept_inbound_dual_funded_channel`] to + /// accept, or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject. + /// + /// [`ChannelManager::accept_inbound_dual_funded_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_dual_funded_channel + /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn + temporary_channel_id: [u8; 32], + /// The node_id of the counterparty requesting to open the channel. + /// + /// When responding to the request, the `counterparty_node_id` should be passed + /// back to the `ChannelManager` through [`ChannelManager::accept_inbound_dual_funded_channel`] to + /// accept the request, or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject the + /// request. + /// + /// [`ChannelManager::accept_inbound_dual_funded_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_dual_funded_channel + /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn + counterparty_node_id: PublicKey, + /// The counterparty's contribution to the channel value in satoshis. + funding_satoshis: u64, + /// The features that this channel will operate with. If you reject the channel, a + /// well-behaved counterparty may automatically re-attempt the channel with a new set of + /// feature flags. + /// + /// Note that if [`ChannelTypeFeatures::supports_scid_privacy`] returns true on this type, + /// the resulting [`ChannelManager`] will not be readable by versions of LDK prior to + /// 0.0.106. + /// + /// Furthermore, note that if [`ChannelTypeFeatures::supports_zero_conf`] returns true on this type, + /// the resulting [`ChannelManager`] will not be readable by versions of LDK prior to + /// 0.0.107. + /// + /// NOTE: Zero-conf dual-funded channels are not currently accepted. + // TODO(dual_funding): Support zero-conf channels. + /// + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + channel_type: ChannelTypeFeatures, + }, /// Indicates that the HTLC was accepted, but could not be processed when or after attempting to /// forward it. /// @@ -1087,6 +1140,12 @@ impl Writeable for Event { (8, funding_txo, required), }); }, + &Event::OpenChannelV2Request { .. } => { + 33u8.write(writer)?; + // We never write the OpenChannelV2Request events as, upon disconnection, peers + // drop any channels which have not yet completed any interactive funding transaction + // construction. + }, // Note that, going forward, all new events must only write data inside of // `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write // data via `write_tlv_fields`. diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index ef674df6d04..922338f9a91 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -610,6 +610,8 @@ impl_writeable_tlv_based!(PendingChannelMonitorUpdate, { pub(super) enum ChannelPhase { UnfundedOutboundV1(OutboundV1Channel), UnfundedInboundV1(InboundV1Channel), + UnfundedOutboundV2(OutboundV2Channel), + UnfundedInboundV2(InboundV2Channel), Funded(Channel), } @@ -619,6 +621,8 @@ impl<'a, Signer: ChannelSigner> ChannelPhase { ChannelPhase::Funded(chan) => &chan.context, ChannelPhase::UnfundedOutboundV1(chan) => &chan.context, ChannelPhase::UnfundedInboundV1(chan) => &chan.context, + ChannelPhase::UnfundedOutboundV2(chan) => &chan.context.common, + ChannelPhase::UnfundedInboundV2(chan) => &chan.context.common, } } @@ -627,6 +631,8 @@ impl<'a, Signer: ChannelSigner> ChannelPhase { ChannelPhase::Funded(ref mut chan) => &mut chan.context, ChannelPhase::UnfundedOutboundV1(ref mut chan) => &mut chan.context, ChannelPhase::UnfundedInboundV1(ref mut chan) => &mut chan.context, + ChannelPhase::UnfundedOutboundV2(ref mut chan) => &mut chan.context.common, + ChannelPhase::UnfundedInboundV2(ref mut chan) => &mut chan.context.common, } } } @@ -1055,6 +1061,143 @@ impl ChannelContext { self.channel_transaction_parameters.funding_outpoint } + fn do_accept_channel_checks(&mut self, default_limits: &ChannelHandshakeLimits, + their_features: &InitFeatures, msg_dust_limit_satoshis: u64, msg_channel_reserve_satoshis: u64, + msg_to_self_delay: u16, msg_max_accepted_htlcs: u16, msg_htlc_minimum_msat: u64, + msg_max_htlc_value_in_flight_msat: u64, msg_minimum_depth: u32, msg_channel_type: &Option, + msg_shutdown_scriptpubkey: &Option