Skip to content

lnwallet+lnwire: handle boundary cases - #11035

Merged
ziggie1984 merged 3 commits into
lightningnetwork:masterfrom
yyforyongyu:fix-p2p-wedges
Aug 14, 2026
Merged

lnwallet+lnwire: handle boundary cases#11035
ziggie1984 merged 3 commits into
lightningnetwork:masterfrom
yyforyongyu:fix-p2p-wedges

Conversation

@yyforyongyu

@yyforyongyu yyforyongyu commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Complete missing wallet reservation responses.
  • Defensively handle zero-block channel ranges and avoid zero-block reply
    prefixes.
  • Add focused regressions and a v0.21.3 release note.

Change Description

The wallet funding handler now returns both completion results when a pending
reservation is absent. Channel-range helpers retain their first height for
zero-block input, and the graph syncer skips a nonexistent prefix when the
first queried block exceeds one reply chunk.

Verified with:

  • go test ./lnwallet ./lnwire ./discovery -count=1
  • go test -race ./lnwallet -run '^TestHandleFundingCounterPartySigsMissingReservation$' -count=1
  • go test -race ./discovery -run '^(TestGossipSyncerReplyChanRangeQueryBlockRange|TestGossipSyncerReplyChanRangeQueryDenseFirstBlock)$' -count=1

@yyforyongyu yyforyongyu added this to the v0.21.3 milestone Aug 6, 2026
@yyforyongyu yyforyongyu added the backport-v0.21.x-branch This label triggers a backport to branch `v0.21.x-branch ` label Aug 6, 2026
@saubyk saubyk added this to v0.21 Aug 6, 2026
@saubyk saubyk moved this to In progress in v0.21 Aug 6, 2026
@github-actions github-actions Bot added the severity-critical Requires expert review - security/consensus critical label Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

🔴 PR Severity: CRITICAL

gh pr view | 6 files | 169 lines changed

🔴 Critical (3 files)
  • lnwallet/wallet.go - wallet operations / channel funding logic
  • lnwire/query_channel_range.go - Lightning wire protocol message
  • lnwire/reply_channel_range.go - Lightning wire protocol message
🟢 Low (3 files)
  • docs/release-notes/release-notes-0.21.3.md - release notes only
  • lnwallet/wallet_test.go - test-only change
  • lnwire/reply_channel_range_test.go - test-only change

Analysis

This PR touches both lnwallet/* (wallet operations) and lnwire/* (wire protocol message encoding/decoding for channel range queries), both of which are CRITICAL-tier packages. The core change is small (1 line in wallet.go, ~8 lines across the two lnwire files) and is accompanied by good test coverage, but changes to wire message encoding and wallet logic warrant expert review given their correctness sensitivity and potential for peer-interop or fund-safety impact.


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

@yyforyongyu
yyforyongyu marked this pull request as ready for review August 7, 2026 11:38

@MPins MPins left a comment

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.

Fix looks right, and I confirmed the behavior locally.

One thought on coverage: TestChannelRangeLastBlockHeight pins the arithmetic, but the bug it's fixing only exists where callers act on the result, and all of those are in discovery/syncer.go.

TestGossipSyncerReplyChanRangeQueryBlockRange is already the boundary table for this (full range, small query, overflow) — it's just missing the empty one. Two entries complete it:

 		// overflow example
 		{
 			FirstBlockHeight: uint32(1000),
 			NumBlocks:        uint32(math.MaxUint32),
 		},
+
+		// empty range at the genesis block
+		{
+			FirstBlockHeight: uint32(0),
+			NumBlocks:        uint32(0),
+		},
+
+		// empty range after the genesis block
+		{
+			FirstBlockHeight: uint32(1000),
+			NumBlocks:        uint32(0),
+		},
 	}

 		{
 			startHeight: uint32(1000),
 			endHeight:   uint32(math.MaxUint32),
 		},
+		{
+			startHeight: uint32(0),
+			endHeight:   uint32(0),
+		},
+		{
+			startHeight: uint32(1000),
+			endHeight:   uint32(1000),
+		},
 	}

@ziggie1984
ziggie1984 self-requested a review August 13, 2026 16:59
@ziggie1984

Copy link
Copy Markdown
Collaborator

Non-blocking proposal: as a follow-up, we could replace the separate completion and error channels with a single buffered result channel.

CompleteReservation currently reconstructs one logical result from two independent receives:

return <-completeChan, <-errChan

That makes every terminal handler path responsible for sending both halves, which is how this missing-reservation branch was able to leave the caller blocked. A small internal result type could make the response atomic:

type fundingCompletionResult struct {
    channel *chanstate.OpenChannel
    err     error
}

Both addCounterPartySigsMsg and addSingleFunderSigsMsg could then carry one chan fundingCompletionResult, with each success or error path performing exactly one send.

I don't think this should block or expand this PR: the current one-line fix is correct, focused, and easier to audit/backport. The single-result-channel change would just remove this class of half-response bug in a separate cleanup.

@ziggie1984 ziggie1984 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.

LGTM

Comment thread docs/release-notes/release-notes-0.21.3.md Outdated
@ziggie1984
ziggie1984 self-requested a review August 14, 2026 13:38
Return both completion results when the reservation is no longer
present.

Add a focused regression test for the missing-reservation response.
Clamp zero-block range boundaries without treating them as valid
empty ranges. Avoid emitting a zero-block prefix when the first queried
block exceeds the reply chunk size, and cover both discovery paths.
Document the channel funding and channel range boundary fixes for the
v0.21.3 maintenance release.
@ziggie1984

Copy link
Copy Markdown
Collaborator

One remaining sender-side zero path is the wrong-chain early return in replyChanRangeQuery. It runs before LastBlockHeight is used and copies query.NumBlocks verbatim. A peer can send a QueryChannelRange with a mismatched ChainHash and NumBlocks=0, and we reply with Complete=0 and NumBlocks=0.

Since this PR also prevents lnd from constructing the dense-first-block zero prefix, should we ensure this branch cannot emit a zero-block reply either? For the current defensive-clamping approach, the narrow fix would be to use at least one block in the wrong-chain response. It would also be good to add a zero-block case to TestGossipSyncerQueryChannelRangeWrongChainHash so the outbound response is covered.

@ziggie1984 ziggie1984 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.

LGTM, had a small thing regarding a wrong chain-hash were we would set the numBlos=0, other than that this is gtg

@ziggie1984
ziggie1984 requested a review from starius August 14, 2026 17:41

@starius starius 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.

LGTM!

@ziggie1984
ziggie1984 merged commit 648d635 into lightningnetwork:master Aug 14, 2026
45 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in v0.21 Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Successfully created backport PR for v0.21.x-branch:

ziggie1984 added a commit that referenced this pull request Aug 14, 2026
…21.x-branch

[v0.21.x-branch] Backport #11035: lnwallet+lnwire: handle boundary cases
@ziggie1984 ziggie1984 added the backport-v0.20.x-branch This label is used to trigger the creation of a backport PR to the branch `v0.20.x-branch`. label Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Created backport PR for v0.20.x-branch:

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-11035-to-v0.20.x-branch
git worktree add --checkout .worktree/backport-11035-to-v0.20.x-branch backport-11035-to-v0.20.x-branch
cd .worktree/backport-11035-to-v0.20.x-branch
git reset --hard HEAD^
git cherry-pick -x 081adebca6d2726f232211f437e8e1f8806aeb18
git push --force-with-lease

@github-actions

Copy link
Copy Markdown

Backport failed for v0.21.x-branch, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin v0.21.x-branch
git worktree add -d .worktree/backport-11035-to-v0.21.x-branch origin/v0.21.x-branch
cd .worktree/backport-11035-to-v0.21.x-branch
git switch --create backport-11035-to-v0.21.x-branch
git cherry-pick -x 8bf173e5638db989741a935067f4a66985614692 b423c8bf07af197f6a56c9c3456b06fec320ba40 081adebca6d2726f232211f437e8e1f8806aeb18

ziggie1984 added a commit that referenced this pull request Aug 14, 2026
…20.x-branch

[v0.20.x-branch] Backport #11035: lnwallet+lnwire: handle boundary cases
ziggie1984 added a commit to ziggie1984/lnd that referenced this pull request Aug 14, 2026
The p2p wedge fixes from lightningnetwork#11035 are being backported to the v0.20.x
branch, so mirror their entries in the 0.20.4 notes on master.
@yyforyongyu
yyforyongyu deleted the fix-p2p-wedges branch August 14, 2026 22:20
ziggie1984 added a commit to ziggie1984/lnd that referenced this pull request Aug 15, 2026
The p2p wedge fixes from lightningnetwork#11035 are being backported to the v0.20.x
branch, so mirror their entries in the 0.20.4 notes on master.
ziggie1984 added a commit to ziggie1984/lnd that referenced this pull request Aug 17, 2026
The regression test added by the backport of lightningnetwork#11035 was taken verbatim
from master, where the `OpenChannel` type lives in the `chanstate`
package. That package does not exist on this branch, so the `lnwallet`
test package failed to compile.

Because the missing package is unresolvable in the module graph, this
broke far more than `go test ./lnwallet`: the unit test jobs, the
linter, `make release` (and therefore cross compilation) and the
`Check commits` job all failed for every PR targeting this branch.

Use `channeldb.OpenChannel`, which is the type `completeChan` actually
carries here.
ziggie1984 added a commit to ziggie1984/lnd that referenced this pull request Aug 17, 2026
The regression test added by the backport of lightningnetwork#11035 was taken verbatim
from master, where the `OpenChannel` type lives in the `chanstate`
package. That package does not exist on this branch, so the `lnwallet`
test package failed to compile.

Because the missing package is unresolvable in the module graph, this
broke far more than `go test ./lnwallet`: the unit test jobs, the
linter, `make release` (and therefore cross compilation) and the
`Check commits` job all failed for every PR targeting this branch.

Use `channeldb.OpenChannel`, which is the type `completeChan` actually
carries here.
ziggie1984 added a commit that referenced this pull request Aug 18, 2026
XCreateAccount is being backported to the v0.21.x branch in #11086, so
its entries belong with the release that first ships it rather than with
0.22.0. This matches how the other changes backported to 0.21.3 (#11035,
#11075, #10869) are documented: their entries live only in the 0.21.3
notes, even though their code is on master and will also ship in 0.22.0.

The entry text is moved verbatim. Elle Mouton is added to the 0.21.3
contributor list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-v0.20.x-branch This label is used to trigger the creation of a backport PR to the branch `v0.20.x-branch`. backport-v0.21.x-branch This label triggers a backport to branch `v0.21.x-branch ` severity-critical Requires expert review - security/consensus critical

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants