htlcswitch: forward blinded payments addressed by node_id#10942
Draft
bitromortac wants to merge 4 commits into
Draft
htlcswitch: forward blinded payments addressed by node_id#10942bitromortac wants to merge 4 commits into
bitromortac wants to merge 4 commits into
Conversation
The forwarding next hop is currently always a short channel ID. To allow a blinded route to identify the next hop by node ID instead, change ForwardingInfo.NextHop to fn.Either[lnwire.ShortChannelID, [33]byte], where the Left is the outgoing channel ID and the Right (wired up in a follow-up commit) is the next node's public key. This commit is a pure representational change with no behavioural effect: every next hop is still a channel ID. The Either is encapsulated behind ForwardingInfo methods so callers never destructure it directly: IsExit() is the single source of truth for exit-hop detection (used by the link and the contract court) and NextHopChannel() yields the outgoing SCID.
Fixes lightningnetwork#10937: forward a blinded-route payment when the recipient identifies the next hop by node ID (next_node_id) instead of a short channel ID, as some implementations (e.g. Core Lightning) do. The blinded-route decode now emits the next node's public key (the Right of ForwardingInfo.NextHop) when the recipient data carries next_node_id but no short_channel_id. The htlcPacket carries this through to the switch, whose handlePacketAdd resolves the pubkey to the peer's links via getLinks() and lets the existing non-strict forwarding logic load-balance across the peer's channels. outgoingChanID stays a ShortChannelID -- it is the persisted CircuitKey -- and is set to the selected channel after non-strict selection; the circular-route check is deferred to that point for the pubkey case.
Add integration tests for an lnd introduction node forwarding a blinded
payment whose non-final hops identify the next hop by node ID (next_node_id)
rather than a short channel ID, as produced by other implementations:
- testBlindedRouteNextNodeID: the outgoing channel is public.
- testBlindedRouteNextNodeIDPrivateChannel: the outgoing channel is
private, so the node ID resolves to an SCID alias.
- testBlindedRouteNextNodeIDRestart: the introduction node is restarted
while the HTLC is in flight, exercising forwarding-package replay and
re-decode of the node-ID blinded hop.
|
PR Severity: CRITICAL Highest-severity file determines level | 10 files (excl. tests) | ~259 lines changed (excl. tests) CRITICAL files (8):
MEDIUM files (1):
LOW files (1):
Analysis: This PR touches two distinct critical packages (contractcourt and htlcswitch), independently triggering CRITICAL severity. The bulk of changes are in htlcswitch/hop/ and htlcswitch/switch.go, at the heart of Lightning payment forwarding. The large itest addition (lnd_route_blinding_test.go, +417 lines) is excluded as a test file. Expert review of htlcswitch and contractcourt changes is required. To override, add a severity-override-{critical,high,medium,low} label. |
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.
Fixes #10937.
When lnd is the introduction node of a blinded path, the recipient may identify the next hop by next_node_id instead of a short_channel_id. lnd only handled the channel-ID case and failed such forwards with next SCID not set for non-final blinded hop.
The next hop now becomes an
fn.Either[ShortChannelID, pubkey]: decode yields the peer's key when onlynext_node_idis present, and the switch resolves it through the same non-strictgetLinkspath that already load-balances across a peer's channels.outgoingChanID(the circuit key) stays a short channel ID, set once a channel is chosen, so private and alias channels need no special handling.Alternative considered
Resolving the node ID to a channel at decode time is smaller but makes onion decoding depend on live link state and re-implements alias handling the switch already owns. Resolving in the switch keeps decode pure and is correct for alias channels by construction.