Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Drop QuiescentError::with_negotiation_failure_reason - #4608

Merged
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups
May 18, 2026
Merged

Drop QuiescentError::with_negotiation_failure_reason#4608
TheBlueMatt merged 3 commits into
lightningdevkit:mainfrom
jkczyz:2026-05-splice-rbf-fail-event-follow-ups

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Drops QuiescentError::with_negotiation_failure_reason as a follow-up to #4514. The placeholder Unknown reason it overrode was a footgun — sites that forgot to chain it could leak Unknown into Event::SpliceNegotiationFailed, and the pattern wired splice-specific reason vocabulary into the generic QuiescentAction machinery. Each error-return site in propose_quiescence now picks its reason at construction. funding_contributed's pending-quiescent-action check is also made exhaustive on QuiescentAction, so a future variant produces a compile error there.

Also includes two minor doc clarifications from the #4514 review: the relationship between Event::SpliceNegotiationFailed::contribution and Event::DiscardFunding, and the script_pubkey-only matching in FundingContribution::into_unique_contributions.

@ldk-reviews-bot

ldk-reviews-bot commented May 8, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattMay 8, 2026 17:09
@ldk-claude-review-bot

ldk-claude-review-bot commented May 8, 2026

Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every hunk in this diff, including reading the surrounding context for the modified functions. My prior review already covered all sections comprehensively.

No issues found.

Comment threadlightning/src/ln/funding.rs Outdated
///
/// Outputs are compared by `script_pubkey` alone (not full `TxOut`), since values may
/// differ between rounds (e.g., a change output adjusted for a new feerate). As a
/// consequence, multiple contribution outputs sharing a `script_pubkey` are all

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that this won't be allowed anymore after #4575

Comment threadlightning/src/ln/channel.rs Outdated
// Only the test-only DoNothing action is expected here; production callers must
// short-circuit before reaching this branch.
#[cfg(any(test, fuzzing, feature = "_test_utils"))]
let is_allowed = matches!(action, QuiescentAction::DoNothing);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but why does this need to be allowed?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some tests calling maybe_propose_quiescence with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I meant why do we need to allow another DoNothing after one is already pending? Removing this doesn't seem to cause any test failures, is it a fuzzing thing?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah... I may have mistakenly thought quiescence_tests was checking this. But indeed that doesn't seem to be the case.

@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (71fdc27) to head (f4139db).
⚠️ Report is 4 commits behind head on main.

Files with missing linesPatch %Lines
lightning/src/ln/channel.rs66.66%10 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #4608 +/- ##
==========================================
+ Coverage 86.44% 86.47% +0.02% 
==========================================
Files 159 159 Lines 109823 109821 -2 Branches 109823 109821 -2 ==========================================
+ Hits 94941 94969 +28 + Misses 12340 12315 -25 + Partials 2542 2537 -5 
FlagCoverage Δ
fuzzing-fake-hashes5.17% <0.00%> (+0.10%)⬆️
fuzzing-real-hashes22.78% <0.00%> (+<0.01%)⬆️
tests86.19% <66.66%> (+0.01%)⬆️

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
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b61f231 to b2b0d43CompareMay 8, 2026 19:13
@jkczyz
jkczyz requested a review from wpaulinoMay 8, 2026 19:14
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @TheBlueMatt@wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

TheBlueMatt
TheBlueMatt previously approved these changes May 11, 2026

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs rebase :(

@TheBlueMattTheBlueMatt added this to the 0.3 milestone May 11, 2026
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 2nd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 3rd Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot

Copy link
Copy Markdown

🔔 4th Reminder

Hey @wpaulino! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

jkczyzand others added 3 commits May 18, 2026 11:27
QuiescentError::FailSplice was built with a placeholder
NegotiationFailureReason::Unknown and expected callers to chain a
with_negotiation_failure_reason builder. Sites that forgot the chain
leaked Unknown into Event::SpliceNegotiationFailed, and the pattern
forced splice-specific reason vocabulary into the generic
QuiescentAction helper.
Each call site in propose_quiescence now picks the reason at
construction. The pending-quiescent-action branch is unreachable, so
it asserts unconditionally; the match retains arms for both action
variants so release builds return a sensible error if the invariant
is violated. abandon_quiescent_action returns SpliceFundingFailed
directly without round-tripping through QuiescentError, since the
reason was always discarded there.
Make funding_contributed's pending-quiescent-action check exhaustive
on QuiescentAction. A future variant produces a compile error here
and at the matching arm in propose_quiescence, forcing the author to
decide how it interacts with funding contribution.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contribution returned in Event::SpliceNegotiationFailed may include
inputs and outputs already committed to a prior negotiated (but not yet
locked) splice transaction. Those overlapping items are intentionally
omitted from the preceding Event::DiscardFunding to avoid prompting the
user to reclaim UTXOs that are still in use elsewhere. The relationship
was documented on the internal SpliceFundingFailed fields but lost when
they were made private; surface it on the public event field doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function compares outputs by script_pubkey alone, not full TxOut,
so any contribution output sharing a script with an existing output is
filtered regardless of value. This is intentional — a change output's
value may shift between rounds (e.g., for a new feerate) and should
still match. But the consequence isn't obvious: multiple contribution
outputs sharing a script are all filtered together when any existing
output uses that script. Document it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jkczyz
jkczyzforce-pushed the 2026-05-splice-rbf-fail-event-follow-ups branch from b2b0d43 to f4139dbCompareMay 18, 2026 16:39
@jkczyz
jkczyz requested a review from TheBlueMattMay 18, 2026 16:40
@TheBlueMatt
TheBlueMatt merged commit 311a986 into lightningdevkit:mainMay 18, 2026
21 checks passed
@jkczyzjkczyz mentioned this pull request Jun 15, 2026
50 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@jkczyz@ldk-reviews-bot@ldk-claude-review-bot@TheBlueMatt@wpaulino