Skip to content

Apply the default routing fee limit to spontaneous sends - #326

Open
ajaysehwal wants to merge 1 commit into
lightningdevkit:mainfrom
ajaysehwal:fix-spontaneous-send-fee-limit
Open

ajaysehwal wants to merge 1 commit into
lightningdevkit:mainfrom
ajaysehwal:fix-spontaneous-send-fee-limit

Conversation

@ajaysehwal

Copy link
Copy Markdown
Contributor

RouteParametersConfig::max_total_routing_fee_msat is documented to default to 1% of the payment amount plus 50 sats. When no route parameters are given at all, ldk-node keeps LDK's default limit. But ldk-node's spontaneous send applies provided route parameters as a whole: it overwrites the limit with the given value, which is None if the field is unset, and None means no limit. A spontaneous send with route parameters but without an explicit fee limit could therefore pay arbitrary routing fees.

This affects every client that sends route parameters without a fee limit. Notably, ldk-server-cli spontaneous-send always sends route parameters (filling the other fields with their defaults), so it did not limit routing fees unless --max-total-routing-fee was passed.

Here, we fill in the documented default (1% of the amount plus 50 sats) in the spontaneous send handler whenever route parameters are provided without a fee limit. Explicit limits, including 0, are left untouched, and nothing changes if no route parameters are sent.

Notes for reviewers

  • BOLT11 and regular BOLT12 payments are not affected: LDK only overrides its default limit if one is given.
  • Payments to BOLT12 async static invoices do not get the default limit at all, even without route parameters (send_payment_for_static_invoice in rust-lightning assigns the config's None). That is outside of this PR and I think it needs a fix in LDK/ldk-node.
  • A related gap that I did not change here: the other three RouteParametersConfig fields are plain uint32s, so a client that sends only a fee limit gets max_path_count = 0 etc. Making them optional would be a small follow-up.
  • I did not touch the proto or the CLI: the proto comment is accurate after this change, and the CLI behaves correctly with the server-side default.

Testing

  • New unit tests for with_default_max_routing_fee: the default is applied for an unset limit (including amount 0 and u64::MAX), explicit limits (0, 1,000, u64::MAX) are kept, other parameters are untouched, and absent parameters stay absent.
  • cargo test -p ldk-server passes (143 tests); cargo fmt is clean. I did not run the e2e tests.

The documented default for `RouteParametersConfig::max_total_routing_fee_msat`
is 1% of the payment amount plus 50 sats. When no route parameters are
given at all, ldk-node keeps LDK's default limit. But ldk-node's
spontaneous send applies provided route parameters as a whole, i.e., it
overwrites the limit with the given value, which is `None` if the field
is unset. A `None` limit means no limit, so a spontaneous send with
route parameters but without an explicit fee limit could pay arbitrary
routing fees.

This affects every client that sends route parameters without a fee
limit. Notably, `ldk-server-cli spontaneous-send` always sends route
parameters (filling the other fields with their defaults), so it didn't
limit routing fees unless `--max-total-routing-fee` was passed.

BOLT11 and (non-async) BOLT12 payments are not affected, as LDK only
overrides the default limit if one is given.

Here, we fill in the documented default (1% of the amount plus 50 sats)
in the spontaneous send handler whenever route parameters are provided
without a fee limit. Explicit limits, including 0, are left untouched.
@ldk-reviews-bot

ldk-reviews-bot commented Nov 4, 2026 •

Copy link
Copy Markdown

👋 Thanks for assigning @benthecarman as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@benthecarman

Copy link
Copy Markdown
Collaborator

this seems more like a bug in ldk-node than ldk-server

@ajaysehwal

Copy link
Copy Markdown
Contributor Author

this seems more like a bug in ldk-node than ldk-server

Agreed, this appears to be an ldk-node bug. Both SpontaneousPayment::send_inner and the BOLT11 probing methods overwrite the default fee limit with None when no fee limit is explicitly configured. I've opened a fix in ldk-node: lightningdevkit/ldk-node#1221. Please review it when you get a chance.

I'll close this PR once the fix is merged and we've bumped the ldk-node dependency.

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.

3 participants