refactor: Move LendingHelpers into libxrpl/ledger/helpers#6638
refactor: Move LendingHelpers into libxrpl/ledger/helpers#6638
LendingHelpers into libxrpl/ledger/helpers#6638Conversation
| #include <xrpl/ledger/helpers/AMMHelpers.h> | ||
| #include <xrpl/ledger/helpers/AMMUtils.h> |
There was a problem hiding this comment.
Can these two files be combined perhaps? Looking at their contents, seems like it should be fine to move the functionality from AMMUtils into AMMHelpers, unless that's problematic for (circular) header inclusion reasons.
There was a problem hiding this comment.
I was going to leave that for a second PR, to keep this one dead simple.
There was a problem hiding this comment.
Took a pass through this
Three concerns worth confirming: (1) missing MPTokenHelpers.h include in EscrowHelpers.h, (2) potential MPToken authorization bypass via EscrowFinish/Cancel, (3) the checkLendingProtocolDependencies refactor may not be behaviorally equivalent to the VaultCreate::checkExtraFeatures it replaced. Also flagged a question about whether AMM transactors have PermissionedDEX credential checks comparable to OfferCreate. See inline comments.
Review by ReviewBot 🤖
Review by Claude Opus 4.6 · Prompt: V12
|
|
||
| if (auto const ter = MPTokenAuthorize::createMPToken(view, mptID, receiver, 0); | ||
| !isTesSuccess(ter)) | ||
| if (auto const ter = createMPToken(view, mptID, receiver, 0); !isTesSuccess(ter)) |
There was a problem hiding this comment.
Header isn't self-contained — createMPToken() is used but MPTokenHelpers.h is never included. Add the missing include near the top of the file:
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
(This was lost when MPTokenAuthorize.h was removed.)
|
|
||
| bool | ||
| checkLendingProtocolDependencies(PreflightContext const& ctx) | ||
| checkLendingProtocolDependencies(Rules const& rules, STTx const& tx) |
There was a problem hiding this comment.
Replacing VaultCreate::checkExtraFeatures(ctx) with inlined logic changes the function signature and behavior. Please confirm the new checks (featureSingleAssetVault, featureMPTokensV1, conditional featurePermissionedDomains) are exactly equivalent to what VaultCreate::checkExtraFeatures enforced — any divergence silently changes preflight acceptance in a consensus system.
| @@ -1,17 +1,16 @@ | |||
| #include <xrpl/ledger/OrderBookDB.h> | |||
There was a problem hiding this comment.
AMM transactors may be missing PermissionedDEX credential checks that OfferCreate enforces via PermissionedDEXHelpers. AMM deposits/withdrawals are economically equivalent to offer placement, so accounts could bypass DEX access controls by routing through an AMM pool. Please verify all AMM transactors apply the same access-control gates as OfferCreate.
There was a problem hiding this comment.
Permissioned DEX doesn't support AMM right now.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #6638 +/- ##
=========================================
- Coverage 81.4% 81.4% -0.0%
=========================================
Files 1006 1006
Lines 74462 74468 +6
Branches 7561 7554 -7
=========================================
+ Hits 60646 60647 +1
- Misses 13816 13821 +5
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Took a pass through this
The MR description says "pure refactor, no source code change" but LendingHelpers.cpp inlines feature checks that previously delegated to VaultCreate::checkExtraFeatures — in a consensus system any behavioral difference could cause forks. Also flagged: a stale forward declaration, a missing MPTokenHelpers.h include in EscrowHelpers.h, and widened visibility of the security-sensitive createMPToken primitive. See inline comments.
Review by ReviewBot 🤖
Review by Claude Opus 4.6 · Prompt: V12
|
|
||
| bool | ||
| checkLendingProtocolDependencies(PreflightContext const& ctx) | ||
| checkLendingProtocolDependencies(Rules const& rules, STTx const& tx) |
There was a problem hiding this comment.
Correctness risk in a consensus system — the old code delegated to VaultCreate::checkExtraFeatures(ctx) but this inlines three explicit checks. Please confirm these are exactly equivalent to what VaultCreate::checkExtraFeatures returned. Any behavioral difference could cause ledger forks.
|
|
||
| bool | ||
| checkLendingProtocolDependencies(PreflightContext const& ctx) | ||
| checkLendingProtocolDependencies(Rules const& rules, STTx const& tx) |
There was a problem hiding this comment.
Possible incomplete feature-gate replication — if VaultCreate::checkExtraFeatures checked flags beyond featureSingleAssetVault, featureMPTokensV1, and featurePermissionedDomains, lending transactions could become reachable in states where they should still be gated. Audit VaultCreate::checkExtraFeatures and add a unit test covering every flag-disabled combination the old code would have rejected.
|
|
||
| if (auto const ter = MPTokenAuthorize::createMPToken(view, mptID, receiver, 0); | ||
| !isTesSuccess(ter)) | ||
| if (auto const ter = createMPToken(view, mptID, receiver, 0); !isTesSuccess(ter)) |
There was a problem hiding this comment.
Missing include: createMPToken (declared in MPTokenHelpers.h) is called here but the header for it was removed with no replacement. Add #include <xrpl/ledger/helpers/MPTokenHelpers.h> — the header currently compiles only by accident via consumer TUs.
| } | ||
|
|
||
| TER | ||
| createMPToken( |
There was a problem hiding this comment.
Widened visibility of a security-sensitive primitive — createMPToken was previously scoped to MPTokenAuthorize and is now a free function callable by any includer. It inserts an MPToken into the ledger with no authorization check. Document in the header that callers must verify authorization independently, add [[nodiscard]] to the return TER, and audit all call sites to confirm authorization is enforced upstream.
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Took a pass through this
Two correctness concerns flagged inline: a potential semantic mismatch in the isFlag() → bitwise replacement in MPTokenHelpers.cpp, and a possibly incomplete inlining of VaultCreate::checkExtraFeatures in LendingHelpers.cpp that could silently drop amendment gates.
Review by ReviewBot 🤖
Review by Claude Opus 4.6 · Prompt: V12
| return tecOBJECT_NOT_FOUND; | ||
|
|
||
| if (!sleIssuance->isFlag(lsfMPTCanTransfer)) | ||
| if ((sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer) == 0u) |
There was a problem hiding this comment.
Verify semantic equivalence with the replaced isFlag() call — confirm lsfMPTCanTransfer is the correct bit mask and no normalization step was dropped. If this tests a different bit position than isFlag() did, flag state written by MPTokenIssuanceSet will be misread here and in MPTokenAuthorize, potentially enabling features (transferability, clawback) that should remain disabled.
Please confirm this is equivalent to the previous:
if (!sleIssuance->isFlag(lsfMPTCanTransfer))| checkLendingProtocolDependencies(Rules const& rules, STTx const& tx) | ||
| { | ||
| return ctx.rules.enabled(featureSingleAssetVault) && VaultCreate::checkExtraFeatures(ctx); | ||
| if (!rules.enabled(featureSingleAssetVault)) |
There was a problem hiding this comment.
Missing amendment gates from the removed VaultCreate::checkExtraFeatures call — verify the inline expansion is complete. The old implementation was:
return ctx.rules.enabled(featureSingleAssetVault) && VaultCreate::checkExtraFeatures(ctx);If checkExtraFeatures enforced additional amendment checks beyond featureMPTokensV1 and featurePermissionedDomains, all eight lending transactors that delegate here will silently skip those gates, potentially accepting transactions that should be rejected — which could cause consensus divergence between nodes on different amendment sets.
There was a problem hiding this comment.
Three issues flagged inline: possible dropped feature-gate constraints in LendingHelpers (high severity), undocumented reserve-check precondition on the new public createMPToken API, and a isFlag() → manual bitwise substitution that needs semantic verification.
Review by Claude Opus 4.6 · Prompt: V12
| beast::Journal j); | ||
|
|
||
| TER | ||
| createMPToken( |
There was a problem hiding this comment.
Newly public createMPToken has no documented reserve-check precondition — callers may skip it.
The function was extracted from MPTokenAuthorize where the reserve check was always performed before calling it. Now that it's a shared public API, document the precondition prominently so future callers know they must validate reserve balance first.
// PRECONDITION: Caller must have already verified the account has
// sufficient owner reserve before invoking this function.
TER
createMPToken(
ApplyView& view,
MPTID const& mptIssuanceID,
AccountID const& account,
std::uint32_t const flags);
|
|
||
| bool | ||
| checkLendingProtocolDependencies(PreflightContext const& ctx) | ||
| checkLendingProtocolDependencies(Rules const& rules, STTx const& tx) |
There was a problem hiding this comment.
Refactor may silently drop constraints from VaultCreate::checkExtraFeatures — verify nothing was lost.
The old implementation was ctx.rules.enabled(featureSingleAssetVault) && VaultCreate::checkExtraFeatures(ctx). The new version inlines only three rules.enabled() checks. If VaultCreate::checkExtraFeatures enforced any additional feature flags, field validations, or invariants beyond these three, those checks are now silently removed. In a consensus-critical path, this could allow transactions that should be rejected to proceed.
Please audit the full implementation of VaultCreate::checkExtraFeatures and confirm that every condition it enforced is either replicated here or explicitly justified as removed. Add regression tests covering each previously-checked condition.
| return tecOBJECT_NOT_FOUND; | ||
|
|
||
| if (!sleIssuance->isFlag(lsfMPTCanTransfer)) | ||
| if ((sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer) == 0u) |
There was a problem hiding this comment.
Manual bitwise check replaces isFlag() — verify the semantics are identical.
If SLE::isFlag() does anything beyond (getFieldU32(sfFlags) & flag) != 0 (e.g., reads a cached/normalized field), this substitution silently changes transfer-authorization logic. Confirm isFlag() is a pure bitwise check, or revert to using it.
| if ((sleIssuance->getFieldU32(sfFlags) & lsfMPTCanTransfer) == 0u) | |
| if (!sleIssuance->isFlag(lsfMPTCanTransfer)) |
This comment was marked as resolved.
This comment was marked as resolved.
|
|
||
| bool | ||
| checkLendingProtocolDependencies(PreflightContext const& ctx) | ||
| checkLendingProtocolDependencies(Rules const& rules, STTx const& tx) |
There was a problem hiding this comment.
This PR is no longer just structural change. Could we keep this logic as it was for now?
There was a problem hiding this comment.
It fails levelization if I don't change it.
There was a problem hiding this comment.
You can run the levelization script, and commit the updated output. Of course, if it introduces a new loop (circular dependency) then that's not great and would need to be fixed through other changes.
There was a problem hiding this comment.
Yes, that's what I had to do here
There was a problem hiding this comment.
@Tapanito this PR has shrunk to just moving LendingHelpers over, so we can discuss specifically this issue. The business logic is still identical with this change.
This comment was marked as resolved.
This comment was marked as resolved.
|
This PR has conflicts, please resolve them in order for the PR to be reviewed. |
|
All conflicts have been resolved. Assigned reviewers can now start or resume their review. |
libxrpl/ledger/helpersLendingHelper into libxrpl/ledger/helpers
LendingHelper into libxrpl/ledger/helpersLendingHelpers into libxrpl/ledger/helpers
|
This PR has conflicts, please resolve them in order for the PR to be reviewed. |
High Level Overview of Change
This PR moves all remaining helper files into the
libxrpl/ledger/helpersfolder, after #6453.This is a pure refactor. There is no functionality change.
Context of Change
Prepping for #6620 and downstream PRs
API Impact
N/A