Skip to content

Commit 8f8eb77

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 <[email protected]>
1 parent 1df9149 commit 8f8eb77

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
@@ -12826,27 +12826,27 @@ where
1282612826
#[rustfmt::skip]
1282712827
pub fn stfu<L: Deref>(
1282812828
&mut self, msg: &msgs::Stfu, logger: &L
12829-
) -> Result<Option<StfuResponse>, ChannelError> where L::Target: Logger {
12829+
) -> Result<Option<StfuResponse>, (ChannelError, Option<SpliceFundingFailed>)> where L::Target: Logger {
1283012830
if self.context.channel_state.is_quiescent() {
12831-
return Err(ChannelError::Warn("Channel is already quiescent".to_owned()));
12831+
return Err((ChannelError::Warn("Channel is already quiescent".to_owned()), None));
1283212832
}
1283312833
if self.context.channel_state.is_remote_stfu_sent() {
12834-
return Err(ChannelError::Warn(
12834+
return Err((ChannelError::Warn(
1283512835
"Peer sent `stfu` when they already sent it and we've yet to become quiescent".to_owned()
12836-
));
12836+
), None));
1283712837
}
1283812838

1283912839
if !self.context.is_live() {
12840-
return Err(ChannelError::Warn(
12840+
return Err((ChannelError::Warn(
1284112841
"Peer sent `stfu` when we were not in a live state".to_owned()
12842-
));
12842+
), None));
1284312843
}
1284412844

1284512845
if !self.context.channel_state.is_local_stfu_sent() {
1284612846
if !msg.initiator {
12847-
return Err(ChannelError::WarnAndDisconnect(
12847+
return Err((ChannelError::WarnAndDisconnect(
1284812848
"Peer sent unexpected `stfu` without signaling as initiator".to_owned()
12849-
));
12849+
), None));
1285012850
}
1285112851

1285212852
// We don't check `is_waiting_on_peer_pending_channel_update` prior to setting the flag
@@ -12860,7 +12860,7 @@ where
1286012860
return self
1286112861
.send_stfu(logger)
1286212862
.map(|stfu| Some(StfuResponse::Stfu(stfu)))
12863-
.map_err(|e| ChannelError::Ignore(e.to_owned()));
12863+
.map_err(|e| (ChannelError::Ignore(e.to_owned()), None));
1286412864
}
1286512865

1286612866
// We already sent `stfu` and are now processing theirs. It may be in response to ours, or
@@ -12879,9 +12879,9 @@ where
1287912879
// have a monitor update pending if we've processed a message from the counterparty, but
1288012880
// we don't consider this when becoming quiescent since the states are not mutually
1288112881
// exclusive.
12882-
return Err(ChannelError::WarnAndDisconnect(
12882+
return Err((ChannelError::WarnAndDisconnect(
1288312883
"Received counterparty stfu while having pending counterparty updates".to_owned()
12884-
));
12884+
), None));
1288512885
}
1288612886

1288712887
self.context.channel_state.clear_local_stfu_sent();
@@ -12897,14 +12897,25 @@ where
1289712897
match self.quiescent_action.take() {
1289812898
None => {
1289912899
debug_assert!(false);
12900-
return Err(ChannelError::WarnAndDisconnect(
12900+
return Err((ChannelError::WarnAndDisconnect(
1290112901
"Internal Error: Didn't have anything to do after reaching quiescence".to_owned()
12902-
));
12902+
), None));
1290312903
},
1290412904
Some(QuiescentAction::Splice(_instructions)) => {
1290512905
return self.send_splice_init(_instructions)
1290612906
.map(|splice_init| Some(StfuResponse::SpliceInit(splice_init)))
12907-
.map_err(|e| ChannelError::WarnAndDisconnect(e.to_owned()));
12907+
.map_err(|e| {
12908+
let splice_failed = SpliceFundingFailed {
12909+
channel_id: self.context.channel_id,
12910+
counterparty_node_id: self.context.counterparty_node_id,
12911+
user_channel_id: self.context.user_id,
12912+
funding_txo: None,
12913+
channel_type: None,
12914+
contributed_inputs: Vec::new(),
12915+
contributed_outputs: Vec::new(),
12916+
};
12917+
(ChannelError::WarnAndDisconnect(e.to_owned()), Some(splice_failed))
12918+
});
1290812919
},
1290912920
#[cfg(any(test, fuzzing))]
1291012921
Some(QuiescentAction::DoNothing) => {

lightning/src/ln/channelmanager.rs

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

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

0 commit comments

Comments
 (0)