Compare commits

..

22 Commits

Author SHA1 Message Date
Ed Hennis
7e881e70ff Merge branch 'develop' into ximinez/lending-shortages 2026-03-12 15:04:59 -04:00
Ed Hennis
56dc85d417 Merge branch 'develop' into ximinez/lending-shortages 2026-03-10 13:39:27 -04:00
Ed Hennis
6e36944ebc Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-shortages
* XRPLF/develop:
  chore: Add custom cmake definitions for gersemi (6491)
  refactor: Update transaction folder structure (6483)
  chore: Apply gersemi changes (6486)
  chore: Use gersemi instead of ancient cmake-format (6486)
  Add Formats and Flags to `server_definitions` (6321)
  fix: Fix docs deployment for pull requests (6482)
  fix: Stop committing generated docs to prevent repo bloat (6474)
2026-03-06 12:33:15 -05:00
Ed Hennis
64a096130f Merge branch 'develop' into ximinez/lending-shortages 2026-03-04 17:12:14 -04:00
Ed Hennis
037f3152a7 Merge branch 'develop' into ximinez/lending-shortages 2026-03-03 18:38:35 -04:00
Ed Hennis
70f535fce2 Merge branch 'develop' into ximinez/lending-shortages 2026-02-24 17:43:47 -04:00
Ed Hennis
368d79515e Merge branch 'develop' into ximinez/lending-shortages 2026-02-20 18:51:11 -04:00
Ed Hennis
142aaa7ae3 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-shortages
* XRPLF/develop:
  ci: [DEPENDABOT] bump actions/checkout from 4.3.0 to 6.0.2 (6397)
  ci: [DEPENDABOT] bump actions/setup-python from 5.6.0 to 6.2.0 (6395)
  ci: [DEPENDABOT] bump tj-actions/changed-files from 46.0.5 to 47.0.4 (6394)
  ci: [DEPENDABOT] bump codecov/codecov-action from 5.4.3 to 5.5.2 (6398)
  ci: Build docs in PRs and in private repos (6400)
  ci: Add dependabot config (6379)
  Fix tautological assertion (6393)
2026-02-20 17:48:27 -05:00
Ed Hennis
39c397a0fd Merge commit '2c1fad1023' into ximinez/lending-shortages
* commit '2c1fad1023':
  chore: Apply clang-format width 100 (6387)
2026-02-20 17:48:23 -05:00
Ed Hennis
6266899acb Update formatting 2026-02-20 17:45:50 -05:00
Ed Hennis
2a8d0ecca7 Merge commit '25cca465538a56cce501477f9e5e2c1c7ea2d84c' into ximinez/lending-shortages
* commit '25cca465538a56cce501477f9e5e2c1c7ea2d84c':
  chore: Set clang-format width to 100 in config file (6387)
2026-02-20 17:39:05 -05:00
Ed Hennis
1fc3f4dedc Merge branch 'develop' into ximinez/lending-shortages 2026-02-19 16:25:25 -05:00
Ed Hennis
6bb09ee163 Merge remote-tracking branch 'XRPLF/develop' into ximinez/lending-shortages
* XRPLF/develop:
  refactor: Modularize app/tx (6228)
  refactor: Decouple app/tx from `Application` and `Config` (6227)
  chore: Update clang-format to 21.1.8 (6352)
  refactor: Modularize `HashRouter`, `Conditions`, and `OrderBookDB` (6226)
  chore: Fix minor issues in comments (6346)
  refactor: Modularize the NetworkOPs interface (6225)
  chore: Fix `gcov` lib coverage build failure on macOS (6350)
  refactor: Modularize RelationalDB (6224)
  refactor: Modularize WalletDB and Manifest (6223)
  fix: Update invariant checks for Permissioned Domains (6134)
  refactor: Change main thread name to `xrpld-main` (6336)
  refactor: Fix spelling issues in tests (6199)
  test: Add file and line location to Env (6276)
  chore: Remove CODEOWNERS (6337)
  perf: Remove unnecessary caches (5439)
  chore: Restore unity builds (6328)
  refactor: Update secp256k1 to 0.7.1 (6331)
  fix: Increment sequence when accepting new manifests (6059)
  fix typo in LendingHelpers unit-test (6215)
2026-02-18 20:13:40 -05:00
Ed Hennis
c679707a39 Merge branch 'develop' into ximinez/lending-shortages 2026-02-04 17:18:38 -04:00
Ed Hennis
f58a0a551b Fix formatting 2026-01-28 19:24:45 -05:00
Ed Hennis
83799db46a Merge branch 'develop' into ximinez/lending-shortages 2026-01-28 19:30:57 -04:00
Ed Hennis
ef97ac2b7a Merge commit '5f638f55536def0d88b970d1018a465a238e55f4' into ximinez/lending-shortages
* commit '5f638f55536def0d88b970d1018a465a238e55f4':
  chore: Set ColumnLimit to 120 in clang-format (6288)
