lnwallet: reply to funding requests with a promise instead of channels - #11152
Open
Roasbeef wants to merge 3 commits into
Open
lnwallet: reply to funding requests with a promise instead of channels#11152Roasbeef wants to merge 3 commits into
Roasbeef wants to merge 3 commits into
Conversation
Roasbeef
force-pushed
the
lnwallet-fn-future
branch
from
August 31, 2026 23:37
fd6f193 to
a63804a
Compare
🔴 PR Severity: CRITICAL
🔴 Critical (4 files)
🟢 Low (1 file, excluded from bump calculation)
Tests (excluded from bump calculation)
AnalysisThis PR modifies core wallet and channel-funding logic ( To override, add a |
In this commit, we lay the groundwork for getting the reply channels out of the wallet's internal request messages. We follow the pattern the gossiper already uses for ProcessRemoteAnnouncement, where a caller is handed an actor.Future instead of being asked to drain a channel the request itself carried in. Two of the wallet's requests answer with a value alongside their error, so those reply with an fn.Result of that value rather than a hand rolled pair of fields. The requests whose only answer is an error get the same treatment through errRequest. Each shape gets an embeddable request type that owns the promise, so a handler answers a request without knowing anything about how the caller waits on it. Resolving the promise on its success side and letting the result carry the error, as the gossiper does, means the concrete error type a caller type switches on reaches it untouched. We await with a background context so the wait can never be cut short. That preserves the semantics of the plain channel receive these helpers are about to replace, where a caller blocks until the request handler answers it.
Roasbeef
force-pushed
the
lnwallet-fn-future
branch
from
August 31, 2026 23:48
a63804a to
60f184e
Compare
In this commit, we drop the err and result channels the wallet's request messages used to carry, and reply through the promise each request now holds instead. The message handler goroutine and the order in which it runs its checks are untouched; only the way an answer travels back to the caller changes. The old shape was easy to get wrong. A caller had to allocate a buffered channel per request, remember that the two-value requests answer over two separate channels, and read them back in the same order the handler wrote them. Every early return in the handler had to remember to write to both, and a missed write wedged the caller for good. A promise is completed once, with everything the caller needs, and completing it twice is harmless. We also add a test that runs the same type switch funding's failFundingFlow does over an error carried by each of the two promise shapes. That switch decides whether an error is safe to forward to the remote peer, so it only works as long as nothing along the reply path wraps a ReservationError.
In this commit, we note the wallet's move from reply channels to promises under code health.
Roasbeef
force-pushed
the
lnwallet-fn-future
branch
from
September 1, 2026 00:55
60f184e to
7c20280
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on #11151, and is based on that branch so the diff here stays to just
the three commits that are new. Land #11151 first.
In this PR, we get the reply channels out of the internal requests the
LightningWalletmessage handler serves. Each of those requests used to carryits own
err chan error, and two of them carried a second channel for the valuethey answer with, which left every caller draining a pair of channels in the
right order. We hand back an
actor.Futureinstead, following the pattern thegossiper already uses for
ProcessRemoteAnnouncement(seediscovery/gossip_result.go).The two requests that answer with a value alongside their error use
actor.Promise[fn.Result[T]], so there's no bespoke result struct anywhere:fn.Resultalready is the value-or-error type, and callers justUnpack()itback into the
(T, error)pair they had before. The requests whose only answeris an error keep an
actor.Promise[error]behind a small embeddederrRequest,same as the gossiper.
On error types
One thing worth calling out for review, since it's the part that would break
silently.
funding.Manager.failFundingFlowdecides whether an error is safe toforward to the remote peer with a plain type switch on
lnwallet.ReservationError, noterrors.As. So anything that wraps an error onits way out of the wallet would quietly turn every reservation error into a
generic one on the wire.
fn.Result.Unpackreturns the stored error verbatim,so the concrete type survives, and
TestReservationErrorTypePreservedinlnwallet/wallet_test.gopins that down by running failFundingFlow's exact typeswitch over both promise shapes.
Behavior
This is a pure refactor. Every check, error string, and early-return ordering in
the request handler is unchanged, and the awaits use
context.Background()so acaller blocks for exactly as long as the bare channel receive did.