Skip to content

Commit

Permalink
event: store the outpoint when is_manual_broadcast
Browse files Browse the repository at this point in the history
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] lightningdevkit#3024

Link: lightningdevkit#3164
Suggested-by: TheBlueMatt
Signed-off-by: Vincenzo Palazzo <[email protected]>
  • Loading branch information
vincenzopalazzo committed Aug 27, 2024
1 parent b2cdc2c commit d0db6d3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
58 changes: 50 additions & 8 deletions lightning/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -50,6 +48,35 @@ 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 tx, the funding transaction info
/// inside the channel struct has a dummy value (See [`ChannelManager::unsafe_manual_funding_transaction_generated`]).
/// In such cases, `FundingInfo` contains the `OutPoint` of the channel.
#[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)]
Expand Down Expand Up @@ -1257,7 +1284,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.
///
Expand Down Expand Up @@ -1541,11 +1568,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 } => {
Expand Down Expand Up @@ -1924,12 +1958,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()
},
Expand Down
15 changes: 13 additions & 2 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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();
Expand All @@ -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));
}
Expand All @@ -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));
}
}
Expand Down

0 comments on commit d0db6d3

Please sign in to comment.