Skip to content

onionmessage: add graph-based send and wire through RPC, server, and CLI#10651

Open
Abdulkbk wants to merge 9 commits intolightningnetwork:masterfrom
Abdulkbk:onion-msg-send
Open

onionmessage: add graph-based send and wire through RPC, server, and CLI#10651
Abdulkbk wants to merge 9 commits intolightningnetwork:masterfrom
Abdulkbk:onion-msg-send

Conversation

@Abdulkbk
Copy link
Copy Markdown
Contributor

Part of #10220
Depends on #10612

Change Description

This PR builds on the BFS pathfinding PR #10612 to complete end-to-end onion message delivery. It introduces the Sender type, connects it through the server and RPC layer, updates the proto API, and adds a CLI.

If pathfinding returns ErrNoPathFound or ErrNodeNotFound (destination not yet in the graph), we fall back to a single-hop direct send to the destination peer.

We also updated SendOnionMessageRequest by replacing its old low-level fields (peer, path_key, onion) with:

  • destination (bytes) — the compressed public key of the target node.
  • final_hop_tlvs (map<uint64, bytes>) — BOLT 12 application TLV records delivered to the destination (keys ≥ 64 per spec).
  • reply_path (BlindedPath, optional) — a blinded path the destination can use to reply.
    The reason is that callers no longer need to perform pathfinding or construct onion packets themselves since the server handles it end-to-end.

We added two lncli subcommands:

  • lncli sendonion — send an onion message to a destination pubkey with optional TLV records.
  • lncli subscribeonion — stream incoming onion messages.

Both itests for sending and forwarding onion messages are simplified to use the new destination-based API.

Steps to Test

lncli sendonionmessage --dest <target node pubkey>

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

📝 Please see our Contribution Guidelines for further guidance.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly advances onion message functionality by enabling end-to-end delivery with automated routing. It builds upon previous work on BFS pathfinding to provide a robust mechanism for sending messages across the Lightning Network. The core change involves a new Sender component that intelligently determines the best path, falling back to direct peer communication if a graph-based route isn't available. This simplifies the user experience by abstracting complex routing logic and introduces new command-line tools for sending and receiving these messages.

Highlights

  • End-to-End Onion Message Delivery: Completed the implementation of end-to-end onion message delivery by introducing a new Sender type and integrating it throughout the server and RPC layers.
  • Graph-Based Pathfinding with Fallback: Implemented graph-based Breadth-First Search (BFS) pathfinding for onion messages, which automatically routes messages through the channel graph. If no graph route is found, it falls back to a direct send to the destination peer.
  • Simplified Onion Message API: Updated the SendOnionMessageRequest protobuf API to be destination-based, replacing low-level fields like peer, path_key, and onion with destination, final_hop_tlvs, and an optional reply_path. This abstracts away pathfinding and onion packet construction from the caller.
  • New CLI Commands: Added two new lncli subcommands: sendonionmessage for sending onion messages to a destination pubkey with optional TLV records, and subscribeonionmessages for streaming incoming onion messages.
  • Integration Test Simplification: Simplified existing integration tests for sending and forwarding onion messages to utilize the new, higher-level destination-based API.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Abdulkbk Abdulkbk changed the title onionmessage: wire graph-based send through RPC, server, and CLI onionmessage: add graph-based send and wire through RPC, server, and CLI Mar 19, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces new RPC commands and backend logic for sending and subscribing to onion messages, including graph-based pathfinding with a direct send fallback. The SendOnionMessageRequest RPC has been refactored to abstract away manual onion construction, now accepting a destination, final hop TLVs, and an optional reply path. Integration tests have been updated to reflect this change. Review comments highlight the need for improved documentation, specifically adding comments to several new functions and methods in cmd/commands, onionmessage/pathfind_test.go, and onionmessage/send_test.go to explain their purpose and assumptions, adhering to the repository's style guide. Additionally, there are minor code style suggestions regarding string literal alignment in CLI command descriptions.

}

// addNode adds a node with the given features.
func (m *mockNodeTraverser) addNode(v route.Vertex,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The addNode function is missing a comment explaining its purpose and assumptions. According to the repository style guide (line 17), "Every function must be commented with its purpose and assumptions."

@Abdulkbk Abdulkbk force-pushed the onion-msg-send branch 2 times, most recently from 9f2bf7d to e491767 Compare March 26, 2026 14:09
@bitromortac bitromortac self-requested a review March 27, 2026 11:06
@Abdulkbk Abdulkbk force-pushed the onion-msg-send branch 4 times, most recently from 5ac89f4 to d8e1999 Compare March 31, 2026 13:46
In this commit we add FindPath, a BFS-based shsortest-path
algorithm that finds routes through the channel graph for
onion messages. The search filters nodes by the
OnionMessage feature bits (38/39).

We also add a  unit tests covering: direct neighbor routing,
multi-hop paths, feature-bit filtering, missing destination
nodes, destination without onion support, max hop limits,
cycle handling, and shortest-path selection.
choice of BFS is because there isn't any weight involve.
Add a Sender type that finds a route via BFS pathfinding,
builds a blinded path from the resulting hops, wraps it in
a sphinx onion packet, and delivers it to the first hop.

If ErrNoPathFound is returned the destination is known to
support onion messages but has no graph route, so a direct
single-hop send is attempted as a fallback.
Initialise onionmessage.Sender in server.Start and replace
the old SendOnionMessage implementation, which required a
pre-built path key and onion blob, with a delegation to
Sender.Send.

Update the RPC handler to treat req.Peer as the
destination and return appropriate gRPC status codes per
error type.
Replace the pre-pathfinding fields (peer, path_key, onion) with
a destination pubkey, final_hop_tlvs for BOLT 12 application
records, and an optional reply_path for response routing.
Export unmarshalBlindedPaymentPaths as UnmarshalBlindedPath to
allow other packages to convert lnrpc.BlindedPath to
sphinx.BlindedPath without duplicating the logic.
Abdulkbk added 3 commits April 2, 2026 09:43
Update server.SendOnionMessage to accept and forward finalHopTLVs
and replyPath to Sender.Send. Update the RPC handler to convert
the proto fields to their internal types.
Now that the server handles pathfinding and blinded path construction
automatically, the integration tests no longer need to manually build
sphinx hop payloads, encode blinded route data, or construct onion
packets. Both tests are simplified to only specify the destination
pubkey and any final-hop TLVs.
@lightninglabs-deploy
Copy link
Copy Markdown
Collaborator

@Abdulkbk, remember to re-request review from reviewers when ready

Sign up for free to 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.

2 participants