Skip to content

Commit e71343a

Browse files
jkczyzclaude
andcommitted
Emit SpliceFailed event when splice initialization fails during quiescence
Users need to be notified when splice operations fail at any stage. Previously, splice failures during the quiescence initialization phase were not reported, leaving users unaware of failed splice attempts. Now emits Event::SpliceFailed when send_splice_init fails during stfu processing of QuiescentAction::Splice, ensuring consistent splice failure reporting across all phases of the splice lifecycle. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent fb34908 commit e71343a

File tree

2 files changed

+44
-15
lines changed

2 files changed

+44
-15
lines changed

lightning/src/ln/channel.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12886,27 +12886,27 @@ where
1288612886
#[rustfmt::skip]
1288712887
pub fn stfu<L: Deref>(
1288812888
&mut self, msg: &msgs::Stfu, logger: &L
12889-
) -> Result<Option<StfuResponse>, ChannelError> where L::Target: Logger {
12889+
) -> Result<Option<StfuResponse>, (ChannelError, Option<SpliceFundingFailed>)> where L::Target: Logger {
1289012890
if self.context.channel_state.is_quiescent() {
12891-
return Err(ChannelError::Warn("Channel is already quiescent".to_owned()));
12891+
return Err((ChannelError::Warn("Channel is already quiescent".to_owned()), None));
1289212892
}
1289312893
if self.context.channel_state.is_remote_stfu_sent() {
12894-
return Err(ChannelError::Warn(
12894+
return Err((ChannelError::Warn(
1289512895
"Peer sent `stfu` when they already sent it and we've yet to become quiescent".to_owned()
12896-
));
12896+
), None));
1289712897
}
1289812898

1289912899
if !self.context.is_live() {
12900-
return Err(ChannelError::Warn(
12900+
return Err((ChannelError::Warn(
1290112901
"Peer sent `stfu` when we were not in a live state".to_owned()
12902-
));
12902+
), None));
1290312903
}
1290412904

1290512905
if !self.context.channel_state.is_local_stfu_sent() {
1290612906
if !msg.initiator {
12907-
return Err(ChannelError::WarnAndDisconnect(
12907+
return Err((ChannelError::WarnAndDisconnect(
1290812908
"Peer sent unexpected `stfu` without signaling as initiator".to_owned()
12909-
));
12909+
), None));
1291012910
}
1291112911

1291212912
// We don't check `is_waiting_on_peer_pending_channel_update` prior to setting the flag
@@ -12920,7 +12920,7 @@ where
1292012920
return self
1292112921
.send_stfu(logger)
1292212922
.map(|stfu| Some(StfuResponse::Stfu(stfu)))
12923-
.map_err(|e| ChannelError::Ignore(e.to_owned()));
12923+
.map_err(|e| (ChannelError::Ignore(e.to_owned()), None));
1292412924
}
1292512925

1292612926
// We already sent `stfu` and are now processing theirs. It may be in response to ours, or
@@ -12939,9 +12939,9 @@ where
1293912939
// have a monitor update pending if we've processed a message from the counterparty, but
1294012940
// we don't consider this when becoming quiescent since the states are not mutually
1294112941
// exclusive.
12942-
return Err(ChannelError::WarnAndDisconnect(
12942+
return Err((ChannelError::WarnAndDisconnect(
1294312943
"Received counterparty stfu while having pending counterparty updates".to_owned()
12944-
));
12944+
), None));
1294512945
}
1294612946

1294712947
self.context.channel_state.clear_local_stfu_sent();
@@ -12957,14 +12957,25 @@ where
1295712957
match self.quiescent_action.take() {
1295812958
None => {
1295912959
debug_assert!(false);
12960-
return Err(ChannelError::WarnAndDisconnect(
12960+
return Err((ChannelError::WarnAndDisconnect(
1296112961
"Internal Error: Didn't have anything to do after reaching quiescence".to_owned()
12962-
));
12962+
), None));
1296312963
},
1296412964
Some(QuiescentAction::Splice(_instructions)) => {
1296512965
return self.send_splice_init(_instructions)
1296612966
.map(|splice_init| Some(StfuResponse::SpliceInit(splice_init)))
12967-
.map_err(|e| ChannelError::WarnAndDisconnect(e.to_owned()));
12967+
.map_err(|e| {
12968+
let splice_failed = SpliceFundingFailed {
12969+
channel_id: self.context.channel_id,
12970+
counterparty_node_id: self.context.counterparty_node_id,
12971+
user_channel_id: self.context.user_id,
12972+
funding_txo: None,
12973+
channel_type: None,
12974+
contributed_inputs: Vec::new(),
12975+
contributed_outputs: Vec::new(),
12976+
};
12977+
(ChannelError::WarnAndDisconnect(e.to_owned()), Some(splice_failed))
12978+
});
1296812979
},
1296912980
#[cfg(any(test, fuzzing))]
1297012981
Some(QuiescentAction::DoNothing) => {

lightning/src/ln/channelmanager.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11033,7 +11033,25 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1103311033
);
1103411034

1103511035
let res = chan.stfu(&msg, &&logger);
11036-
let resp = try_channel_entry!(self, peer_state, res, chan_entry);
11036+
let resp = match res {
11037+
Ok(resp) => resp,
11038+
Err((e, splice_funding_failed)) => {
11039+
// Emit SpliceFailed event if there was an active splice negotiation
11040+
if let Some(splice_failed) = splice_funding_failed {
11041+
let pending_events = &mut self.pending_events.lock().unwrap();
11042+
pending_events.push_back((events::Event::SpliceFailed {
11043+
channel_id: splice_failed.channel_id,
11044+
counterparty_node_id: splice_failed.counterparty_node_id,
11045+
user_channel_id: splice_failed.user_channel_id,
11046+
funding_txo: splice_failed.funding_txo,
11047+
channel_type: splice_failed.channel_type,
11048+
contributed_inputs: splice_failed.contributed_inputs,
11049+
contributed_outputs: splice_failed.contributed_outputs,
11050+
}, None));
11051+
}
11052+
try_channel_entry!(self, peer_state, Err(e), chan_entry)
11053+
},
11054+
};
1103711055
match resp {
1103811056
None => Ok(false),
1103911057
Some(StfuResponse::Stfu(msg)) => {

0 commit comments

Comments
 (0)