From cecea828358e5e86676558f0ff9a4461a4c19aa8 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 2 Jul 2026 13:22:04 -0400 Subject: [PATCH] refactor: Use ApplyViewContext everywhere instead of ApplyView+STTx (#7618) --- include/xrpl/ledger/ApplyView.h | 7 ++ include/xrpl/ledger/View.h | 3 +- .../xrpl/ledger/helpers/AccountRootHelpers.h | 4 +- include/xrpl/ledger/helpers/EscrowHelpers.h | 48 ++++++------- include/xrpl/ledger/helpers/MPTokenHelpers.h | 13 ++-- .../xrpl/ledger/helpers/RippleStateHelpers.h | 6 +- include/xrpl/ledger/helpers/SponsorHelpers.h | 6 +- include/xrpl/ledger/helpers/TokenHelpers.h | 7 +- include/xrpl/tx/ApplyContext.h | 9 +++ .../transactors/token/MPTokenIssuanceCreate.h | 2 +- src/libxrpl/ledger/View.cpp | 16 ++--- .../ledger/helpers/AccountRootHelpers.cpp | 11 ++- src/libxrpl/ledger/helpers/MPTokenHelpers.cpp | 69 +++++++++---------- .../ledger/helpers/RippleStateHelpers.cpp | 44 ++++++------ src/libxrpl/ledger/helpers/TokenHelpers.cpp | 18 ++--- .../tx/transactors/Sponsor/SponsorshipSet.cpp | 8 +-- .../Sponsor/SponsorshipTransfer.cpp | 18 ++--- .../tx/transactors/account/SignerListSet.cpp | 5 +- .../tx/transactors/check/CheckCash.cpp | 7 +- .../tx/transactors/check/CheckCreate.cpp | 5 +- .../tx/transactors/delegate/DelegateSet.cpp | 5 +- .../tx/transactors/escrow/EscrowCancel.cpp | 3 +- .../tx/transactors/escrow/EscrowCreate.cpp | 7 +- .../tx/transactors/escrow/EscrowFinish.cpp | 3 +- .../lending/LoanBrokerCoverWithdraw.cpp | 9 ++- .../transactors/lending/LoanBrokerDelete.cpp | 2 +- .../tx/transactors/lending/LoanBrokerSet.cpp | 4 +- .../tx/transactors/lending/LoanPay.cpp | 6 +- .../tx/transactors/lending/LoanSet.cpp | 9 ++- .../tx/transactors/payment/DepositPreauth.cpp | 19 +++-- .../payment_channel/PaymentChannelCreate.cpp | 12 ++-- .../payment_channel/PaymentChannelFund.cpp | 8 +-- .../tx/transactors/token/MPTokenAuthorize.cpp | 3 +- .../token/MPTokenIssuanceCreate.cpp | 20 +++--- src/libxrpl/tx/transactors/token/TrustSet.cpp | 19 ++--- .../tx/transactors/vault/VaultClawback.cpp | 3 +- .../tx/transactors/vault/VaultCreate.cpp | 18 +++-- .../tx/transactors/vault/VaultDelete.cpp | 5 +- .../tx/transactors/vault/VaultDeposit.cpp | 9 ++- .../tx/transactors/vault/VaultWithdraw.cpp | 5 +- src/test/app/Vault_test.cpp | 4 +- 41 files changed, 244 insertions(+), 235 deletions(-) diff --git a/include/xrpl/ledger/ApplyView.h b/include/xrpl/ledger/ApplyView.h index 3bf5d479d1..4ee10dfd01 100644 --- a/include/xrpl/ledger/ApplyView.h +++ b/include/xrpl/ledger/ApplyView.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -411,6 +412,12 @@ public: emptyDirDelete(Keylet const& directory); }; +struct ApplyViewContext +{ + ApplyView& view; + STTx const& tx; +}; + namespace directory { /** Helper functions for managing low-level directory operations. These are not part of the ApplyView interface. diff --git a/include/xrpl/ledger/View.h b/include/xrpl/ledger/View.h index c89764df1d..7fad61d407 100644 --- a/include/xrpl/ledger/View.h +++ b/include/xrpl/ledger/View.h @@ -210,8 +210,7 @@ canWithdraw(ReadView const& view, STTx const& tx); [[nodiscard]] TER doWithdraw( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& senderAcct, AccountID const& dstAcct, AccountID const& sourceAcct, diff --git a/include/xrpl/ledger/helpers/AccountRootHelpers.h b/include/xrpl/ledger/helpers/AccountRootHelpers.h index 73d50d09ab..41361a7e39 100644 --- a/include/xrpl/ledger/helpers/AccountRootHelpers.h +++ b/include/xrpl/ledger/helpers/AccountRootHelpers.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -99,8 +98,7 @@ accountReserve(ReadView const& view, AccountID const& id, beast::Journal j, Adju */ [[nodiscard]] TER checkInsufficientReserve( - ApplyView const& view, - STTx const& tx, + ApplyViewContext ctx, SLE::const_ref accSle, STAmount const& accBalance, SLE::const_ref sponsorSle, diff --git a/include/xrpl/ledger/helpers/EscrowHelpers.h b/include/xrpl/ledger/helpers/EscrowHelpers.h index 9ed8272b10..6a7d182dce 100644 --- a/include/xrpl/ledger/helpers/EscrowHelpers.h +++ b/include/xrpl/ledger/helpers/EscrowHelpers.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -29,8 +28,7 @@ namespace xrpl { template TER escrowUnlockApplyHelper( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, Rate lockedRate, SLE::ref sleDest, STAmount const& xrpBalance, @@ -44,8 +42,7 @@ escrowUnlockApplyHelper( template <> inline TER escrowUnlockApplyHelper( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, Rate lockedRate, SLE::ref sleDest, STAmount const& xrpBalance, @@ -68,15 +65,15 @@ escrowUnlockApplyHelper( if (receiverIssuer) return tesSUCCESS; - if (!view.exists(trustLineKey) && createAsset) + if (!ctx.view.exists(trustLineKey) && createAsset) { // Can the account cover the trust line's reserve? - auto const sponsorSle = getTxReserveSponsor(view, tx); + auto const sponsorSle = getTxReserveSponsor(ctx); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE if (auto const ret = checkInsufficientReserve( - view, tx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal); + ctx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal); !isTesSuccess(ret)) { JLOG(journal.trace()) << "Trust line does not exist. " @@ -90,7 +87,7 @@ escrowUnlockApplyHelper( initialBalance.get().account = noAccount(); if (TER const ter = trustCreate( - view, // payment sandbox + ctx.view, // payment sandbox recvLow, // is dest low? issuer, // source receiver, // destination @@ -111,13 +108,13 @@ escrowUnlockApplyHelper( return ter; // LCOV_EXCL_LINE } - view.update(sleDest); + ctx.view.update(sleDest); } - if (!view.exists(trustLineKey) && !receiverIssuer) + if (!ctx.view.exists(trustLineKey) && !receiverIssuer) return tecNO_LINE; - auto const xferRate = transferRate(view, amount); + auto const xferRate = transferRate(ctx.view, amount); // update if issuer rate is less than locked rate if (xferRate < lockedRate) lockedRate = xferRate; @@ -145,7 +142,7 @@ escrowUnlockApplyHelper( // of the funds if (!createAsset) { - auto const sleRippleState = view.peek(trustLineKey); + auto const sleRippleState = ctx.view.peek(trustLineKey); if (!sleRippleState) return tecINTERNAL; // LCOV_EXCL_LINE @@ -171,7 +168,7 @@ escrowUnlockApplyHelper( // if destination is not the issuer then transfer funds if (!receiverIssuer) { - auto const ter = directSendNoFee(view, issuer, receiver, finalAmt, true, journal); + auto const ter = directSendNoFee(ctx.view, issuer, receiver, finalAmt, true, journal); if (!isTesSuccess(ter)) return ter; // LCOV_EXCL_LINE } @@ -181,8 +178,7 @@ escrowUnlockApplyHelper( template <> inline TER escrowUnlockApplyHelper( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, Rate lockedRate, SLE::ref sleDest, STAmount const& xrpBalance, @@ -199,33 +195,33 @@ escrowUnlockApplyHelper( auto const mptID = amount.get().getMptID(); auto const issuanceKey = keylet::mptokenIssuance(mptID); auto const mptKeylet = keylet::mptoken(issuanceKey.key, receiver); - if (!view.exists(mptKeylet) && createAsset && !receiverIssuer) + if (!ctx.view.exists(mptKeylet) && createAsset && !receiverIssuer) { - auto const sponsorSle = getTxReserveSponsor(view, tx); + auto const sponsorSle = getTxReserveSponsor(ctx); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE if (auto const ret = checkInsufficientReserve( - view, tx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal); + ctx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal); !isTesSuccess(ret)) return ret; - if (auto const ter = createMPToken(view, mptID, receiver, *sponsorSle, 0); + if (auto const ter = createMPToken(ctx.view, mptID, receiver, *sponsorSle, 0); !isTesSuccess(ter)) { return ter; // LCOV_EXCL_LINE } // update owner count. - increaseOwnerCount(view, sleDest, *sponsorSle, 1, journal); - auto mptSle = view.peek(mptKeylet); + increaseOwnerCount(ctx.view, sleDest, *sponsorSle, 1, journal); + auto mptSle = ctx.view.peek(mptKeylet); addSponsorToLedgerEntry(mptSle, *sponsorSle); } - if (!view.exists(mptKeylet) && !receiverIssuer) + if (!ctx.view.exists(mptKeylet) && !receiverIssuer) return tecNO_PERMISSION; - auto const xferRate = transferRate(view, amount); + auto const xferRate = transferRate(ctx.view, amount); // update if issuer rate is less than locked rate if (xferRate < lockedRate) lockedRate = xferRate; @@ -248,11 +244,11 @@ escrowUnlockApplyHelper( finalAmt = amount.value() - xferFee; } return unlockEscrowMPT( - view, + ctx.view, sender, receiver, finalAmt, - view.rules().enabled(fixTokenEscrowV1) ? amount : finalAmt, + ctx.view.rules().enabled(fixTokenEscrowV1) ? amount : finalAmt, journal); } diff --git a/include/xrpl/ledger/helpers/MPTokenHelpers.h b/include/xrpl/ledger/helpers/MPTokenHelpers.h index 094656332b..8a2a4a5b84 100644 --- a/include/xrpl/ledger/helpers/MPTokenHelpers.h +++ b/include/xrpl/ledger/helpers/MPTokenHelpers.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -87,8 +86,7 @@ canAddHolding(ReadView const& view, MPTIssue const& mptIssue); [[nodiscard]] TER authorizeMPToken( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, XRPAmount const& priorBalance, MPTID const& mptIssuanceID, AccountID const& account, @@ -119,8 +117,7 @@ requireAuth( */ [[nodiscard]] TER enforceMPTokenAuthorization( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, MPTID const& mptIssuanceID, AccountID const& account, XRPAmount const& priorBalance, @@ -206,8 +203,7 @@ canMPTTradeAndTransfer( [[nodiscard]] TER addEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, XRPAmount priorBalance, MPTIssue const& mptIssue, @@ -215,8 +211,7 @@ addEmptyHolding( [[nodiscard]] TER removeEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, MPTIssue const& mptIssue, beast::Journal journal); diff --git a/include/xrpl/ledger/helpers/RippleStateHelpers.h b/include/xrpl/ledger/helpers/RippleStateHelpers.h index ec92619aad..322bbcafb5 100644 --- a/include/xrpl/ledger/helpers/RippleStateHelpers.h +++ b/include/xrpl/ledger/helpers/RippleStateHelpers.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -237,8 +236,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc /// canAddHolding() in preflight with the same View and Asset [[nodiscard]] TER addEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, XRPAmount priorBalance, Issue const& issue, @@ -246,7 +244,7 @@ addEmptyHolding( [[nodiscard]] TER removeEmptyHolding( - ApplyView& view, + ApplyViewContext ctx, AccountID const& accountID, Issue const& issue, beast::Journal journal); diff --git a/include/xrpl/ledger/helpers/SponsorHelpers.h b/include/xrpl/ledger/helpers/SponsorHelpers.h index 27e35498a4..0a1fc0691a 100644 --- a/include/xrpl/ledger/helpers/SponsorHelpers.h +++ b/include/xrpl/ledger/helpers/SponsorHelpers.h @@ -42,12 +42,12 @@ getTxReserveSponsorAccountID(STTx const& tx) } inline std::expected -getTxReserveSponsor(ApplyView& view, STTx const& tx) +getTxReserveSponsor(ApplyViewContext ctx) { - auto const sponsorID = getTxReserveSponsorAccountID(tx); + auto const sponsorID = getTxReserveSponsorAccountID(ctx.tx); if (sponsorID) { - auto sle = view.peek(keylet::account(*sponsorID)); + auto sle = ctx.view.peek(keylet::account(*sponsorID)); // already checked in Transactor::checkSponsor if (!sle) diff --git a/include/xrpl/ledger/helpers/TokenHelpers.h b/include/xrpl/ledger/helpers/TokenHelpers.h index b41fa5b5d4..6820b61f5f 100644 --- a/include/xrpl/ledger/helpers/TokenHelpers.h +++ b/include/xrpl/ledger/helpers/TokenHelpers.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -304,8 +303,7 @@ canAddHolding(ReadView const& view, Asset const& asset); [[nodiscard]] TER addEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, XRPAmount priorBalance, Asset const& asset, @@ -313,8 +311,7 @@ addEmptyHolding( [[nodiscard]] TER removeEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, Asset const& asset, beast::Journal journal); diff --git a/include/xrpl/tx/ApplyContext.h b/include/xrpl/tx/ApplyContext.h index ca778387cd..f64957dd35 100644 --- a/include/xrpl/tx/ApplyContext.h +++ b/include/xrpl/tx/ApplyContext.h @@ -127,6 +127,15 @@ public: TER checkInvariants(TER const result, XRPAmount const fee); + ApplyViewContext + getApplyViewContext() + { + XRPL_ASSERT( + view_.has_value(), + "xrpl::ApplyContext::getApplyViewContext : view_ emplaced in constructor"); + return {.view = *view_, .tx = tx}; + } + private: static TER failInvariantCheck(TER const result); diff --git a/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h b/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h index 2fc045c477..5d35f65f44 100644 --- a/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h +++ b/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h @@ -76,7 +76,7 @@ public: beast::Journal const& j) override; static std::expected - create(ApplyView& view, STTx const& tx, beast::Journal journal, MPTCreateArgs const& args); + create(ApplyViewContext ctx, beast::Journal journal, MPTCreateArgs const& args); }; } // namespace xrpl diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index f19b8b9e1f..7a624677df 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -432,8 +432,7 @@ canWithdraw(ReadView const& view, STTx const& tx) TER doWithdraw( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& senderAcct, AccountID const& dstAcct, AccountID const& sourceAcct, @@ -444,20 +443,20 @@ doWithdraw( // Create trust line or MPToken for the receiving account if (dstAcct == senderAcct) { - if (auto const ter = addEmptyHolding(view, tx, senderAcct, priorBalance, amount.asset(), j); + if (auto const ter = addEmptyHolding(ctx, senderAcct, priorBalance, amount.asset(), j); !isTesSuccess(ter) && ter != tecDUPLICATE) return ter; } else { - auto dstSle = view.read(keylet::account(dstAcct)); - if (auto err = verifyDepositPreauth(tx, view, senderAcct, dstAcct, dstSle, j)) + auto dstSle = ctx.view.read(keylet::account(dstAcct)); + if (auto err = verifyDepositPreauth(ctx.tx, ctx.view, senderAcct, dstAcct, dstSle, j)) return err; } // Sanity check if (accountHolds( - view, + ctx.view, sourceAcct, amount.asset(), FreezeHandling::IgnoreFreeze, @@ -470,13 +469,14 @@ doWithdraw( // LCOV_EXCL_STOP } - auto const sponsorSle = getTxReserveSponsor(view, tx); + auto const sponsorSle = getTxReserveSponsor(ctx); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE // Move the funds directly from the broker's pseudo-account to the // dstAcct - return accountSend(view, sourceAcct, dstAcct, amount, j, *sponsorSle, WaiveTransferFee::Yes); + return accountSend( + ctx.view, sourceAcct, dstAcct, amount, j, *sponsorSle, WaiveTransferFee::Yes); } TER diff --git a/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp index e7aaf94547..d8e34622db 100644 --- a/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp +++ b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp @@ -330,8 +330,7 @@ accountReserve(ReadView const& view, SLE::const_ref sle, beast::Journal j, Adjus TER checkInsufficientReserve( - ApplyView const& view, - STTx const& tx, + ApplyViewContext ctx, SLE::const_ref accSle, STAmount const& accBalance, SLE::const_ref sponsorSle, @@ -340,14 +339,14 @@ checkInsufficientReserve( { if (sponsorSle) { - auto const sle = view.read( + auto const sle = ctx.view.read( keylet::sponsorship( sponsorSle->getAccountID(sfAccount), accSle->getAccountID(sfAccount))); // A reserve-sponsored tx must carry a sponsor signature // (cosigning path) and/or have a pre-existing sponsorship SLE // (prefunded path). Absence of both is an internal invariant break. - if (isReserveSponsored(tx) && !sle && !tx.isFieldPresent(sfSponsorSignature)) + if (isReserveSponsored(ctx.tx) && !sle && !ctx.tx.isFieldPresent(sfSponsorSignature)) return tecINTERNAL; // LCOV_EXCL_LINE if (sle) @@ -359,14 +358,14 @@ checkInsufficientReserve( } auto const sponsorBalance = sponsorSle->getFieldAmount(sfBalance); - STAmount const sponsorReserve = accountReserve(view, sponsorSle, j, adj); + STAmount const sponsorReserve = accountReserve(ctx.view, sponsorSle, j, adj); if (sponsorBalance < sponsorReserve) return tecINSUFFICIENT_RESERVE; } else { - STAmount const reserve = accountReserve(view, accSle, j, adj); + STAmount const reserve = accountReserve(ctx.view, accSle, j, adj); if (accBalance < reserve) return tecINSUFFICIENT_RESERVE; } diff --git a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp index f930a7765d..f87171a3b7 100644 --- a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -127,31 +126,29 @@ canAddHolding(ReadView const& view, MPTIssue const& mptIssue) [[nodiscard]] TER addEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, XRPAmount priorBalance, MPTIssue const& mptIssue, beast::Journal journal) { auto const& mptID = mptIssue.getMptID(); - auto const mpt = view.peek(keylet::mptokenIssuance(mptID)); + auto const mpt = ctx.view.peek(keylet::mptokenIssuance(mptID)); if (!mpt) return tefINTERNAL; // LCOV_EXCL_LINE if (mpt->isFlag(lsfMPTLocked)) return tefINTERNAL; // LCOV_EXCL_LINE - if (view.peek(keylet::mptoken(mptID, accountID))) + if (ctx.view.peek(keylet::mptoken(mptID, accountID))) return tecDUPLICATE; if (accountID == mptIssue.getIssuer()) return tesSUCCESS; - return authorizeMPToken(view, tx, priorBalance, mptID, accountID, journal, 0, std::nullopt); + return authorizeMPToken(ctx, priorBalance, mptID, accountID, journal, 0, std::nullopt); } [[nodiscard]] TER authorizeMPToken( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, XRPAmount const& priorBalance, MPTID const& mptIssuanceID, AccountID const& account, @@ -159,7 +156,7 @@ authorizeMPToken( std::uint32_t flags, std::optional holderID) { - auto const sleAcct = view.peek(keylet::account(account)); + auto const sleAcct = ctx.view.peek(keylet::account(account)); if (!sleAcct) return tecINTERNAL; // LCOV_EXCL_LINE @@ -174,19 +171,19 @@ authorizeMPToken( if ((flags & tfMPTUnauthorize) != 0u) { auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); - auto const sleMpt = view.peek(mptokenKey); + auto const sleMpt = ctx.view.peek(mptokenKey); if (!sleMpt || (*sleMpt)[sfMPTAmount] != 0 || - (view.rules().enabled(fixCleanup3_1_3) && + (ctx.view.rules().enabled(fixCleanup3_1_3) && (*sleMpt)[~sfLockedAmount].valueOr(0) != 0)) return tecINTERNAL; // LCOV_EXCL_LINE - if (!view.dirRemove( + if (!ctx.view.dirRemove( keylet::ownerDir(account), (*sleMpt)[sfOwnerNode], sleMpt->key(), false)) return tecINTERNAL; // LCOV_EXCL_LINE - decreaseOwnerCountForObject(view, sleAcct, sleMpt, 1, journal); + decreaseOwnerCountForObject(ctx.view, sleAcct, sleMpt, 1, journal); - view.erase(sleMpt); + ctx.view.erase(sleMpt); return tesSUCCESS; } @@ -195,9 +192,9 @@ authorizeMPToken( // - create the MPToken object for the holder SLE::pointer sponsorSle; - if (account == tx[sfAccount]) + if (account == ctx.tx[sfAccount]) { - auto sle = getTxReserveSponsor(view, tx); + auto sle = getTxReserveSponsor(ctx); if (!sle) return sle.error(); // LCOV_EXCL_LINE sponsorSle = std::move(*sle); @@ -214,40 +211,40 @@ authorizeMPToken( if (sponsorSle || ownerCount(sleAcct, journal) >= 2) { if (auto const ret = checkInsufficientReserve( - view, tx, sleAcct, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal); + ctx, sleAcct, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal); !isTesSuccess(ret)) return ret; } // Defensive check before we attempt to create MPToken for the issuer - auto const mpt = view.read(keylet::mptokenIssuance(mptIssuanceID)); + auto const mpt = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID)); if (!mpt || mpt->getAccountID(sfIssuer) == account) { // LCOV_EXCL_START UNREACHABLE("xrpl::authorizeMPToken : invalid issuance or issuers token"); - if (view.rules().enabled(featureLendingProtocol)) + if (ctx.view.rules().enabled(featureLendingProtocol)) return tecINTERNAL; // LCOV_EXCL_STOP } auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); auto mptoken = std::make_shared(mptokenKey); - if (auto ter = dirLink(view, account, mptoken)) + if (auto ter = dirLink(ctx.view, account, mptoken)) return ter; // LCOV_EXCL_LINE (*mptoken)[sfAccount] = account; (*mptoken)[sfMPTokenIssuanceID] = mptIssuanceID; (*mptoken)[sfFlags] = 0; - view.insert(mptoken); + ctx.view.insert(mptoken); // Update owner count. - increaseOwnerCount(view, sleAcct, sponsorSle, 1, journal); + increaseOwnerCount(ctx.view, sleAcct, sponsorSle, 1, journal); addSponsorToLedgerEntry(mptoken, sponsorSle); return tesSUCCESS; } - auto const sleMptIssuance = view.read(keylet::mptokenIssuance(mptIssuanceID)); + auto const sleMptIssuance = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID)); if (!sleMptIssuance) return tecINTERNAL; // LCOV_EXCL_LINE @@ -257,7 +254,7 @@ authorizeMPToken( if (account != (*sleMptIssuance)[sfIssuer]) return tecINTERNAL; // LCOV_EXCL_LINE - auto const sleMpt = view.peek(keylet::mptoken(mptIssuanceID, *holderID)); + auto const sleMpt = ctx.view.peek(keylet::mptoken(mptIssuanceID, *holderID)); if (!sleMpt) return tecINTERNAL; // LCOV_EXCL_LINE @@ -280,14 +277,13 @@ authorizeMPToken( if (flagsIn != flagsOut) sleMpt->setFieldU32(sfFlags, flagsOut); - view.update(sleMpt); + ctx.view.update(sleMpt); return tesSUCCESS; } [[nodiscard]] TER removeEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, MPTIssue const& mptIssue, beast::Journal journal) @@ -297,7 +293,7 @@ removeEmptyHolding( // a token does exist, it will get deleted. If not, return success. bool const accountIsIssuer = accountID == mptIssue.getIssuer(); auto const& mptID = mptIssue.getMptID(); - auto const mptoken = view.peek(keylet::mptoken(mptID, accountID)); + auto const mptoken = ctx.view.peek(keylet::mptoken(mptID, accountID)); if (!mptoken) return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND; // Unlike a trust line, if the account is the issuer, and the token has a @@ -305,7 +301,7 @@ removeEmptyHolding( // accounting out of balance, so fail. Since this should be impossible // anyway, I'm not going to put any effort into it. if (mptoken->at(sfMPTAmount) != 0 || - (view.rules().enabled(fixCleanup3_1_3) && (*mptoken)[~sfLockedAmount].valueOr(0) != 0)) + (ctx.view.rules().enabled(fixCleanup3_1_3) && (*mptoken)[~sfLockedAmount].valueOr(0) != 0)) return tecHAS_OBLIGATIONS; // Don't delete if the token still has confidential balances @@ -318,8 +314,7 @@ removeEmptyHolding( } return authorizeMPToken( - view, - tx, + ctx, {}, // priorBalance mptID, accountID, @@ -438,14 +433,13 @@ requireAuth( [[nodiscard]] TER enforceMPTokenAuthorization( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, MPTID const& mptIssuanceID, AccountID const& account, XRPAmount const& priorBalance, // for MPToken authorization beast::Journal j) { - auto const sleIssuance = view.read(keylet::mptokenIssuance(mptIssuanceID)); + auto const sleIssuance = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID)); if (!sleIssuance) return tefINTERNAL; // LCOV_EXCL_LINE @@ -457,7 +451,7 @@ enforceMPTokenAuthorization( return tefINTERNAL; // LCOV_EXCL_LINE auto const keylet = keylet::mptoken(mptIssuanceID, account); - auto const sleToken = view.read(keylet); // NOTE: might be null + auto const sleToken = ctx.view.read(keylet); // NOTE: might be null auto const maybeDomainID = sleIssuance->at(~sfDomainID); bool expired = false; bool const authorizedByDomain = [&]() -> bool { @@ -465,7 +459,7 @@ enforceMPTokenAuthorization( if (!maybeDomainID.has_value()) return false; // LCOV_EXCL_LINE - auto const ter = verifyValidDomain(view, account, *maybeDomainID, j); + auto const ter = verifyValidDomain(ctx.view, account, *maybeDomainID, j); if (isTesSuccess(ter)) return true; if (ter == tecEXPIRED) @@ -520,8 +514,7 @@ enforceMPTokenAuthorization( maybeDomainID.has_value() && sleToken == nullptr, "xrpl::enforceMPTokenAuthorization : new MPToken for domain"); if (auto const err = authorizeMPToken( - view, - tx, + ctx, priorBalance, // priorBalance mptIssuanceID, // mptIssuanceID account, // account diff --git a/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp index ac9bf4ebcf..d6e1d499a4 100644 --- a/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp +++ b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -634,8 +633,7 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc TER addEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, XRPAmount priorBalance, Issue const& issue, @@ -647,29 +645,29 @@ addEmptyHolding( auto const& issuerId = issue.getIssuer(); auto const& currency = issue.currency; - if (isGlobalFrozen(view, issuerId)) + if (isGlobalFrozen(ctx.view, issuerId)) return tecFROZEN; // LCOV_EXCL_LINE auto const& srcId = issuerId; auto const& dstId = accountID; auto const high = srcId > dstId; auto const index = keylet::trustLine(srcId, dstId, currency); - auto const sleSrc = view.peek(keylet::account(srcId)); - auto const sleDst = view.peek(keylet::account(dstId)); + auto const sleSrc = ctx.view.peek(keylet::account(srcId)); + auto const sleDst = ctx.view.peek(keylet::account(dstId)); if (!sleDst || !sleSrc) return tefINTERNAL; // LCOV_EXCL_LINE if (!sleSrc->isFlag(lsfDefaultRipple)) return tecINTERNAL; // LCOV_EXCL_LINE // If the line already exists, don't create it again. - if (view.read(index)) + if (ctx.view.read(index)) return tecDUPLICATE; SLE::pointer sponsorSle; // A reserve sponsor only covers tx.Account's own objects. - if (!isPseudoAccount(sleDst) && accountID == tx[sfAccount]) + if (!isPseudoAccount(sleDst) && accountID == ctx.tx[sfAccount]) { - auto sle = getTxReserveSponsor(view, tx); + auto sle = getTxReserveSponsor(ctx); if (!sle) return sle.error(); // LCOV_EXCL_LINE sponsorSle = std::move(*sle); @@ -677,12 +675,12 @@ addEmptyHolding( // Can the account cover the trust line reserve ? if (auto const ret = checkInsufficientReserve( - view, tx, sleDst, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal); + ctx, sleDst, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal); !isTesSuccess(ret)) return tecNO_LINE_INSUF_RESERVE; return trustCreate( - view, + ctx.view, high, srcId, dstId, @@ -702,14 +700,14 @@ addEmptyHolding( TER removeEmptyHolding( - ApplyView& view, + ApplyViewContext ctx, AccountID const& accountID, Issue const& issue, beast::Journal journal) { if (issue.native()) { - auto const sle = view.read(keylet::account(accountID)); + auto const sle = ctx.view.read(keylet::account(accountID)); if (!sle) return tecINTERNAL; // LCOV_EXCL_LINE @@ -724,7 +722,7 @@ removeEmptyHolding( // If the account is the issuer, then no line should exist. Check anyway. // If a line does exist, it will get deleted. If not, return success. bool const accountIsIssuer = accountID == issue.account; - auto const line = view.peek(keylet::trustLine(accountID, issue)); + auto const line = ctx.view.peek(keylet::trustLine(accountID, issue)); if (!line) return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND; if (!accountIsIssuer && line->at(sfBalance)->iou() != beast::kZero) @@ -734,13 +732,13 @@ removeEmptyHolding( if (line->isFlag(lsfLowReserve)) { // Clear reserve for low account. - auto sleLowAccount = view.peek(keylet::account(line->at(sfLowLimit)->getIssuer())); + auto sleLowAccount = ctx.view.peek(keylet::account(line->at(sfLowLimit)->getIssuer())); if (!sleLowAccount) return tecINTERNAL; // LCOV_EXCL_LINE - auto const currentLowSponsor = getLedgerEntryReserveSponsor(view, line, sfLowSponsor); + auto const currentLowSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfLowSponsor); - decreaseOwnerCount(view, sleLowAccount, currentLowSponsor, 1, journal); + decreaseOwnerCount(ctx.view, sleLowAccount, currentLowSponsor, 1, journal); // It's not really necessary to clear the reserve flag, since the line // is about to be deleted, but this will make the metadata reflect an // accurate state at the time of deletion. @@ -751,13 +749,13 @@ removeEmptyHolding( if (line->isFlag(lsfHighReserve)) { // Clear reserve for high account. - auto sleHighAccount = view.peek(keylet::account(line->at(sfHighLimit)->getIssuer())); + auto sleHighAccount = ctx.view.peek(keylet::account(line->at(sfHighLimit)->getIssuer())); if (!sleHighAccount) return tecINTERNAL; // LCOV_EXCL_LINE - auto const currentHighSponsor = getLedgerEntryReserveSponsor(view, line, sfHighSponsor); + auto const currentHighSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfHighSponsor); - decreaseOwnerCount(view, sleHighAccount, currentHighSponsor, 1, journal); + decreaseOwnerCount(ctx.view, sleHighAccount, currentHighSponsor, 1, journal); // It's not really necessary to clear the reserve flag, since the line // is about to be deleted, but this will make the metadata reflect an // accurate state at the time of deletion. @@ -766,7 +764,11 @@ removeEmptyHolding( } return trustDelete( - view, line, line->at(sfLowLimit)->getIssuer(), line->at(sfHighLimit)->getIssuer(), journal); + ctx.view, + line, + line->at(sfLowLimit)->getIssuer(), + line->at(sfHighLimit)->getIssuer(), + journal); } TER diff --git a/src/libxrpl/ledger/helpers/TokenHelpers.cpp b/src/libxrpl/ledger/helpers/TokenHelpers.cpp index d0c8ce9fbd..cbdbd13b30 100644 --- a/src/libxrpl/ledger/helpers/TokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/TokenHelpers.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -573,8 +572,7 @@ canAddHolding(ReadView const& view, Asset const& asset) TER addEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, XRPAmount priorBalance, Asset const& asset, @@ -582,29 +580,21 @@ addEmptyHolding( { return std::visit( [&](TIss const& issue) -> TER { - return addEmptyHolding(view, tx, accountID, priorBalance, issue, journal); + return addEmptyHolding(ctx, accountID, priorBalance, issue, journal); }, asset.value()); } TER removeEmptyHolding( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, AccountID const& accountID, Asset const& asset, beast::Journal journal) { return std::visit( [&](TIss const& issue) -> TER { - if constexpr (std::is_same_v) - { - return removeEmptyHolding(view, accountID, issue, journal); - } - else - { - return removeEmptyHolding(view, tx, accountID, issue, journal); - } + return removeEmptyHolding(ctx, accountID, issue, journal); }, asset.value()); } diff --git a/src/libxrpl/tx/transactors/Sponsor/SponsorshipSet.cpp b/src/libxrpl/tx/transactors/Sponsor/SponsorshipSet.cpp index d5eb860677..fa29b45902 100644 --- a/src/libxrpl/tx/transactors/Sponsor/SponsorshipSet.cpp +++ b/src/libxrpl/tx/transactors/Sponsor/SponsorshipSet.cpp @@ -207,7 +207,7 @@ SponsorshipSet::doApply() bool const hasPositiveFeeAmount = feeAmount.has_value() && *feeAmount > beast::kZero; - auto reserveSponsorAccSle = getTxReserveSponsor(view(), ctx_.tx); + auto reserveSponsorAccSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!reserveSponsorAccSle) return reserveSponsorAccSle.error(); // LCOV_EXCL_LINE @@ -226,8 +226,7 @@ SponsorshipSet::doApply() sponsorBalanceAfterFee -= *feeAmount; if (auto const ret = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sponsorAccSle, sponsorBalanceAfterFee.xrp(), *reserveSponsorAccSle, @@ -294,8 +293,7 @@ SponsorshipSet::doApply() sponsorBalanceAfterFee -= feeAmountDelta; if (auto const ret = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sponsorAccSle, sponsorBalanceAfterFee.xrp(), *reserveSponsorAccSle, diff --git a/src/libxrpl/tx/transactors/Sponsor/SponsorshipTransfer.cpp b/src/libxrpl/tx/transactors/Sponsor/SponsorshipTransfer.cpp index e19a005925..a9b8504a97 100644 --- a/src/libxrpl/tx/transactors/Sponsor/SponsorshipTransfer.cpp +++ b/src/libxrpl/tx/transactors/Sponsor/SponsorshipTransfer.cpp @@ -322,8 +322,7 @@ SponsorshipTransfer::doApply() // check new sponsor have sufficient balance // NOLINTNEXTLINE(readability-suspicious-call-argument) if (auto const ter = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sponseeSle, sponseeSle->getFieldAmount(sfBalance), newSponsorSle, @@ -376,8 +375,7 @@ SponsorshipTransfer::doApply() // check new sponsor have sufficient balance // NOLINTNEXTLINE(readability-suspicious-call-argument) if (auto const ter = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sponseeSle, sponseeSle->getFieldAmount(sfBalance), newSponsorSle, @@ -425,8 +423,7 @@ SponsorshipTransfer::doApply() // The owner takes the reserve burden back when the object is // no longer sponsored. if (auto const ter = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), ownerSle, balanceBeforeFee(ownerSle), SLE::pointer(), @@ -466,8 +463,7 @@ SponsorshipTransfer::doApply() return tefINTERNAL; // LCOV_EXCL_LINE if (auto const ter = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sponseeSle, sponseeSle->getFieldAmount(sfBalance), newSponsorSle, @@ -495,8 +491,7 @@ SponsorshipTransfer::doApply() return tefINTERNAL; // LCOV_EXCL_LINE if (auto const ter = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sponseeSle, sponseeSle->getFieldAmount(sfBalance), newSponsorSle, @@ -532,8 +527,7 @@ SponsorshipTransfer::doApply() // The sponsee must be able to hold its own account reserve after // the sponsorship is removed. if (auto const ter = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sponseeSle, balanceBeforeFee(sponseeSle), SLE::pointer(), diff --git a/src/libxrpl/tx/transactors/account/SignerListSet.cpp b/src/libxrpl/tx/transactors/account/SignerListSet.cpp index 6bda37537f..457639195a 100644 --- a/src/libxrpl/tx/transactors/account/SignerListSet.cpp +++ b/src/libxrpl/tx/transactors/account/SignerListSet.cpp @@ -319,12 +319,11 @@ SignerListSet::replaceSignerList() // We check the reserve against the starting balance because we want to // allow dipping into the reserve to pay fees. This behavior is consistent // with TicketCreate. - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE if (auto const ret = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sle, preFeeBalance_, *sponsorSle, diff --git a/src/libxrpl/tx/transactors/check/CheckCash.cpp b/src/libxrpl/tx/transactors/check/CheckCash.cpp index 60053075ef..3597dd8358 100644 --- a/src/libxrpl/tx/transactors/check/CheckCash.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCash.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -388,7 +389,8 @@ CheckCash::doApply() STAmount const flowDeliver{ optDeliverMin ? maxDeliverMin() : ctx_.tx.getFieldAmount(sfAmount)}; - auto const sponsorSle = getTxReserveSponsor(psb, ctx_.tx); + auto applyViewContext = ApplyViewContext({.view = psb, .tx = ctx_.tx}); + auto const sponsorSle = getTxReserveSponsor(applyViewContext); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE @@ -399,8 +401,7 @@ CheckCash::doApply() // Can the account cover the trust line's or MPT reserve? if (auto const ret = checkInsufficientReserve( - psb, - ctx_.tx, + applyViewContext, sleDst, preFeeBalance_, *sponsorSle, diff --git a/src/libxrpl/tx/transactors/check/CheckCreate.cpp b/src/libxrpl/tx/transactors/check/CheckCreate.cpp index eacf9d238a..10d5b778fd 100644 --- a/src/libxrpl/tx/transactors/check/CheckCreate.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCreate.cpp @@ -195,12 +195,11 @@ CheckCreate::doApply() // A check counts against the reserve of the issuing account, but we // check the starting balance because we want to allow dipping into the // reserve to pay fees. - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE if (auto const ret = checkInsufficientReserve( - view(), - ctx_.tx, + ctx_.getApplyViewContext(), sle, preFeeBalance_, *sponsorSle, diff --git a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp index 653829a755..9fc4a81029 100644 --- a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp +++ b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp @@ -99,12 +99,11 @@ DelegateSet::doApply() if (permissions.empty()) return tecINTERNAL; // LCOV_EXCL_LINE - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE if (auto const ret = checkInsufficientReserve( - view(), - ctx_.tx, + ctx_.getApplyViewContext(), sleOwner, preFeeBalance_, *sponsorSle, diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp index 72b7ceddfb..feed43d410 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp @@ -181,8 +181,7 @@ EscrowCancel::doApply() if (auto const ret = std::visit( [&](T const&) { return escrowUnlockApplyHelper( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), kParityRate, ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle : slep, preFeeBalance_, diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp index 8fb386f3fe..4b2f853b1b 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp @@ -437,7 +437,7 @@ EscrowCreate::doApply() STAmount const amount{ctx_.tx[sfAmount]}; auto const balance = sle->getFieldAmount(sfBalance).xrp(); - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE // First check: whoever is on the hook for the new owner increment @@ -446,7 +446,7 @@ EscrowCreate::doApply() // unsponsored this hits the source branch and validates the // source's pre-lock balance against base + (currentOC+1)*increment. if (auto const ret = checkInsufficientReserve( - ctx_.view(), ctx_.tx, sle, balance, *sponsorSle, {.ownerCountDelta = 1}, j_); + ctx_.getApplyViewContext(), sle, balance, *sponsorSle, {.ownerCountDelta = 1}, j_); !isTesSuccess(ret)) return ret; @@ -463,8 +463,7 @@ EscrowCreate::doApply() // - unsponsored: adj=1 — source owes base + the new increment. std::int32_t const ownerCountAdj = *sponsorSle ? 0 : 1; if (auto const ret = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sle, balance - STAmount(amount).xrp(), {}, diff --git a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp index d7a0fcbb42..3483384869 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp @@ -365,8 +365,7 @@ EscrowFinish::doApply() if (auto const ret = std::visit( [&](T const&) { return escrowUnlockApplyHelper( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), lockedRate, sled, preFeeBalance_, diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp index 008857a4ad..498f3c99eb 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.cpp @@ -211,7 +211,14 @@ LoanBrokerCoverWithdraw::doApply() associateAsset(*broker, vaultAsset); - return doWithdraw(view(), tx, accountID_, dstAcct, brokerPseudoID, preFeeBalance_, amount, j_); + return doWithdraw( + ctx_.getApplyViewContext(), + accountID_, + dstAcct, + brokerPseudoID, + preFeeBalance_, + amount, + j_); } void diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp index a19c776580..240a4e3016 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp @@ -159,7 +159,7 @@ LoanBrokerDelete::doApply() return ter; } - if (auto ter = removeEmptyHolding(view(), tx, brokerPseudoID, vaultAsset, j_)) + if (auto ter = removeEmptyHolding(ctx_.getApplyViewContext(), brokerPseudoID, vaultAsset, j_)) return ter; auto brokerPseudoSLE = view().peek(keylet::account(brokerPseudoID)); diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp index 02bb7acc30..e9c153404c 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp @@ -248,8 +248,8 @@ LoanBrokerSet::doApply() auto& pseudo = *maybePseudo; auto pseudoId = pseudo->at(sfAccount); - if (auto ter = - addEmptyHolding(view, tx, pseudoId, preFeeBalance_, sleVault->at(sfAsset), j_)) + if (auto ter = addEmptyHolding( + ctx_.getApplyViewContext(), pseudoId, preFeeBalance_, sleVault->at(sfAsset), j_)) return ter; // Initialize data fields: diff --git a/src/libxrpl/tx/transactors/lending/LoanPay.cpp b/src/libxrpl/tx/transactors/lending/LoanPay.cpp index 45e5e8aca0..158985ee7d 100644 --- a/src/libxrpl/tx/transactors/lending/LoanPay.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanPay.cpp @@ -625,7 +625,11 @@ LoanPay::doApply() { // The broker may have deleted their holding. Recreate it if needed if (auto const ter = addEmptyHolding( - view, tx, brokerPayee, brokerPayeeSle->at(sfBalance).value().xrp(), asset, j_); + ctx_.getApplyViewContext(), + brokerPayee, + brokerPayeeSle->at(sfBalance).value().xrp(), + asset, + j_); ter && ter != tecDUPLICATE) { // ignore tecDUPLICATE. That means the holding already exists, diff --git a/src/libxrpl/tx/transactors/lending/LoanSet.cpp b/src/libxrpl/tx/transactors/lending/LoanSet.cpp index cfcd345250..c22c1405a5 100644 --- a/src/libxrpl/tx/transactors/lending/LoanSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanSet.cpp @@ -538,8 +538,9 @@ LoanSet::doApply() borrower == accountID_ || borrower == counterparty, "xrpl::LoanSet::doApply", "borrower signed transaction"); + auto applyViewContext = ctx_.getApplyViewContext(); if (auto const ter = addEmptyHolding( - view, tx, borrower, borrowerSle->at(sfBalance).value().xrp(), vaultAsset, j_); + applyViewContext, borrower, borrowerSle->at(sfBalance).value().xrp(), vaultAsset, j_); ter && ter != tecDUPLICATE) { // ignore tecDUPLICATE. That means the holding already exists, and @@ -562,7 +563,11 @@ LoanSet::doApply() "broker owner signed transaction"); if (auto const ter = addEmptyHolding( - view, tx, brokerOwner, brokerOwnerSle->at(sfBalance).value().xrp(), vaultAsset, j_); + applyViewContext, + brokerOwner, + brokerOwnerSle->at(sfBalance).value().xrp(), + vaultAsset, + j_); ter && ter != tecDUPLICATE) { // ignore tecDUPLICATE. That means the holding already exists, diff --git a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp index 734581192e..195e4d2df7 100644 --- a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp +++ b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp @@ -152,6 +152,7 @@ DepositPreauth::preclaim(PreclaimContext const& ctx) TER DepositPreauth::doApply() { + auto applyViewContext = ctx_.getApplyViewContext(); if (ctx_.tx.isFieldPresent(sfAuthorize)) { auto const sleOwner = view().peek(keylet::account(accountID_)); @@ -161,11 +162,16 @@ DepositPreauth::doApply() // A preauth counts against the reserve of the issuing account, but we // check the starting balance because we want to allow dipping into the // reserve to pay fees. - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(applyViewContext); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE if (auto const ret = checkInsufficientReserve( - view(), ctx_.tx, sleOwner, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_); + applyViewContext, + sleOwner, + preFeeBalance_, + *sponsorSle, + {.ownerCountDelta = 1}, + j_); !isTesSuccess(ret)) return ret; @@ -209,11 +215,16 @@ DepositPreauth::doApply() // A preauth counts against the reserve of the issuing account, but we // check the starting balance because we want to allow dipping into the // reserve to pay fees. - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(applyViewContext); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE if (auto const ret = checkInsufficientReserve( - view(), ctx_.tx, sleOwner, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_); + applyViewContext, + sleOwner, + preFeeBalance_, + *sponsorSle, + {.ownerCountDelta = 1}, + j_); !isTesSuccess(ret)) return ret; diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp index 96a869af8f..1b82fcf88f 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp @@ -135,7 +135,7 @@ PaymentChannelCreate::doApply() return tecEXPIRED; } - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE @@ -147,7 +147,12 @@ PaymentChannelCreate::doApply() // unsponsored this hits the source branch and validates the // source's pre-lock balance against base + (currentOC+1)*increment. if (auto const ret = checkInsufficientReserve( - ctx_.view(), ctx_.tx, sle, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_); + ctx_.getApplyViewContext(), + sle, + preFeeBalance_, + *sponsorSle, + {.ownerCountDelta = 1}, + j_); !isTesSuccess(ret)) return ret; @@ -161,8 +166,7 @@ PaymentChannelCreate::doApply() // - unsponsored: adj=1 — source owes base + the new increment. std::int32_t const ownerCountAdj = *sponsorSle ? 0 : 1; if (auto const ret = checkInsufficientReserve( - ctx_.view(), - ctx_.tx, + ctx_.getApplyViewContext(), sle, preFeeBalance_ - ctx_.tx[sfAmount].xrp(), {}, diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp index d0681718ce..ab0635068b 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp @@ -90,16 +90,16 @@ PaymentChannelFund::doApply() { // Check reserve and funds availability auto const balance = (*sle)[sfBalance]; - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE - if (auto const ret = - checkInsufficientReserve(ctx_.view(), ctx_.tx, sle, balance, *sponsorSle, {}, j_); + if (auto const ret = checkInsufficientReserve( + ctx_.getApplyViewContext(), sle, balance, *sponsorSle, {}, j_); !isTesSuccess(ret)) return ret; if (auto const ret = checkInsufficientReserve( - ctx_.view(), ctx_.tx, sle, balance - ctx_.tx[sfAmount], {}, {}, j_); + ctx_.getApplyViewContext(), sle, balance - ctx_.tx[sfAmount], {}, {}, j_); !isTesSuccess(ret)) return tecUNFUNDED; } diff --git a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp index 2bbed74baa..0aeb6f33d1 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp @@ -164,8 +164,7 @@ MPTokenAuthorize::doApply() { auto const& tx = ctx_.tx; return authorizeMPToken( - ctx_.view(), - tx, + ctx_.getApplyViewContext(), preFeeBalance_, tx[sfMPTokenIssuanceID], accountID_, diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp index 7e3d4503de..a1a75ac531 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp @@ -116,19 +116,18 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) std::expected MPTokenIssuanceCreate::create( - ApplyView& view, - STTx const& tx, + ApplyViewContext ctx, beast::Journal journal, MPTCreateArgs const& args) { - auto const acct = view.peek(keylet::account(args.account)); + auto const acct = ctx.view.peek(keylet::account(args.account)); if (!acct) return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE SLE::pointer sponsorSle; if (!isPseudoAccount(acct)) { - auto sle = getTxReserveSponsor(view, tx); + auto sle = getTxReserveSponsor(ctx); if (!sle) return std::unexpected(sle.error()); sponsorSle = std::move(*sle); @@ -137,7 +136,7 @@ MPTokenIssuanceCreate::create( if (args.priorBalance) { if (auto const ret = checkInsufficientReserve( - view, tx, acct, *(args.priorBalance), sponsorSle, {.ownerCountDelta = 1}, journal); + ctx, acct, *(args.priorBalance), sponsorSle, {.ownerCountDelta = 1}, journal); !isTesSuccess(ret)) return std::unexpected(ret); // tecINSUFFICIENT_RESERVE } @@ -147,7 +146,7 @@ MPTokenIssuanceCreate::create( // create the MPTokenIssuance { - auto const ownerNode = view.dirInsert( + auto const ownerNode = ctx.view.dirInsert( keylet::ownerDir(args.account), mptIssuanceKeylet, describeOwnerDir(args.account)); if (!ownerNode) @@ -185,7 +184,7 @@ MPTokenIssuanceCreate::create( // populate this after the pseudo-account's MPToken / // RippleState has been installed. A missing holding here // would dangle the pointer and is a programmer error. - auto const sleHolding = view.read(keylet::unchecked(*args.referenceHolding)); + auto const sleHolding = ctx.view.read(keylet::unchecked(*args.referenceHolding)); if (!sleHolding) return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE auto const type = sleHolding->getType(); @@ -196,11 +195,11 @@ MPTokenIssuanceCreate::create( addSponsorToLedgerEntry(mptIssuance, sponsorSle); - view.insert(mptIssuance); + ctx.view.insert(mptIssuance); } // Update owner count. - increaseOwnerCount(view, acct, sponsorSle, 1, journal); + increaseOwnerCount(ctx.view, acct, sponsorSle, 1, journal); return mptId; } @@ -210,8 +209,7 @@ MPTokenIssuanceCreate::doApply() { auto const& tx = ctx_.tx; auto const result = create( - view(), - tx, + ctx_.getApplyViewContext(), j_, { .priorBalance = preFeeBalance_, diff --git a/src/libxrpl/tx/transactors/token/TrustSet.cpp b/src/libxrpl/tx/transactors/token/TrustSet.cpp index 32eb0ddda0..cf3f05152d 100644 --- a/src/libxrpl/tx/transactors/token/TrustSet.cpp +++ b/src/libxrpl/tx/transactors/token/TrustSet.cpp @@ -328,7 +328,7 @@ TrustSet::doApply() // well. A person with no intention of using the gateway // could use the extra XRP for their own purposes. - auto const sponsorSle = getTxReserveSponsor(view(), ctx_.tx); + auto const sponsorSle = getTxReserveSponsor(ctx_.getApplyViewContext()); if (!sponsorSle) return sponsorSle.error(); // LCOV_EXCL_LINE @@ -539,8 +539,7 @@ TrustSet::doApply() // For PreFunded sponsors, we need to check if there are sufficient reserves before // calling increaseOwnerCount(). if (auto const ret = checkInsufficientReserve( - view(), - ctx_.tx, + ctx_.getApplyViewContext(), sleLowAccount, preFeeBalance_, *sponsorSle, @@ -574,8 +573,7 @@ TrustSet::doApply() // For PreFunded sponsors, we need to check if there are sufficient reserves before // calling increaseOwnerCount(). if (auto const ret = checkInsufficientReserve( - view(), - ctx_.tx, + ctx_.getApplyViewContext(), sleHighAccount, preFeeBalance_, *sponsorSle, @@ -614,8 +612,8 @@ TrustSet::doApply() } // Reserve is not scaled by load. else if ( - auto const ret = - checkInsufficientReserve(view(), ctx_.tx, sle, preFeeBalance_, *sponsorSle, {}, j_); + auto const ret = checkInsufficientReserve( + ctx_.getApplyViewContext(), sle, preFeeBalance_, *sponsorSle, {}, j_); !freeTrustLine && bReserveIncrease && !isTesSuccess(ret)) { JLOG(j_.trace()) << "Delay transaction: Insufficent reserve to " @@ -646,7 +644,12 @@ TrustSet::doApply() } else if ( auto const ret = checkInsufficientReserve( - ctx_.view(), ctx_.tx, sle, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1}, j_); + ctx_.getApplyViewContext(), + sle, + preFeeBalance_, + *sponsorSle, + {.ownerCountDelta = 1}, + j_); !freeTrustLine && !isTesSuccess(ret)) // Reserve is not scaled by load. { JLOG(j_.trace()) << "Delay transaction: Line does not exist. " diff --git a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp index 4ab23f9d8f..d77286b667 100644 --- a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp @@ -399,7 +399,8 @@ VaultClawback::doApply() // Keep MPToken if holder is the vault owner. if (holder != vault->at(sfOwner)) { - if (auto const ter = removeEmptyHolding(view(), tx, holder, sharesDestroyed.asset(), j_); + if (auto const ter = + removeEmptyHolding(ctx_.getApplyViewContext(), holder, sharesDestroyed.asset(), j_); isTesSuccess(ter)) { JLOG(j_.debug()) // diff --git a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp index 94d926b8dc..e1f5873a89 100644 --- a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp @@ -146,6 +146,7 @@ VaultCreate::doApply() // we can consider downgrading them to `tef` or `tem`. auto const& tx = ctx_.tx; + auto applyViewContext = ctx_.getApplyViewContext(); auto const sequence = tx.getSeqValue(); auto const owner = view().peek(keylet::account(accountID_)); if (owner == nullptr) @@ -167,7 +168,7 @@ VaultCreate::doApply() AccountID const pseudoId = pseudo->at(sfAccount); auto const asset = tx[sfAsset]; - if (auto ter = addEmptyHolding(view(), tx, pseudoId, preFeeBalance_, asset, j_); + if (auto ter = addEmptyHolding(applyViewContext, pseudoId, preFeeBalance_, asset, j_); !isTesSuccess(ter)) return ter; @@ -197,8 +198,7 @@ VaultCreate::doApply() : keylet::trustLine(pseudoId, asset.get()).key; }(); auto const maybeShare = MPTokenIssuanceCreate::create( - view(), - tx, + applyViewContext, j_, { .priorBalance = std::nullopt, @@ -244,8 +244,8 @@ VaultCreate::doApply() view().insert(vault); // Explicitly create MPToken for the vault owner - if (auto const err = - authorizeMPToken(view(), tx, preFeeBalance_, mptIssuanceID, accountID_, ctx_.journal); + if (auto const err = authorizeMPToken( + applyViewContext, preFeeBalance_, mptIssuanceID, accountID_, ctx_.journal); !isTesSuccess(err)) return err; @@ -253,7 +253,13 @@ VaultCreate::doApply() if (tx.isFlag(tfVaultPrivate)) { if (auto const err = authorizeMPToken( - view(), tx, preFeeBalance_, mptIssuanceID, pseudoId, ctx_.journal, {}, accountID_); + applyViewContext, + preFeeBalance_, + mptIssuanceID, + pseudoId, + ctx_.journal, + {}, + accountID_); !isTesSuccess(err)) return err; } diff --git a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp index 67aafe5c25..551e3501fa 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp @@ -96,13 +96,14 @@ TER VaultDelete::doApply() { auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID])); + auto applyViewContext = ctx_.getApplyViewContext(); if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE // Destroy the asset holding. auto asset = vault->at(sfAsset); - if (auto ter = removeEmptyHolding(view(), ctx_.tx, vault->at(sfAccount), asset, j_); + if (auto ter = removeEmptyHolding(applyViewContext, vault->at(sfAccount), asset, j_); !isTesSuccess(ter)) return ter; @@ -132,7 +133,7 @@ VaultDelete::doApply() if (auto const mptoken = view().peek(keylet::mptoken(shareMPTID, accountID_))) { if (auto const ter = - removeEmptyHolding(view(), ctx_.tx, accountID_, MPTIssue(shareMPTID), j_); + removeEmptyHolding(applyViewContext, accountID_, MPTIssue(shareMPTID), j_); !isTesSuccess(ter)) { // LCOV_EXCL_START diff --git a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp index e7a0cbc1b7..aa9cfc8537 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp @@ -197,6 +197,7 @@ VaultDeposit::doApply() { bool const fix320Enabled = view().rules().enabled(fixCleanup3_2_0); auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID])); + auto applyViewContext = ctx_.getApplyViewContext(); if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE auto const vaultAsset = vault->at(sfAsset); @@ -231,7 +232,7 @@ VaultDeposit::doApply() if (vault->isFlag(lsfVaultPrivate) && accountID_ != vault->at(sfOwner)) { if (auto const err = enforceMPTokenAuthorization( - ctx_.view(), ctx_.tx, mptIssuanceID, accountID_, preFeeBalance_, j_); + applyViewContext, mptIssuanceID, accountID_, preFeeBalance_, j_); !isTesSuccess(err)) return err; } @@ -241,8 +242,7 @@ VaultDeposit::doApply() if (!view().exists(keylet::mptoken(mptIssuanceID, accountID_))) { if (auto const err = authorizeMPToken( - view(), - ctx_.tx, + applyViewContext, preFeeBalance_, mptIssuanceID->value(), accountID_, @@ -258,8 +258,7 @@ VaultDeposit::doApply() XRPL_ASSERT( accountID_ == vault->at(sfOwner), "xrpl::VaultDeposit::doApply : account is owner"); if (auto const err = authorizeMPToken( - view(), - ctx_.tx, + applyViewContext, preFeeBalance_, // priorBalance mptIssuanceID->value(), // mptIssuanceID sleIssuance->at(sfIssuer), // account diff --git a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp index 9d1d53e394..ec63b7d769 100644 --- a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp @@ -194,6 +194,7 @@ TER VaultWithdraw::doApply() { auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID])); + auto applyViewContext = ctx_.getApplyViewContext(); if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE @@ -362,7 +363,7 @@ VaultWithdraw::doApply() if (accountID_ != vault->at(sfOwner)) { if (auto const ter = - removeEmptyHolding(view(), ctx_.tx, accountID_, sharesRedeemed.asset(), j_); + removeEmptyHolding(applyViewContext, accountID_, sharesRedeemed.asset(), j_); isTesSuccess(ter)) { JLOG(j_.debug()) // @@ -388,7 +389,7 @@ VaultWithdraw::doApply() auto const dstAcct = ctx_.tx[~sfDestination].value_or(accountID_); return doWithdraw( - view(), ctx_.tx, accountID_, dstAcct, vaultAccount, preFeeBalance_, assetsWithdrawn, j_); + applyViewContext, accountID_, dstAcct, vaultAccount, preFeeBalance_, assetsWithdrawn, j_); } void diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index 10cf11512f..7e6b2612d1 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -5930,7 +5930,7 @@ class Vault_test : public beast::unit_test::Suite auto const dummyTx = *env.jt(noop(holder)).stx; BEAST_EXPECT( - removeEmptyHolding(sb, dummyTx, holder.id(), MPTIssue(mpt.issuanceID()), j) == + removeEmptyHolding({sb, dummyTx}, holder.id(), MPTIssue(mpt.issuanceID()), j) == tecHAS_OBLIGATIONS); BEAST_EXPECT(sb.peek(tokenKeylet) != nullptr); } @@ -7544,7 +7544,7 @@ class Vault_test : public beast::unit_test::Suite // Transaction fails if the data field is set, but is empty { testcase("VaultDelete memo data featureLendingProtocolV1_1 enabled data empty"); - delTx[sfMemoData] = strHex(std::string(0, 'A')); + delTx[sfMemoData] = std::string(); env(delTx, Ter(temMALFORMED)); env.close(); }