Add channel funding txo to Channel Event::ChannelClosed
authoroptout <13562139+optout21@users.noreply.github.com>
Thu, 11 Jan 2024 08:15:53 +0000 (09:15 +0100)
committeroptout <13562139+optout21@users.noreply.github.com>
Thu, 11 Jan 2024 08:15:53 +0000 (09:15 +0100)
lightning/src/events/mod.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs

index 76e5f25c0e5f6eef87b2ff48102dd19acc239231..b3aa79fca88d65759a5ad62bc090f268fa2cf3c2 100644 (file)
@@ -24,6 +24,7 @@ use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
 use crate::ln::features::ChannelTypeFeatures;
 use crate::ln::msgs;
 use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
+use crate::chain::transaction;
 use crate::routing::gossip::NetworkUpdate;
 use crate::util::errors::APIError;
 use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, RequiredWrapper, UpgradableRequired, WithoutLength};
@@ -861,7 +862,7 @@ pub enum Event {
        ///
        /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
        /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
-       ChannelClosed  {
+       ChannelClosed {
                /// The `channel_id` of the channel which has been closed. Note that on-chain transactions
                /// resolving the channel are likely still awaiting confirmation.
                channel_id: ChannelId,
@@ -886,6 +887,10 @@ pub enum Event {
                ///
                /// This field will be `None` for objects serialized prior to LDK 0.0.117.
                channel_capacity_sats: Option<u64>,
+               /// The original channel funding TXO; this helps checking for the existence and confirmation
+               /// status of the closing tx.
+               /// Note that for instances serialized in v0.0.119 or prior this will be missing (None).
+               channel_funding_txo: Option<transaction::OutPoint>,
        },
        /// Used to indicate to the user that they can abandon the funding transaction and recycle the
        /// inputs for another purpose.
@@ -1091,7 +1096,7 @@ impl Writeable for Event {
                                });
                        },
                        &Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason,
-                               ref counterparty_node_id, ref channel_capacity_sats
+                               ref counterparty_node_id, ref channel_capacity_sats, ref channel_funding_txo
                        } => {
                                9u8.write(writer)?;
                                // `user_channel_id` used to be a single u64 value. In order to remain backwards
@@ -1106,6 +1111,7 @@ impl Writeable for Event {
                                        (3, user_channel_id_high, required),
                                        (5, counterparty_node_id, option),
                                        (7, channel_capacity_sats, option),
+                                       (9, channel_funding_txo, option),
                                });
                        },
                        &Event::DiscardFunding { ref channel_id, ref transaction } => {
@@ -1405,6 +1411,7 @@ impl MaybeReadable for Event {
                                        let mut user_channel_id_high_opt: Option<u64> = None;
                                        let mut counterparty_node_id = None;
                                        let mut channel_capacity_sats = None;
+                                       let mut channel_funding_txo = None;
                                        read_tlv_fields!(reader, {
                                                (0, channel_id, required),
                                                (1, user_channel_id_low_opt, option),
@@ -1412,6 +1419,7 @@ impl MaybeReadable for Event {
                                                (3, user_channel_id_high_opt, option),
                                                (5, counterparty_node_id, option),
                                                (7, channel_capacity_sats, option),
+                                               (9, channel_funding_txo, option),
                                        });
 
                                        // `user_channel_id` used to be a single u64 value. In order to remain
@@ -1421,7 +1429,7 @@ impl MaybeReadable for Event {
                                                ((user_channel_id_high_opt.unwrap_or(0) as u128) << 64);
 
                                        Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: _init_tlv_based_struct_field!(reason, upgradable_required),
-                                               counterparty_node_id, channel_capacity_sats }))
+                                               counterparty_node_id, channel_capacity_sats, channel_funding_txo }))
                                };
                                f()
                        },
index 7026ab6d3766f04cad24c31f429f3626077ad8d8..8e389d3a8167daed5a28a6c801a5a0ff4b7d53b8 100644 (file)
@@ -827,6 +827,7 @@ pub(crate) struct ShutdownResult {
        pub(crate) channel_capacity_satoshis: u64,
        pub(crate) counterparty_node_id: PublicKey,
        pub(crate) unbroadcasted_funding_tx: Option<Transaction>,
+       pub(crate) channel_funding_txo: Option<OutPoint>,
 }
 
 /// If the majority of the channels funds are to the fundee and the initiator holds only just
