]> git.bitcoin.ninja Git - rust-lightning/commitdiff
event: store the outpoint when is_manual_broadcast
authorVincenzo Palazzo <vincenzopalazzodev@gmail.com>
Tue, 27 Aug 2024 08:18:28 +0000 (10:18 +0200)
committerVincenzo Palazzo <vincenzopalazzodev@gmail.com>
Tue, 27 Aug 2024 17:50:18 +0000 (19:50 +0200)
With [1], it's possible to specify `manual_broadcast` for
the channel funding transaction. When `is_manual_broadcast` is
set to true, the transaction in the `DiscardFunding` event is
replaced with a dummy empty transaction.

This commit checks if `is_manual_broadcast` is true and
stores the funding OutPoint in the DiscardFunding event instead.

[1] https://github.com/lightningdevkit/rust-lightning/pull/3024

Link: https://github.com/lightningdevkit/rust-lightning/issues/3164
Suggested-by: TheBlueMatt
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
lightning/src/events/mod.rs
lightning/src/ln/channelmanager.rs

index d756eff1bad30e63bc41a4301e9ac1ee08d46420..e6de488a0f2814166ce15a040b1600e1b74a5a33 100644 (file)
@@ -36,12 +36,10 @@ use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReada
 use crate::util::string::UntrustedString;
 
 use bitcoin::{Transaction, OutPoint};
-use bitcoin::locktime::absolute::LockTime;
 use bitcoin::script::ScriptBuf;
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::secp256k1::PublicKey;
-use bitcoin::transaction::Version;
 use crate::io;
 use core::time::Duration;
 use core::ops::Deref;
@@ -50,6 +48,38 @@ use crate::sync::Arc;
 #[allow(unused_imports)]
 use crate::prelude::*;
 
+/// `FundingInfo` holds information about a channel's funding transaction.
+///
+/// When LDK is set to manual propagation of the funding transaction
+/// (via [`ChannelManager::unsafe_manual_funding_transaction_generated`),
+/// LDK does not have the full transaction data. Instead, the `OutPoint`
+/// for the funding is provided here.
+///
+/// [`ChannelManager::unsafe_manual_funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::unsafe_manual_funding_transaction_generated
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum FundingInfo {
+       /// The full funding `Transaction`.
+       Tx {
+               /// The funding transaction
+               transaction: Transaction
+       },
+       /// The `OutPoint` of the funding.
+       OutPoint {
+               /// The outpoint of the funding
+               outpoint: transaction::OutPoint
+       },
+}
+
+impl_writeable_tlv_based_enum!(FundingInfo,
+       (0, Tx) => {
+               (0, transaction, required)
+       },
+       (1, OutPoint) => {
+               (1, outpoint, required)
+       }
+);
+
+
 /// Some information provided on receipt of payment depends on whether the payment received is a
 /// spontaneous payment or a "conventional" lightning payment that's paying an invoice.
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -1257,7 +1287,7 @@ pub enum Event {
                /// The channel_id of the channel which has been closed.
                channel_id: ChannelId,
                /// The full transaction received from the user
-               transaction: Transaction
+               funding_info: FundingInfo,
        },
        /// Indicates a request to open a new channel by a peer.
        ///
@@ -1541,11 +1571,18 @@ impl Writeable for Event {
                                        (9, channel_funding_txo, option),
                                });
                        },
-                       &Event::DiscardFunding { ref channel_id, ref transaction } => {
+                       &Event::DiscardFunding { ref channel_id, ref funding_info } => {
                                11u8.write(writer)?;
+
+                               let transaction = if let FundingInfo::Tx { transaction } = funding_info {
+                                       Some(transaction)
+                               } else {
+                                       None
+                               };
                                write_tlv_fields!(writer, {
                                        (0, channel_id, required),
-                                       (2, transaction, required)
+                                       (2, transaction, option),
+                                       (4, funding_info, required),
                                })
                        },
                        &Event::PaymentPathSuccessful { ref payment_id, ref payment_hash, ref path } => {
@@ -1924,12 +1961,20 @@ impl MaybeReadable for Event {
                        11u8 => {
                                let mut f = || {
                                        let mut channel_id = ChannelId::new_zero();
-                                       let mut transaction = Transaction{ version: Version::TWO, lock_time: LockTime::ZERO, input: Vec::new(), output: Vec::new() };
+                                       let mut transaction: Option<Transaction> = None;
+                                       let mut funding_info: Option<FundingInfo> = None;
                                        read_tlv_fields!(reader, {
                                                (0, channel_id, required),
-                                               (2, transaction, required),
+                                               (2, transaction, option),
+                                               (4, funding_info, option),
                                        });
-                                       Ok(Some(Event::DiscardFunding { channel_id, transaction } ))
+
+                                       let funding_info = if let Some(tx) = transaction {
+                                               FundingInfo::Tx { transaction: tx }
+                                       } else {
+                                               funding_info.ok_or(msgs::DecodeError::InvalidValue)?
+                                       };
+                                       Ok(Some(Event::DiscardFunding { channel_id, funding_info } ))
                                };
                                f()
                        },
index 167ab0ac8fd8a16475abc99890939df39e372e6f..29020c8503833865d476e3b5d6dce307a9455cf7 100644 (file)
@@ -32,6 +32,7 @@ use bitcoin::secp256k1::{SecretKey,PublicKey};
 use bitcoin::secp256k1::Secp256k1;
 use bitcoin::{secp256k1, Sequence};
 
+use crate::events::FundingInfo;
 use crate::blinded_path::message::{MessageContext, OffersContext};
 use crate::blinded_path::NodeIdLookUp;
 use crate::blinded_path::message::{BlindedMessagePath, ForwardNode};
@@ -3509,6 +3510,7 @@ where
                        let _ = self.chain_monitor.update_channel(funding_txo, &monitor_update);
                }
                let mut shutdown_results = Vec::new();
+               let mut is_manual_broadcast = false;
                if let Some(txid) = shutdown_res.unbroadcasted_batch_funding_txid {
                        let mut funding_batch_states = self.funding_batch_states.lock().unwrap();
                        let affected_channels = funding_batch_states.remove(&txid).into_iter().flatten();
@@ -3518,6 +3520,10 @@ where
                                if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_node_id) {
                                        let mut peer_state = peer_state_mutex.lock().unwrap();
                                        if let Some(mut chan) = peer_state.channel_by_id.remove(&channel_id) {
+                                               // We override the previous value, so we could change from true -> false,
+                                               // but this is fine because if a channel has manual_broadcast set to false
+                                               // we should choose the safier condition.
+                                               is_manual_broadcast = chan.context().is_manual_broadcast();
                                                update_maps_on_chan_removal!(self, &chan.context());
                                                shutdown_results.push(chan.context_mut().force_shutdown(false, ClosureReason::FundingBatchClosure));
                                        }
@@ -3541,9 +3547,14 @@ where
                                channel_funding_txo: shutdown_res.channel_funding_txo,
                        }, None));
 
-                       if let Some(transaction) = shutdown_res.unbroadcasted_funding_tx {
+                       let funding_info = if is_manual_broadcast {
+                               shutdown_res.channel_funding_txo.map(|outpoint| FundingInfo::OutPoint{ outpoint })
+                       } else {
+                               shutdown_res.unbroadcasted_funding_tx.map(|transaction| FundingInfo::Tx{ transaction })
+                       };
+                       if let Some(funding_info) = funding_info {
                                pending_events.push_back((events::Event::DiscardFunding {
-                                       channel_id: shutdown_res.channel_id, transaction
+                                       channel_id: shutdown_res.channel_id, funding_info
                                }, None));
                        }
                }