Skip to content

Exit quiescence when splice_init and tx_init_rbf are rejected#4495

Draft
jkczyz wants to merge 4 commits intolightningdevkit:mainfrom
jkczyz:2026-03-splicing-rbf-follow-ups
Draft

Exit quiescence when splice_init and tx_init_rbf are rejected#4495
jkczyz wants to merge 4 commits intolightningdevkit:mainfrom
jkczyz:2026-03-splicing-rbf-follow-ups

Conversation

@jkczyz
Copy link
Copy Markdown
Contributor

@jkczyz jkczyz commented Mar 18, 2026

Summary

  • Fix quiescence not being exited when tx_init_rbf or splice_init is rejected with Abort (e.g., insufficient RBF feerate, negotiation in progress), which left the channel stuck in a quiescent state
  • Refactor both handlers to return InteractiveTxMsgError, reusing the same pattern already used by the interactive TX message handlers, with a shared handle_interactive_tx_msg_err helper in channelmanager

Test plan

  • Existing test_splice_rbf_insufficient_feerate updated to verify quiescence is properly exited after tx_abort
  • Existing test_splice_feerate_too_high updated to verify quiescence is properly exited after splice_init rejection
  • All splicing tests pass

🤖 Generated with Claude Code

Based on #4494.

@ldk-reviews-bot
Copy link
Copy Markdown

👋 Hi! I see this is a draft PR.
I'll wait to assign reviewers until you mark it as ready for review.
Just convert it out of draft status when you're ready for review!

@jkczyz jkczyz changed the title Exit quiescence when splice_init and tx_init_rbf are rejected Exit quiescence when splice_init and tx_init_rbf are rejected Mar 18, 2026
@jkczyz jkczyz force-pushed the 2026-03-splicing-rbf-follow-ups branch from a5d670c to 57aad34 Compare March 18, 2026 18:57
@jkczyz jkczyz self-assigned this Mar 19, 2026
@jkczyz jkczyz mentioned this pull request Mar 19, 2026
36 tasks
@jkczyz jkczyz force-pushed the 2026-03-splicing-rbf-follow-ups branch 3 times, most recently from 8cdc480 to 959b553 Compare March 31, 2026 00:16
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

❌ Patch coverage is 61.79775% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.22%. Comparing base (8d00139) to head (959b553).
⚠️ Report is 111 commits behind head on main.

Files with missing lines Patch % Lines
lightning/src/ln/channelmanager.rs 42.85% 30 Missing and 2 partials ⚠️
lightning/src/ln/channel.rs 92.30% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4495      +/-   ##
==========================================
- Coverage   86.24%   86.22%   -0.02%     
==========================================
  Files         160      161       +1     
  Lines      107909   108651     +742     
  Branches   107909   108651     +742     
==========================================
+ Hits        93061    93681     +620     
- Misses      12212    12339     +127     
+ Partials     2636     2631       -5     
Flag Coverage Δ
tests 86.22% <61.79%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

jkczyz and others added 4 commits March 31, 2026 17:24
The spec's 25/24 multiplier doesn't always satisfy BIP125's relay
requirement of an absolute fee increase at low feerates, while a flat
+25 sat/kwu increment falls below the spec's 25/24 rule above 600
sat/kwu. Use max(prev + 25, ceil(prev * 25/24)) for our own RBFs to
satisfy both constraints, while still accepting the bare 25/24 rule
from counterparties.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When tx_init_rbf is rejected with ChannelError::Abort (e.g.,
insufficient RBF feerate, negotiation in progress, feerate too high),
the error is converted to a tx_abort message but quiescence is never
exited and holding cells are never freed. This leaves the channel stuck
in a quiescent state.

Fix this by intercepting ChannelError::Abort before try_channel_entry!
in internal_tx_init_rbf, calling exit_quiescence on the channel, and
returning the error with exited_quiescence set so that handle_error
frees holding cells. Also make exit_quiescence available in non-test
builds by removing its cfg gate.

Update tests to use the proper RBF initiation flow (with tampered
feerates) so that handle_tx_abort correctly echoes the abort and exits
quiescence, rather than manually crafting tx_init_rbf messages that
leave node 0 without proper negotiation state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
The prior two commits manually intercepted ChannelError::Abort in the
channelmanager handlers for splice_init and tx_init_rbf to exit
quiescence before returning, since the channel methods didn't signal
this themselves. The interactive TX message handlers already solved this
by returning InteractiveTxMsgError which bundles exited_quiescence into
the error type.

Apply the same pattern: change splice_init and tx_init_rbf to return
InteractiveTxMsgError, adding a quiescent_negotiation_err helper on
FundedChannel that exits quiescence for Abort errors and passes through
other variants unchanged. Extract handle_interactive_tx_msg_err in
channelmanager to deduplicate the error handling across internal_tx_msg,
internal_splice_init, and internal_tx_init_rbf.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jkczyz jkczyz force-pushed the 2026-03-splicing-rbf-follow-ups branch from 959b553 to 69a1a1c Compare March 31, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants