Skip to content

multi: expose local and remote spendable balance in listchannels#10624

Open
Euler-B wants to merge 5 commits intolightningnetwork:masterfrom
Euler-B:feature/listchannels-spendable-balance
Open

multi: expose local and remote spendable balance in listchannels#10624
Euler-B wants to merge 5 commits intolightningnetwork:masterfrom
Euler-B:feature/listchannels-spendable-balance

Conversation

@Euler-B
Copy link
Contributor

@Euler-B Euler-B commented Mar 3, 2026

Change Description

This PR addresses the request to expose the actual "spendable" balance in the listchannels RPC.
Currently, local_balance and remote_balance only show total funds, not considering:

  • Channel reserves (ChanReserve).
  • Commitment fees (paid by the initiator).
  • The cost of adding new HTLCs.

Fixes: #4951

Steps to Test

  1. Automated Tests:
$ go test -v -run "TestChanRemoteAvailableBalance|TestApplyCommitmentFee" github.com/lightningnetwork/lnd/lnwallet
  1. Manual: Build with make install and verify local_spendable_msat in lncli listchannels.

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

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 improves the listchannels RPC by providing a more precise and actionable view of channel liquidity. By introducing new fields that account for channel reserves, commitment fees, and potential HTLC costs, users can now accurately determine the actual amount of funds available for immediate spending or forwarding, both locally and by the remote peer. This enhancement addresses a long-standing request to move beyond simple total balance reporting, offering a more realistic and useful metric for channel management.

Highlights

  • New RPC Fields for Spendable Balance: Introduced local_spendable_msat and remote_spendable_msat fields to the Channel message in the listchannels RPC response. These fields provide a more accurate representation of funds available for sending by factoring in channel reserves and commitment fees.
  • Remote Bandwidth Calculation: Implemented a new RemoteBandwidth() method within the ChannelLink interface and its concrete types to expose the remote party's available bandwidth, considering their reserves and commitment fees.
  • Refactored Balance Logic: Refactored the internal channel balance calculation logic to be more generic, allowing for accurate determination of spendable balances from both local and remote perspectives, and updated the applyCommitFee function to explicitly handle initiator status.

🧠 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.

Changelog
  • htlcswitch/interfaces.go
    • Added RemoteBandwidth() method to the ChannelUpdateHandler interface.
    • Updated the comment for the existing Bandwidth() method to clarify its scope for the local party.
  • htlcswitch/link.go
    • Implemented the RemoteBandwidth() method for the channelLink type, which returns the remote party's available balance.
  • htlcswitch/mock.go
    • Added a mock implementation for the RemoteBandwidth() method to the mockChannelLink type.
    • Updated the comment for the existing Bandwidth() method.
  • lnrpc/lightning.proto
    • Added local_spendable_msat and remote_spendable_msat fields to the Channel message, including detailed descriptions of their calculation.
  • lnrpc/lightning.swagger.json
    • Updated the Swagger definition to include the newly added local_spendable_msat and remote_spendable_msat fields in the Channel object.
  • lnwallet/channel.go
    • Modified the applyCommitFee function to accept an isInitiator boolean parameter, allowing for more flexible fee application logic.
    • Introduced RemoteAvailableBalance() to calculate the remote party's spendable balance.
    • Refactored the balance calculation logic into a new generic function availableBalanceGeneric to handle both local and remote perspectives, reducing code duplication.
    • Adjusted availableCommitmentBalance to use the new generic balance calculation and correctly apply reserves and fees based on the isRemote and initiator flags.
  • lnwallet/channel_test.go
    • Added TestChanRemoteAvailableBalance to thoroughly test the accuracy of the RemoteAvailableBalance calculation.
    • Updated calls to applyCommitFee in existing tests to pass the new isInitiator parameter.
    • Modified TestChanCommitWeightDustHtlcs to pass the isRemote parameter to availableCommitmentBalance.
  • rpcserver.go
    • Updated the createRPCOpenChannel function to retrieve and populate the LocalSpendableMsat and RemoteSpendableMsat fields in the Channel RPC response using the new Bandwidth() and RemoteBandwidth() methods from the htlcSwitch link.
Activity
  • No specific activity (comments, reviews, or progress updates) was provided in the context.
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.

