Skip to content

Commit fcd8cb3

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 66ecc40 commit fcd8cb3

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
@@ -1222,6 +1222,9 @@ pub(crate) struct ShutdownResult {
12221222
pub(crate) unbroadcasted_funding_tx: Option<Transaction>,
12231223
pub(crate) channel_funding_txo: Option<OutPoint>,
12241224
pub(crate) last_local_balance_msat: u64,
1225+
/// If a splice was in progress when the channel was shut down, this contains
1226+
/// the splice funding information for emitting a SpliceFailed event.
1227+
pub(crate) splice_funding_failed: Option<SpliceFundingFailed>,
12251228
}
12261229

12271230
/// Tracks the transaction number, along with current and next commitment points.
@@ -6092,6 +6095,7 @@ where
60926095
is_manual_broadcast: self.is_manual_broadcast,
60936096
channel_funding_txo: funding.get_funding_txo(),
60946097
last_local_balance_msat: funding.value_to_self_msat,
6098+
splice_funding_failed: None,
60956099
}
60966100
}
60976101

@@ -6899,7 +6903,37 @@ where
68996903
}
69006904

69016905
pub fn force_shutdown(&mut self, closure_reason: ClosureReason) -> ShutdownResult {
6902-
self.context.force_shutdown(&self.funding, closure_reason)
6906+
// Capture splice funding failed information if we have an active splice negotiation
6907+
let splice_funding_failed = self.pending_splice.as_mut()
6908+
.and_then(|pending_splice| pending_splice.funding_negotiation.take())
6909+
.map(|funding_negotiation| {
6910+
// Create SpliceFundingFailed for any active splice negotiation during shutdown
6911+
let (funding_txo, channel_type) = match &funding_negotiation {
6912+
FundingNegotiation::AwaitingAck { .. } => {
6913+
(None, None)
6914+
},
6915+
FundingNegotiation::ConstructingTransaction { funding, .. } => {
6916+
(funding.get_funding_txo().map(|txo| txo.into_bitcoin_outpoint()), Some(funding.get_channel_type().clone()))
6917+
},
6918+
FundingNegotiation::AwaitingSignatures { funding, .. } => {
6919+
(funding.get_funding_txo().map(|txo| txo.into_bitcoin_outpoint()), Some(funding.get_channel_type().clone()))
6920+
},
6921+
};
6922+
6923+
SpliceFundingFailed {
6924+
channel_id: self.context.channel_id,
6925+
counterparty_node_id: self.context.counterparty_node_id,
6926+
user_channel_id: self.context.user_id,
6927+
funding_txo,
6928+
channel_type,
6929+
contributed_inputs: Vec::new(),
6930+
contributed_outputs: Vec::new(),
6931+
}
6932+
});
6933+
6934+
let mut shutdown_result = self.context.force_shutdown(&self.funding, closure_reason);
6935+
shutdown_result.splice_funding_failed = splice_funding_failed;
6936+
shutdown_result
69036937
}
69046938

69056939
fn interactive_tx_constructor_mut(&mut self) -> Option<&mut InteractiveTxConstructor> {
@@ -10295,6 +10329,7 @@ where
1029510329
is_manual_broadcast: self.context.is_manual_broadcast,
1029610330
channel_funding_txo: self.funding.get_funding_txo(),
1029710331
last_local_balance_msat: self.funding.value_to_self_msat,
10332+
splice_funding_failed: None,
1029810333
}
1029910334
}
1030010335

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)