@@ -2420,6 +2421,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider  {
                        channel_capacity_satoshis: self.channel_value_satoshis,
                        counterparty_node_id: self.counterparty_node_id,
                        unbroadcasted_funding_tx,
+                       channel_funding_txo: self.get_funding_txo(),
                }
        }
 
@@ -4956,6 +4958,7 @@ impl<SP: Deref> Channel<SP> where
                                        channel_capacity_satoshis: self.context.channel_value_satoshis,
                                        counterparty_node_id: self.context.counterparty_node_id,
                                        unbroadcasted_funding_tx: self.context.unbroadcasted_funding(),
+                                       channel_funding_txo: self.context.get_funding_txo(),
                                };
                                let tx = self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &sig);
                                self.context.channel_state = ChannelState::ShutdownComplete;
@@ -4990,6 +4993,7 @@ impl<SP: Deref> Channel<SP> where
                                                                channel_capacity_satoshis: self.context.channel_value_satoshis,
                                                                counterparty_node_id: self.context.counterparty_node_id,
                                                                unbroadcasted_funding_tx: self.context.unbroadcasted_funding(),
+                                                               channel_funding_txo: self.context.get_funding_txo(),
                                                        };
                                                        self.context.channel_state = ChannelState::ShutdownComplete;
                                                        self.context.update_time_counter += 1;
index 81b9d766d7b39a3e91b633e62ea72b94e1eab5bb..b76ba3c3db7e1a62866c94d0d2dbe9e1e6b9926a 100644 (file)
@@ -2878,6 +2878,7 @@ where
                                reason: shutdown_res.closure_reason,
                                counterparty_node_id: Some(shutdown_res.counterparty_node_id),
                                channel_capacity_sats: Some(shutdown_res.channel_capacity_satoshis),
+                               channel_funding_txo: shutdown_res.channel_funding_txo,
                        }, None));
 
                        if let Some(transaction) = shutdown_res.unbroadcasted_funding_tx {
@@ -10304,6 +10305,7 @@ where
                                                reason: ClosureReason::OutdatedChannelManager,
                                                counterparty_node_id: Some(channel.context.get_counterparty_node_id()),
                                                channel_capacity_sats: Some(channel.context.get_value_satoshis()),
+                                               channel_funding_txo: channel.context.get_funding_txo(),
                                        }, None));
                                        for (channel_htlc_source, payment_hash) in channel.inflight_htlc_sources() {
                                                let mut found_htlc = false;
@@ -10357,6 +10359,7 @@ where
                                        reason: ClosureReason::DisconnectedPeer,
                                        counterparty_node_id: Some(channel.context.get_counterparty_node_id()),
                                        channel_capacity_sats: Some(channel.context.get_value_satoshis()),
+                                       channel_funding_txo: channel.context.get_funding_txo(),
                                }, None));
                        } else {
                                log_error!(logger, "Missing ChannelMonitor for channel {} needed by ChannelManager.", &channel.context.channel_id());
index 2adfe2f9379c04c6352a709ff2471232f87d6141..d153a0a4c2d7b964f6c4d4f6656e7959a7de6c88 100644 (file)
@@ -1539,6 +1539,8 @@ pub struct ExpectedCloseEvent {
        pub counterparty_node_id: Option<PublicKey>,
        pub discard_funding: bool,
        pub reason: Option<ClosureReason>,
+       pub channel_funding_txo: Option<OutPoint>,
+       pub user_channel_id: Option<u128>,
 }
 
 impl ExpectedCloseEvent {
@@ -1549,6 +1551,8 @@ impl ExpectedCloseEvent {
                        counterparty_node_id: None,
                        discard_funding,
                        reason: Some(reason),
+                       channel_funding_txo: None,
+                       user_channel_id: None,
                }
        }
 }
