Skip to content

Commit f40f597

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 f67fdad commit f40f597

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.
@@ -6090,6 +6093,7 @@ where
60906093
is_manual_broadcast: self.is_manual_broadcast,
60916094
channel_funding_txo: funding.get_funding_txo(),
60926095
last_local_balance_msat: funding.value_to_self_msat,
6096+
splice_funding_failed: None,
60936097
}
60946098
}
60956099

@@ -6846,7 +6850,37 @@ where
68466850
}
68476851

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

68526886
fn interactive_tx_constructor_mut(&mut self) -> Option<&mut InteractiveTxConstructor> {
@@ -10242,6 +10276,7 @@ where
1024210276
is_manual_broadcast: self.context.is_manual_broadcast,
1024310277
channel_funding_txo: self.funding.get_funding_txo(),
1024410278
last_local_balance_msat: self.funding.value_to_self_msat,
10279+
splice_funding_failed: None,
1024510280
}
1024610281
}
1024710282

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)