diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 5e3d72a6241..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(OutboundV2Channel), - #[allow(dead_code)] // TODO(dual_funding): Remove once accepting V2 channels is enabled. - UnfundedInboundV2(InboundV2Channel), + 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, } } } @@ -1684,63 +1680,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 +1745,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 +1783,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 +1802,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,51 +1825,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 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 { - 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, @@ -8822,24 +8771,24 @@ 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, /// The current interactive transaction construction session under negotiation. - interactive_tx_constructor: Option, + pub 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 +8860,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 +8913,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..21ab790bf9c 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -48,9 +48,9 @@ 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::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))] @@ -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) }, } @@ -7702,10 +7695,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( ( @@ -7718,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)) }) }, } @@ -7837,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 && @@ -7845,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; }, @@ -7983,16 +7984,17 @@ 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, msg: channel.accept_inbound_dual_funded_channel(), }; - (ChannelPhase::UnfundedInboundV2(channel), Some(message_send_event)) + (ChannelPhase::UnfundedV2(channel), Some(message_send_event)) }, }; @@ -8239,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"), @@ -8253,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"), @@ -8267,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"), @@ -8281,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"), @@ -8307,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( ( @@ -8322,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( @@ -8334,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( @@ -8431,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) => chan.interactive_tx_constructor_mut(), - ChannelPhase::UnfundedOutboundV2(chan) => chan.interactive_tx_constructor_mut(), + 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 @@ -8579,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); @@ -9556,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, } }; @@ -10993,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 { @@ -11521,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 }, }; @@ -11677,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) { @@ -11687,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); - } + }, } } } @@ -11799,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(_)) => (), } } 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,