@@ -1567,12 +1571,20 @@ pub fn check_closed_events(node: &Node, expected_close_events: &[ExpectedCloseEv
                                reason,
                                counterparty_node_id,
                                channel_capacity_sats,
+                               channel_funding_txo,
+                               user_channel_id,
                                ..
                        } if (
                                expected_event.channel_id.map(|expected| *channel_id == expected).unwrap_or(true) &&
                                expected_event.reason.as_ref().map(|expected| reason == expected).unwrap_or(true) &&
-                               expected_event.counterparty_node_id.map(|expected| *counterparty_node_id == Some(expected)).unwrap_or(true) &&
-                               expected_event.channel_capacity_sats.map(|expected| *channel_capacity_sats == Some(expected)).unwrap_or(true)
+                               expected_event.
+                                       counterparty_node_id.map(|expected| *counterparty_node_id == Some(expected)).unwrap_or(true) &&
+                               expected_event.channel_capacity_sats
+                                       .map(|expected| *channel_capacity_sats == Some(expected)).unwrap_or(true) &&
+                               expected_event.channel_funding_txo
+                                       .map(|expected| *channel_funding_txo == Some(expected)).unwrap_or(true) &&
+                               expected_event.user_channel_id
+                                       .map(|expected| *user_channel_id == expected).unwrap_or(true)
                        )
                )));
        }
@@ -1597,6 +1609,8 @@ pub fn check_closed_event(node: &Node, events_count: usize, expected_reason: Clo
                counterparty_node_id: Some(*node_id),
                discard_funding: is_check_discard_funding,
                reason: Some(expected_reason.clone()),
+               channel_funding_txo: None,
+               user_channel_id: None,
        }).collect::<Vec<_>>();
        check_closed_events(node, expected_close_events.as_slice());
 }
index 78207c57b45f6aa25e153d61a6dd7778c617b42f..59d8625b0d72406b12074ecd2f7be9fbba829c21 100644 (file)
@@ -10687,17 +10687,23 @@ fn test_disconnect_in_funding_batch() {
        nodes[0].node.peer_disconnected(&nodes[2].node.get_our_node_id());
 
        // The channels in the batch will close immediately.
-       let channel_id_1 = OutPoint { txid: tx.txid(), index: 0 }.to_channel_id();
-       let channel_id_2 = OutPoint { txid: tx.txid(), index: 1 }.to_channel_id();
+       let funding_txo_1 = OutPoint { txid: tx.txid(), index: 0 };
+       let funding_txo_2 = OutPoint { txid: tx.txid(), index: 1 };
+       let channel_id_1 = funding_txo_1.to_channel_id();
+       let channel_id_2 = funding_txo_2.to_channel_id();
        check_closed_events(&nodes[0], &[
                ExpectedCloseEvent {
                        channel_id: Some(channel_id_1),
                        discard_funding: true,
+                       channel_funding_txo: Some(funding_txo_1),
+                       user_channel_id: Some(42),
                        ..Default::default()
                },
                ExpectedCloseEvent {
                        channel_id: Some(channel_id_2),
                        discard_funding: true,
+                       channel_funding_txo: Some(funding_txo_2),
+                       user_channel_id: Some(43),
                        ..Default::default()
                },
        ]);
@@ -10755,8 +10761,10 @@ fn test_batch_funding_close_after_funding_signed() {
        assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
 
        // Force-close the channel for which we've completed the initial monitor.
-       let channel_id_1 = OutPoint { txid: tx.txid(), index: 0 }.to_channel_id();
-       let channel_id_2 = OutPoint { txid: tx.txid(), index: 1 }.to_channel_id();
+       let funding_txo_1 = OutPoint { txid: tx.txid(), index: 0 };
+       let funding_txo_2 = OutPoint { txid: tx.txid(), index: 1 };
+       let channel_id_1 = funding_txo_1.to_channel_id();
+       let channel_id_2 = funding_txo_2.to_channel_id();
        nodes[0].node.force_close_broadcasting_latest_txn(&channel_id_1, &nodes[1].node.get_our_node_id()).unwrap();
        check_added_monitors(&nodes[0], 2);
        {
@@ -10788,11 +10796,15 @@ fn test_batch_funding_close_after_funding_signed() {
                ExpectedCloseEvent {
                        channel_id: Some(channel_id_1),
                        discard_funding: true,
+                       channel_funding_txo: Some(funding_txo_1),
+                       user_channel_id: Some(42),
                        ..Default::default()
                },
                ExpectedCloseEvent {
                        channel_id: Some(channel_id_2),
                        discard_funding: true,
+                       channel_funding_txo: Some(funding_txo_2),
+                       user_channel_id: Some(43),
                        ..Default::default()
                },
        ]);