Skip to content

Commit 0d4c84f

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 3c46529 commit 0d4c84f

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
@@ -13264,6 +13264,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1326413264
&self.get_our_node_id(),
1326513265
&self.logger,
1326613266
);
13267+
if let Err(ChannelError::Abort(_)) = &init_res {
13268+
funded_channel.exit_quiescence();
13269+
let chan_id = funded_channel.context.channel_id();
13270+
let res = MsgHandleErrInternal::from_chan_no_close(
13271+
init_res.unwrap_err(),
13272+
chan_id,
13273+
);
13274+
return Err(res.with_exited_quiescence(true));
13275+
}
1326713276
let splice_ack_msg = try_channel_entry!(self, peer_state, init_res, chan_entry);
1326813277
peer_state.pending_msg_events.push(MessageSendEvent::SendSpliceAck {
1326913278
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
@@ -1816,10 +1816,25 @@ fn test_splice_tiebreak_feerate_too_high_rejected() {
18161816
let splice_init = get_event_msg!(nodes[0], MessageSendEvent::SendSpliceInit, node_id_1);
18171817

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

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

18251840
#[cfg(test)]

0 commit comments

Comments
 (0)