Skip to content

contractcourt: validate timeout second-level outputs - #11085

Draft
yyforyongyu wants to merge 6 commits into
lightningnetwork:masterfrom
yyforyongyu:fix-htlc-timeout-output-matching
Draft

contractcourt: validate timeout second-level outputs#11085
yyforyongyu wants to merge 6 commits into
lightningnetwork:masterfrom
yyforyongyu:fix-htlc-timeout-output-matching

Conversation

@yyforyongyu

@yyforyongyu yyforyongyu commented Aug 16, 2026

Copy link
Copy Markdown
Member

Summary

Validate re-signed outgoing HTLC timeout spends before treating their indexed
output as the second-level sweep target.

Change Description

  • Share second-level output matching across success and timeout resolvers.
  • Validate confirmed and mempool timeout spends at the watcher boundary.
  • Treat foreign live and restored spends as terminal timeouts without offering
    phantom sweeper inputs.
  • Document the companion fix in the 0.20.4 and 0.21.3 release notes.

Notes

Draft follow-up to #10869, now rebased onto its merge in master. This resolves
the outgoing-timeout follow-up raised in the originating review comment
and the request to track it.

@github-actions github-actions Bot added the severity-critical Requires expert review - security/consensus critical label Aug 16, 2026
@github-actions

Copy link
Copy Markdown

🔴 PR Severity: CRITICAL

file-based classification | 11 files | 2322 lines changed

🔴 Critical (3 files)
  • contractcourt/htlc_success_resolver.go - on-chain dispute resolution, second-level sweep target matching
  • contractcourt/htlc_timeout_resolver.go - on-chain dispute resolution, HTLC timeout spend validation
  • input/script_utils.go - script signing / witness generation utilities
🟢 Low (7 files)
  • contractcourt/channel_arbitrator_test.go - test-only change
  • contractcourt/htlc_outgoing_contest_resolver_test.go - test-only change
  • contractcourt/htlc_success_resolver_test.go - test-only change
  • contractcourt/htlc_timeout_resolver_test.go - test-only change
  • contractcourt/mock_htlcnotifier_test.go - mock/test-only change
  • docs/release-notes/release-notes-0.20.4.md - release notes
  • docs/release-notes/release-notes-0.21.3.md - release notes
  • input/script_utils_test.go - test-only change

Analysis

This PR modifies contractcourt/htlc_success_resolver.go and
contractcourt/htlc_timeout_resolver.go (on-chain breach/timeout dispute
resolution logic) as well as input/script_utils.go (witness/script
validation for re-signed HTLC timeout spends). Both packages are on the
CRITICAL list, and the PR touches two distinct critical packages
(contractcourt/* and input/*), with non-test/non-doc line changes
(~535 lines across the three core files) exceeding the 500-line bump
threshold as well. Since the base classification is already CRITICAL,
these bump conditions don't change the outcome but reinforce it. This
touches consensus-critical validation of timeout-spend outputs feeding
the sweeper — expert review recommended.


To override, add a severity-override-{critical,high,medium,low} label.

@yyforyongyu
yyforyongyu force-pushed the fix-htlc-timeout-output-matching branch from 858c983 to cb14b56 Compare August 17, 2026 10:55
Make second-level output matching independent of the success resolver by
passing the expected output explicitly.

Keep malformed outputs distinct from complete non-matches and return the
confirmed transaction outpoint only for an exact value and script match.
Validate confirmed and mempool spend details at the watcher boundary
before logging or classifying their spending transactions.

Return malformed notifier data as resolver errors and correct legacy test
fixtures to spend the outpoints their resolvers actually watch.
Extract the existing incoming failure message and terminal checkpoint
sequence into a reusable timeout-spend helper.

Keep the direct remote-commit timeout and preimage paths unchanged.
Match confirmed zero-fee timeout outputs before entering the second-level
sweep and observation path.

Treat complete foreign output spends as terminal timeouts using normalized
transaction provenance while preserving preimage and legacy behavior.
Match replayed commitment spends before updating stage-two state or
offering a restored timeout output to the sweeper.

Leave complete foreign spends unresolved during Launch so Resolve owns the
terminal failure message and checkpoint.
@yyforyongyu
yyforyongyu force-pushed the fix-htlc-timeout-output-matching branch from cb14b56 to 99e0fc2 Compare August 17, 2026 11:13
Document the outgoing HTLC timeout resolver fix in the 0.20.4 and
0.21.3 release notes.

Link the follow-up PR beside the related incoming resolver fix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity-critical Requires expert review - security/consensus critical

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant