Skip to content

Commit 92006c1

Browse files
jkczyzclaude
andcommitted
Exit quiescence when splice_init is rejected with Abort
The same bug fixed in the prior commit for tx_init_rbf also exists in internal_splice_init: when splice_init triggers FeeRateTooHigh in resolve_queued_contribution, the ChannelError::Abort goes through try_channel_entry! without exiting quiescence. Apply the same fix: intercept ChannelError::Abort before try_channel_entry!, call exit_quiescence, and return the error with exited_quiescence set. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 88f0ea5 commit 92006c1

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13106,6 +13106,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1310613106
&self.get_our_node_id(),
1310713107
&self.logger,
1310813108
);
13109+
if let Err(ChannelError::Abort(_)) = &init_res {
13110+
funded_channel.exit_quiescence();
13111+
let chan_id = funded_channel.context.channel_id();
13112+
let res = MsgHandleErrInternal::from_chan_no_close(
13113+
init_res.unwrap_err(),
13114+
chan_id,
13115+
);
13116+
return Err(res.with_exited_quiescence(true));
13117+
}
1310913118
let splice_ack_msg = try_channel_entry!(self, peer_state, init_res, chan_entry);
1311013119
peer_state.pending_msg_events.push(MessageSendEvent::SendSpliceAck {
1311113120
node_id: *counterparty_node_id,

lightning/src/ln/splicing_tests.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,10 +1813,25 @@ fn test_splice_tiebreak_feerate_too_high_rejected() {
18131813
let splice_init = get_event_msg!(nodes[0], MessageSendEvent::SendSpliceInit, node_id_1);
18141814

18151815
// Node 1 handles SpliceInit — TooHigh: target (100k) >> max (3k) and fair fee > budget.
1816+
// Node 1 exits quiescence upon rejecting with tx_abort, and since it has a pending
1817+
// QuiescentAction (from its own splice attempt), it immediately re-proposes quiescence.
18161818
nodes[1].node.handle_splice_init(node_id_0, &splice_init);
18171819

1818-
let tx_abort = get_event_msg!(nodes[1], MessageSendEvent::SendTxAbort, node_id_0);
1819-
assert_eq!(tx_abort.channel_id, channel_id);
1820+
let msg_events = nodes[1].node.get_and_clear_pending_msg_events();
1821+
assert_eq!(msg_events.len(), 2);
1822+
match &msg_events[0] {
1823+
MessageSendEvent::SendTxAbort { node_id, msg } => {
1824+
assert_eq!(*node_id, node_id_0);
1825+
assert_eq!(msg.channel_id, channel_id);
1826+
},
1827+
_ => panic!("Expected SendTxAbort, got {:?}", msg_events[0]),
1828+
};
1829+
match &msg_events[1] {
1830+
MessageSendEvent::SendStfu { node_id, .. } => {
1831+
assert_eq!(*node_id, node_id_0);
1832+
},
1833+
_ => panic!("Expected SendStfu, got {:?}", msg_events[1]),
1834+
};
18201835
}
18211836

18221837
#[cfg(test)]

0 commit comments

Comments
 (0)