From 91ff6c1a32396cb615ecc6ea2e1241f15ba0be46 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 19 Dec 2024 15:11:12 -0600 Subject: [PATCH 1/3] Combine InboundV2Channel and OutboundV2Channel Pending v2 channels will need to be broken up into separate phases for constructing and signing the funding transaction. To avoid increasing the number of phases, combine the InboundV2Channel and OutboundV2Channel types so that the can be used in one phase. Whether the channel is inbound or outbound can be inferred from the ChannelContext. --- lightning/src/ln/channel.rs | 66 ++++++-------------------- lightning/src/ln/channelmanager.rs | 22 +++++---- lightning/src/ln/dual_funding_tests.rs | 4 +- 3 files changed, 29 insertions(+), 63 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 5e3d72a6241..5d551050b0f 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1127,9 +1127,9 @@ pub(super) enum ChannelPhase where SP::Target: SignerProvider { UnfundedOutboundV1(OutboundV1Channel), UnfundedInboundV1(InboundV1Channel), #[allow(dead_code)] // TODO(dual_funding): Remove once creating V2 channels is enabled. - UnfundedOutboundV2(OutboundV2Channel), + UnfundedOutboundV2(PendingV2Channel), #[allow(dead_code)] // TODO(dual_funding): Remove once accepting V2 channels is enabled. - UnfundedInboundV2(InboundV2Channel), + UnfundedInboundV2(PendingV2Channel), Funded(Channel), } @@ -1849,25 +1849,7 @@ pub(super) trait InteractivelyFunded where SP::Target: SignerProvider } } -impl InteractivelyFunded for OutboundV2Channel where SP::Target: SignerProvider { - fn context(&self) -> &ChannelContext { - &self.context - } - fn context_mut(&mut self) -> &mut ChannelContext { - &mut self.context - } - fn dual_funding_context(&self) -> &DualFundingChannelContext { - &self.dual_funding_context - } - fn unfunded_context(&self) -> &UnfundedChannelContext { - &self.unfunded_context - } - fn interactive_tx_constructor_mut(&mut self) -> &mut Option { - &mut self.interactive_tx_constructor - } -} - -impl InteractivelyFunded for InboundV2Channel where SP::Target: SignerProvider { +impl InteractivelyFunded for PendingV2Channel where SP::Target: SignerProvider { fn context(&self) -> &ChannelContext { &self.context } @@ -8822,8 +8804,8 @@ impl InboundV1Channel where SP::Target: SignerProvider { } } -// A not-yet-funded outbound (from holder) channel using V2 channel establishment. -pub(super) struct OutboundV2Channel where SP::Target: SignerProvider { +// A not-yet-funded channel using V2 channel establishment. +pub(super) struct PendingV2Channel where SP::Target: SignerProvider { pub context: ChannelContext, pub unfunded_context: UnfundedChannelContext, pub dual_funding_context: DualFundingChannelContext, @@ -8831,15 +8813,15 @@ pub(super) struct OutboundV2Channel where SP::Target: SignerProvider interactive_tx_constructor: Option, } -impl OutboundV2Channel where SP::Target: SignerProvider { +impl PendingV2Channel where SP::Target: SignerProvider { #[allow(dead_code)] // TODO(dual_funding): Remove once creating V2 channels is enabled. - pub fn new( + pub fn new_outbound( fee_estimator: &LowerBoundedFeeEstimator, entropy_source: &ES, signer_provider: &SP, counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64, funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>, user_id: u128, config: &UserConfig, current_chain_height: u32, outbound_scid_alias: u64, funding_confirmation_target: ConfirmationTarget, logger: L, - ) -> Result, APIError> + ) -> Result where ES::Target: EntropySource, F::Target: FeeEstimator, L::Target: Logger, @@ -8911,6 +8893,10 @@ impl OutboundV2Channel where SP::Target: SignerProvider { } pub fn get_open_channel_v2(&self, chain_hash: ChainHash) -> msgs::OpenChannelV2 { + if !self.context.is_outbound() { + debug_assert!(false, "Tried to send open_channel2 for an inbound channel?"); + } + if self.context.have_received_message() { debug_assert!(false, "Cannot generate an open_channel2 after we've moved forward"); } @@ -8960,40 +8946,16 @@ impl OutboundV2Channel where SP::Target: SignerProvider { } } - pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result, ChannelError>{ - let holder_commitment_point = self.unfunded_context.holder_commitment_point.ok_or(ChannelError::close( - format!("Expected to have holder commitment points available upon finishing interactive tx construction for channel {}", - self.context.channel_id())))?; - let channel = Channel { - context: self.context, - interactive_tx_signing_session: Some(signing_session), - holder_commitment_point, - }; - - Ok(channel) - } -} - -// A not-yet-funded inbound (from counterparty) channel using V2 channel establishment. -pub(super) struct InboundV2Channel where SP::Target: SignerProvider { - pub context: ChannelContext, - pub unfunded_context: UnfundedChannelContext, - pub dual_funding_context: DualFundingChannelContext, - /// The current interactive transaction construction session under negotiation. - interactive_tx_constructor: Option, -} - -impl InboundV2Channel where SP::Target: SignerProvider { /// Creates a new dual-funded channel from a remote side's request for one. /// Assumes chain_hash has already been checked and corresponds with what we expect! #[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled. - pub fn new( + pub fn new_inbound( fee_estimator: &LowerBoundedFeeEstimator, entropy_source: &ES, signer_provider: &SP, holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures, their_features: &InitFeatures, msg: &msgs::OpenChannelV2, funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>, total_witness_weight: Weight, user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L, - ) -> Result, ChannelError> + ) -> Result where ES::Target: EntropySource, F::Target: FeeEstimator, L::Target: Logger, diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index a5ae07eab7f..b215639a234 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -50,7 +50,7 @@ use crate::ln::types::ChannelId; use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret}; use crate::ln::channel::{self, Channel, ChannelPhase, ChannelError, ChannelUpdateStatus, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext, InteractivelyFunded as _}; #[cfg(any(dual_funding, splicing))] -use crate::ln::channel::InboundV2Channel; +use crate::ln::channel::PendingV2Channel; use crate::ln::channel_state::ChannelDetails; use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; #[cfg(any(feature = "_test_utils", test))] @@ -7702,10 +7702,13 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ }, #[cfg(dual_funding)] OpenChannelMessage::V2(open_channel_msg) => { - InboundV2Channel::new(&self.fee_estimator, &self.entropy_source, &self.signer_provider, - self.get_our_node_id(), *counterparty_node_id, &self.channel_type_features(), &peer_state.latest_features, - &open_channel_msg, _funding_inputs, _total_witness_weight, user_channel_id, - &self.default_configuration, best_block_height, &self.logger + PendingV2Channel::new_inbound( + &self.fee_estimator, &self.entropy_source, &self.signer_provider, + self.get_our_node_id(), *counterparty_node_id, + &self.channel_type_features(), &peer_state.latest_features, + &open_channel_msg, _funding_inputs, _total_witness_weight, + user_channel_id, &self.default_configuration, best_block_height, + &self.logger, ).map_err(|_| MsgHandleErrInternal::from_chan_no_close( ChannelError::Close( ( @@ -7983,10 +7986,11 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ }, #[cfg(dual_funding)] OpenChannelMessageRef::V2(msg) => { - let channel = InboundV2Channel::new(&self.fee_estimator, &self.entropy_source, - &self.signer_provider, self.get_our_node_id(), *counterparty_node_id, - &self.channel_type_features(), &peer_state.latest_features, msg, vec![], Weight::from_wu(0), - user_channel_id, &self.default_configuration, best_block_height, &self.logger + let channel = PendingV2Channel::new_inbound( + &self.fee_estimator, &self.entropy_source, &self.signer_provider, + self.get_our_node_id(), *counterparty_node_id, &self.channel_type_features(), + &peer_state.latest_features, msg, vec![], Weight::from_wu(0), user_channel_id, + &self.default_configuration, best_block_height, &self.logger, ).map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.common_fields.temporary_channel_id))?; let message_send_event = events::MessageSendEvent::SendAcceptChannelV2 { node_id: *counterparty_node_id, diff --git a/lightning/src/ln/dual_funding_tests.rs b/lightning/src/ln/dual_funding_tests.rs index c0a79ba303d..8cd47ad1765 100644 --- a/lightning/src/ln/dual_funding_tests.rs +++ b/lightning/src/ln/dual_funding_tests.rs @@ -18,7 +18,7 @@ use { CounterpartyChannelTransactionParameters, }, crate::ln::channel::{ - calculate_our_funding_satoshis, OutboundV2Channel, MIN_CHAN_DUST_LIMIT_SATOSHIS, + calculate_our_funding_satoshis, PendingV2Channel, MIN_CHAN_DUST_LIMIT_SATOSHIS, }, crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint}, crate::ln::functional_test_utils::*, @@ -71,7 +71,7 @@ fn do_test_v2_channel_establishment( MIN_CHAN_DUST_LIMIT_SATOSHIS, ) .unwrap(); - let mut channel = OutboundV2Channel::new( + let mut channel = PendingV2Channel::new_outbound( &LowerBoundedFeeEstimator(node_cfgs[0].fee_estimator), &nodes[0].node.entropy_source, &nodes[0].node.signer_provider, From 270c5ab7abc80318c827f331eddb1ebcc340f905 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 19 Dec 2024 15:57:42 -0600 Subject: [PATCH 2/3] Remove InteractivelyFunded trait Now that InboundV2Channel and OutboundV2Channel have been combined into a PendingV2Channel, the InteractivelyFunded trait is no longer needed. --- lightning/src/ln/channel.rs | 99 +++++++++++------------------- lightning/src/ln/channelmanager.rs | 6 +- 2 files changed, 38 insertions(+), 67 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 5d551050b0f..f51d82ecddf 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1684,63 +1684,53 @@ impl InitialRemoteCommitmentReceiver for Channel where SP::Ta } } -pub(super) trait InteractivelyFunded where SP::Target: SignerProvider { - fn context(&self) -> &ChannelContext; - - fn context_mut(&mut self) -> &mut ChannelContext; - - fn interactive_tx_constructor_mut(&mut self) -> &mut Option; - - fn dual_funding_context(&self) -> &DualFundingChannelContext; - - fn unfunded_context(&self) -> &UnfundedChannelContext; - - fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult { - InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() { +impl PendingV2Channel where SP::Target: SignerProvider { + pub fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult { + InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor { Some(ref mut tx_constructor) => tx_constructor.handle_tx_add_input(msg).map_err( - |reason| reason.into_tx_abort_msg(self.context().channel_id())), + |reason| reason.into_tx_abort_msg(self.context.channel_id())), None => Err(msgs::TxAbort { - channel_id: self.context().channel_id(), + channel_id: self.context.channel_id(), data: b"No interactive transaction negotiation in progress".to_vec() }), }) } - fn tx_add_output(&mut self, msg: &msgs::TxAddOutput)-> InteractiveTxMessageSendResult { - InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() { + pub fn tx_add_output(&mut self, msg: &msgs::TxAddOutput)-> InteractiveTxMessageSendResult { + InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor { Some(ref mut tx_constructor) => tx_constructor.handle_tx_add_output(msg).map_err( - |reason| reason.into_tx_abort_msg(self.context().channel_id())), + |reason| reason.into_tx_abort_msg(self.context.channel_id())), None => Err(msgs::TxAbort { - channel_id: self.context().channel_id(), + channel_id: self.context.channel_id(), data: b"No interactive transaction negotiation in progress".to_vec() }), }) } - fn tx_remove_input(&mut self, msg: &msgs::TxRemoveInput)-> InteractiveTxMessageSendResult { - InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() { + pub fn tx_remove_input(&mut self, msg: &msgs::TxRemoveInput)-> InteractiveTxMessageSendResult { + InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor { Some(ref mut tx_constructor) => tx_constructor.handle_tx_remove_input(msg).map_err( - |reason| reason.into_tx_abort_msg(self.context().channel_id())), + |reason| reason.into_tx_abort_msg(self.context.channel_id())), None => Err(msgs::TxAbort { - channel_id: self.context().channel_id(), + channel_id: self.context.channel_id(), data: b"No interactive transaction negotiation in progress".to_vec() }), }) } - fn tx_remove_output(&mut self, msg: &msgs::TxRemoveOutput)-> InteractiveTxMessageSendResult { - InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() { + pub fn tx_remove_output(&mut self, msg: &msgs::TxRemoveOutput)-> InteractiveTxMessageSendResult { + InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor { Some(ref mut tx_constructor) => tx_constructor.handle_tx_remove_output(msg).map_err( - |reason| reason.into_tx_abort_msg(self.context().channel_id())), + |reason| reason.into_tx_abort_msg(self.context.channel_id())), None => Err(msgs::TxAbort { - channel_id: self.context().channel_id(), + channel_id: self.context.channel_id(), data: b"No interactive transaction negotiation in progress".to_vec() }), }) } - fn tx_complete(&mut self, msg: &msgs::TxComplete) -> HandleTxCompleteResult { - let tx_constructor = match self.interactive_tx_constructor_mut() { + pub fn tx_complete(&mut self, msg: &msgs::TxComplete) -> HandleTxCompleteResult { + let tx_constructor = match &mut self.interactive_tx_constructor { Some(ref mut tx_constructor) => tx_constructor, None => { let tx_abort = msgs::TxAbort { @@ -1759,26 +1749,25 @@ pub(super) trait InteractivelyFunded where SP::Target: SignerProvider }; if let HandleTxCompleteValue::SendTxComplete(_, ref signing_session) = tx_complete { - self.context_mut().next_funding_txid = Some(signing_session.unsigned_tx.compute_txid()); + self.context.next_funding_txid = Some(signing_session.unsigned_tx.compute_txid()); }; HandleTxCompleteResult(Ok(tx_complete)) } - fn funding_tx_constructed( + pub fn funding_tx_constructed( &mut self, signing_session: &mut InteractiveTxSigningSession, logger: &L ) -> Result<(msgs::CommitmentSigned, Option), ChannelError> where L::Target: Logger { - let our_funding_satoshis = self.dual_funding_context().our_funding_satoshis; - let transaction_number = self.unfunded_context().transaction_number(); - let context = self.context_mut(); + let our_funding_satoshis = self.dual_funding_context.our_funding_satoshis; + let transaction_number = self.unfunded_context.transaction_number(); let mut output_index = None; - let expected_spk = context.get_funding_redeemscript().to_p2wsh(); + let expected_spk = self.context.get_funding_redeemscript().to_p2wsh(); for (idx, outp) in signing_session.unsigned_tx.outputs().enumerate() { - if outp.script_pubkey() == &expected_spk && outp.value() == context.get_value_satoshis() { + if outp.script_pubkey() == &expected_spk && outp.value() == self.context.get_value_satoshis() { if output_index.is_some() { return Err(ChannelError::Close( ( @@ -1798,18 +1787,18 @@ pub(super) trait InteractivelyFunded where SP::Target: SignerProvider ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }, ))); }; - context.channel_transaction_parameters.funding_outpoint = Some(outpoint); - context.holder_signer.as_mut().provide_channel_parameters(&context.channel_transaction_parameters); + self.context.channel_transaction_parameters.funding_outpoint = Some(outpoint); + self.context.holder_signer.as_mut().provide_channel_parameters(&self.context.channel_transaction_parameters); - context.assert_no_commitment_advancement(transaction_number, "initial commitment_signed"); - let commitment_signed = context.get_initial_commitment_signed(logger); + self.context.assert_no_commitment_advancement(transaction_number, "initial commitment_signed"); + let commitment_signed = self.context.get_initial_commitment_signed(logger); let commitment_signed = match commitment_signed { Ok(commitment_signed) => { - context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx()); + self.context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx()); commitment_signed }, Err(err) => { - context.channel_transaction_parameters.funding_outpoint = None; + self.context.channel_transaction_parameters.funding_outpoint = None; return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }))) }, }; @@ -1817,7 +1806,7 @@ pub(super) trait InteractivelyFunded where SP::Target: SignerProvider let funding_ready_for_sig_event = None; if signing_session.local_inputs_count() == 0 { debug_assert_eq!(our_funding_satoshis, 0); - if signing_session.provide_holder_witnesses(context.channel_id, Vec::new()).is_err() { + if signing_session.provide_holder_witnesses(self.context.channel_id, Vec::new()).is_err() { debug_assert!( false, "Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found", @@ -1840,33 +1829,15 @@ pub(super) trait InteractivelyFunded where SP::Target: SignerProvider // } - context.channel_state = ChannelState::FundingNegotiated; + self.context.channel_state = ChannelState::FundingNegotiated; // Clear the interactive transaction constructor - self.interactive_tx_constructor_mut().take(); + self.interactive_tx_constructor.take(); Ok((commitment_signed, funding_ready_for_sig_event)) } } -impl InteractivelyFunded for PendingV2Channel where SP::Target: SignerProvider { - fn context(&self) -> &ChannelContext { - &self.context - } - fn context_mut(&mut self) -> &mut ChannelContext { - &mut self.context - } - fn dual_funding_context(&self) -> &DualFundingChannelContext { - &self.dual_funding_context - } - fn unfunded_context(&self) -> &UnfundedChannelContext { - &self.unfunded_context - } - fn interactive_tx_constructor_mut(&mut self) -> &mut Option { - &mut self.interactive_tx_constructor - } -} - impl ChannelContext where SP::Target: SignerProvider { fn new_for_inbound_channel<'a, ES: Deref, F: Deref, L: Deref>( fee_estimator: &'a LowerBoundedFeeEstimator, @@ -8810,7 +8781,7 @@ pub(super) struct PendingV2Channel where SP::Target: SignerProvider { pub unfunded_context: UnfundedChannelContext, pub dual_funding_context: DualFundingChannelContext, /// The current interactive transaction construction session under negotiation. - interactive_tx_constructor: Option, + pub interactive_tx_constructor: Option, } impl PendingV2Channel where SP::Target: SignerProvider { diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index b215639a234..a54e56d37d9 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -48,7 +48,7 @@ use crate::events::{self, Event, EventHandler, EventsProvider, InboundChannelFun use crate::ln::inbound_payment; use crate::ln::types::ChannelId; use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret}; -use crate::ln::channel::{self, Channel, ChannelPhase, ChannelError, ChannelUpdateStatus, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext, InteractivelyFunded as _}; +use crate::ln::channel::{self, Channel, ChannelPhase, ChannelError, ChannelUpdateStatus, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext}; #[cfg(any(dual_funding, splicing))] use crate::ln::channel::PendingV2Channel; use crate::ln::channel_state::ChannelDetails; @@ -8435,8 +8435,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ hash_map::Entry::Occupied(mut chan_phase_entry) => { let channel_phase = chan_phase_entry.get_mut(); let tx_constructor = match channel_phase { - ChannelPhase::UnfundedInboundV2(chan) => chan.interactive_tx_constructor_mut(), - ChannelPhase::UnfundedOutboundV2(chan) => chan.interactive_tx_constructor_mut(), + ChannelPhase::UnfundedInboundV2(chan) => &mut chan.interactive_tx_constructor, + ChannelPhase::UnfundedOutboundV2(chan) => &mut chan.interactive_tx_constructor, ChannelPhase::Funded(_) => { // TODO(splicing)/TODO(RBF): We'll also be doing interactive tx construction // for a "ChannelPhase::Funded" when we want to bump the fee on an interactively From d6637d7d0414c57c23b7907a84f9dbaed9563c66 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 19 Dec 2024 16:57:39 -0600 Subject: [PATCH 3/3] Combine UnfundedInboundV2 and UnfundedOutboundV2 Now that InboundV2Channel and OutboundV2Channel have been combined into a PendingV2Channel, only one ChannelPhase variant is needed. --- lightning/src/ln/channel.rs | 10 +-- lightning/src/ln/channelmanager.rs | 120 ++++++++++++----------------- 2 files changed, 54 insertions(+), 76 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index f51d82ecddf..f86a42c6e02 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1127,9 +1127,7 @@ pub(super) enum ChannelPhase where SP::Target: SignerProvider { UnfundedOutboundV1(OutboundV1Channel), UnfundedInboundV1(InboundV1Channel), #[allow(dead_code)] // TODO(dual_funding): Remove once creating V2 channels is enabled. - UnfundedOutboundV2(PendingV2Channel), - #[allow(dead_code)] // TODO(dual_funding): Remove once accepting V2 channels is enabled. - UnfundedInboundV2(PendingV2Channel), + UnfundedV2(PendingV2Channel), Funded(Channel), } @@ -1142,8 +1140,7 @@ impl<'a, SP: Deref> ChannelPhase where ChannelPhase::Funded(chan) => &chan.context, ChannelPhase::UnfundedOutboundV1(chan) => &chan.context, ChannelPhase::UnfundedInboundV1(chan) => &chan.context, - ChannelPhase::UnfundedOutboundV2(chan) => &chan.context, - ChannelPhase::UnfundedInboundV2(chan) => &chan.context, + ChannelPhase::UnfundedV2(chan) => &chan.context, } } @@ -1152,8 +1149,7 @@ impl<'a, SP: Deref> ChannelPhase where 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, - ChannelPhase::UnfundedInboundV2(ref mut chan) => &mut chan.context, + ChannelPhase::UnfundedV2(ref mut chan) => &mut chan.context, } } } diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index a54e56d37d9..21ab790bf9c 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1370,8 +1370,7 @@ impl PeerState where SP::Target: SignerProvider { match phase { ChannelPhase::Funded(_) | ChannelPhase::UnfundedOutboundV1(_) => true, ChannelPhase::UnfundedInboundV1(_) => false, - ChannelPhase::UnfundedOutboundV2(_) => true, - ChannelPhase::UnfundedInboundV2(_) => false, + ChannelPhase::UnfundedV2(chan) => chan.context.is_outbound(), } ) && self.monitor_update_blocked_actions.is_empty() @@ -3048,10 +3047,7 @@ macro_rules! convert_chan_phase_err { ChannelPhase::UnfundedInboundV1(channel) => { convert_chan_phase_err!($self, $peer_state, $err, channel, $channel_id, UNFUNDED_CHANNEL) }, - ChannelPhase::UnfundedOutboundV2(channel) => { - convert_chan_phase_err!($self, $peer_state, $err, channel, $channel_id, UNFUNDED_CHANNEL) - }, - ChannelPhase::UnfundedInboundV2(channel) => { + ChannelPhase::UnfundedV2(channel) => { convert_chan_phase_err!($self, $peer_state, $err, channel, $channel_id, UNFUNDED_CHANNEL) }, } @@ -4114,7 +4110,7 @@ where ) }, ChannelPhase::UnfundedOutboundV1(_) | ChannelPhase::UnfundedInboundV1(_) | - ChannelPhase::UnfundedOutboundV2(_) | ChannelPhase::UnfundedInboundV2(_) => { + ChannelPhase::UnfundedV2(_) => { // Unfunded channel has no update (chan_phase_entry.get_mut().context_mut().force_shutdown(false, closure_reason), None) }, @@ -6540,10 +6536,7 @@ where ChannelPhase::UnfundedOutboundV1(chan) => { process_unfunded_channel_tick!(peer_state, chan, pending_msg_events) }, - ChannelPhase::UnfundedInboundV2(chan) => { - process_unfunded_channel_tick!(peer_state, chan, pending_msg_events) - }, - ChannelPhase::UnfundedOutboundV2(chan) => { + ChannelPhase::UnfundedV2(chan) => { process_unfunded_channel_tick!(peer_state, chan, pending_msg_events) }, } @@ -7721,7 +7714,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ node_id: channel.context.get_counterparty_node_id(), msg: channel.accept_inbound_dual_funded_channel() }; - (channel.context.channel_id(), ChannelPhase::UnfundedInboundV2(channel), Some(message_send_event)) + (channel.context.channel_id(), ChannelPhase::UnfundedV2(channel), Some(message_send_event)) }) }, } @@ -7840,7 +7833,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ num_unfunded_channels += 1; } }, - ChannelPhase::UnfundedInboundV2(chan) => { + ChannelPhase::UnfundedV2(chan) => { + // Outbound channels don't contribute to the unfunded count in the DoS context. + if chan.context.is_outbound() { + continue; + } + // Only inbound V2 channels that are not 0conf and that we do not contribute to will be // included in the unfunded count. if chan.context.minimum_depth().unwrap_or(1) != 0 && @@ -7848,7 +7846,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ num_unfunded_channels += 1; } }, - ChannelPhase::UnfundedOutboundV1(_) | ChannelPhase::UnfundedOutboundV2(_) => { + ChannelPhase::UnfundedOutboundV1(_) => { // Outbound channels don't contribute to the unfunded count in the DoS context. continue; }, @@ -7996,7 +7994,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ node_id: *counterparty_node_id, msg: channel.accept_inbound_dual_funded_channel(), }; - (ChannelPhase::UnfundedInboundV2(channel), Some(message_send_event)) + (ChannelPhase::UnfundedV2(channel), Some(message_send_event)) }, }; @@ -8243,10 +8241,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ fn internal_tx_add_input(&self, counterparty_node_id: PublicKey, msg: &msgs::TxAddInput) -> Result<(), MsgHandleErrInternal> { self.internal_tx_msg(&counterparty_node_id, msg.channel_id, |channel_phase: &mut ChannelPhase| { match channel_phase { - ChannelPhase::UnfundedInboundV2(ref mut channel) => { - Ok(channel.tx_add_input(msg).into_msg_send_event(counterparty_node_id)) - }, - ChannelPhase::UnfundedOutboundV2(ref mut channel) => { + ChannelPhase::UnfundedV2(ref mut channel) => { Ok(channel.tx_add_input(msg).into_msg_send_event(counterparty_node_id)) }, _ => Err("tx_add_input"), @@ -8257,10 +8252,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ fn internal_tx_add_output(&self, counterparty_node_id: PublicKey, msg: &msgs::TxAddOutput) -> Result<(), MsgHandleErrInternal> { self.internal_tx_msg(&counterparty_node_id, msg.channel_id, |channel_phase: &mut ChannelPhase| { match channel_phase { - ChannelPhase::UnfundedInboundV2(ref mut channel) => { - Ok(channel.tx_add_output(msg).into_msg_send_event(counterparty_node_id)) - }, - ChannelPhase::UnfundedOutboundV2(ref mut channel) => { + ChannelPhase::UnfundedV2(ref mut channel) => { Ok(channel.tx_add_output(msg).into_msg_send_event(counterparty_node_id)) }, _ => Err("tx_add_output"), @@ -8271,10 +8263,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ fn internal_tx_remove_input(&self, counterparty_node_id: PublicKey, msg: &msgs::TxRemoveInput) -> Result<(), MsgHandleErrInternal> { self.internal_tx_msg(&counterparty_node_id, msg.channel_id, |channel_phase: &mut ChannelPhase| { match channel_phase { - ChannelPhase::UnfundedInboundV2(ref mut channel) => { - Ok(channel.tx_remove_input(msg).into_msg_send_event(counterparty_node_id)) - }, - ChannelPhase::UnfundedOutboundV2(ref mut channel) => { + ChannelPhase::UnfundedV2(ref mut channel) => { Ok(channel.tx_remove_input(msg).into_msg_send_event(counterparty_node_id)) }, _ => Err("tx_remove_input"), @@ -8285,10 +8274,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ fn internal_tx_remove_output(&self, counterparty_node_id: PublicKey, msg: &msgs::TxRemoveOutput) -> Result<(), MsgHandleErrInternal> { self.internal_tx_msg(&counterparty_node_id, msg.channel_id, |channel_phase: &mut ChannelPhase| { match channel_phase { - ChannelPhase::UnfundedInboundV2(ref mut channel) => { - Ok(channel.tx_remove_output(msg).into_msg_send_event(counterparty_node_id)) - }, - ChannelPhase::UnfundedOutboundV2(ref mut channel) => { + ChannelPhase::UnfundedV2(ref mut channel) => { Ok(channel.tx_remove_output(msg).into_msg_send_event(counterparty_node_id)) }, _ => Err("tx_remove_output"), @@ -8311,9 +8297,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ hash_map::Entry::Occupied(mut chan_phase_entry) => { let channel_phase = chan_phase_entry.get_mut(); let (msg_send_event_opt, signing_session_opt) = match channel_phase { - ChannelPhase::UnfundedInboundV2(channel) => channel.tx_complete(msg) - .into_msg_send_event_or_signing_session(counterparty_node_id), - ChannelPhase::UnfundedOutboundV2(channel) => channel.tx_complete(msg) + ChannelPhase::UnfundedV2(channel) => channel.tx_complete(msg) .into_msg_send_event_or_signing_session(counterparty_node_id), _ => try_chan_phase_entry!(self, peer_state, Err(ChannelError::Close( ( @@ -8326,10 +8310,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ }; if let Some(mut signing_session) = signing_session_opt { let (commitment_signed, funding_ready_for_sig_event_opt) = match chan_phase_entry.get_mut() { - ChannelPhase::UnfundedOutboundV2(chan) => { - chan.funding_tx_constructed(&mut signing_session, &self.logger) - }, - ChannelPhase::UnfundedInboundV2(chan) => { + ChannelPhase::UnfundedV2(chan) => { chan.funding_tx_constructed(&mut signing_session, &self.logger) }, _ => Err(ChannelError::Warn( @@ -8338,8 +8319,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ }.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?; let (channel_id, channel_phase) = chan_phase_entry.remove_entry(); let channel = match channel_phase { - ChannelPhase::UnfundedOutboundV2(chan) => chan.into_channel(signing_session), - ChannelPhase::UnfundedInboundV2(chan) => chan.into_channel(signing_session), + ChannelPhase::UnfundedV2(chan) => chan.into_channel(signing_session), _ => { debug_assert!(false); // It cannot be another variant as we are in the `Ok` branch of the above match. Err(ChannelError::Warn( @@ -8435,8 +8415,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ hash_map::Entry::Occupied(mut chan_phase_entry) => { let channel_phase = chan_phase_entry.get_mut(); let tx_constructor = match channel_phase { - ChannelPhase::UnfundedInboundV2(chan) => &mut chan.interactive_tx_constructor, - ChannelPhase::UnfundedOutboundV2(chan) => &mut chan.interactive_tx_constructor, + ChannelPhase::UnfundedV2(chan) => &mut chan.interactive_tx_constructor, ChannelPhase::Funded(_) => { // TODO(splicing)/TODO(RBF): We'll also be doing interactive tx construction // for a "ChannelPhase::Funded" when we want to bump the fee on an interactively @@ -8583,7 +8562,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ } }, ChannelPhase::UnfundedInboundV1(_) | ChannelPhase::UnfundedOutboundV1(_) | - ChannelPhase::UnfundedInboundV2(_) | ChannelPhase::UnfundedOutboundV2(_) => { + ChannelPhase::UnfundedV2(_) => { let context = phase.context_mut(); let logger = WithChannelContext::from(&self.logger, context, None); log_error!(logger, "Immediately closing unfunded channel {} as peer asked to cooperatively shut it down (which is unnecessary)", &msg.channel_id); @@ -9560,7 +9539,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/ } None }, - ChannelPhase::UnfundedInboundV2(_) | ChannelPhase::UnfundedOutboundV2(_) => None, + ChannelPhase::UnfundedV2(_) => None, } }; @@ -10997,7 +10976,7 @@ where match phase { // Retain unfunded channels. ChannelPhase::UnfundedOutboundV1(_) | ChannelPhase::UnfundedInboundV1(_) | - ChannelPhase::UnfundedOutboundV2(_) | ChannelPhase::UnfundedInboundV2(_) => true, + ChannelPhase::UnfundedV2(_) => true, ChannelPhase::Funded(channel) => { let res = f(channel); if let Ok((channel_ready_opt, mut timed_out_pending_htlcs, announcement_sigs)) = res { @@ -11525,10 +11504,7 @@ where ChannelPhase::UnfundedInboundV1(chan) => { &mut chan.context }, - ChannelPhase::UnfundedOutboundV2(chan) => { - &mut chan.context - }, - ChannelPhase::UnfundedInboundV2(chan) => { + ChannelPhase::UnfundedV2(chan) => { &mut chan.context }, }; @@ -11681,8 +11657,7 @@ where node_id: chan.context.get_counterparty_node_id(), msg: chan.get_channel_reestablish(&&logger), }); - } - + }, ChannelPhase::UnfundedOutboundV1(chan) => { let logger = WithChannelContext::from(&self.logger, &chan.context, None); if let Some(msg) = chan.get_open_channel(self.chain_hash, &&logger) { @@ -11691,21 +11666,26 @@ where msg, }); } - } - - ChannelPhase::UnfundedOutboundV2(chan) => { - pending_msg_events.push(events::MessageSendEvent::SendOpenChannelV2 { - node_id: chan.context.get_counterparty_node_id(), - msg: chan.get_open_channel_v2(self.chain_hash), - }); }, - - ChannelPhase::UnfundedInboundV1(_) | ChannelPhase::UnfundedInboundV2(_) => { + ChannelPhase::UnfundedV2(chan) => { + if chan.context.is_outbound() { + pending_msg_events.push(events::MessageSendEvent::SendOpenChannelV2 { + node_id: chan.context.get_counterparty_node_id(), + msg: chan.get_open_channel_v2(self.chain_hash), + }); + } else { + // Since unfunded inbound channel maps are cleared upon disconnecting a peer, + // they are not persisted and won't be recovered after a crash. + // Therefore, they shouldn't exist at this point. + debug_assert!(false); + } + }, + ChannelPhase::UnfundedInboundV1(_) => { // Since unfunded inbound channel maps are cleared upon disconnecting a peer, // they are not persisted and won't be recovered after a crash. // Therefore, they shouldn't exist at this point. debug_assert!(false); - } + }, } } } @@ -11803,16 +11783,18 @@ where return; } }, - Some(ChannelPhase::UnfundedOutboundV2(ref mut chan)) => { - if let Ok(msg) = chan.maybe_handle_error_without_close(self.chain_hash, &self.fee_estimator) { - peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannelV2 { - node_id: counterparty_node_id, - msg, - }); - return; + Some(ChannelPhase::UnfundedV2(ref mut chan)) => { + if chan.context.is_outbound() { + if let Ok(msg) = chan.maybe_handle_error_without_close(self.chain_hash, &self.fee_estimator) { + peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannelV2 { + node_id: counterparty_node_id, + msg, + }); + return; + } } }, - None | Some(ChannelPhase::UnfundedInboundV1(_) | ChannelPhase::UnfundedInboundV2(_) | ChannelPhase::Funded(_)) => (), + None | Some(ChannelPhase::UnfundedInboundV1(_) | ChannelPhase::Funded(_)) => (), } }