2026-01-28 18:28:42 -05:00
Ed Hennis
3823dbc74c Merge commit '92046785d1fea5f9efe5a770d636792ea6cab78b' into ximinez/lending-shortages
* commit '92046785d1fea5f9efe5a770d636792ea6cab78b':
  test: Fix the `xrpl.net` unit test using async read (6241)
  ci: Upload Conan recipes for develop, release candidates, and releases (6286)
  fix: Stop embedded tests from hanging on ARM by using `atomic_flag` (6248)
  fix:  Remove DEFAULT fields that change to the default in associateAsset (6259) (6273)
  refactor: Update Boost to 1.90 (6280)
  refactor: clean up uses of `std::source_location` (6272)
  ci: Pass missing sanitizers input to actions (6266)
  ci: Properly propagate Conan credentials (6265)
  ci: Explicitly set version when exporting the Conan recipe (6264)
  ci: Use plus instead of hyphen for Conan recipe version suffix (6261)
  chore: Detect uninitialized variables in CMake files (6247)
  ci: Run on-trigger and on-pr when generate-version is modified (6257)
  refactor: Enforce 15-char limit and simplify labels for thread naming (6212)
  docs: Update Ripple Bug Bounty public key (6258)
  ci: Add missing commit hash to Conan recipe version (6256)
  fix: Include `<functional>` header in `Number.h` (6254)
  ci: Upload Conan recipe for merges into develop and commits to release (6235)
  Limit reply size on `TMGetObjectByHash` queries (6110)
  ci: remove 'master' branch as a trigger (6234)
  Improve ledger_entry lookups for fee, amendments, NUNL, and hashes (5644)
2026-01-28 18:27:50 -05:00
Ed Hennis
958a7c12c6 Merge branch 'develop' into ximinez/lending-shortages 2026-01-15 13:16:46 -04:00
Ed Hennis
20d9cb89dd Merge branch 'develop' into ximinez/lending-shortages 2026-01-15 12:06:39 -04:00
Ed Hennis
e105d59b90 Revert "Partially revert aed8e2b166 Fill in payment computation shortages (#5941)"
This reverts commit 95fdbe520f.
2026-01-15 11:03:37 -05:00
Ed Hennis
8cae6b0adc Revert "Remove the shortage code completely"
This reverts commit 165478b929.
2026-01-14 20:43:03 -05:00
6 changed files with 65 additions and 54 deletions

View File

@@ -27,33 +27,6 @@ namespace xrpl {
* communicate the interface required of any invariant checker. Any invariant
* check implementation should implement the public methods documented here.
*
* ## Rules for implementing `finalize`
*
* ### Invariants must run regardless of transaction result
*
* An invariant's `finalize` method MUST perform meaningful checks even when
* the transaction has failed (i.e., `!isTesSuccess(tec)`). The following
* pattern is almost certainly wrong and must never be used:
*
* @code
* // WRONG: skipping all checks on failure defeats the purpose of invariants
* if (!isTesSuccess(tec))
* return true;
* @endcode
*
* The entire purpose of invariants is to detect and prevent the impossible.
* A bug or exploit could cause a failed transaction to mutate ledger state in
* unexpected ways. Invariants are the last line of defense against such
* scenarios.
*
* In general: an invariant that expects a domain-specific state change to
* occur (e.g., a new object being created) should only expect that change
* when the transaction succeeded. A failed VaultCreate must not have created
* a Vault. A failed LoanSet must not have created a Loan.
*
* Also be aware that failed transactions, regardless of type, carry no
* Privileges. Any privilege-gated checks must therefore also be applied to
* failed transactions.
*/
class InvariantChecker_PROTOTYPE
{
@@ -75,11 +48,7 @@ public:
/**
* @brief called after all ledger entries have been visited to determine
* the final status of the check.
*
* This method MUST perform meaningful checks even when `tec` indicates a
* failed transaction. See the class-level documentation for the rules
* governing how failed transactions must be handled.
* the final status of the check
*
* @param tx the transaction being applied
* @param tec the current TER result of the transaction

View File

@@ -107,7 +107,7 @@ CredentialCreate::doApply()
return tecEXPIRED;
}
sleCred->setFieldU32(sfExpiration, *optExp);
sleCred->setFieldU32(sfExpiration, ctx_.tx.getFieldU32(sfExpiration));
}
auto const sleIssuer = view().peek(keylet::account(account_));

View File

@@ -676,7 +676,7 @@ AMMWithdraw::equalWithdrawTokens(
STAmount const& lpTokens,
STAmount const& lpTokensWithdraw,
std::uint16_t tfee,
FreezeHandling freezeHandling,
FreezeHandling freezeHanding,
WithdrawAll withdrawAll,
XRPAmount const& priorBalance,
beast::Journal const& journal)
@@ -697,7 +697,7 @@ AMMWithdraw::equalWithdrawTokens(
lptAMMBalance,
lpTokensWithdraw,
tfee,
freezeHandling,
freezeHanding,
WithdrawAll::Yes,
priorBalance,
journal);
@@ -731,7 +731,7 @@ AMMWithdraw::equalWithdrawTokens(
lptAMMBalance,
tokensAdj,
tfee,
freezeHandling,
freezeHanding,
withdrawAll,
priorBalance,
journal);

View File

@@ -214,10 +214,8 @@ CreateOffer::checkAcceptAsset(
return (flags & tapRETRY) ? TER{terNO_ACCOUNT} : TER{tecNO_ISSUER};
}
// An account cannot create a trustline to itself, so no line can exist
// to be frozen. Additionally, an issuer can always accept its own
// issuance.
if (issue.account == id)
// An account can always accept its own issuance.
return tesSUCCESS;
if ((*issuerAccount)[sfFlags] & lsfRequireAuth)
@@ -244,6 +242,14 @@ CreateOffer::checkAcceptAsset(
}
}
// An account can not create a trustline to itself, so no line can exist
// to be frozen. Additionally, an issuer can always accept its own
// issuance.
if (issue.account == id)
{
return tesSUCCESS;
}
auto const trustLine = view.read(keylet::line(id, issue.account, issue.currency));
if (!trustLine)

View File

@@ -995,18 +995,34 @@ computePaymentComponents(
XRPL_ASSERT_PARTS(
excess >= beast::zero, "xrpl::detail::computePaymentComponents", "excess non-negative");
};
// Helper to reduce deltas when they collectively exceed a limit.
// Order matters: we prefer to reduce interest first (most flexible),
// then management fee, then principal (least flexible).
auto giveTo = [](Number& component, Number& shortage, Number const& maximum) {
if (shortage > beast::zero)
{
// Put as much of the shortage as we can into the provided part
// and the total
auto part = std::min(maximum - component, shortage);
component += part;
shortage -= part;
}
// If the shortage goes negative, we put too much, which should be
// impossible
XRPL_ASSERT_PARTS(
shortage >= beast::zero,
"ripple::detail::computePaymentComponents",
"excess non-negative");
};
auto addressExcess = [&takeFrom](LoanStateDeltas& deltas, Number& excess) {
// This order is based on where errors are the least problematic
takeFrom(deltas.interest, excess);
takeFrom(deltas.managementFee, excess);
takeFrom(deltas.principal, excess);
};
// Check if deltas exceed the total outstanding value. This should never
// happen due to earlier caps, but handle it defensively.
auto addressShortage =
[&giveTo](LoanStateDeltas& deltas, Number& shortage, LoanState const& current) {
giveTo(deltas.interest, shortage, current.interestDue);
giveTo(deltas.managementFee, shortage, current.managementFeeDue);
giveTo(deltas.principal, shortage, current.principalOutstanding);
};
Number totalOverpayment = deltas.total() - currentLedgerState.valueOutstanding;
if (totalOverpayment > beast::zero)
@@ -1034,12 +1050,33 @@ computePaymentComponents(
addressExcess(deltas, excess);
shortage = -excess;
}
else if (shortage > beast::zero && totalOverpayment < beast::zero)
{
// If there's a shortage, and there's room in the loan itself, we can
// top up the parts to make the payment correct.
shortage = std::min(-totalOverpayment, shortage);
addressShortage(deltas, shortage, currentLedgerState);
}
// At this point, shortage >= 0 means we're paying less than the full
// periodic payment (due to rounding or component caps).
// shortage < 0 would mean we're trying to pay more than allowed (bug).
// The shortage should never be negative, which indicates that the parts are
// trying to take more than the whole payment. The shortage should not be
// positive, either, which indicates that we're not going to take the whole
// payment amount. Only the last payment should be allowed to have a
// shortage, and that's handled in a special case above.
XRPL_ASSERT_PARTS(
shortage >= beast::zero, "xrpl::detail::computePaymentComponents", "no shortage or excess");
shortage == beast::zero,
"ripple::detail::computePaymentComponents",
"no shortage or excess");
#if LOANCOMPLETE
/*
// This used to be part of the above assert. It will eventually be removed
// if proved accurate
||
(shortage > beast::zero &&
((asset.integral() && shortage < 3) ||
(scale - shortage.exponent() > 14)))
*/
#endif
// Final validation that all components are valid
XRPL_ASSERT_PARTS(

View File

@@ -2492,11 +2492,10 @@ protected:
state.paymentRemaining,
broker.params.managementFeeRate);
BEAST_EXPECTS(
paymentComponents.specialCase == detail::PaymentSpecialCase::final ||
paymentComponents.trackedValueDelta <= roundedPeriodicPayment,
"Delta: " + to_string(paymentComponents.trackedValueDelta) +
", periodic payment: " + to_string(roundedPeriodicPayment));
BEAST_EXPECT(
paymentComponents.trackedValueDelta == roundedPeriodicPayment ||
(paymentComponents.specialCase == detail::PaymentSpecialCase::final &&
paymentComponents.trackedValueDelta < roundedPeriodicPayment));
xrpl::LoanState const nextTrueState = computeTheoreticalLoanState(
state.periodicPayment,