Skip to content

Commit 1df9149

Browse files
jkczyzclaude
andcommitted
Emit SpliceFailed event when funded channels shut down with active splice negotiations
Adds SpliceFailed event emission immediately after ChannelClosed events when a FundedChannel is shut down while having an active splice negotiation. This ensures users are notified when splice operations are terminated due to channel closure. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 22b11c0 commit 1df9149

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

lightning/src/ln/channel.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,9 @@ pub(crate) struct ShutdownResult {
12551255
pub(crate) unbroadcasted_funding_tx: Option<Transaction>,
12561256
pub(crate) channel_funding_txo: Option<OutPoint>,
12571257
pub(crate) last_local_balance_msat: u64,
1258+
/// If a splice was in progress when the channel was shut down, this contains
1259+
/// the splice funding information for emitting a SpliceFailed event.
1260+
pub(crate) splice_funding_failed: Option<SpliceFundingFailed>,
12581261
}
12591262

12601263
/// Tracks the transaction number, along with current and next commitment points.
@@ -6094,6 +6097,7 @@ where
60946097
is_manual_broadcast: self.is_manual_broadcast,
60956098
channel_funding_txo: funding.get_funding_txo(),
60966099
last_local_balance_msat: funding.value_to_self_msat,
6100+
splice_funding_failed: None,
60976101
}
60986102
}
60996103

@@ -6850,7 +6854,37 @@ where
68506854
}
68516855

68526856
pub fn force_shutdown(&mut self, closure_reason: ClosureReason) -> ShutdownResult {
6853-
self.context.force_shutdown(&self.funding, closure_reason)
6857+
// Capture splice funding failed information if we have an active splice negotiation
6858+
let splice_funding_failed = self.pending_splice.as_mut()
6859+
.and_then(|pending_splice| pending_splice.funding_negotiation.take())
6860+
.map(|funding_negotiation| {
6861+
// Create SpliceFundingFailed for any active splice negotiation during shutdown
6862+
let (funding_txo, channel_type) = match &funding_negotiation {
6863+
FundingNegotiation::AwaitingAck { .. } => {
6864+
(None, None)
6865+
},
6866+
FundingNegotiation::ConstructingTransaction { funding, .. } => {
6867+
(funding.get_funding_txo().map(|txo| txo.into_bitcoin_outpoint()), Some(funding.get_channel_type().clone()))
6868+
},
6869+
FundingNegotiation::AwaitingSignatures { funding } => {
6870+
(funding.get_funding_txo().map(|txo| txo.into_bitcoin_outpoint()), Some(funding.get_channel_type().clone()))
6871+
},
6872+
};
6873+
6874+
SpliceFundingFailed {
6875+
channel_id: self.context.channel_id,
6876+
counterparty_node_id: self.context.counterparty_node_id,
6877+
user_channel_id: self.context.user_id,
6878+
funding_txo,
6879+
channel_type,
6880+
contributed_inputs: Vec::new(),
6881+
contributed_outputs: Vec::new(),
6882+
}
6883+
});
6884+
6885+
let mut shutdown_result = self.context.force_shutdown(&self.funding, closure_reason);
6886+
shutdown_result.splice_funding_failed = splice_funding_failed;
6887+
shutdown_result
68546888
}
68556889

68566890
fn interactive_tx_constructor_mut(&mut self) -> Option<&mut InteractiveTxConstructor> {
@@ -10237,6 +10271,7 @@ where
1023710271
is_manual_broadcast: self.context.is_manual_broadcast,
1023810272
channel_funding_txo: self.funding.get_funding_txo(),
1023910273
last_local_balance_msat: self.funding.value_to_self_msat,
10274+
splice_funding_failed: None,
1024010275
}
1024110276
}
1024210277

lightning/src/ln/channelmanager.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4419,6 +4419,19 @@ where
44194419
last_local_balance_msat: Some(shutdown_res.last_local_balance_msat),
44204420
}, None));
44214421

4422+
// Emit SpliceFailed event immediately after ChannelClosed if there was an active splice negotiation
4423+
if let Some(splice_funding_failed) = shutdown_res.splice_funding_failed.take() {
4424+
pending_events.push_back((events::Event::SpliceFailed {
4425+
channel_id: splice_funding_failed.channel_id,
4426+
counterparty_node_id: splice_funding_failed.counterparty_node_id,
4427+
user_channel_id: splice_funding_failed.user_channel_id,
4428+
funding_txo: splice_funding_failed.funding_txo,
4429+
channel_type: splice_funding_failed.channel_type,
4430+
contributed_inputs: splice_funding_failed.contributed_inputs,
4431+
contributed_outputs: splice_funding_failed.contributed_outputs,
4432+
}, None));
4433+
}
4434+
44224435
if let Some(transaction) = shutdown_res.unbroadcasted_funding_tx {
44234436
let funding_info = if shutdown_res.is_manual_broadcast {
44244437
FundingInfo::OutPoint {

0 commit comments

Comments
 (0)