This commit is contained in:
Mayukha Vadari
2026-07-02 17:36:28 -04:00
parent 4afd95e4b3
commit d7623f272f
6 changed files with 48 additions and 45 deletions

View File

@@ -196,6 +196,30 @@ decreaseOwnerCountForObject(
decreaseOwnerCountForObject(view, accountSle, objectSle, count, j);
}
/** Owner-count helpers scoped to the lending protocol. Kept in a nested
* namespace so this broker-specific handling can't be reached accidentally by
* the generic account-reserve code paths (which only ever operate on an
* ACCOUNT_ROOT).
*/
namespace lending {
/** Adjust a LoanBroker's own sfOwnerCount.
*
* A LoanBroker's OwnerCount tracks the number of outstanding loans it holds,
* and is distinct from the broker's pseudo-account's owner count. Unlike an
* account's OwnerCount it carries no reserve and cannot be sponsored, so it is
* adjusted directly rather than through ReserveContext / increaseOwnerCount.
*
* @param view The apply view for making changes
* @param brokerSle The LoanBroker ledger entry
* @param amount Signed amount to add to the loan count (nonzero)
* @param j Journal for logging
*/
void
adjustOwnerCount(ApplyView& view, SLE::ref brokerSle, std::int32_t amount, beast::Journal j);
} // namespace lending
/** Returns IOU issuer transfer fee as Rate. Rate specifies
* the fee as fractions of 1 billion. For example, 1% transfer rate
* is represented as 1,010,000,000.

View File

@@ -58,21 +58,6 @@ canApplyToBrokerCover(
bool
checkLendingProtocolDependencies(Rules const& rules, STTx const& tx);
/** Adjust a LoanBroker's own sfOwnerCount.
*
* A LoanBroker's OwnerCount tracks the number of outstanding loans it holds,
* and is distinct from the broker's pseudo-account's owner count. Unlike an
* account's OwnerCount it carries no reserve and cannot be sponsored, so it is
* adjusted directly here rather than through ReserveContext / increaseOwnerCount.
*
* @param view The apply view for making changes
* @param brokerSle The LoanBroker ledger entry
* @param amount Signed amount to add to the loan count (nonzero)
* @param j Journal for logging
*/
void
adjustOwnerCount(ApplyView& view, SLE::ref brokerSle, std::int32_t amount, beast::Journal j);
static constexpr std::uint32_t kSecondsInYear = 365 * 24 * 60 * 60;
Number

View File

@@ -310,6 +310,28 @@ decreaseOwnerCountForObject(
decreaseOwnerCount(view, ReserveContext::makeFromObject(view, objectSle, accountSle), count, j);
}
namespace lending {
void
adjustOwnerCount(ApplyView& view, SLE::ref brokerSle, std::int32_t amount, beast::Journal j)
{
XRPL_ASSERT(
brokerSle && brokerSle->getType() == ltLOAN_BROKER,
"xrpl::lending::adjustOwnerCount : valid LoanBroker sle");
if (!brokerSle || brokerSle->getType() != ltLOAN_BROKER)
return; // LCOV_EXCL_LINE
XRPL_ASSERT(amount, "xrpl::lending::adjustOwnerCount : nonzero amount input");
// A LoanBroker's OwnerCount tracks its outstanding loans; it carries no
// reserve or sponsor, so adjust the counter directly (reusing the shared
// confine/hook/update logic) without any reserve accounting.
adjustOwnerCountImpl(
view, brokerSle, sfOwnerCount, brokerSle->getAccountID(sfAccount), amount, j);
}
} // namespace lending
XRPAmount
accountReserve(ReadView const& view, SLE::const_ref sle, beast::Journal j, Adjustment adj)
{

View File

@@ -9,7 +9,6 @@
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/LedgerFormats.h>
@@ -26,7 +25,6 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <limits>
#include <string_view>
#include <utility>
@@ -63,32 +61,6 @@ canApplyToBrokerCover(
return tesSUCCESS;
}
void
adjustOwnerCount(ApplyView& view, SLE::ref brokerSle, std::int32_t amount, beast::Journal j)
{
XRPL_ASSERT(
brokerSle && brokerSle->getType() == ltLOAN_BROKER,
"xrpl::adjustOwnerCount : valid LoanBroker sle");
if (!brokerSle)
return; // LCOV_EXCL_LINE
XRPL_ASSERT(amount, "xrpl::adjustOwnerCount : nonzero amount input");
// A LoanBroker's OwnerCount counts its outstanding loans; it carries no
// reserve, so clamp against underflow/overflow (as an account owner count
// would) but skip all reserve/sponsor accounting.
std::uint32_t const current = brokerSle->at(sfOwnerCount);
std::uint32_t adjusted = current + amount;
if (amount > 0 && adjusted < current)
adjusted = std::numeric_limits<std::uint32_t>::max(); // LCOV_EXCL_LINE
else if (amount < 0 && adjusted > current)
adjusted = 0; // LCOV_EXCL_LINE
AccountID const id = brokerSle->getAccountID(sfAccount);
view.adjustOwnerCountHook(id, current, adjusted);
brokerSle->at(sfOwnerCount) = adjusted;
view.update(brokerSle);
}
bool
checkLendingProtocolDependencies(Rules const& rules, STTx const& tx)
{

View File

@@ -110,7 +110,7 @@ LoanDelete::doApply()
// Decrement the LoanBroker's owner count.
// The broker's owner count is solely for the number of outstanding loans,
// and is distinct from the broker's pseudo-account's owner count
adjustOwnerCount(view, brokerSle, -1, j_);
lending::adjustOwnerCount(view, brokerSle, -1, j_);
// If there are no loans left, then any remaining debt must be forgiven,
// because there is no other way to pay it back.

View File

@@ -647,7 +647,7 @@ LoanSet::doApply()
adjustImpreciseNumber(brokerSle->at(sfDebtTotal), newDebtDelta, vaultAsset, vaultScale);
// The broker's owner count is solely for the number of outstanding loans,
// and is distinct from the broker's pseudo-account's owner count
adjustOwnerCount(view, brokerSle, 1, j_);
lending::adjustOwnerCount(view, brokerSle, 1, j_);
loanSequenceProxy += 1;
// The sequence should be extremely unlikely to roll over, but fail if it
// does