diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 46b35a94038..4de66dd1575 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1383,6 +1383,8 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { /// The transaction which funds this channel. Note that for manually-funded channels (i.e., /// is_manual_broadcast is true) this will be a dummy empty transaction. funding_transaction: Option, + /// Rememeber whether the funding transaction has been (re)broadcast (legacy) + funding_transaction_rebroadcast_flag: bool, /// This flag indicates that it is the user's responsibility to validated and broadcast the /// funding transaction. is_manual_broadcast: bool, @@ -1791,6 +1793,7 @@ impl ChannelContext where SP::Target: SignerProvider { channel_type_features: channel_type.clone() }, funding_transaction: None, + funding_transaction_rebroadcast_flag: false, is_batch_funding: None, counterparty_cur_commitment_point: Some(open_channel_fields.first_per_commitment_point), @@ -2024,6 +2027,7 @@ impl ChannelContext where SP::Target: SignerProvider { channel_type_features: channel_type.clone() }, funding_transaction: None, + funding_transaction_rebroadcast_flag: false, is_batch_funding: None, counterparty_cur_commitment_point: None, @@ -3445,13 +3449,22 @@ impl ChannelContext where SP::Target: SignerProvider { } } + /// Returns funding_transaction unless it has been broadcast already + pub fn funding_transaction_unless_rebroadcast(&self) -> Option { + if !self.funding_transaction_rebroadcast_flag { + self.funding_transaction.clone() + } else { + None + } + } + /// Returns the transaction if there is a pending funding transaction that is yet to be /// broadcast. /// /// Note that if [`Self::is_manual_broadcast`] is true the transaction will be a dummy /// transaction. pub fn unbroadcasted_funding(&self) -> Option { - self.if_unbroadcasted_funding(|| self.funding_transaction.clone()) + self.if_unbroadcasted_funding(|| self.funding_transaction_unless_rebroadcast()) } /// Returns the transaction ID if there is a pending funding transaction that is yet to be @@ -5336,7 +5349,10 @@ impl Channel where (matches!(self.context.channel_state, ChannelState::AwaitingChannelReady(flags) if !flags.is_set(AwaitingChannelReadyFlags::WAITING_FOR_BATCH)) || matches!(self.context.channel_state, ChannelState::ChannelReady(_))) { - self.context.funding_transaction.take() + let res = self.context.funding_transaction_unless_rebroadcast(); + // Note: this is legacy logic, prevents (re)broadcasting twice, unclear if needed + self.context.funding_transaction_rebroadcast_flag = true; + res } else { None }; // That said, if the funding transaction is already confirmed (ie we're active with a // minimum_depth over 0) don't bother re-broadcasting the confirmed funding tx. @@ -6594,7 +6610,9 @@ impl Channel where // Because deciding we're awaiting initial broadcast spuriously could result in // funds-loss (as we don't have a monitor, but have the funding transaction confirmed), // we hard-assert here, even in production builds. - if self.context.is_outbound() { assert!(self.context.funding_transaction.is_some()); } + if self.context.is_outbound() { + assert!(self.context.funding_transaction_unless_rebroadcast().is_some()); + } assert!(self.context.monitor_pending_channel_ready); assert_eq!(self.context.latest_monitor_update_id, 0); return true; @@ -7740,7 +7758,9 @@ impl OutboundV1Channel where SP::Target: SignerProvider { self.context.minimum_depth = Some(COINBASE_MATURITY); } + debug_assert!(self.context.funding_transaction.is_none()); self.context.funding_transaction = Some(funding_transaction); + self.context.funding_transaction_rebroadcast_flag = false; self.context.is_batch_funding = Some(()).filter(|_| is_batch_funding); let funding_created = self.get_funding_created_msg(logger); @@ -8934,6 +8954,8 @@ impl Writeable for Channel where SP::Target: SignerProvider { let cur_holder_commitment_point = Some(self.context.holder_commitment_point.current_point()); let next_holder_commitment_point = self.context.holder_commitment_point.next_point(); + let funding_transaction_rebroadcast_flag = Some(self.context.funding_transaction_rebroadcast_flag); + write_tlv_fields!(writer, { (0, self.context.announcement_sigs, option), // minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a @@ -8974,7 +8996,8 @@ impl Writeable for Channel where SP::Target: SignerProvider { (47, next_holder_commitment_point, option), (49, self.context.local_initiated_shutdown, option), // Added in 0.0.122 (51, is_manual_broadcast, option), // Added in 0.0.124 - (53, funding_tx_broadcast_safe_event_emitted, option) // Added in 0.0.124 + (53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124 + (55, funding_transaction_rebroadcast_flag, option), // Added in 0.1 }); Ok(()) @@ -9289,6 +9312,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch let mut next_holder_commitment_point_opt: Option = None; let mut is_manual_broadcast = None; + let mut funding_transaction_rebroadcast_flag: Option = None; + read_tlv_fields!(reader, { (0, announcement_sigs, option), (1, minimum_depth, option), @@ -9324,6 +9349,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch (49, local_initiated_shutdown, option), (51, is_manual_broadcast, option), (53, funding_tx_broadcast_safe_event_emitted, option), + (55, funding_transaction_rebroadcast_flag, option), // Added in 0.1 }); let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id { @@ -9542,6 +9568,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch channel_transaction_parameters: channel_parameters, funding_transaction, + // If value is missing, we use false, which may result in rebroadcast + funding_transaction_rebroadcast_flag: funding_transaction_rebroadcast_flag.unwrap_or(false), is_batch_funding, counterparty_cur_commitment_point,