@lightninglabs-deploy lightninglabs-deploy added the severity-critical Requires expert review - security/consensus critical label Mar 3, 2026
@lightninglabs-deploy
Copy link
Collaborator

🔴 PR Severity: CRITICAL

PR #10624 | 9 files | 5754 lines changed (262 non-excluded lines across 7 non-excluded files)

🔴 Critical (5 files)
  • htlcswitch/interfaces.go - HTLC switch interface definitions — core payment routing state machine
  • htlcswitch/link.go - HTLC forwarding link — central to payment forwarding logic
  • htlcswitch/mock.go - HTLC switch mock (test infrastructure within a critical package)
  • lnwallet/channel.go - Channel operations and commitment transactions — wallet-level fund management
  • rpcserver.go - Core RPC server coordination
🟠 High (1 file, auto-generated)
  • lnrpc/lightning.pb.go - Auto-generated protobuf RPC definitions (excluded from line/file counting)
🟡 Medium (2 files)
  • lnrpc/lightning.proto - Protobuf API definition (.proto file)
  • lnrpc/lightning.swagger.json - Swagger/OpenAPI spec (auto-generated API description)
🟢 Low / Test (1 file)
  • lnwallet/channel_test.go - Test file (excluded from severity bump counting)

Analysis

This PR touches three distinct critical packages: htlcswitch, lnwallet, and rpcserver.go. Each of these individually qualifies for CRITICAL severity:

  • htlcswitch/* governs HTLC forwarding and the payment routing state machine — changes here can directly affect in-flight payment correctness.
  • lnwallet/channel.go contains commitment transaction and channel state logic — any regression here risks fund loss or channel corruption.
  • rpcserver.go is the core server entry point for RPC calls.

Excluding test files (*_test.go) and auto-generated files (*.pb.go), the PR modifies 7 files with approximately 262 non-excluded lines changed — below the 500-line bump threshold. However, the baseline severity is already CRITICAL due to the packages touched, so no bump is needed.

Expert review is warranted given the breadth of changes across HTLC switching, wallet channel management, and the RPC surface.


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

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 successfully exposes the local and remote spendable balances in the listchannels RPC. The core of the change is a significant but well-executed refactoring in lnwallet/channel.go to create a generic balance calculation logic applicable to both local and remote parties. The new test case, TestChanRemoteAvailableBalance, is thorough and provides good coverage for the new logic. The changes to the RPC layer are consistent with the core modifications. I have a couple of minor suggestions related to code comments to improve documentation clarity and adhere to the style guide.

Note: Security Review is unavailable for this PR.

@Euler-B Euler-B force-pushed the feature/listchannels-spendable-balance branch 2 times, most recently from a639166 to 4b7cb99 Compare March 6, 2026 19:56
Euler-B added 4 commits March 9, 2026 12:24
This commit refactors availableCommitmentBalance and applyCommitFee to
be party-agnostic, allowing the calculation of the available balance
from the perspective of either the local or remote party. We also
introduce RemoteAvailableBalance to expose this new functionality.

A new test TestChanRemoteAvailableBalance has been added to verify
the accuracy of these calculations across various states.
This commit adds a new RemoteBandwidth method to the ChannelLink
interface and implements it in channelLink by calling the new
RemoteAvailableBalance method in lnwallet.

The mockChannelLink has also been updated to satisfy the interface.
This commit adds local_spendable_msat and remote_spendable_msat to the
Channel message in lightning.proto. This allows clients to see the
actual amount of funds that can be sent or received in a channel,
accounting for reserves and fees.
This commit updates the ListChannels RPC to populate the new
local_spendable_msat and remote_spendable_msat fields by querying the
active channel link from the htlcSwitch.
@Euler-B Euler-B force-pushed the feature/listchannels-spendable-balance branch from 4b7cb99 to 1affd68 Compare March 9, 2026 16:26
@Euler-B Euler-B force-pushed the feature/listchannels-spendable-balance branch from 1affd68 to 6bc0965 Compare March 9, 2026 21:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity-critical Requires expert review - security/consensus critical

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rpc: expose potential HTLC addition cost to channels list for spendable balance calculation

2 participants