Skip to content

Conversation

@ximinez
Copy link
Collaborator

@ximinez ximinez commented Jan 31, 2025

High Level Overview of Change

Implement the Lending Protocol as described in XLS-66

Context of Change

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Refactor (non-breaking change that only restructures code)
  • Tests (you added tests for code that already exists, or your new feature included in this PR)

API Impact

  • Public API: New feature (new methods and/or new fields)
  • Public API: Breaking change (in general, breaking changes should only impact the next api_version)
  • libxrpl change (any change that may affect libxrpl or dependents of libxrpl)
  • Peer protocol change (must be backward compatible or bump the peer protocol version)

@ximinez ximinez force-pushed the ximinez/lending-XLS-66 branch 4 times, most recently from 1240135 to 6f5d1ad Compare February 4, 2025 19:35
@codecov
Copy link

codecov bot commented Feb 4, 2025

Codecov Report

❌ Patch coverage is 90.63685% with 247 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.0%. Comparing base (c9f17dd) to head (3ca1593).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
src/xrpld/app/misc/detail/LendingHelpers.cpp 85.7% 78 Missing ⚠️
src/xrpld/app/tx/detail/InvariantCheck.cpp 89.0% 27 Missing ⚠️
src/xrpld/app/tx/detail/LoanManage.cpp 84.9% 27 Missing ⚠️
src/xrpld/app/tx/detail/LoanSet.cpp 91.4% 27 Missing ⚠️
src/xrpld/app/tx/detail/LoanBrokerDelete.cpp 72.5% 25 Missing ⚠️
src/xrpld/rpc/handlers/LedgerEntry.cpp 0.0% 20 Missing ⚠️
src/libxrpl/ledger/View.cpp 94.5% 16 Missing ⚠️
src/xrpld/app/tx/detail/LoanPay.cpp 95.5% 11 Missing ⚠️
...rc/xrpld/app/tx/detail/LoanBrokerCoverClawback.cpp 97.8% 3 Missing ⚠️
src/xrpld/app/tx/detail/LoanBrokerCoverDeposit.cpp 94.8% 3 Missing ⚠️
... and 6 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           develop   #5270     +/-   ##
=========================================
+ Coverage     78.6%   79.0%   +0.5%     
=========================================
  Files          818     839     +21     
  Lines        68938   71377   +2439     
  Branches      8240    8339     +99     
=========================================
+ Hits         54177   56422   +2245     
- Misses       14761   14955    +194     
Files with missing lines Coverage Δ
include/xrpl/basics/Number.h 100.0% <ø> (ø)
include/xrpl/json/json_value.h 98.5% <ø> (ø)
include/xrpl/ledger/ApplyView.h 100.0% <ø> (ø)
include/xrpl/ledger/View.h 100.0% <100.0%> (ø)
include/xrpl/protocol/Asset.h 96.3% <100.0%> (+0.8%) ⬆️
include/xrpl/protocol/Indexes.h 100.0% <100.0%> (ø)
include/xrpl/protocol/Protocol.h 100.0% <100.0%> (ø)
include/xrpl/protocol/SField.h 100.0% <ø> (ø)
include/xrpl/protocol/STAmount.h 95.7% <100.0%> (+1.2%) ⬆️
include/xrpl/protocol/STObject.h 93.1% <ø> (ø)
... and 50 more

... and 13 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.

@ximinez ximinez force-pushed the ximinez/lending-XLS-66 branch 3 times, most recently from 27e4c4f to 2d209c4 Compare February 8, 2025 00:58
@ximinez ximinez force-pushed the ximinez/lending-XLS-66 branch 5 times, most recently from e8fbd22 to a697138 Compare February 28, 2025 19:24
@ximinez ximinez force-pushed the ximinez/lending-XLS-66 branch 7 times, most recently from 72d979e to 441d5b5 Compare March 17, 2025 20:23
@ximinez ximinez changed the base branch from develop to ximinez/Bronek/vault March 17, 2025 22:52
@ximinez ximinez force-pushed the ximinez/Bronek/vault branch from b1e091c to 2a8861d Compare March 19, 2025 00:44
@ximinez ximinez force-pushed the ximinez/lending-XLS-66 branch 8 times, most recently from 5223459 to c7b296c Compare March 25, 2025 16:30
@ximinez ximinez force-pushed the ximinez/lending-XLS-66 branch from 6bc30ca to f8ee979 Compare November 23, 2025 02:49
Copy link
Collaborator Author

@ximinez ximinez left a comment

Choose a reason for hiding this comment

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

Posting a bunch of pending comments?

return {
Validity::SigBad,
"Malformed: Invalid inner batch transaction."};

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Does removing this check have to be amendment-gated?

Ugh. I really want to say no, but it's called from Transactor::preflight, so to be safe, I guess it needs to be.

I've restored the code on this branch, and made a separate PR with a fix amendment to skip over the block: #6069

Valid values are between 0 and 10% inclusive.
*/
TenthBips16 constexpr maxManagementFeeRate(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should it be moved to a namespace to avoid potential name collisions in the future?

I'm having a hard time imagining what would use the names that wasn't lending related, but a namespace doesn't hurt, so I'll do that.

{
// Fixed fields can not be specified if we're modifying an existing
// LoanBroker Object
if (tx.isFieldPresent(sfManagementFeeRate) ||
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As sfVaultID is also not allowed to be modified, do we want to check if it presents?

The VaultID field is defined as required in the transaction, so it will be present. It just has to match.

broker->at(sfVaultID) = vaultID;
broker->at(sfOwner) = account_;
broker->at(sfAccount) = pseudoId;
broker->at(sfLoanSequence) = 1;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Shouldn't it be the default value 0 as we don't have a Loan object at this moment?

No. In XRPL, sequence numbers are read then incremented, so we start with 1. 0 is an invalid sequence.

If you look at the pre-DeletableAccounts code, you'll see that new account roots were originally created with a sequence of 1. This just follows that same pattern.

}

// These values are only going to decrease, and can't be less than 0, so
// there's no need for integer range enforcement.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Leaving a comment here since the github doesn't let adding it to unchanged code. There is this code in doApply() just before the funds are transferred:

auto const dstAcct = ctx_.tx[~sfDestination].value_or(account_);
if (!vaultAsset.native() &&               //
    dstAcct != vaultAsset.getIssuer() &&  //
    dstAcct == account_)
{
    if (auto const ter = addEmptyHolding(
            view(), account_, mPriorBalance, vaultAsset, j_);
        !isTesSuccess(ter) && ter != tecDUPLICATE)
        return ter;
}

There is no need to check for native() and non issuer account - addEmptyHolding() has these checks.

These extra checks have since been removed in another PR.

return valueFields;
}

std::uint32_t
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It should be static function.

I assume you're talking about getStartDate, in which case, this is fixed in 1ceff3d

ximinez added a commit that referenced this pull request Nov 24, 2025
- Revert Payment transactor (Payment.*) back to what is in "develop".
- Change LoanBrokerCoverWithdraw to do a direct transfer, whether it's
  too the account or the destination. Similar to VaultWithdraw, and as
  specified
- #5270 (comment)
Comment on lines 500 to +505
[[maybe_unused]] bool const enforce =
view.rules().enabled(featureInvariantsV1_1) ||
view.rules().enabled(featureSingleAssetVault);
view.rules().enabled(featureSingleAssetVault) ||
view.rules().enabled(featureLendingProtocol);
Copy link
Collaborator

Choose a reason for hiding this comment

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

If featureInvariantsV1_1 is enabled, but one node hasn’t upgraded to the rippled version that includes lending while another node has (and therefore runs the new invariant checks), wouldn’t they end up producing different transaction results? (I guess it would be okay since invaraints are meant to be defensive checks)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If featureInvariantsV1_1 is enabled, but one node hasn’t upgraded to the rippled version that includes lending while another node has (and therefore runs the new invariant checks), wouldn’t they end up producing different transaction results? (I guess it would be okay since invaraints are meant to be defensive checks)

Nope. That's not a problem, since the checks are joined by "or". In your scenario, assuming both nodes are running a version that supports featureInvariantsV1_1 (it's not supported in any version at the moment), then they would both run the invariant check and get identical results. (If one of them did not support it, it would be amendment blocked.)

Copy link
Collaborator

@shawnxie999 shawnxie999 Dec 1, 2025

Choose a reason for hiding this comment

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

To clarify, I'm taking about the scenario where:

  • featureInvariantsV1_1 is enabled across the network and featureLendingProtocol is not enabled
  • Node A supports featureInvariantsV1_1 but does not support featureLendingProtocol (didn't upgrade to latest rippled version)
  • Node B supports both featureInvariantsV1_1 and featureLendingProtocol (upgraded to latest rippled version)

Now with the invariant checks below introduced in lending, gated by enforce

image

If one of these new checks fails for a transaction, Node A would still succeed (since it runs on an older version and does not have these checks) but Node B would fail.

Anyways, since featureInvariantsV1_1 is not supported, this can be left for later discussion.

Copy link
Collaborator

@dangell7 dangell7 left a comment

Choose a reason for hiding this comment

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

non amendment guarded code review

Copy link
Collaborator

@shawnxie999 shawnxie999 left a comment

Choose a reason for hiding this comment

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

Approving the PR (non amendment gated portion) in its current state, given that we are keeping the lending feature unsupported for the time being.

Copy link
Collaborator

@gregtatcam gregtatcam left a comment

Choose a reason for hiding this comment

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

👍 LGTM

@ximinez ximinez requested a review from dangell7 December 1, 2025 22:48
@ximinez
Copy link
Collaborator Author

ximinez commented Dec 2, 2025

@dangell7 I've addressed your comments. Could you re-review ASAP, so I can resolve the issue with unsigned commits, and get this thing merged?

Copy link
Collaborator

@dangell7 dangell7 left a comment

Choose a reason for hiding this comment

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

Approving ONLY non amendment gated code

- Spec: XLS-66
- Introduces amendment "featureLendingProtocol", but leaves it
  UNSUPPORTED to allow for future development work.
- AccountInfo RPC will indicate the type of pseudo-account when
  appropriate.
- Refactors and improves several existing classes and functional areas,
  including Number, STAmount, STObject, json_value, Asset, directory
  handling, View helper functions, and unit test helpers.
@ximinez ximinez force-pushed the ximinez/lending-XLS-66 branch from a5a2b38 to 3ca1593 Compare December 2, 2025 16:17
@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 Dec 2, 2025
@ximinez
Copy link
Collaborator Author

ximinez commented Dec 2, 2025

Commit message:

Implement Lending Protocol (unsupported) (#5270)

- Spec: XLS-66
- Introduces amendment "LendingProtocol", but leaves it UNSUPPORTED to
  allow for standalone testing, future development work, and potential
  bug fixes.
- AccountInfo RPC will indicate the type of pseudo-account when
  appropriate.
- Refactors and improves several existing classes and functional areas,
  including Number, STAmount, STObject, json_value, Asset, directory
  handling, View helper functions, and unit test helpers.

@ximinez ximinez enabled auto-merge (squash) December 2, 2025 16:31
@ximinez ximinez merged commit 6c67f1f into develop Dec 2, 2025
24 checks passed
@ximinez ximinez deleted the ximinez/lending-XLS-66 branch December 2, 2025 16:38
ximinez added a commit that referenced this pull request Dec 2, 2025
ximinez added a commit that referenced this pull request Dec 2, 2025
- Spec: XLS-66
- Introduces amendment "LendingProtocol", but leaves it UNSUPPORTED to
  allow for standalone testing, future development work, and potential
  bug fixes.
- AccountInfo RPC will indicate the type of pseudo-account when
  appropriate.
- Refactors and improves several existing classes and functional areas,
  including Number, STAmount, STObject, json_value, Asset, directory
  handling, View helper functions, and unit test helpers.
@ximinez ximinez mentioned this pull request Dec 2, 2025
13 tasks
ximinez added a commit that referenced this pull request Dec 2, 2025
- Spec: XLS-66
- Introduces amendment "LendingProtocol", but leaves it UNSUPPORTED to
  allow for standalone testing, future development work, and potential
  bug fixes.
- AccountInfo RPC will indicate the type of pseudo-account when
  appropriate.
- Refactors and improves several existing classes and functional areas,
  including Number, STAmount, STObject, json_value, Asset, directory
  handling, View helper functions, and unit test helpers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Amendment JiraRefresh Manually trigger Jira automation to run for this item. 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.