Sponsored Content
Skip to content

fix: Cap the base fee for LoanPay - #6969

Merged
ximinez merged 8 commits into
ripple/staging-313from
ximinez/loanpay-fee-overflow-313
Apr 22, 2026
Merged

fix: Cap the base fee for LoanPay#6969
ximinez merged 8 commits into
ripple/staging-313from
ximinez/loanpay-fee-overflow-313

Conversation

@ximinez

@ximinez ximinez commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

High Level Overview of Change

If a LoanPay pays more than periodicPayment * loanMaximumPaymentsPerTransaction calculate the maximum fee as maxFeeIncrements * baseFee.

maxFeeIncrements is loanMaximumPaymentsPerTransaction / loanPaymentsPerFeeIncrement.

develop port: #6970

@ximinez ximinez added this to the 3.1.3 milestone Apr 17, 2026

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

@ximinez

ximinez commented Apr 17, 2026

Copy link
Copy Markdown
Contributor Author

I've got a handful of failing unit tests. I'll fix those on Monday.

@vlntb
vlntb self-requested a review April 20, 2026 14:04

@vlntb vlntb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The proposed change fixes the root of the problem by capping the fee at loanMaximumPaymentsPerTransaction * normalCost, avoiding fee calculation for impossibly high payment counts that could cause overflow.

I'll review again once unit tests are finalised. The current Loan_test.cpp lacks explicit coverage for the fee capping logic. Please add tests for:

  1. Amount exactly at threshold → capped fee
  2. Amount below threshold → normal calculation
  3. Amount well above threshold → capped fee
  4. Amendment guard (fixSecurity3_1_3 on/off)

Note: testDosLoanPay() verifies payment capping but not fee capping.

Comment thread src/xrpld/app/tx/detail/LoanPay.cpp Outdated

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

@mathbunnyru mathbunnyru left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The name of this PR will have to be changed along with the on based on develop, to follow conventional commit rules

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

- Old and busted: Computing max fee as loanMaximumPaymentsPerTransaction * normalCost;
- New hotness: Computing max fee increments as
  loanMaximumPaymentsPerTransaction / loanPaymentsPerFeeIncrement,
  then computing max fee as
  maxFeeIncrements * normalCost,
  if payment amount >= maxFeeIncrements * periodicPayment.

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Went through the changes

Ungated assert will abort pre-amendment when amount is large — see inline.


Review by ReviewBot 🤖

Review by Claude Opus 4.6 · Prompt: V15

Comment thread src/xrpld/app/tx/detail/LoanPay.cpp
@ximinez ximinez changed the title Cap the base fee for LoanPay based on loanMaximumPaymentsPerTransaction fix: Cap the base fee for LoanPay Apr 20, 2026
@codecov

codecov Bot commented Apr 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.4%. Comparing base (31d4d08) to head (90b1284).
⚠️ Report is 1 commits behind head on ripple/staging-313.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##           ripple/staging-313   #6969   +/-   ##
==================================================
  Coverage                80.4%   80.4%           
==================================================
  Files                     840     840           
  Lines                   75347   75352    +5     
  Branches                 8200    8200           
==================================================
+ Hits                    60585   60590    +5     
  Misses                  14762   14762           
Files with missing lines Coverage Δ
src/xrpld/app/tx/detail/LoanPay.cpp 94.6% <100.0%> (+0.1%) ⬆️

... and 3 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts LoanPay::calculateBaseFee to cap the minimum fee when the transaction amount implies more payments than can actually be processed per transaction, specifically when fixSecurity3_1_3 is enabled.

Changes:

  • Introduces a computed maxFeeIncrements based on protocol limits.
  • Adds an early-return cap intended to prevent charging more fee increments than the transaction can consume in work.
  • Adds an XRPL_ASSERT to enforce the (intended) invariant that fee increments do not exceed the cap under the amendment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/xrpld/app/tx/detail/LoanPay.cpp Outdated
Comment thread src/xrpld/app/tx/detail/LoanPay.cpp
Comment thread src/xrpld/app/tx/detail/LoanPay.cpp
Comment thread src/xrpld/app/tx/detail/LoanPay.cpp Outdated
- Add test cases to exercise the LoanPay fee cap calculation
- Fix a bug in the fee cap calculation.

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

@ximinez
ximinez force-pushed the ximinez/loanpay-fee-overflow-313 branch from b3d6f82 to d3e31de Compare April 22, 2026 00:16

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

@mathbunnyru
mathbunnyru dismissed their stale review April 22, 2026 08:35

The thing I asked for was addressed

NumberRoundModeGuard mg(
tx.isFlag(tfLoanOverpayment) ? Number::upward : Number::downward);

static_assert(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is this using static assert instead of XRPL_ASSERT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because static_assert fails at compile time. If the values are ever changed to something that doesn't match this expectation, it won't build, and thus will fail immediately.

@kuznetsss kuznetsss left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues.

Review by Claude Opus 4.6 · Prompt: V15

@vlntb vlntb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The changes since my last approval look correct. All the missing test cases that I highlighted have been addressed.
Approving.

@ximinez ximinez added the Ready to merge *PR author* thinks it's ready to merge. Has passed code review. Perf sign-off may still be required. label Apr 22, 2026
@ximinez
ximinez added this pull request to the merge queue Apr 22, 2026
Merged via the queue into ripple/staging-313 Apr 22, 2026
3 checks passed
@ximinez
ximinez deleted the ximinez/loanpay-fee-overflow-313 branch April 22, 2026 18:44
ximinez added a commit that referenced this pull request Apr 22, 2026
godexsoft pushed a commit to godexsoft/rippled that referenced this pull request May 7, 2026
Co-authored-by: Bart <bthomee@users.noreply.github.com>
beartec-jpg pushed a commit to beartec-jpg/FalconLedger that referenced this pull request Jun 1, 2026
Co-authored-by: Bart <bthomee@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready to merge *PR author* thinks it's ready to merge. Has passed code review. Perf sign-off may still be required.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants