Skip to content

chainfee: make relay fee floor configurable via --fee.min-relay-feerate#10783

Open
Kilombino wants to merge 1 commit intolightningnetwork:masterfrom
Kilombino:feat/configurable-min-relay-feerate
Open

chainfee: make relay fee floor configurable via --fee.min-relay-feerate#10783
Kilombino wants to merge 1 commit intolightningnetwork:masterfrom
Kilombino:feat/configurable-min-relay-feerate

Conversation

@Kilombino
Copy link
Copy Markdown

Summary

LND currently hardcodes a minimum fee rate floor of 253 sat/kw (~1 sat/vb) in the chainfee package. This floor is applied in three places:

  • minFeeManager: clamps the fee returned by the chain backend
  • WebAPIEstimator.EstimateFeePerKW: clamps the cached API result
  • sweep/walletsweep.go: silently bumps 1 sat/vb inputs to 253 sat/kw

This prevents operators who run a Bitcoin backend with a lower minrelaytxfee (e.g. a personal mining setup, signet, regtest, or a node connected directly to a cooperative miner) from opening channels or sweeping funds below 1 sat/vb.

This PR introduces a new --fee.min-relay-feerate config option (sat/vb) that lets operators lower the floor when their setup permits it. The default value is unchanged (1 sat/vb = 253 sat/kw), so existing nodes are unaffected.

Changes

File Change
lnwallet/chainfee/minfeemanager.go feeFloor SatPerKWeight field + param; replaces constant clamp
lnwallet/chainfee/estimator.go feeFloor field on BtcdEstimator, BitcoindEstimator, WebAPIEstimator; constructors updated; hardcoded FeePerKwFloor references replaced
sweep/walletsweep.go Remove unconditional 250→253 bump; the existing minFeeRate check downstream already enforces the relay floor
chainreg/chainregistry.go Pass cfg.Fee.FeeFloorKW() to all three estimator constructors
lncfg/fee.go MinRelayFeeRate chainfee.SatPerVByte field + Validate() + FeeFloorKW() helper
sample-lnd.conf Document the new option
lnwallet/chainfee/minfeemanager_test.go Update existing test; add two new tests for custom floor behaviour
lnwallet/chainfee/estimator_test.go Update NewWebAPIEstimator calls for new signature

Usage

[fee]
# Lower the floor for a node with minrelaytxfee=0 in bitcoin.conf
fee.min-relay-feerate=0

Safety

The commit message and sample-lnd.conf include a clear warning:

Lowering this value below 1 sat/vb means your node will create transactions that standard Bitcoin nodes will not relay. Only use this option if your backend has a matching minrelaytxfee and you have a direct path to a miner's mempool.

Test plan

  • go test ./lnwallet/chainfee/... — existing tests pass, new floor tests pass
  • go test ./sweep/... — walletsweep tests unaffected
  • go build ./... — compiles cleanly
  • Start lnd with fee.min-relay-feerate=0; open a channel specifying a fee rate of 100 sat/kw; verify the channel opens without the old "fee too low" error

Fixes: operators running nodes with minrelaytxfee=0 or sub-1 sat/vb mempool policies unable to transact at their configured fee rates.

@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 enables greater flexibility for LND node operators running on custom Bitcoin backends with non-standard mempool policies. By introducing a configurable minimum relay fee rate, operators can now transact at lower fee rates than the default 1 sat/vb, provided their infrastructure supports it. The changes maintain backward compatibility by defaulting to the existing 1 sat/vb floor.

Highlights

  • Configurable Fee Floor: Introduced a new configuration option --fee.min-relay-feerate allowing operators to lower the minimum relay fee rate floor below the default 1 sat/vb (253 sat/kw).
  • Refactored Fee Estimation: Updated minFeeManager and fee estimators (BtcdEstimator, BitcoindEstimator, WebAPIEstimator) to support a configurable fee floor instead of relying on hardcoded constants.
  • Removed Hardcoded Bumps: Removed the unconditional 250→253 sat/kw bump in walletsweep.go, allowing downstream enforcement of the configured relay floor.

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

@github-actions github-actions Bot added the severity-critical Requires expert review - security/consensus critical label Apr 30, 2026
@github-actions
Copy link
Copy Markdown

PR Severity: CRITICAL. Automated classification | 6 files | 127 lines changed (excl tests). Critical files: lnwallet/chainfee/estimator.go, lnwallet/chainfee/minfeemanager.go (lnwallet/* package), sweep/walletsweep.go (sweep/* package). Medium files: chainreg/chainregistry.go, lncfg/fee.go, sample-lnd.conf. Two distinct critical packages touched. Expert review required. <!-- pr-severity-bot -->

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 a configurable minimum relay fee rate floor, allowing operators to specify values below the default 1 sat/vb. The changes update the configuration struct, fee estimators, and the minimum fee manager to respect the new setting. Review feedback identifies that using zero as a sentinel value in the configuration and estimator logic prevents the implementation of an actual zero floor. Additionally, a regression was noted in the wallet sweep logic regarding the handling of 1 sat/vb fee rates, and a documentation error was found in the fee rate conversion description.

Comment thread lncfg/fee.go
Comment thread lnwallet/chainfee/minfeemanager.go Outdated
Comment thread lnwallet/chainfee/estimator.go Outdated
Comment thread sweep/walletsweep.go
The minimum relay fee rate is currently hardcoded to FeePerKwFloor
(253 sat/kw, ~1 sat/vb). This prevents operators running nodes that
connect to a Bitcoin backend with a lower minrelaytxfee from opening
channels or sweeping funds at sub-1 sat/vb rates.

This commit introduces a new --fee.min-relay-feerate option (in sat/vb)
that lets operators lower the floor when their setup permits it. The
default remains 1 sat/vb, preserving existing behaviour for all nodes.

Changes:
- lnwallet/chainfee/minfeemanager: accept a feeFloor parameter instead
  of always clamping to the package-level FeePerKwFloor constant
- lnwallet/chainfee/estimator: thread feeFloor through BtcdEstimator,
  BitcoindEstimator, and WebAPIEstimator constructors; use the
  configured floor in EstimateFeePerKW clamping and relay fee fallback
- sweep/walletsweep: remove the unconditional 250→253 sat/kw bump; the
  downstream minFeeRate check already enforces the relay floor
- chainreg/chainregistry: pass cfg.Fee.FeeFloorKW() to all estimator
  constructors and to the static estimator
- lncfg/fee: add MinRelayFeeRate field with Validate() and FeeFloorKW()
  helpers
- sample-lnd.conf: document the new fee.min-relay-feerate option

WARNING: lowering this value below 1 sat/vb means your node will create
transactions that standard Bitcoin nodes will not relay. Only use this
option if your backend has a matching minrelaytxfee and you have a
direct path to a miner's mempool.

Signed-off-by: Kilombino <kilombino@proton.me>
@Kilombino Kilombino force-pushed the feat/configurable-min-relay-feerate branch from 1803b49 to 532d237 Compare April 30, 2026 18:19
@lightninglabs-deploy
Copy link
Copy Markdown
Collaborator

@Kilombino, 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

severity-critical Requires expert review - security/consensus critical

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants