Skip to content

Conversation

@ziggie1984
Copy link
Collaborator

@ziggie1984 ziggie1984 commented Dec 12, 2025

backports: #10396

The comment was incorrectly referring to HasLightningNode but the
function is named HasNode. Update the comment to match the actual
function name.
This commit adds the HasNode function to the RouterBackend struct,
which checks if a node exists in the graph (i.e., has public channels).
This function is needed by the LSP detection heuristic to determine
if a node is publicly reachable.

The function is wired up in rpcserver.go to query the graph database.
This commit implements a comprehensive LSP (Lightning Service Provider)
detection heuristic and updates the payment probing logic to handle
multiple LSPs with worst-case fee estimation.

Key changes:

1. LSP Detection Heuristic (isLSP function):
   Implements three rules to detect LSP setups:
   - Rule 1: If invoice target is public → NOT an LSP (route directly)
   - Rule 2: If at least one destination hop is public → IS an LSP
   - Rule 3: If all destination hops are private → NOT an LSP

2. LSP Route Preparation (prepareLspRouteHints function):
   - Groups route hints by unique public LSP nodes
   - Filters out non-LSP routes based on the heuristic
   - Tracks worst-case fees and CLTV delays for each LSP
   - Returns adjusted route hints with LSP hop stripped

3. Multi-LSP Probing (probePaymentRequest updates):
   - Probes up to 3 unique LSPs maximum (griefing protection)
   - Selects the WORST-CASE (most expensive) route for conservative
     fee estimation
   - Adds comprehensive debug logging for worst-case selection process
   - Properly formats vertex logging using %v (calls Vertex.String())

The worst-case approach ensures users won't be surprised by higher fees
when the actual payment is sent, providing a more conservative and
reliable fee estimate.

This commit also  adds extensive unit test coverage for the LSP detection
heuristic and route preparation logic.

TestIsLsp:
- Edge cases: empty route hints, nil scenarios
- Rule 1: Public invoice target (3 tests)
- Rule 2: All private destination hops (4 tests)
- Rule 3: At least one public destination hop (6 tests)

TestPrepareLspRouteHints:
- LSP grouping and filtering logic
- Worst-case fee selection across route hints
- Worst-case CLTV delta tracking
- Adjusted route hints validation (LSP hop stripped)
- Multi-LSP scenarios with different fees
This commit enhances the integration test to validate the LSP heuristic
end-to-end with real network topology and payment probing.

Network topology additions:
- Added Frank node as a private destination
- Created multi-LSP test scenario with Bob, Eve, and Dave as LSPs

New test cases:

1. "probe based estimate, public target with public hop hints"
   - Validates Rule 1: public invoice target routes directly
   - Even with public hop hints, direct routing is used
   - Expected: standard single-hop fees

2. "probe based estimate, multiple different public LSPs"
   - Validates multi-LSP worst-case selection
   - Frank has routes through Bob (low fee), Eve (HIGH fee), Dave (medium)
   - Expected: Eve's worst-case fees (most expensive)
   - Tests griefing protection (max 3 LSP probes)
@gemini-code-assist
Copy link

Summary of Changes

Hello @ziggie1984, 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 refines the EstimateRouteFee RPC by introducing an advanced heuristic for detecting Lightning Service Provider (LSP) configurations. The new logic intelligently distinguishes between direct payments and LSP-assisted payments, and for the latter, it performs worst-case fee estimation by probing multiple potential LSPs. This enhancement aims to provide more accurate and conservative fee estimates, improving the user experience for payments involving LSPs.

Highlights

  • Enhanced LSP Detection Heuristic: The EstimateRouteFee RPC now includes a more robust LSP detection heuristic, which identifies LSP setups based on three sequential rules involving the invoice target and destination hop hints.
  • Multi-LSP Worst-Case Probing: The system can now probe up to MaxLspsToProbe (currently 3) unique Lightning Service Providers when an LSP setup is detected, returning the worst-case (most expensive) fee estimate for conservative budgeting and griefing protection.
  • Updated HasNode Functionality: A new HasNode backend function has been introduced and integrated to efficiently check for the existence of public nodes in the graph, crucial for the updated LSP detection logic.
  • Comprehensive Test Coverage: New integration tests have been added to testEstimateRouteFee to cover various multi-LSP scenarios, ensuring the reliability of the enhanced heuristic.
  • API Documentation and Release Notes: The API documentation for estimateRouteFee has been updated to reflect the new LSP detection rules, and a release note entry has been added for LND 20.1.
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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

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.

Copy link

@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 significantly enhances the LSP detection heuristic for fee estimation. The new logic, based on a clear set of rules, is more robust and correctly handles multi-LSP scenarios by probing for worst-case fees. The changes are well-tested and the documentation has been updated to reflect the new behavior. My feedback is focused on a couple of comments in the implementation that seem to contradict the new logic of finding the most expensive route, not the cheapest.

Comment on lines +577 to +579
// If the heuristic indicates an LSP, we filter and group route hints by
// public LSP nodes, then probe each unique LSP separately and return
// the cheapest route.

Choose a reason for hiding this comment

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

medium

The comment here states that the logic will return the 'cheapest route'. However, the implementation, particularly the logic for worstCaseResp, is designed to find and return the worst-case (most expensive) route. The release notes and test comments also confirm this. To avoid confusion, this comment should be updated to reflect that the goal is to find the most expensive route for conservative fee estimation.

Suggested change
// If the heuristic indicates an LSP, we filter and group route hints by
// public LSP nodes, then probe each unique LSP separately and return
// the cheapest route.
// If the heuristic indicates an LSP, we filter and group route hints by
// public LSP nodes, then probe each unique LSP separately and return
// the worst-case (most expensive) route.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

not changing it here because it needs to be changed on master as well

Comment on lines +798 to +800
// LspRouteGroup represents a group of route hints that share the same public
// LSP destination node. This is needed when probing LSPs separately to find
// the cheapest route.

Choose a reason for hiding this comment

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

medium

The comment for LspRouteGroup mentions that it's used for finding the 'cheapest route'. This seems to contradict the implementation's goal of finding the worst-case (most expensive) fee estimate. To maintain consistency with the implementation and the overall goal of this feature, I suggest updating the comment to mention 'worst-case' or 'most expensive' route.

Suggested change
// LspRouteGroup represents a group of route hints that share the same public
// LSP destination node. This is needed when probing LSPs separately to find
// the cheapest route.
// LspRouteGroup represents a group of route hints that share the same public
// LSP destination node. This is needed when probing LSPs separately to find
// the worst-case (most expensive) route.

@Roasbeef Roasbeef merged commit c6467a6 into lightningnetwork:v0.20.x-branch Dec 13, 2025
38 of 40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants