From 9d11ba0ca7d0fbf3ee030e45d340aa165575734c Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 10 Jul 2026 10:51:08 -0400 Subject: [PATCH] migrate --- .../ledger/helpers/PaymentChannelHelpers.h | 7 +- include/xrpl/ledger/helpers/VaultHelpers.h | 24 ++-- .../tx/transactors/account/SignerListSet.h | 3 +- include/xrpl/tx/transactors/dex/AMMWithdraw.h | 3 +- .../tx/transactors/nft/NFTokenAcceptOffer.h | 5 +- .../xrpl/tx/transactors/vault/VaultClawback.h | 5 +- src/libxrpl/ledger/helpers/AMMHelpers.cpp | 23 ++-- .../ledger/helpers/AccountRootHelpers.cpp | 11 +- .../ledger/helpers/CredentialHelpers.cpp | 23 ++-- src/libxrpl/ledger/helpers/MPTokenHelpers.cpp | 104 +++++++++--------- src/libxrpl/ledger/helpers/NFTokenHelpers.cpp | 99 +++++++++-------- .../ledger/helpers/PaymentChannelHelpers.cpp | 14 ++- .../ledger/helpers/PermissionedDEXHelpers.cpp | 9 +- .../ledger/helpers/RippleStateHelpers.cpp | 89 ++++++++------- src/libxrpl/ledger/helpers/SponsorHelpers.cpp | 3 +- src/libxrpl/ledger/helpers/TokenHelpers.cpp | 82 +++++++------- src/libxrpl/ledger/helpers/VaultHelpers.cpp | 25 +++-- .../tx/transactors/account/AccountDelete.cpp | 24 ++-- .../tx/transactors/account/AccountSet.cpp | 10 +- .../tx/transactors/account/SetRegularKey.cpp | 10 +- .../tx/transactors/account/SignerListSet.cpp | 22 ++-- .../tx/transactors/bridge/XChainBridge.cpp | 36 +++--- .../tx/transactors/check/CheckCancel.cpp | 11 +- .../tx/transactors/check/CheckCash.cpp | 18 +-- .../tx/transactors/check/CheckCreate.cpp | 22 ++-- .../credentials/CredentialAccept.cpp | 17 +-- .../credentials/CredentialCreate.cpp | 10 +- .../credentials/CredentialDelete.cpp | 5 +- .../tx/transactors/delegate/DelegateSet.cpp | 19 ++-- .../tx/transactors/dex/AMMClawback.cpp | 3 +- src/libxrpl/tx/transactors/dex/AMMCreate.cpp | 7 +- .../tx/transactors/dex/AMMWithdraw.cpp | 7 +- src/libxrpl/tx/transactors/did/DIDDelete.cpp | 11 +- src/libxrpl/tx/transactors/did/DIDSet.cpp | 18 +-- .../tx/transactors/escrow/EscrowCancel.cpp | 18 +-- .../tx/transactors/escrow/EscrowCreate.cpp | 25 +++-- .../tx/transactors/escrow/EscrowFinish.cpp | 25 +++-- .../tx/transactors/nft/NFTokenAcceptOffer.cpp | 30 ++--- .../tx/transactors/oracle/OracleDelete.cpp | 10 +- .../tx/transactors/oracle/OracleSet.cpp | 20 ++-- .../tx/transactors/payment/Payment.cpp | 17 +-- .../payment_channel/PaymentChannelClaim.cpp | 16 +-- .../payment_channel/PaymentChannelFund.cpp | 10 +- .../PermissionedDomainDelete.cpp | 12 +- .../PermissionedDomainSet.cpp | 19 ++-- src/libxrpl/tx/transactors/system/Change.cpp | 32 +++--- .../tx/transactors/system/TicketCreate.cpp | 10 +- .../tx/transactors/token/MPTokenAuthorize.cpp | 5 +- .../transactors/token/MPTokenIssuanceSet.cpp | 17 +-- src/libxrpl/tx/transactors/token/TrustSet.cpp | 28 ++--- .../tx/transactors/vault/VaultClawback.cpp | 24 ++-- .../tx/transactors/vault/VaultCreate.cpp | 7 +- .../tx/transactors/vault/VaultDelete.cpp | 30 ++--- .../tx/transactors/vault/VaultDeposit.cpp | 12 +- src/libxrpl/tx/transactors/vault/VaultSet.cpp | 16 +-- .../tx/transactors/vault/VaultWithdraw.cpp | 15 ++- src/test/app/LendingHelpers_test.cpp | 10 +- 57 files changed, 654 insertions(+), 533 deletions(-) diff --git a/include/xrpl/ledger/helpers/PaymentChannelHelpers.h b/include/xrpl/ledger/helpers/PaymentChannelHelpers.h index 6e8cd17f7f..d2a9430ac8 100644 --- a/include/xrpl/ledger/helpers/PaymentChannelHelpers.h +++ b/include/xrpl/ledger/helpers/PaymentChannelHelpers.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,11 @@ namespace xrpl { * fails; tefINTERNAL if the source account SLE cannot be found. */ TER -closeChannel(SLE::ref slep, ApplyView& view, uint256 const& key, beast::Journal j); +closeChannel( + PayChannelEntry& slep, + ApplyView& view, + uint256 const& key, + beast::Journal j); /** Add two uint32_t values with saturation at UINT32_MAX. * diff --git a/include/xrpl/ledger/helpers/VaultHelpers.h b/include/xrpl/ledger/helpers/VaultHelpers.h index 2344b4de77..a6453c433f 100644 --- a/include/xrpl/ledger/helpers/VaultHelpers.h +++ b/include/xrpl/ledger/helpers/VaultHelpers.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -20,7 +21,10 @@ namespace xrpl { @return The number of shares, or nullopt on error. */ [[nodiscard]] std::optional -assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& assets); +assetsToSharesDeposit( + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, + STAmount const& assets); /** From the perspective of a vault, return the number of assets to take from depositor when they receive a fixed amount of shares. Note, since shares are @@ -33,7 +37,10 @@ assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount co @return The number of assets, or nullopt on error. */ [[nodiscard]] std::optional -sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& shares); +sharesToAssetsDeposit( + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, + STAmount const& shares); /** Controls whether to truncate shares instead of rounding. */ enum class TruncateShares : bool { No = false, Yes = true }; @@ -62,8 +69,8 @@ enum class WaiveUnrealizedLoss : bool { No = false, Yes = true }; */ [[nodiscard]] std::optional assetsToSharesWithdraw( - SLE::const_ref vault, - SLE::const_ref issuance, + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, STAmount const& assets, TruncateShares truncate = TruncateShares::No, WaiveUnrealizedLoss waive = WaiveUnrealizedLoss::No); @@ -82,8 +89,8 @@ assetsToSharesWithdraw( */ [[nodiscard]] std::optional sharesToAssetsWithdraw( - SLE::const_ref vault, - SLE::const_ref issuance, + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, STAmount const& shares, WaiveUnrealizedLoss waive = WaiveUnrealizedLoss::No); @@ -97,6 +104,9 @@ sharesToAssetsWithdraw( both the share MPTID and the outstanding-amount total. */ [[nodiscard]] bool -isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref issuance); +isSoleShareholder( + ReadView const& view, + AccountID const& account, + MPTokenIssuanceEntry const& issuance); } // namespace xrpl diff --git a/include/xrpl/tx/transactors/account/SignerListSet.h b/include/xrpl/tx/transactors/account/SignerListSet.h index da2274a1de..c14282ddae 100644 --- a/include/xrpl/tx/transactors/account/SignerListSet.h +++ b/include/xrpl/tx/transactors/account/SignerListSet.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,7 @@ private: destroySignerList(); void - writeSignersToSLE(SLE::pointer const& ledgerEntry, std::uint32_t flags) const; + writeSignersToSLE(SignerListEntry& ledgerEntry, std::uint32_t flags) const; }; } // namespace xrpl diff --git a/include/xrpl/tx/transactors/dex/AMMWithdraw.h b/include/xrpl/tx/transactors/dex/AMMWithdraw.h index 8f6700037d..a998f900fb 100644 --- a/include/xrpl/tx/transactors/dex/AMMWithdraw.h +++ b/include/xrpl/tx/transactors/dex/AMMWithdraw.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -166,7 +167,7 @@ public: static std::pair deleteAMMAccountIfEmpty( Sandbox& sb, - SLE::pointer const ammSle, + AMMEntry& ammSle, STAmount const& lpTokenBalance, Asset const& asset1, Asset const& asset2, diff --git a/include/xrpl/tx/transactors/nft/NFTokenAcceptOffer.h b/include/xrpl/tx/transactors/nft/NFTokenAcceptOffer.h index 28037ae3b9..92c9e8b45c 100644 --- a/include/xrpl/tx/transactors/nft/NFTokenAcceptOffer.h +++ b/include/xrpl/tx/transactors/nft/NFTokenAcceptOffer.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -21,10 +22,10 @@ private: pay(AccountID const& from, AccountID const& to, STAmount const& amount); TER - acceptOffer(SLE::ref offer); + acceptOffer(NFTokenOfferEntry const& offer); TER - bridgeOffers(SLE::ref buy, SLE::ref sell); + bridgeOffers(NFTokenOfferEntry const& buy, NFTokenOfferEntry const& sell); TER transferNFToken(AccountID const& buyer, AccountID const& seller, uint256 const& nfTokenID); diff --git a/include/xrpl/tx/transactors/vault/VaultClawback.h b/include/xrpl/tx/transactors/vault/VaultClawback.h index ba0eb9f320..c8ff175e60 100644 --- a/include/xrpl/tx/transactors/vault/VaultClawback.h +++ b/include/xrpl/tx/transactors/vault/VaultClawback.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -48,8 +49,8 @@ public: private: std::expected, TER> assetsToClawback( - SLE::ref vault, - SLE::const_ref sleShareIssuance, + VaultEntry& vault, + MPTokenIssuanceEntry const& sleShareIssuance, AccountID const& holder, STAmount const& clawbackAmount); }; diff --git a/src/libxrpl/ledger/helpers/AMMHelpers.cpp b/src/libxrpl/ledger/helpers/AMMHelpers.cpp index df6d335085..f760c5caec 100644 --- a/src/libxrpl/ledger/helpers/AMMHelpers.cpp +++ b/src/libxrpl/ledger/helpers/AMMHelpers.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -555,7 +556,7 @@ ammLPHolds( auto const currency = ammLPTCurrency(asset1, asset2); STAmount amount; - auto const sle = view.read(keylet::trustLine(lpAccount, ammAccount, currency)); + RippleStateEntry const sle{keylet::trustLine(lpAccount, ammAccount, currency), view}; if (!sle) { amount.clear(Issue{currency, ammAccount}); @@ -632,7 +633,7 @@ ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Asset const // Get the actual AMM balance without factoring in the balance hook return asset.visit( [&](MPTIssue const& issue) { - if (auto const sle = view.read(keylet::mptoken(issue, ammAccountID)); + if (MPTokenEntry const sle{keylet::mptoken(issue, ammAccountID), view}; sle && !isFrozen(view, ammAccountID, issue)) return STAmount{issue, (*sle)[sfMPTAmount]}; return STAmount{asset}; @@ -640,12 +641,12 @@ ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Asset const [&](Issue const& issue) { if (isXRP(issue)) { - if (auto const sle = view.read(keylet::account(ammAccountID))) + if (AccountRootEntry const sle{keylet::account(ammAccountID), view}) return (*sle)[sfBalance]; } else if ( - auto const sle = - view.read(keylet::trustLine(ammAccountID, issue.account, issue.currency)); + RippleStateEntry const sle{ + keylet::trustLine(ammAccountID, issue.account, issue.currency), view}; sle && !isFrozen(view, ammAccountID, issue.currency, issue.account)) { STAmount amount = (*sle)[sfBalance]; @@ -746,7 +747,7 @@ deleteAMMMPTokens(Sandbox& sb, AccountID const& ammAccountID, beast::Journal j) TER deleteAMMAccount(Sandbox& sb, Asset const& asset, Asset const& asset2, beast::Journal j) { - auto ammSle = sb.peek(keylet::amm(asset, asset2)); + AMMEntry ammSle{keylet::amm(asset, asset2), sb}; if (!ammSle) { // LCOV_EXCL_START @@ -756,7 +757,7 @@ deleteAMMAccount(Sandbox& sb, Asset const& asset, Asset const& asset2, beast::Jo } auto const ammAccountID = (*ammSle)[sfAccount]; - auto sleAMMRoot = sb.peek(keylet::account(ammAccountID)); + AccountRootEntry sleAMMRoot{keylet::account(ammAccountID), sb}; if (!sleAMMRoot) { // LCOV_EXCL_START @@ -793,8 +794,8 @@ deleteAMMAccount(Sandbox& sb, Asset const& asset, Asset const& asset2, beast::Jo // LCOV_EXCL_STOP } - sb.erase(ammSle); - sb.erase(sleAMMRoot); + ammSle.erase(); + sleAMMRoot.erase(); return tesSUCCESS; } @@ -885,12 +886,12 @@ isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID c // Iterate over AMM owner directory objects. while (limit-- >= 1) { - auto const ownerDir = view.read(currentIndex); + DirectoryNodeEntry const ownerDir{currentIndex, view}; if (!ownerDir) return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE for (auto const& key : ownerDir->getFieldV256(sfIndexes)) { - auto const sle = view.read(keylet::child(key)); + ReadOnlySLE const sle{keylet::child(key), view}; if (!sle) return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE auto const entryType = sle->getFieldU16(sfLedgerEntryType); diff --git a/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp index 1c4acc7bc4..6c06f31c7f 100644 --- a/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp +++ b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ isGlobalFrozen(ReadView const& view, AccountID const& issuer) { if (isXRP(issuer)) return false; - if (auto const sle = view.read(keylet::account(issuer))) + if (AccountRootEntry sle{keylet::account(issuer), view}) return sle->isFlag(lsfGlobalFreeze); return false; } @@ -86,8 +87,8 @@ confineOwnerCount( XRPAmount xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j) { - auto const sle = view.read(keylet::account(id)); - if (sle == nullptr) + AccountRootEntry sle{keylet::account(id), view}; + if (!sle) return beast::kZero; // Return balance minus reserve @@ -96,7 +97,7 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, // Pseudo-accounts have no reserve requirement auto const reserve = - isPseudoAccount(sle) ? XRPAmount{0} : view.fees().accountReserve(ownerCount); + isPseudoAccount(sle.sle()) ? XRPAmount{0} : view.fees().accountReserve(ownerCount); auto const fullBalance = sle->getFieldAmount(sfBalance); @@ -116,7 +117,7 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, Rate transferRate(ReadView const& view, AccountID const& issuer) { - auto const sle = view.read(keylet::account(issuer)); + AccountRootEntry sle{keylet::account(issuer), view}; if (sle && sle->isFieldPresent(sfTransferRate)) return Rate{sle->getFieldU32(sfTransferRate)}; diff --git a/src/libxrpl/ledger/helpers/CredentialHelpers.cpp b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp index 6fc2faf03e..86cf4225c1 100644 --- a/src/libxrpl/ledger/helpers/CredentialHelpers.cpp +++ b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -53,13 +54,13 @@ removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j) { // Credentials already checked in preclaim. Look only for expired here. auto const k = keylet::credential(h); - auto const sleCred = view.peek(k); + CredentialEntry sleCred{k, view}; if (sleCred && checkExpired(*sleCred, closeTime)) { JLOG(j.trace()) << "Credentials are expired. Cred: " << sleCred->getText(); // delete expired credentials even if the transaction failed - auto const err = deleteSLE(view, sleCred, j); + auto const err = deleteSLE(view, sleCred.mutableSle(), j); if (view.rules().enabled(fixCleanup3_1_3) && !isTesSuccess(err)) return std::unexpected(err); foundExpired = true; @@ -77,7 +78,7 @@ deleteSLE(ApplyView& view, SLE::ref sleCredential, beast::Journal j) auto delSLE = [&view, &sleCredential, j]( AccountID const& account, SField const& node, bool isOwner) -> TER { - auto const sleAccount = view.peek(keylet::account(account)); + AccountRootEntry sleAccount{keylet::account(account), view}; if (!sleAccount) { // LCOV_EXCL_START @@ -97,7 +98,7 @@ deleteSLE(ApplyView& view, SLE::ref sleCredential, beast::Journal j) } if (isOwner) - adjustOwnerCount(view, sleAccount, -1, j); + adjustOwnerCount(view, sleAccount.mutableSle(), -1, j); return tesSUCCESS; }; @@ -160,7 +161,7 @@ valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal auto const& credIDs(tx.getFieldV256(sfCredentialIDs)); for (auto const& h : credIDs) { - auto const sleCred = view.read(keylet::credential(h)); + CredentialEntry sleCred{keylet::credential(h), view}; if (!sleCred) { JLOG(j.trace()) << "Credential doesn't exist. Cred: " << h; @@ -189,7 +190,7 @@ TER validDomain(ReadView const& view, uint256 domainID, AccountID const& subject) { // Note, permissioned domain objects can be deleted at any time - auto const slePD = view.read(keylet::permissionedDomain(domainID)); + PermissionedDomainEntry slePD{keylet::permissionedDomain(domainID), view}; if (!slePD) return tecOBJECT_NOT_FOUND; @@ -200,7 +201,7 @@ validDomain(ReadView const& view, uint256 domainID, AccountID const& subject) auto const issuer = h.getAccountID(sfIssuer); auto const type = h.getFieldVL(sfCredentialType); auto const keyletCredential = keylet::credential(subject, issuer, makeSlice(type)); - auto const sleCredential = view.read(keyletCredential); + CredentialEntry sleCredential{keyletCredential, view}; // We cannot delete expired credentials, that would require ApplyView& // However we can check if credentials are expired. Expected transaction @@ -234,14 +235,14 @@ authorizedDepositPreauth(ReadView const& view, STVector256 const& credIDs, Accou lifeExtender.reserve(credIDs.size()); for (auto const& h : credIDs) { - auto sleCred = view.read(keylet::credential(h)); + CredentialEntry sleCred{keylet::credential(h), view}; if (!sleCred) // already checked in preclaim return tefINTERNAL; // LCOV_EXCL_LINE auto [it, ins] = sorted.emplace((*sleCred)[sfIssuer], (*sleCred)[sfCredentialType]); if (!ins) return tefINTERNAL; // LCOV_EXCL_LINE - lifeExtender.push_back(std::move(sleCred)); + lifeExtender.push_back(sleCred.sle()); } if (!view.exists(keylet::depositPreauth(dst, sorted))) @@ -312,7 +313,7 @@ checkArray(STArray const& credentials, unsigned maxSize, beast::Journal j) TER verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, beast::Journal j) { - auto const slePD = view.read(keylet::permissionedDomain(domainID)); + PermissionedDomainEntry slePD{keylet::permissionedDomain(domainID), view}; if (!slePD) return tecOBJECT_NOT_FOUND; @@ -334,7 +335,7 @@ verifyValidDomain(ApplyView& view, AccountID const& account, uint256 domainID, b for (auto const& h : credentials) { - auto sleCredential = view.read(keylet::credential(h)); + CredentialEntry sleCredential{keylet::credential(h), view}; if (!sleCredential) continue; // expired, i.e. deleted in credentials::removeExpired diff --git a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp index 3c4e55a16e..8af80f76dc 100644 --- a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,8 @@ namespace xrpl { bool isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue) { - if (auto const sle = view.read(keylet::mptokenIssuance(mptIssue.getMptID()))) + if (MPTokenIssuanceEntry const sle{ + keylet::mptokenIssuance(mptIssue.getMptID()), view}) return sle->isFlag(lsfMPTLocked); return false; } @@ -48,7 +50,7 @@ isGlobalFrozen(ReadView const& view, MPTIssue const& mptIssue) bool isIndividualFrozen(ReadView const& view, AccountID const& account, MPTIssue const& mptIssue) { - if (auto const sle = view.read(keylet::mptoken(mptIssue.getMptID(), account))) + if (MPTokenEntry const sle{keylet::mptoken(mptIssue.getMptID(), account), view}) return sle->isFlag(lsfMPTLocked); return false; } @@ -95,7 +97,7 @@ transferRate(ReadView const& view, MPTID const& issuanceID) // fee is 0-50,000 (0-50%), rate is 1,000,000,000-2,000,000,000 // For example, if transfer fee is 50% then 10,000 * 50,000 = 500,000 // which represents 50% of 1,000,000,000 - if (auto const sle = view.read(keylet::mptokenIssuance(issuanceID)); + if (MPTokenIssuanceEntry const sle{keylet::mptokenIssuance(issuanceID), view}; sle && sle->isFieldPresent(sfTransferFee)) { auto const fee = sle->getFieldU16(sfTransferFee); @@ -110,7 +112,7 @@ transferRate(ReadView const& view, MPTID const& issuanceID) canAddHolding(ReadView const& view, MPTIssue const& mptIssue) { auto mptID = mptIssue.getMptID(); - auto issuance = view.read(keylet::mptokenIssuance(mptID)); + MPTokenIssuanceEntry const issuance{keylet::mptokenIssuance(mptID), view}; if (!issuance) { return tecOBJECT_NOT_FOUND; @@ -132,7 +134,7 @@ addEmptyHolding( beast::Journal journal) { auto const& mptID = mptIssue.getMptID(); - auto const mpt = view.peek(keylet::mptokenIssuance(mptID)); + MPTokenIssuanceEntry const mpt{keylet::mptokenIssuance(mptID), view}; if (!mpt) return tefINTERNAL; // LCOV_EXCL_LINE if (mpt->isFlag(lsfMPTLocked)) @@ -155,7 +157,7 @@ authorizeMPToken( std::uint32_t flags, std::optional holderID) { - auto const sleAcct = view.peek(keylet::account(account)); + AccountRootEntry const sleAcct{keylet::account(account), view}; if (!sleAcct) return tecINTERNAL; // LCOV_EXCL_LINE @@ -170,7 +172,7 @@ authorizeMPToken( if ((flags & tfMPTUnauthorize) != 0u) { auto const mptokenKey = keylet::mptoken(mptIssuanceID, account); - auto const sleMpt = view.peek(mptokenKey); + MPTokenEntry sleMpt{mptokenKey, view}; if (!sleMpt || (*sleMpt)[sfMPTAmount] != 0 || (view.rules().enabled(fixCleanup3_1_3) && (*sleMpt)[~sfLockedAmount].valueOr(0) != 0)) @@ -180,9 +182,9 @@ authorizeMPToken( keylet::ownerDir(account), (*sleMpt)[sfOwnerNode], sleMpt->key(), false)) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleAcct, -1, journal); + adjustOwnerCount(view, sleAcct.mutableSle(), -1, journal); - view.erase(sleMpt); + sleMpt.erase(); return tesSUCCESS; } @@ -204,7 +206,7 @@ authorizeMPToken( return tecINSUFFICIENT_RESERVE; // Defensive check before we attempt to create MPToken for the issuer - auto const mpt = view.read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry const mpt{keylet::mptokenIssuance(mptIssuanceID), view}; if (!mpt || mpt->getAccountID(sfIssuer) == account) { // LCOV_EXCL_START @@ -225,12 +227,13 @@ authorizeMPToken( view.insert(mptoken); // Update owner count. - adjustOwnerCount(view, sleAcct, 1, journal); + adjustOwnerCount(view, sleAcct.mutableSle(), 1, journal); return tesSUCCESS; } - auto const sleMptIssuance = view.read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry const sleMptIssuance{ + keylet::mptokenIssuance(mptIssuanceID), view}; if (!sleMptIssuance) return tecINTERNAL; // LCOV_EXCL_LINE @@ -240,7 +243,7 @@ authorizeMPToken( if (account != (*sleMptIssuance)[sfIssuer]) return tecINTERNAL; // LCOV_EXCL_LINE - auto const sleMpt = view.peek(keylet::mptoken(mptIssuanceID, *holderID)); + MPTokenEntry sleMpt{keylet::mptoken(mptIssuanceID, *holderID), view}; if (!sleMpt) return tecINTERNAL; // LCOV_EXCL_LINE @@ -263,7 +266,7 @@ authorizeMPToken( if (flagsIn != flagsOut) sleMpt->setFieldU32(sfFlags, flagsOut); - view.update(sleMpt); + sleMpt.update(); return tesSUCCESS; } @@ -279,7 +282,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)); + MPTokenEntry mptoken{keylet::mptoken(mptID, accountID), view}; 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 @@ -330,7 +333,7 @@ requireAuth( }; auto const mptID = keylet::mptokenIssuance(mptIssue.getMptID()); - auto const sleIssuance = view.read(mptID); + MPTokenIssuanceEntry const sleIssuance{mptID, view}; if (!sleIssuance) return tecOBJECT_NOT_FOUND; @@ -355,13 +358,14 @@ requireAuth( } // requireAuth is recursive if the issuer is a vault pseudo-account - auto const sleIssuer = view.read(keylet::account(mptIssuer)); + AccountRootEntry const sleIssuer{keylet::account(mptIssuer), view}; if (!sleIssuer) return tefINTERNAL; // LCOV_EXCL_LINE if (sleIssuer->isFieldPresent(sfVaultID)) { - auto const sleVault = view.read(keylet::vault(sleIssuer->getFieldH256(sfVaultID))); + VaultEntry const sleVault{ + keylet::vault(sleIssuer->getFieldH256(sfVaultID)), view}; if (!sleVault) return tefINTERNAL; // LCOV_EXCL_LINE @@ -377,7 +381,7 @@ requireAuth( } auto const mptokenID = keylet::mptoken(mptID.key, account); - auto const sleToken = view.read(mptokenID); + MPTokenEntry const sleToken{mptokenID, view}; // if account has no MPToken, fail if (!sleToken && (authType == AuthType::StrongAuth || authType == AuthType::Legacy)) @@ -425,7 +429,7 @@ enforceMPTokenAuthorization( XRPAmount const& priorBalance, // for MPToken authorization beast::Journal j) { - auto const sleIssuance = view.read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry const sleIssuance{keylet::mptokenIssuance(mptIssuanceID), view}; if (!sleIssuance) return tefINTERNAL; // LCOV_EXCL_LINE @@ -437,7 +441,7 @@ enforceMPTokenAuthorization( return tefINTERNAL; // LCOV_EXCL_LINE auto const keylet = keylet::mptoken(mptIssuanceID, account); - auto const sleToken = view.read(keylet); // NOTE: might be null + MPTokenEntry const sleToken{keylet, view}; // NOTE: might be null auto const maybeDomainID = sleIssuance->at(~sfDomainID); bool expired = false; bool const authorizedByDomain = [&]() -> bool { @@ -453,7 +457,7 @@ enforceMPTokenAuthorization( return false; }(); - if (!authorizedByDomain && sleToken == nullptr) + if (!authorizedByDomain && !sleToken) { // Could not find MPToken and won't create one, could be either of: // @@ -476,14 +480,14 @@ enforceMPTokenAuthorization( // We found an MPToken, but sfDomainID is not set, so this is a classic // MPToken which requires authorization by the token issuer. XRPL_ASSERT( - sleToken != nullptr && !maybeDomainID.has_value(), + sleToken && !maybeDomainID.has_value(), "xrpl::enforceMPTokenAuthorization : found MPToken"); if (sleToken->isFlag(lsfMPTAuthorized)) return tesSUCCESS; return tecNO_AUTH; } - if (authorizedByDomain && sleToken != nullptr) + if (authorizedByDomain && sleToken) { // Found an MPToken, authorized by the domain. Ignore authorization flag // lsfMPTAuthorized because it is meaningless. Return tesSUCCESS @@ -497,7 +501,7 @@ enforceMPTokenAuthorization( // Could not find MPToken but there should be one because we are // authorized by domain. Proceed to create it, then return tesSUCCESS XRPL_ASSERT( - maybeDomainID.has_value() && sleToken == nullptr, + maybeDomainID.has_value() && !sleToken, "xrpl::enforceMPTokenAuthorization : new MPToken for domain"); if (auto const err = authorizeMPToken( view, @@ -550,7 +554,7 @@ canTransfer( std::uint8_t depth) { auto const mptID = keylet::mptokenIssuance(mptIssue.getMptID()); - auto const sleIssuance = view.read(mptID); + MPTokenIssuanceEntry const sleIssuance{mptID, view}; if (!sleIssuance) return tecOBJECT_NOT_FOUND; @@ -580,8 +584,8 @@ canTransfer( // LCOV_EXCL_STOP } - auto const sleHolding = - view.read(keylet::unchecked(sleIssuance->getFieldH256(sfReferenceHolding))); + ReadOnlySLE const sleHolding{ + keylet::unchecked(sleIssuance->getFieldH256(sfReferenceHolding)), view}; if (!sleHolding) return tefINTERNAL; // LCOV_EXCL_LINE @@ -603,7 +607,8 @@ canTrade(ReadView const& view, Asset const& asset, std::uint8_t depth) return asset.visit( [&](Issue const&) -> TER { return tesSUCCESS; }, [&](MPTIssue const& mptIssue) -> TER { - auto const sleIssuance = view.read(keylet::mptokenIssuance(mptIssue.getMptID())); + MPTokenIssuanceEntry const sleIssuance{ + keylet::mptokenIssuance(mptIssue.getMptID()), view}; if (!sleIssuance) return tecOBJECT_NOT_FOUND; if (!sleIssuance->isFlag(lsfMPTCanTrade)) @@ -625,8 +630,8 @@ canTrade(ReadView const& view, Asset const& asset, std::uint8_t depth) return tecINTERNAL; // LCOV_EXCL_STOP } - auto const sleHolding = - view.read(keylet::unchecked(sleIssuance->getFieldH256(sfReferenceHolding))); + ReadOnlySLE const sleHolding{ + keylet::unchecked(sleIssuance->getFieldH256(sfReferenceHolding)), view}; if (!sleHolding) return tefINTERNAL; // LCOV_EXCL_LINE @@ -658,7 +663,7 @@ lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, { auto const mptIssue = amount.get(); auto const mptID = keylet::mptokenIssuance(mptIssue.getMptID()); - auto sleIssuance = view.peek(mptID); + MPTokenIssuanceEntry sleIssuance{mptID, view}; if (!sleIssuance) { // LCOV_EXCL_START JLOG(j.error()) << "lockEscrowMPT: MPT issuance not found for " << mptIssue.getMptID(); @@ -675,7 +680,7 @@ lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, // 2. Increase the MPT Holder EscrowedAmount { auto const mptokenID = keylet::mptoken(mptID.key, sender); - auto sle = view.peek(mptokenID); + MPTokenEntry sle{mptokenID, view}; if (!sle) { // LCOV_EXCL_START JLOG(j.error()) << "lockEscrowMPT: MPToken not found for " << sender; @@ -714,7 +719,7 @@ lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, sle->setFieldU64(sfLockedAmount, pay); } - view.update(sle); + sle.update(); } // 1. Increase the Issuance EscrowedAmount @@ -741,7 +746,7 @@ lockEscrowMPT(ApplyView& view, AccountID const& sender, STAmount const& amount, sleIssuance->setFieldU64(sfLockedAmount, pay); } - view.update(sleIssuance); + sleIssuance.update(); } return tesSUCCESS; } @@ -763,7 +768,7 @@ unlockEscrowMPT( auto const& issuer = netAmount.getIssuer(); auto const& mptIssue = netAmount.get(); auto const mptID = keylet::mptokenIssuance(mptIssue.getMptID()); - auto sleIssuance = view.peek(mptID); + MPTokenIssuanceEntry sleIssuance{mptID, view}; if (!sleIssuance) { // LCOV_EXCL_START JLOG(j.error()) << "unlockEscrowMPT: MPT issuance not found for " << mptIssue.getMptID(); @@ -799,14 +804,14 @@ unlockEscrowMPT( { sleIssuance->setFieldU64(sfLockedAmount, newLocked); } - view.update(sleIssuance); + sleIssuance.update(); } if (issuer != receiver) { // Increase the MPT Holder MPTAmount auto const mptokenID = keylet::mptoken(mptID.key, receiver); - auto sle = view.peek(mptokenID); + MPTokenEntry sle{mptokenID, view}; if (!sle) { // LCOV_EXCL_START JLOG(j.error()) << "unlockEscrowMPT: MPToken not found for " << receiver; @@ -825,7 +830,7 @@ unlockEscrowMPT( } // LCOV_EXCL_STOP (*sle)[sfMPTAmount] += delta; - view.update(sle); + sle.update(); } else { @@ -842,7 +847,7 @@ unlockEscrowMPT( } // LCOV_EXCL_STOP sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - redeem); - view.update(sleIssuance); + sleIssuance.update(); } if (issuer == sender) @@ -853,7 +858,7 @@ unlockEscrowMPT( } // LCOV_EXCL_STOP // Decrease the MPT Holder EscrowedAmount auto const mptokenID = keylet::mptoken(mptID.key, sender); - auto sle = view.peek(mptokenID); + MPTokenEntry sle{mptokenID, view}; if (!sle) { // LCOV_EXCL_START JLOG(j.error()) << "unlockEscrowMPT: MPToken not found for " << sender; @@ -886,7 +891,7 @@ unlockEscrowMPT( { sle->setFieldU64(sfLockedAmount, newLocked); } - view.update(sle); + sle.update(); // Note: The gross amount is the amount that was locked, the net // amount is the amount that is being unlocked. The difference is the fee @@ -905,7 +910,7 @@ unlockEscrowMPT( } // LCOV_EXCL_STOP sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - diff); - view.update(sleIssuance); + sleIssuance.update(); } return tesSUCCESS; } @@ -925,13 +930,14 @@ createMPToken( if (!ownerNode) return tecDIR_FULL; // LCOV_EXCL_LINE - auto mptoken = std::make_shared(mptokenKey); + MPTokenEntry mptoken{mptokenKey, view}; + mptoken.newSLE(); (*mptoken)[sfAccount] = account; (*mptoken)[sfMPTokenIssuanceID] = mptIssuanceID; (*mptoken)[sfFlags] = flags; (*mptoken)[sfOwnerNode] = *ownerNode; - view.insert(mptoken); + mptoken.insert(); return tesSUCCESS; } @@ -955,12 +961,12 @@ checkCreateMPT( { return err; } - auto const sleAcct = view.peek(keylet::account(holder)); + AccountRootEntry const sleAcct{keylet::account(holder), view}; if (!sleAcct) { return tecINTERNAL; } - adjustOwnerCount(view, sleAcct, 1, j); + adjustOwnerCount(view, sleAcct.mutableSle(), 1, j); } return tesSUCCESS; } @@ -982,7 +988,7 @@ availableMPTAmount(SLE const& sleIssuance) std::int64_t availableMPTAmount(ReadView const& view, MPTID const& mptID) { - auto const sle = view.read(keylet::mptokenIssuance(mptID)); + MPTokenIssuanceEntry const sle{keylet::mptokenIssuance(mptID), view}; if (!sle) Throw(transHuman(tecINTERNAL)); return availableMPTAmount(*sle); @@ -1006,7 +1012,7 @@ issuerFundsToSelfIssue(ReadView const& view, MPTIssue const& issue) { STAmount amount{issue}; - auto const sle = view.read(keylet::mptokenIssuance(issue)); + MPTokenIssuanceEntry const sle{keylet::mptokenIssuance(issue), view}; if (!sle) return amount; auto const available = availableMPTAmount(*sle); diff --git a/src/libxrpl/ledger/helpers/NFTokenHelpers.cpp b/src/libxrpl/ledger/helpers/NFTokenHelpers.cpp index 6dca715a8c..bf633bb066 100644 --- a/src/libxrpl/ledger/helpers/NFTokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/NFTokenHelpers.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -182,7 +183,8 @@ getPageForToken( ? narr[kDirMaxTokensPerPage - 1].getFieldH256(sfNFTokenID).next() : carr[0].getFieldH256(sfNFTokenID); - auto np = std::make_shared(keylet::nftokenPage(base, tokenIDForNewPage)); + NFTokenPageEntry np{base, tokenIDForNewPage, view}; + np.newSLE(); XRPL_ASSERT(np->key() > base.key, "xrpl::nft::getPageForToken : valid NFT page index"); np->setFieldArray(sfNFTokens, narr); np->setFieldH256(sfNextPageMin, cp->key()); @@ -191,14 +193,14 @@ getPageForToken( { np->setFieldH256(sfPreviousPageMin, *ppm); - if (auto p3 = view.peek(Keylet(ltNFTOKEN_PAGE, *ppm))) + if (NFTokenPageEntry p3{Keylet(ltNFTOKEN_PAGE, *ppm), view}) { p3->setFieldH256(sfNextPageMin, np->key()); - view.update(p3); + p3.update(); } } - view.insert(np); + np.insert(); cp->setFieldArray(sfNFTokens, carr); cp->setFieldH256(sfPreviousPageMin, np->key()); @@ -206,7 +208,7 @@ getPageForToken( createCallback(view, owner); - return (first.key < np->key()) ? np : cp; + return (first.key < np->key()) ? np.mutableSle() : cp; } bool @@ -230,7 +232,7 @@ changeTokenURI( uint256 const& nftokenID, std::optional const& uri) { - SLE::pointer const page = locatePage(view, owner, nftokenID); + NFTokenPageEntry page{locatePage(view, owner, nftokenID), view}; // If the page couldn't be found, the given NFT isn't owned by this account if (!page) @@ -254,7 +256,7 @@ changeTokenURI( nftIter->makeFieldAbsent(sfURI); } - view.update(page); + page.update(); return tesSUCCESS; } @@ -267,14 +269,19 @@ insertToken(ApplyView& view, AccountID owner, STObject&& nft) // First, we need to locate the page the NFT belongs to, creating it // if necessary. This operation may fail if it is impossible to insert // the NFT. - SLE::pointer const page = - getPageForToken(view, owner, nft[sfNFTokenID], [](ApplyView& view, AccountID const& owner) { - adjustOwnerCount( - view, - view.peek(keylet::account(owner)), - 1, - beast::Journal{beast::Journal::getNullSink()}); - }); + NFTokenPageEntry page{ + getPageForToken( + view, + owner, + nft[sfNFTokenID], + [](ApplyView& view, AccountID const& owner) { + adjustOwnerCount( + view, + view.peek(keylet::account(owner)), + 1, + beast::Journal{beast::Journal::getNullSink()}); + }), + view}; if (!page) return tecNO_SUITABLE_NFTOKEN_PAGE; @@ -290,7 +297,7 @@ insertToken(ApplyView& view, AccountID owner, STObject&& nft) page->setFieldArray(sfNFTokens, arr); } - view.update(page); + page.update(); return tesSUCCESS; } @@ -334,13 +341,13 @@ mergePages(ApplyView& view, SLE::ref p1, SLE::ref p2) if (auto const ppm = (*p1)[~sfPreviousPageMin]) { - auto p0 = view.peek(Keylet(ltNFTOKEN_PAGE, *ppm)); + NFTokenPageEntry p0{Keylet(ltNFTOKEN_PAGE, *ppm), view}; if (!p0) Throw("mergePages: p0 can't be located!"); p0->setFieldH256(sfNextPageMin, p2->key()); - view.update(p0); + p0.update(); p2->setFieldH256(sfPreviousPageMin, *ppm); } @@ -355,13 +362,13 @@ mergePages(ApplyView& view, SLE::ref p1, SLE::ref p2) TER removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID) { - SLE::pointer const page = locatePage(view, owner, nftokenID); + NFTokenPageEntry page{locatePage(view, owner, nftokenID), view}; // If the page couldn't be found, the given NFT isn't owned by this account if (!page) return tecNO_ENTRY; - return removeToken(view, owner, nftokenID, page); + return removeToken(view, owner, nftokenID, page.mutableSle()); } /** Remove the token from the owner's token directory. */ @@ -400,8 +407,8 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S return page2; }; - auto const prev = loadPage(curr, sfPreviousPageMin); - auto const next = loadPage(curr, sfNextPageMin); + NFTokenPageEntry prev{loadPage(curr, sfPreviousPageMin), view}; + NFTokenPageEntry next{loadPage(curr, sfNextPageMin), view}; if (!arr.empty()) { @@ -413,10 +420,10 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S int cnt = 0; - if (prev && mergePages(view, prev, curr)) + if (prev && mergePages(view, prev.mutableSle(), curr)) cnt--; - if (next && mergePages(view, curr, next)) + if (next && mergePages(view, curr, next.mutableSle())) cnt--; if (cnt != 0) @@ -451,9 +458,9 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S curr->at(sfPreviousPageMin) = *prevLink; // Also fix up the NextPageMin link in the new Previous. - auto const newPrev = loadPage(curr, sfPreviousPageMin); + NFTokenPageEntry newPrev{loadPage(curr, sfPreviousPageMin), view}; newPrev->at(sfNextPageMin) = curr->key(); - view.update(newPrev); + newPrev.update(); } else { @@ -467,7 +474,7 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S beast::Journal{beast::Journal::getNullSink()}); view.update(curr); - view.erase(prev); + prev.erase(); return tesSUCCESS; } @@ -482,7 +489,7 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S prev->makeFieldAbsent(sfNextPageMin); } - view.update(prev); + prev.update(); } if (next) @@ -497,7 +504,7 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S next->makeFieldAbsent(sfPreviousPageMin); } - view.update(next); + next.update(); } view.erase(curr); @@ -531,7 +538,7 @@ removeToken(ApplyView& view, AccountID const& owner, uint256 const& nftokenID, S std::optional findToken(ReadView const& view, AccountID const& owner, uint256 const& nftokenID) { - SLE::const_pointer const page = locatePage(view, owner, nftokenID); + NFTokenPageEntry const page{locatePage(view, owner, nftokenID), view}; // If the page couldn't be found, the given NFT isn't owned by this account if (!page) @@ -579,7 +586,7 @@ removeTokenOffersWithLimit(ApplyView& view, Keylet const& directory, std::size_t do { - auto const page = view.peek(keylet::page(directory, *pageIndex)); + DirectoryNodeEntry const page{keylet::page(directory, *pageIndex), view}; if (!page) break; @@ -597,9 +604,10 @@ removeTokenOffersWithLimit(ApplyView& view, Keylet const& directory, std::size_t // deleting during iteration. for (int i = offerIndexes.size() - 1; i >= 0; --i) { - if (auto const offer = view.peek(keylet::nftokenOffer(offerIndexes[i]))) + if (NFTokenOfferEntry const offer{ + keylet::nftokenOffer(offerIndexes[i]), view}) { - if (deleteTokenOffer(view, offer)) + if (deleteTokenOffer(view, offer.mutableSle())) { ++deletedOffersCount; } @@ -740,7 +748,7 @@ repairNFTokenDirectoryLinks(ApplyView& view, AccountID const& owner) nextPage->at(sfPreviousPageMin) = *prevLink; // Also fix up the NextPageMin link in the new Previous. - auto const newPrev = view.peek(Keylet(ltNFTOKEN_PAGE, *prevLink)); + NFTokenPageEntry newPrev{Keylet(ltNFTOKEN_PAGE, *prevLink), view}; if (!newPrev) { Throw( @@ -748,7 +756,7 @@ repairNFTokenDirectoryLinks(ApplyView& view, AccountID const& owner) " cannot be repaired. Unexpected link problem."); } newPrev->at(sfNextPageMin) = nextPage->key(); - view.update(newPrev); + newPrev.update(); } view.erase(page); view.insert(nextPage); @@ -853,7 +861,7 @@ tokenOfferCreatePreclaim( if (nftIssuer != acctID && ((nftFlags & nft::kFlagTransferable) == 0)) { - auto const root = view.read(keylet::account(nftIssuer)); + AccountRootEntry const root{keylet::account(nftIssuer), view}; XRPL_ASSERT(root, "xrpl::nft::tokenOfferCreatePreclaim : non-null account"); if (auto minter = (*root)[~sfNFTokenMinter]; minter != acctID) @@ -878,7 +886,7 @@ tokenOfferCreatePreclaim( { // If a destination is specified, the destination must already be in // the ledger. - auto const sleDst = view.read(keylet::account(*dest)); + AccountRootEntry const sleDst{keylet::account(*dest), view}; if (!sleDst) return tecNO_DST; @@ -890,7 +898,7 @@ tokenOfferCreatePreclaim( if (owner) { - auto const sleOwner = view.read(keylet::account(*owner)); + AccountRootEntry const sleOwner{keylet::account(*owner), view}; // defensively check // it should not be possible to specify owner that doesn't exist @@ -930,7 +938,7 @@ tokenOfferCreateApply( std::uint32_t txFlags) { Keylet const acctKeylet = keylet::account(acctID); - if (auto const acct = view.read(acctKeylet); + if (AccountRootEntry const acct{acctKeylet, view}; priorBalance < view.fees().accountReserve((*acct)[sfOwnerCount] + 1)) return tecINSUFFICIENT_RESERVE; @@ -965,7 +973,8 @@ tokenOfferCreateApply( if (isSellOffer) sleFlags |= lsfSellNFToken; - auto offer = std::make_shared(offerID); + NFTokenOfferEntry offer{offerID, view}; + offer.newSLE(); (*offer)[sfOwner] = acctID; (*offer)[sfNFTokenID] = nftokenID; (*offer)[sfAmount] = amount; @@ -979,7 +988,7 @@ tokenOfferCreateApply( if (dest) (*offer)[sfDestination] = *dest; - view.insert(offer); + offer.insert(); } // Update owner count. @@ -1000,7 +1009,7 @@ checkTrustlineAuthorized( if (view.rules().enabled(fixEnforceNFTokenTrustlineV2)) { - auto const issuerAccount = view.read(keylet::account(issue.account)); + AccountRootEntry const issuerAccount{keylet::account(issue.account), view}; if (!issuerAccount) { JLOG(j.debug()) << "xrpl::nft::checkTrustlineAuthorized: can't " @@ -1020,7 +1029,7 @@ checkTrustlineAuthorized( if (issuerAccount->isFlag(lsfRequireAuth)) { - auto const trustLine = view.read(keylet::trustLine(id, issue.account, issue.currency)); + RippleStateEntry const trustLine{id, issue.account, issue.currency, view}; if (!trustLine) { @@ -1052,7 +1061,7 @@ checkTrustlineDeepFrozen( if (view.rules().enabled(featureDeepFreeze)) { - auto const issuerAccount = view.read(keylet::account(issue.account)); + AccountRootEntry const issuerAccount{keylet::account(issue.account), view}; if (!issuerAccount) { JLOG(j.debug()) << "xrpl::nft::checkTrustlineDeepFrozen: can't " @@ -1070,7 +1079,7 @@ checkTrustlineDeepFrozen( return tesSUCCESS; } - auto const trustLine = view.read(keylet::trustLine(id, issue.account, issue.currency)); + RippleStateEntry const trustLine{id, issue.account, issue.currency, view}; if (!trustLine) { diff --git a/src/libxrpl/ledger/helpers/PaymentChannelHelpers.cpp b/src/libxrpl/ledger/helpers/PaymentChannelHelpers.cpp index 03b68e8860..b2fb70d41a 100644 --- a/src/libxrpl/ledger/helpers/PaymentChannelHelpers.cpp +++ b/src/libxrpl/ledger/helpers/PaymentChannelHelpers.cpp @@ -22,7 +22,11 @@ namespace xrpl { TER -closeChannel(SLE::ref slep, ApplyView& view, uint256 const& key, beast::Journal j) +closeChannel( + PayChannelEntry& slep, + ApplyView& view, + uint256 const& key, + beast::Journal j) { AccountID const src = (*slep)[sfAccount]; // Remove PayChan from owner directory @@ -51,18 +55,18 @@ closeChannel(SLE::ref slep, ApplyView& view, uint256 const& key, beast::Journal } // Transfer amount back to owner, decrement owner count - auto const sle = view.peek(keylet::account(src)); + AccountRootEntry sle{src, view}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE XRPL_ASSERT( (*slep)[sfAmount] >= (*slep)[sfBalance], "xrpl::closeChannel : minimum channel amount"); (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount] - (*slep)[sfBalance]; - adjustOwnerCount(view, sle, -1, j); - view.update(sle); + adjustOwnerCount(view, sle.mutableSle(), -1, j); + sle.update(); // Remove PayChan from ledger - view.erase(slep); + slep.erase(); return tesSUCCESS; } diff --git a/src/libxrpl/ledger/helpers/PermissionedDEXHelpers.cpp b/src/libxrpl/ledger/helpers/PermissionedDEXHelpers.cpp index f8653f7111..d7e22c9659 100644 --- a/src/libxrpl/ledger/helpers/PermissionedDEXHelpers.cpp +++ b/src/libxrpl/ledger/helpers/PermissionedDEXHelpers.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ accountInDomain(ReadView const& view, AccountID const& account, Domain const& do // LCOV_EXCL_STOP } - auto const sleDomain = view.read(keylet::permissionedDomain(domainID)); + PermissionedDomainEntry sleDomain{keylet::permissionedDomain(domainID), view}; if (!sleDomain) return false; @@ -42,8 +43,8 @@ accountInDomain(ReadView const& view, AccountID const& account, Domain const& do auto const& credentials = sleDomain->getFieldArray(sfAcceptedCredentials); bool const inDomain = std::ranges::any_of(credentials, [&](auto const& credential) { - auto const sleCred = view.read( - keylet::credential(account, credential[sfIssuer], credential[sfCredentialType])); + CredentialEntry sleCred{ + keylet::credential(account, credential[sfIssuer], credential[sfCredentialType]), view}; if (!sleCred || !sleCred->isFlag(lsfAccepted)) return false; @@ -60,7 +61,7 @@ offerInDomain( Domain const& domainID, beast::Journal j) { - auto const sleOffer = view.read(keylet::offer(offerID)); + OfferEntry sleOffer{keylet::offer(offerID), view}; // The following are defensive checks that should never happen, since this // function is used to check against the order book offers, which should not diff --git a/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp index 5a2995c030..79810b8473 100644 --- a/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp +++ b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,7 @@ creditLimit( { STAmount result(Issue{currency, account}); - auto sleRippleState = view.read(keylet::trustLine(account, issuer, currency)); + RippleStateEntry sleRippleState{keylet::trustLine(account, issuer, currency), view}; if (sleRippleState) { @@ -78,7 +79,7 @@ creditBalance( { STAmount result(Issue{currency, account}); - auto sleRippleState = view.read(keylet::trustLine(account, issuer, currency)); + RippleStateEntry sleRippleState{keylet::trustLine(account, issuer, currency), view}; if (sleRippleState) { @@ -114,7 +115,7 @@ isIndividualFrozen( if (issuer != account) { // Check if the issuer froze the line - auto const sle = view.read(keylet::trustLine(account, issuer, currency)); + RippleStateEntry const sle{keylet::trustLine(account, issuer, currency), view}; if (sle && sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze)) return true; } @@ -162,7 +163,7 @@ isDeepFrozen( return false; } - auto const sle = view.read(keylet::trustLine(account, issuer, currency)); + RippleStateEntry const sle{keylet::trustLine(account, issuer, currency), view}; if (!sle) { return false; @@ -211,8 +212,9 @@ trustCreate( // LCOV_EXCL_STOP } - auto const sleRippleState = std::make_shared(ltRIPPLE_STATE, uIndex); - view.insert(sleRippleState); + RippleStateEntry sleRippleState{Keylet(ltRIPPLE_STATE, uIndex), view}; + sleRippleState.newSLE(); + sleRippleState.insert(); auto lowNode = view.dirInsert( keylet::ownerDir(uLowAccountID), sleRippleState->key(), describeOwnerDir(uLowAccountID)); @@ -236,7 +238,8 @@ trustCreate( XRPL_ASSERT( sleAccount->getAccountID(sfAccount) == (bSetHigh ? uHighAccountID : uLowAccountID), "xrpl::trustCreate : matching account ID"); - auto const slePeer = view.peek(keylet::account(bSetHigh ? uLowAccountID : uHighAccountID)); + AccountRootEntry const slePeer{ + keylet::account(bSetHigh ? uLowAccountID : uHighAccountID), view}; if (!slePeer) return tecNO_TARGET; @@ -342,7 +345,7 @@ updateTrustLine( if (!state) return false; - auto sle = view.peek(keylet::account(sender)); + AccountRootEntry sle{keylet::account(sender), view}; if (!sle) return false; @@ -369,7 +372,7 @@ updateTrustLine( { // VFALCO Where is the line being deleted? // Clear the reserve of the sender, possibly delete the line! - adjustOwnerCount(view, sle, -1, j); + adjustOwnerCount(view, sle.mutableSle(), -1, j); // Clear reserve flag. state->clearFlag(senderReserveFlag); @@ -405,7 +408,7 @@ issueIOU( auto const index = keylet::trustLine(issue.account, account, issue.currency); - if (auto state = view.peek(index)) + if (RippleStateEntry state{index, view}) { STAmount finalBalance = state->getFieldAmount(sfBalance); @@ -416,8 +419,8 @@ issueIOU( finalBalance -= amount; - auto const mustDelete = - updateTrustLine(view, state, bSenderHigh, issue.account, startBalance, finalBalance, j); + auto const mustDelete = updateTrustLine( + view, state.mutableSle(), bSenderHigh, issue.account, startBalance, finalBalance, j); view.creditHookIOU(issue.account, account, amount, startBalance); @@ -432,13 +435,13 @@ issueIOU( { return trustDelete( view, - state, + state.mutableSle(), bSenderHigh ? account : issue.account, bSenderHigh ? issue.account : account, j); } - view.update(state); + state.update(); return tesSUCCESS; } @@ -451,7 +454,7 @@ issueIOU( finalBalance.get().account = noAccount(); - auto const receiverAccount = view.peek(keylet::account(account)); + AccountRootEntry const receiverAccount{keylet::account(account), view}; if (!receiverAccount) return tefINTERNAL; // LCOV_EXCL_LINE @@ -463,7 +466,7 @@ issueIOU( issue.account, account, index.key, - receiverAccount, + receiverAccount.mutableSle(), false, noRipple, false, @@ -497,7 +500,8 @@ redeemIOU( bool const bSenderHigh = account > issue.account; - if (auto state = view.peek(keylet::trustLine(account, issue.account, issue.currency))) + if (RippleStateEntry state{ + keylet::trustLine(account, issue.account, issue.currency), view}) { STAmount finalBalance = state->getFieldAmount(sfBalance); @@ -508,8 +512,8 @@ redeemIOU( finalBalance -= amount; - auto const mustDelete = - updateTrustLine(view, state, bSenderHigh, account, startBalance, finalBalance, j); + auto const mustDelete = updateTrustLine( + view, state.mutableSle(), bSenderHigh, account, startBalance, finalBalance, j); view.creditHookIOU(account, issue.account, amount, startBalance); @@ -525,13 +529,13 @@ redeemIOU( { return trustDelete( view, - state, + state.mutableSle(), bSenderHigh ? issue.account : account, bSenderHigh ? account : issue.account, j); } - view.update(state); + state.update(); return tesSUCCESS; } @@ -558,14 +562,15 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account, if (isXRP(issue) || issue.account == account) return tesSUCCESS; - auto const trustLine = view.read(keylet::trustLine(account, issue.account, issue.currency)); + RippleStateEntry const trustLine{ + keylet::trustLine(account, issue.account, issue.currency), view}; // If account has no line, and this is a strong check, fail if (!trustLine && authType == AuthType::StrongAuth) return tecNO_LINE; // If this is a weak or legacy check, or if the account has a line, fail if // auth is required and not set on the line - if (auto const issuerAccount = view.read(keylet::account(issue.account)); + if (AccountRootEntry const issuerAccount{keylet::account(issue.account), view}; issuerAccount && issuerAccount->isFlag(lsfRequireAuth)) { if (trustLine) @@ -589,14 +594,14 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc auto const& issuerId = issue.getIssuer(); if (issuerId == from || issuerId == to) return tesSUCCESS; - auto const sleIssuer = view.read(keylet::account(issuerId)); - if (sleIssuer == nullptr) + AccountRootEntry const sleIssuer{keylet::account(issuerId), view}; + if (!sleIssuer) return tefINTERNAL; // LCOV_EXCL_LINE auto const isRippleDisabled = [&](AccountID account) -> bool { // Line might not exist, but some transfers can create it. If this // is the case, just check the default ripple on the issuer account. - auto const line = view.read(keylet::trustLine(account, issue)); + RippleStateEntry const line{keylet::trustLine(account, issue), view}; if (line) { bool const issuerHigh = issuerId > account; @@ -639,8 +644,8 @@ addEmptyHolding( 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)); + AccountRootEntry const sleSrc{keylet::account(srcId), view}; + AccountRootEntry const sleDst{keylet::account(dstId), view}; if (!sleDst || !sleSrc) return tefINTERNAL; // LCOV_EXCL_LINE if (!sleSrc->isFlag(lsfDefaultRipple)) @@ -660,7 +665,7 @@ addEmptyHolding( srcId, dstId, index.key, - sleDst, + sleDst.mutableSle(), /*bAuth=*/false, /*bNoRipple=*/true, /*bFreeze=*/false, @@ -681,7 +686,7 @@ removeEmptyHolding( { if (issue.native()) { - auto const sle = view.read(keylet::account(accountID)); + AccountRootEntry const sle{keylet::account(accountID), view}; if (!sle) return tecINTERNAL; // LCOV_EXCL_LINE @@ -696,7 +701,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)); + RippleStateEntry line{keylet::trustLine(accountID, issue), view}; if (!line) return accountIsIssuer ? (TER)tesSUCCESS : (TER)tecOBJECT_NOT_FOUND; if (!accountIsIssuer && line->at(sfBalance)->iou() != beast::kZero) @@ -706,11 +711,12 @@ removeEmptyHolding( if (line->isFlag(lsfLowReserve)) { // Clear reserve for low account. - auto sleLowAccount = view.peek(keylet::account(line->at(sfLowLimit)->getIssuer())); + AccountRootEntry sleLowAccount{ + keylet::account(line->at(sfLowLimit)->getIssuer()), view}; if (!sleLowAccount) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleLowAccount, -1, journal); + adjustOwnerCount(view, sleLowAccount.mutableSle(), -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. @@ -720,11 +726,12 @@ removeEmptyHolding( if (line->isFlag(lsfHighReserve)) { // Clear reserve for high account. - auto sleHighAccount = view.peek(keylet::account(line->at(sfHighLimit)->getIssuer())); + AccountRootEntry sleHighAccount{ + keylet::account(line->at(sfHighLimit)->getIssuer()), view}; if (!sleHighAccount) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleHighAccount, -1, journal); + adjustOwnerCount(view, sleHighAccount.mutableSle(), -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. @@ -732,7 +739,11 @@ removeEmptyHolding( } return trustDelete( - view, line, line->at(sfLowLimit)->getIssuer(), line->at(sfHighLimit)->getIssuer(), journal); + view, + line.mutableSle(), + line->at(sfLowLimit)->getIssuer(), + line->at(sfHighLimit)->getIssuer(), + journal); } TER @@ -748,8 +759,8 @@ deleteAMMTrustLine( auto const& [low, high] = std::minmax( sleState->getFieldAmount(sfLowLimit).getIssuer(), sleState->getFieldAmount(sfHighLimit).getIssuer()); - auto sleLow = view.peek(keylet::account(low)); - auto sleHigh = view.peek(keylet::account(high)); + AccountRootEntry sleLow{keylet::account(low), view}; + AccountRootEntry sleHigh{keylet::account(high), view}; if (!sleLow || !sleHigh) return tecINTERNAL; // LCOV_EXCL_LINE @@ -778,7 +789,7 @@ deleteAMMTrustLine( if (!sleState->isFlag(uFlags)) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j); + adjustOwnerCount(view, !ammLow ? sleLow.mutableSle() : sleHigh.mutableSle(), -1, j); return tesSUCCESS; } diff --git a/src/libxrpl/ledger/helpers/SponsorHelpers.cpp b/src/libxrpl/ledger/helpers/SponsorHelpers.cpp index 30fc92ad8c..c8eef4358b 100644 --- a/src/libxrpl/ledger/helpers/SponsorHelpers.cpp +++ b/src/libxrpl/ledger/helpers/SponsorHelpers.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ getLedgerEntryOwner(ReadView const& view, SLE const& sle, AccountID const& accou case ltMPTOKEN_ISSUANCE: return sle.getAccountID(sfIssuer); case ltSIGNER_LIST: { - auto const signerList = view.read(keylet::signerList(account)); + SignerListEntry signerList{keylet::signerList(account), view}; if (!signerList) return std::nullopt; if (signerList->key() == sle.key()) diff --git a/src/libxrpl/ledger/helpers/TokenHelpers.cpp b/src/libxrpl/ledger/helpers/TokenHelpers.cpp index 0ab97a4b60..8c7821cc7e 100644 --- a/src/libxrpl/ledger/helpers/TokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/TokenHelpers.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -275,7 +276,7 @@ getLineIfUsable( FreezeHandling zeroIfFrozen, beast::Journal j) { - auto sle = view.read(keylet::trustLine(account, issuer, currency)); + RippleStateEntry sle{keylet::trustLine(account, issuer, currency), view}; if (!sle) { @@ -294,14 +295,14 @@ getLineIfUsable( // we need to check if the associated assets have been frozen if (view.rules().enabled(fixFrozenLPTokenTransfer)) { - auto const sleIssuer = view.read(keylet::account(issuer)); + AccountRootEntry const sleIssuer{keylet::account(issuer), view}; if (!sleIssuer) { return nullptr; // LCOV_EXCL_LINE } if (sleIssuer->isFieldPresent(sfAMMID)) { - auto const sleAmm = view.read(keylet::amm((*sleIssuer)[sfAMMID])); + AMMEntry const sleAmm{keylet::amm((*sleIssuer)[sfAMMID]), view}; if (!sleAmm || isLPTokenFrozen(view, account, (*sleAmm)[sfAsset], (*sleAmm)[sfAsset2])) @@ -312,7 +313,7 @@ getLineIfUsable( } } - return sle; + return sle.sle(); } static STAmount @@ -416,7 +417,8 @@ accountHolds( { // if the account is the issuer, and the issuance exists, their limit is // the issuance limit minus the outstanding value - auto const issuance = view.read(keylet::mptokenIssuance(mptIssue.getMptID())); + MPTokenIssuanceEntry const issuance{ + keylet::mptokenIssuance(mptIssue.getMptID()), view}; if (!issuance) { @@ -428,7 +430,7 @@ accountHolds( return view.balanceHookMPT(issuer, mptIssue, available); } - auto const sleMpt = view.read(keylet::mptoken(mptIssue.getMptID(), account)); + MPTokenEntry const sleMpt{keylet::mptoken(mptIssue.getMptID(), account), view}; if (!sleMpt || (zeroIfFrozen == FreezeHandling::ZeroIfFrozen && isFrozen(view, account, mptIssue))) @@ -451,7 +453,8 @@ accountHolds( } else if (zeroIfUnauthorized == AuthHandling::ZeroIfUnauthorized) { - auto const sleIssuance = view.read(keylet::mptokenIssuance(mptIssue.getMptID())); + MPTokenIssuanceEntry const sleIssuance{ + keylet::mptokenIssuance(mptIssue.getMptID()), view}; // if auth is enabled on the issuance and mpt is not authorized, // clear amount @@ -548,7 +551,7 @@ canAddHolding(ReadView const& view, Issue const& issue) return tesSUCCESS; // No special checks for XRP } - auto const issuer = view.read(keylet::account(issue.getIssuer())); + AccountRootEntry const issuer{keylet::account(issue.getIssuer()), view}; if (!issuer) { return terNO_ACCOUNT; @@ -672,7 +675,7 @@ directSendNoFeeIOU( "xrpl::directSendNoFeeIOU : receiver is not XRP"); // If the line exists, modify it accordingly. - if (auto const sleRippleState = view.peek(index)) + if (RippleStateEntry sleRippleState{index, view}) { STAmount saBalance = sleRippleState->getFieldAmount(sfBalance); @@ -739,13 +742,13 @@ directSendNoFeeIOU( { return trustDelete( view, - sleRippleState, + sleRippleState.mutableSle(), bSenderHigh ? uReceiverID : uSenderID, bSenderHigh ? uSenderID : uReceiverID, j); } - view.update(sleRippleState); + sleRippleState.update(); return tesSUCCESS; } @@ -759,7 +762,7 @@ directSendNoFeeIOU( << to_string(uSenderID) << " -> " << to_string(uReceiverID) << " : " << saAmount.getFullText(); - auto const sleAccount = view.peek(keylet::account(uReceiverID)); + AccountRootEntry const sleAccount{keylet::account(uReceiverID), view}; if (!sleAccount) return tefINTERNAL; // LCOV_EXCL_LINE @@ -771,7 +774,7 @@ directSendNoFeeIOU( uSenderID, uReceiverID, index.key, - sleAccount, + sleAccount.mutableSle(), false, noRipple, false, @@ -956,10 +959,11 @@ accountSendIOU( */ TER terResult(tesSUCCESS); - SLE::pointer const sender = - uSenderID != beast::kZero ? view.peek(keylet::account(uSenderID)) : SLE::pointer(); - SLE::pointer const receiver = - uReceiverID != beast::kZero ? view.peek(keylet::account(uReceiverID)) : SLE::pointer(); + AccountRootEntry sender{ + uSenderID != beast::kZero ? view.peek(keylet::account(uSenderID)) : SLE::pointer(), view}; + AccountRootEntry receiver{ + uReceiverID != beast::kZero ? view.peek(keylet::account(uReceiverID)) : SLE::pointer(), + view}; if (auto stream = j.trace()) { @@ -993,7 +997,7 @@ accountSendIOU( // Decrement XRP balance. sender->setFieldAmount(sfBalance, sndBal - saAmount); - view.update(sender); + sender.update(); } } @@ -1004,7 +1008,7 @@ accountSendIOU( receiver->setFieldAmount(sfBalance, rcvBal + saAmount); view.creditHookIOU(xrpAccount(), uReceiverID, saAmount, -rcvBal); - view.update(receiver); + receiver.update(); } if (auto stream = j.trace()) @@ -1052,8 +1056,8 @@ accountSendMultiIOU( * ensure that transfers are balanced. */ - SLE::pointer const sender = - senderID != beast::kZero ? view.peek(keylet::account(senderID)) : SLE::pointer(); + AccountRootEntry sender{ + senderID != beast::kZero ? view.peek(keylet::account(senderID)) : SLE::pointer(), view}; if (auto stream = j.trace()) { @@ -1084,8 +1088,9 @@ accountSendMultiIOU( if (!amount || (senderID == receiverID)) continue; - SLE::pointer const receiver = - receiverID != beast::kZero ? view.peek(keylet::account(receiverID)) : SLE::pointer(); + AccountRootEntry receiver{ + receiverID != beast::kZero ? view.peek(keylet::account(receiverID)) : SLE::pointer(), + view}; if (auto stream = j.trace()) { @@ -1106,7 +1111,7 @@ accountSendMultiIOU( receiver->setFieldAmount(sfBalance, rcvBal + amount); view.creditHookIOU(xrpAccount(), receiverID, amount, -rcvBal); - view.update(receiver); + receiver.update(); // Take what is actually sent takeFromSender += amount; @@ -1136,7 +1141,7 @@ accountSendMultiIOU( // Decrement XRP balance. sender->setFieldAmount(sfBalance, sndBal - takeFromSender); - view.update(sender); + sender.update(); } if (auto stream = j.trace()) @@ -1163,7 +1168,7 @@ directSendNoFeeMPT( // Do not check MPT authorization here - it must have been checked earlier auto const mptID = keylet::mptokenIssuance(saAmount.get().getMptID()); auto const& issuer = saAmount.getIssuer(); - auto sleIssuance = view.peek(mptID); + MPTokenIssuanceEntry sleIssuance{mptID, view}; if (!sleIssuance) return tecOBJECT_NOT_FOUND; @@ -1180,19 +1185,19 @@ directSendNoFeeMPT( return tecPATH_DRY; } (*sleIssuance)[sfOutstandingAmount] += amt; - view.update(sleIssuance); + sleIssuance.update(); } else { auto const mptokenID = keylet::mptoken(mptID.key, uSenderID); - if (auto sle = view.peek(mptokenID)) + if (MPTokenEntry sle{mptokenID, view}) { auto const senderBalance = sle->getFieldU64(sfMPTAmount); if (senderBalance < amt) return tecINSUFFICIENT_FUNDS; view.creditHookMPT(uSenderID, uReceiverID, saAmount, (*sle)[sfMPTAmount], available); (*sle)[sfMPTAmount] = senderBalance - amt; - view.update(sle); + sle.update(); } else { @@ -1205,7 +1210,7 @@ directSendNoFeeMPT( if (outstanding >= amt) { sleIssuance->setFieldU64(sfOutstandingAmount, outstanding - amt); - view.update(sleIssuance); + sleIssuance.update(); } else { @@ -1215,7 +1220,7 @@ directSendNoFeeMPT( else { auto const mptokenID = keylet::mptoken(mptID.key, uReceiverID); - if (auto sle = view.peek(mptokenID)) + if (MPTokenEntry sle{mptokenID, view}) { if (view.rules().enabled(featureMPTokensV2)) { @@ -1226,7 +1231,7 @@ directSendNoFeeMPT( } view.creditHookMPT(uSenderID, uReceiverID, saAmount, (*sle)[sfMPTAmount], available); (*sle)[sfMPTAmount] += amt; - view.update(sle); + sle.update(); } else { @@ -1253,7 +1258,8 @@ directSendNoLimitMPT( // Safe to get MPT since directSendNoLimitMPT is only called by accountSendMPT auto const& issuer = saAmount.getIssuer(); - auto const sle = view.read(keylet::mptokenIssuance(saAmount.get().getMptID())); + MPTokenIssuanceEntry const sle{ + keylet::mptokenIssuance(saAmount.get().getMptID()), view}; if (!sle) return tecOBJECT_NOT_FOUND; @@ -1310,7 +1316,7 @@ directSendNoLimitMultiMPT( { auto const& issuer = mptIssue.getIssuer(); - auto const sle = view.read(keylet::mptokenIssuance(mptIssue.getMptID())); + MPTokenIssuanceEntry const sle{keylet::mptokenIssuance(mptIssue.getMptID()), view}; if (!sle) return tecOBJECT_NOT_FOUND; @@ -1536,8 +1542,8 @@ transferXRP( XRPL_ASSERT(from != to, "xrpl::transferXRP : sender is not receiver"); XRPL_ASSERT(amount.native(), "xrpl::transferXRP : amount is XRP"); - SLE::pointer const sender = view.peek(keylet::account(from)); - SLE::pointer const receiver = view.peek(keylet::account(to)); + AccountRootEntry sender{keylet::account(from), view}; + AccountRootEntry receiver{keylet::account(to), view}; if (!sender || !receiver) return tefINTERNAL; // LCOV_EXCL_LINE @@ -1556,10 +1562,10 @@ transferXRP( // Decrement XRP balance. sender->setFieldAmount(sfBalance, sender->getFieldAmount(sfBalance) - amount); - view.update(sender); + sender.update(); receiver->setFieldAmount(sfBalance, receiver->getFieldAmount(sfBalance) + amount); - view.update(receiver); + receiver.update(); return tesSUCCESS; } diff --git a/src/libxrpl/ledger/helpers/VaultHelpers.cpp b/src/libxrpl/ledger/helpers/VaultHelpers.cpp index b5b076d1cb..8bec7c9c50 100644 --- a/src/libxrpl/ledger/helpers/VaultHelpers.cpp +++ b/src/libxrpl/ledger/helpers/VaultHelpers.cpp @@ -17,7 +17,10 @@ namespace xrpl { [[nodiscard]] std::optional -assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& assets) +assetsToSharesDeposit( + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, + STAmount const& assets) { XRPL_ASSERT(!assets.negative(), "xrpl::assetsToSharesDeposit : non-negative assets"); XRPL_ASSERT( @@ -41,7 +44,10 @@ assetsToSharesDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount co } [[nodiscard]] std::optional -sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount const& shares) +sharesToAssetsDeposit( + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, + STAmount const& shares) { XRPL_ASSERT(!shares.negative(), "xrpl::sharesToAssetsDeposit : non-negative shares"); XRPL_ASSERT( @@ -65,8 +71,8 @@ sharesToAssetsDeposit(SLE::const_ref vault, SLE::const_ref issuance, STAmount co [[nodiscard]] std::optional assetsToSharesWithdraw( - SLE::const_ref vault, - SLE::const_ref issuance, + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, STAmount const& assets, TruncateShares truncate, WaiveUnrealizedLoss waive) @@ -94,8 +100,8 @@ assetsToSharesWithdraw( [[nodiscard]] std::optional sharesToAssetsWithdraw( - SLE::const_ref vault, - SLE::const_ref issuance, + VaultEntry const& vault, + MPTokenIssuanceEntry const& issuance, STAmount const& shares, WaiveUnrealizedLoss waive) { @@ -118,7 +124,10 @@ sharesToAssetsWithdraw( } [[nodiscard]] bool -isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref issuance) +isSoleShareholder( + ReadView const& view, + AccountID const& account, + MPTokenIssuanceEntry const& issuance) { XRPL_ASSERT( issuance && issuance->getType() == ltMPTOKEN_ISSUANCE, @@ -130,7 +139,7 @@ isSoleShareholder(ReadView const& view, AccountID const& account, SLE::const_ref auto const shareMPTID = makeMptID(issuance->getFieldU32(sfSequence), issuance->getAccountID(sfIssuer)); - auto const sleToken = view.read(keylet::mptoken(shareMPTID, account)); + MPTokenEntry sleToken{keylet::mptoken(shareMPTID, account), view}; if (!sleToken) return false; // LCOV_EXCL_LINE diff --git a/src/libxrpl/tx/transactors/account/AccountDelete.cpp b/src/libxrpl/tx/transactors/account/AccountDelete.cpp index 254733a618..1e810bfddc 100644 --- a/src/libxrpl/tx/transactors/account/AccountDelete.cpp +++ b/src/libxrpl/tx/transactors/account/AccountDelete.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -225,7 +226,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx) AccountID const account{ctx.tx[sfAccount]}; AccountID const dst{ctx.tx[sfDestination]}; - auto sleDst = ctx.view.read(keylet::account(dst)); + AccountRootEntry sleDst{keylet::account(dst), ctx.view}; if (!sleDst) return tecNO_DST; @@ -249,7 +250,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx) } } - auto sleAccount = ctx.view.read(keylet::account(account)); + AccountRootEntry sleAccount{keylet::account(account), ctx.view}; XRPL_ASSERT(sleAccount, "xrpl::AccountDelete::preclaim : non-null account"); if (!sleAccount) return terNO_ACCOUNT; @@ -263,8 +264,9 @@ AccountDelete::preclaim(PreclaimContext const& ctx) Keylet const first = keylet::nftokenPageMin(account); Keylet const last = keylet::nftokenPageMax(account); - auto const cp = ctx.view.read( - Keylet(ltNFTOKEN_PAGE, ctx.view.succ(first.key, last.key.next()).value_or(last.key))); + NFTokenPageEntry const cp{ + Keylet(ltNFTOKEN_PAGE, ctx.view.succ(first.key, last.key.next()).value_or(last.key)), + ctx.view}; if (cp) return tecHAS_OBLIGATIONS; @@ -314,7 +316,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx) { // Make sure any directory node types that we find are the kind // we can delete. - auto sleItem = ctx.view.read(keylet::child(dirEntry)); + ReadOnlySLE sleItem{keylet::child(dirEntry), ctx.view}; if (!sleItem) { // Directory node has an invalid index. Bail out. @@ -343,11 +345,11 @@ AccountDelete::preclaim(PreclaimContext const& ctx) TER AccountDelete::doApply() { - auto src = view().peek(keylet::account(accountID_)); + AccountRootEntry src{keylet::account(accountID_), view()}; XRPL_ASSERT(src, "xrpl::AccountDelete::doApply : non-null source account"); auto const dstID = ctx_.tx[sfDestination]; - auto dst = view().peek(keylet::account(dstID)); + AccountRootEntry dst{keylet::account(dstID), view()}; XRPL_ASSERT(dst, "xrpl::AccountDelete::doApply : non-null destination account"); if (!src || !dst) @@ -355,8 +357,8 @@ AccountDelete::doApply() if (ctx_.tx.isFieldPresent(sfCredentialIDs)) { - if (auto err = - verifyDepositPreauth(ctx_.tx, ctx_.view(), accountID_, dstID, dst, ctx_.journal); + if (auto err = verifyDepositPreauth( + ctx_.tx, ctx_.view(), accountID_, dstID, dst.sle(), ctx_.journal); !isTesSuccess(err)) return err; } @@ -409,8 +411,8 @@ AccountDelete::doApply() if (remainingBalance > XRPAmount(0) && dst->isFlag(lsfPasswordSpent)) dst->clearFlag(lsfPasswordSpent); - view().update(dst); - view().erase(src); + dst.update(); + src.erase(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/account/AccountSet.cpp b/src/libxrpl/tx/transactors/account/AccountSet.cpp index f0ad5b113a..4236257e8c 100644 --- a/src/libxrpl/tx/transactors/account/AccountSet.cpp +++ b/src/libxrpl/tx/transactors/account/AccountSet.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -170,7 +171,7 @@ AccountSet::preclaim(PreclaimContext const& ctx) { auto const id = ctx.tx[sfAccount]; - auto const sle = ctx.view.read(keylet::account(id)); + AccountRootEntry const sle{keylet::account(id), ctx.view}; if (!sle) return terNO_ACCOUNT; @@ -224,7 +225,7 @@ AccountSet::preclaim(PreclaimContext const& ctx) TER AccountSet::doApply() { - auto const sle = view().peek(keylet::account(accountID_)); + AccountRootEntry sle{keylet::account(accountID_), view()}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -312,7 +313,8 @@ AccountSet::doApply() return tecNEED_MASTER_KEY; } - if ((!sle->isFieldPresent(sfRegularKey)) && (!view().peek(keylet::signerList(accountID_)))) + if ((!sle->isFieldPresent(sfRegularKey)) && + (!SignerListEntry{keylet::signerList(accountID_), view()})) { // Account has no regular key or multi-signer signer list. return tecNO_ALTERNATIVE_KEY; @@ -582,7 +584,7 @@ AccountSet::doApply() if (uFlagsIn != uFlagsOut) sle->setFieldU32(sfFlags, uFlagsOut); - ctx_.view().update(sle); + sle.update(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/account/SetRegularKey.cpp b/src/libxrpl/tx/transactors/account/SetRegularKey.cpp index f408f31690..7bcdc6de52 100644 --- a/src/libxrpl/tx/transactors/account/SetRegularKey.cpp +++ b/src/libxrpl/tx/transactors/account/SetRegularKey.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,7 @@ SetRegularKey::calculateBaseFee(ReadView const& view, STTx const& tx) { if (calcAccountID(PublicKey(makeSlice(spk))) == id) { - auto const sle = view.read(keylet::account(id)); + AccountRootEntry const sle{keylet::account(id), view}; if (sle && !sle->isFlag(lsfPasswordSpent)) { @@ -53,7 +54,7 @@ SetRegularKey::preflight(PreflightContext const& ctx) TER SetRegularKey::doApply() { - auto const sle = view().peek(keylet::account(accountID_)); + AccountRootEntry sle{keylet::account(accountID_), view()}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -67,13 +68,14 @@ SetRegularKey::doApply() else { // Account has disabled master key and no multi-signer signer list. - if (sle->isFlag(lsfDisableMaster) && !view().peek(keylet::signerList(accountID_))) + if (sle->isFlag(lsfDisableMaster) && + !SignerListEntry{keylet::signerList(accountID_), view()}) return tecNO_ALTERNATIVE_KEY; sle->makeFieldAbsent(sfRegularKey); } - ctx_.view().update(sle); + sle.update(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/account/SignerListSet.cpp b/src/libxrpl/tx/transactors/account/SignerListSet.cpp index 2f95d32664..3f8cc37b4d 100644 --- a/src/libxrpl/tx/transactors/account/SignerListSet.cpp +++ b/src/libxrpl/tx/transactors/account/SignerListSet.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -187,7 +188,7 @@ removeSignersFromLedger( { // We have to examine the current SignerList so we know how much to // reduce the OwnerCount. - SLE::pointer const signers = view.peek(signerListKeylet); + SignerListEntry signers{signerListKeylet, view}; // If the signer list doesn't exist we've already succeeded in deleting it. if (!signers) @@ -215,10 +216,10 @@ removeSignersFromLedger( // LCOV_EXCL_STOP } - adjustOwnerCount( - view, view.peek(accountKeylet), removeFromOwnerCount, registry.getJournal("View")); + AccountRootEntry account{accountKeylet, view}; + adjustOwnerCount(view, account.mutableSle(), removeFromOwnerCount, registry.getJournal("View")); - view.erase(signers); + signers.erase(); return tesSUCCESS; } @@ -311,7 +312,7 @@ SignerListSet::replaceSignerList() ctx_.registry, view(), accountKeylet, ownerDirKeylet, signerListKeylet, j_)) return ter; - auto const sle = view().peek(accountKeylet); + AccountRootEntry const sle{accountKeylet, view()}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -330,8 +331,9 @@ SignerListSet::replaceSignerList() return tecINSUFFICIENT_RESERVE; // Everything's ducky. Add the ltSIGNER_LIST to the ledger. - auto signerList = std::make_shared(signerListKeylet); - view().insert(signerList); + SignerListEntry signerList{signerListKeylet, view()}; + signerList.newSLE(); + signerList.insert(); writeSignersToSLE(signerList, flags); auto viewJ = ctx_.registry.get().getJournal("View"); @@ -349,7 +351,7 @@ SignerListSet::replaceSignerList() // If we succeeded, the new entry counts against the // creator's reserve. - adjustOwnerCount(view(), sle, kAddedOwnerCount, viewJ); + adjustOwnerCount(view(), sle.mutableSle(), kAddedOwnerCount, viewJ); return tesSUCCESS; } @@ -359,7 +361,7 @@ SignerListSet::destroySignerList() auto const accountKeylet = keylet::account(accountID_); // Destroying the signer list is only allowed if either the master key // is enabled or there is a regular key. - SLE::pointer const ledgerEntry = view().peek(accountKeylet); + AccountRootEntry const ledgerEntry{accountKeylet, view()}; if (!ledgerEntry) return tefINTERNAL; // LCOV_EXCL_LINE @@ -373,7 +375,7 @@ SignerListSet::destroySignerList() } void -SignerListSet::writeSignersToSLE(SLE::pointer const& ledgerEntry, std::uint32_t flags) const +SignerListSet::writeSignersToSLE(SignerListEntry& ledgerEntry, std::uint32_t flags) const { // Assign the quorum, default SignerListID, and flags. if (ctx_.view().rules().enabled(fixIncludeKeyletFields)) diff --git a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp index f3ea97a341..a9d4d1ad13 100644 --- a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp +++ b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -797,24 +798,27 @@ readOrpeekBridge(F&& getter, STXChainBridge const& bridgeSpec) return tryGet(STXChainBridge::ChainType::Issuing); } -SLE::pointer +BridgeEntry peekBridge(ApplyView& v, STXChainBridge const& bridgeSpec) { - return readOrpeekBridge( - [&v](STXChainBridge const& b, STXChainBridge::ChainType ct) -> SLE::pointer { - return v.peek(keylet::bridge(b, ct)); - }, - bridgeSpec); + return BridgeEntry{ + readOrpeekBridge( + [&v](STXChainBridge const& b, STXChainBridge::ChainType ct) -> std::shared_ptr { + return v.peek(keylet::bridge(b, ct)); + }, + bridgeSpec), + v}; } -SLE::const_pointer +BridgeEntry readBridge(ReadView const& v, STXChainBridge const& bridgeSpec) { - return readOrpeekBridge( - [&v](STXChainBridge const& b, STXChainBridge::ChainType ct) -> SLE::const_pointer { - return v.read(keylet::bridge(b, ct)); - }, - bridgeSpec); + return BridgeEntry{ + readOrpeekBridge( + [&v](STXChainBridge const& b, STXChainBridge::ChainType ct) + -> std::shared_ptr { return v.read(keylet::bridge(b, ct)); }, + bridgeSpec), + v}; } // Precondition: all the claims in the range are consistent. They must sign for @@ -2008,7 +2012,7 @@ XChainCreateClaimID::doApply() if (!sleAcct) return tecINTERNAL; // LCOV_EXCL_LINE - auto const sleBridge = peekBridge(ctx_.view(), bridgeSpec); + auto sleBridge = peekBridge(ctx_.view(), bridgeSpec); if (!sleBridge) return tecINTERNAL; // LCOV_EXCL_LINE @@ -2049,7 +2053,7 @@ XChainCreateClaimID::doApply() adjustOwnerCount(ctx_.view(), sleAcct, 1, ctx_.journal); ctx_.view().insert(sleClaimID); - ctx_.view().update(sleBridge); + sleBridge.update(); ctx_.view().update(sleAcct); return tesSUCCESS; @@ -2192,7 +2196,7 @@ XChainCreateAccountCommit::doApply() if (!sle) return tecINTERNAL; // LCOV_EXCL_LINE - auto const sleBridge = peekBridge(psb, bridge); + auto sleBridge = peekBridge(psb, bridge); if (!sleBridge) return tecINTERNAL; // LCOV_EXCL_LINE @@ -2220,7 +2224,7 @@ XChainCreateAccountCommit::doApply() return thTer; (*sleBridge)[sfXChainAccountCreateCount] = (*sleBridge)[sfXChainAccountCreateCount] + 1; - psb.update(sleBridge); + sleBridge.update(); psb.apply(ctx_.rawView()); diff --git a/src/libxrpl/tx/transactors/check/CheckCancel.cpp b/src/libxrpl/tx/transactors/check/CheckCancel.cpp index d966772191..ed19159abb 100644 --- a/src/libxrpl/tx/transactors/check/CheckCancel.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCancel.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,7 @@ CheckCancel::preflight(PreflightContext const& ctx) TER CheckCancel::preclaim(PreclaimContext const& ctx) { - auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID])); + CheckEntry sleCheck{keylet::check(ctx.tx[sfCheckID]), ctx.view}; if (!sleCheck) { JLOG(ctx.j.warn()) << "Check does not exist."; @@ -54,7 +55,7 @@ CheckCancel::preclaim(PreclaimContext const& ctx) TER CheckCancel::doApply() { - auto const sleCheck = view().peek(keylet::check(ctx_.tx[sfCheckID])); + CheckEntry sleCheck{keylet::check(ctx_.tx[sfCheckID]), view()}; if (!sleCheck) { // Error should have been caught in preclaim. @@ -91,11 +92,11 @@ CheckCancel::doApply() } // If we succeeded, update the check owner's reserve. - auto const sleSrc = view().peek(keylet::account(srcId)); - adjustOwnerCount(view(), sleSrc, -1, viewJ); + AccountRootEntry sleSrc{keylet::account(srcId), view()}; + adjustOwnerCount(view(), sleSrc.mutableSle(), -1, viewJ); // Remove check from ledger. - view().erase(sleCheck); + sleCheck.erase(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/check/CheckCash.cpp b/src/libxrpl/tx/transactors/check/CheckCash.cpp index 80ef742f52..a168941c50 100644 --- a/src/libxrpl/tx/transactors/check/CheckCash.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCash.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,7 @@ CheckCash::preflight(PreflightContext const& ctx) TER CheckCash::preclaim(PreclaimContext const& ctx) { - auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID])); + CheckEntry sleCheck{keylet::check(ctx.tx[sfCheckID]), ctx.view}; if (!sleCheck) { JLOG(ctx.j.warn()) << "Check does not exist."; @@ -105,8 +106,8 @@ CheckCash::preclaim(PreclaimContext const& ctx) // LCOV_EXCL_STOP } { - auto const sleSrc = ctx.view.read(keylet::account(srcId)); - auto const sleDst = ctx.view.read(keylet::account(dstId)); + AccountRootEntry sleSrc{keylet::account(srcId), ctx.view}; + AccountRootEntry sleDst{keylet::account(dstId), ctx.view}; if (!sleSrc || !sleDst) { // If the check exists this should never occur. @@ -191,10 +192,10 @@ CheckCash::preclaim(PreclaimContext const& ctx) return value.asset().visit( [&](Issue const& issue) -> TER { Currency const currency{issue.currency}; - auto const sleTrustLine = - ctx.view.read(keylet::trustLine(dstId, issuerId, currency)); + RippleStateEntry sleTrustLine{ + keylet::trustLine(dstId, issuerId, currency), ctx.view}; - auto const sleIssuer = ctx.view.read(keylet::account(issuerId)); + AccountRootEntry sleIssuer{keylet::account(issuerId), ctx.view}; if (!sleIssuer) { JLOG(ctx.j.warn()) << "Can't receive IOUs from " @@ -246,7 +247,7 @@ CheckCash::preclaim(PreclaimContext const& ctx) return tesSUCCESS; }, [&](MPTIssue const& issue) -> TER { - auto const sleIssuer = ctx.view.read(keylet::account(issuerId)); + AccountRootEntry sleIssuer{keylet::account(issuerId), ctx.view}; if (!sleIssuer) { JLOG(ctx.j.warn()) << "Can't receive MPTs from " @@ -581,7 +582,8 @@ CheckCash::doApply() } // If we succeeded, update the check owner's reserve. - adjustOwnerCount(psb, psb.peek(keylet::account(srcId)), -1, viewJ); + AccountRootEntry sleSrcAccount{keylet::account(srcId), psb}; + adjustOwnerCount(psb, sleSrcAccount.mutableSle(), -1, viewJ); // Remove check from ledger. psb.erase(sleCheck); diff --git a/src/libxrpl/tx/transactors/check/CheckCreate.cpp b/src/libxrpl/tx/transactors/check/CheckCreate.cpp index 595bcc4ab1..d780ffbeae 100644 --- a/src/libxrpl/tx/transactors/check/CheckCreate.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCreate.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -79,7 +80,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) { AccountID const dstId{ctx.tx[sfDestination]}; AccountID const srcId{ctx.tx[sfAccount]}; - auto const sleDst = ctx.view.read(keylet::account(dstId)); + AccountRootEntry sleDst{keylet::account(dstId), ctx.view}; if (!sleDst) { JLOG(ctx.j.warn()) << "Destination account does not exist."; @@ -94,7 +95,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) // because all writes to pseudo-account discriminator fields **are** // amendment gated, hence the behaviour of this check will always match the // currently active amendments. - if (isPseudoAccount(sleDst)) + if (isPseudoAccount(sleDst.sle())) return tecNO_PERMISSION; if (sleDst->isFlag(lsfRequireDestTag) && !ctx.tx.isFieldPresent(sfDestinationTag)) @@ -126,8 +127,8 @@ CheckCreate::preclaim(PreclaimContext const& ctx) if (issuerId != srcId) { // Check if the issuer froze the line - auto const sleTrust = - ctx.view.read(keylet::trustLine(srcId, issuerId, issue.currency)); + RippleStateEntry sleTrust{ + keylet::trustLine(srcId, issuerId, issue.currency), ctx.view}; if (sleTrust && sleTrust->isFlag((issuerId > srcId) ? lsfHighFreeze : lsfLowFreeze)) { @@ -138,8 +139,8 @@ CheckCreate::preclaim(PreclaimContext const& ctx) if (issuerId != dstId) { // Check if dst froze the line. - auto const sleTrust = - ctx.view.read(keylet::trustLine(issuerId, dstId, issue.currency)); + RippleStateEntry sleTrust{ + keylet::trustLine(issuerId, dstId, issue.currency), ctx.view}; if (sleTrust && sleTrust->isFlag((dstId > issuerId) ? lsfHighFreeze : lsfLowFreeze)) { @@ -187,7 +188,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx) TER CheckCreate::doApply() { - auto const sle = view().peek(keylet::account(accountID_)); + AccountRootEntry sle{keylet::account(accountID_), view()}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -205,7 +206,8 @@ CheckCreate::doApply() // Check sequence. For more explanation see comments in SeqProxy.h. std::uint32_t const seq = ctx_.tx.getSeqValue(); Keylet const checkKeylet = keylet::check(accountID_, seq); - auto sleCheck = std::make_shared(checkKeylet); + CheckEntry sleCheck{checkKeylet, view()}; + sleCheck.newSLE(); sleCheck->setAccountID(sfAccount, accountID_); AccountID const dstAccountId = ctx_.tx[sfDestination]; @@ -221,7 +223,7 @@ CheckCreate::doApply() if (auto const expiry = ctx_.tx[~sfExpiration]) sleCheck->setFieldU32(sfExpiration, *expiry); - view().insert(sleCheck); + sleCheck.insert(); auto viewJ = ctx_.registry.get().getJournal("View"); // If it's not a self-send (and it shouldn't be), add Check to the @@ -253,7 +255,7 @@ CheckCreate::doApply() sleCheck->setFieldU64(sfOwnerNode, *page); } // If we succeeded, the new entry counts against the creator's reserve. - adjustOwnerCount(view(), sle, 1, viewJ); + adjustOwnerCount(view(), sle.mutableSle(), 1, viewJ); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp index e0ebdd893a..69fccb1cb2 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -63,7 +64,7 @@ CredentialAccept::preclaim(PreclaimContext const& ctx) return tecNO_ISSUER; } - auto const sleCred = ctx.view.read(keylet::credential(subject, issuer, credType)); + CredentialEntry sleCred{keylet::credential(subject, issuer, credType), ctx.view}; if (!sleCred) { JLOG(ctx.j.warn()) << "No credential: " << to_string(subject) << ", " << to_string(issuer) @@ -87,8 +88,8 @@ CredentialAccept::doApply() AccountID const issuer{ctx_.tx[sfIssuer]}; // Both exist as credential object exist itself (checked in preclaim) - auto const sleSubject = view().peek(keylet::account(accountID_)); - auto const sleIssuer = view().peek(keylet::account(issuer)); + AccountRootEntry sleSubject{keylet::account(accountID_), view()}; + AccountRootEntry sleIssuer{keylet::account(issuer), view()}; if (!sleSubject || !sleIssuer) return tefINTERNAL; // LCOV_EXCL_LINE @@ -102,7 +103,7 @@ CredentialAccept::doApply() auto const credType(ctx_.tx[sfCredentialType]); Keylet const credentialKey = keylet::credential(accountID_, issuer, credType); - auto const sleCred = view().peek(credentialKey); // Checked in preclaim() + CredentialEntry sleCred{credentialKey, view()}; // Checked in preclaim() if (!sleCred) return tefINTERNAL; // LCOV_EXCL_LINE @@ -110,15 +111,15 @@ CredentialAccept::doApply() { JLOG(j_.trace()) << "Credential is expired: " << sleCred->getText(); // delete expired credentials even if the transaction failed - auto const err = credentials::deleteSLE(view(), sleCred, j_); + auto const err = credentials::deleteSLE(view(), sleCred.mutableSle(), j_); return isTesSuccess(err) ? tecEXPIRED : err; } sleCred->setFieldU32(sfFlags, lsfAccepted); - view().update(sleCred); + sleCred.update(); - adjustOwnerCount(view(), sleIssuer, -1, j_); - adjustOwnerCount(view(), sleSubject, 1, j_); + adjustOwnerCount(view(), sleIssuer.mutableSle(), -1, j_); + adjustOwnerCount(view(), sleSubject.mutableSle(), 1, j_); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp index acca408a95..c7a8ad42f0 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp @@ -7,6 +7,7 @@ #include #include // IWYU pragma: keep #include +#include #include #include #include @@ -106,7 +107,8 @@ CredentialCreate::doApply() auto const credType(ctx_.tx[sfCredentialType]); Keylet const credentialKey = keylet::credential(subject, accountID_, credType); - auto const sleCred = std::make_shared(credentialKey); + CredentialEntry sleCred{credentialKey, view()}; + sleCred.newSLE(); if (!sleCred) return tefINTERNAL; // LCOV_EXCL_LINE @@ -126,7 +128,7 @@ CredentialCreate::doApply() sleCred->setFieldU32(sfExpiration, *optExp); } - auto const sleIssuer = view().peek(keylet::account(accountID_)); + AccountRootEntry sleIssuer{keylet::account(accountID_), view()}; if (!sleIssuer) return tefINTERNAL; // LCOV_EXCL_LINE @@ -153,7 +155,7 @@ CredentialCreate::doApply() return tecDIR_FULL; sleCred->setFieldU64(sfIssuerNode, *page); - adjustOwnerCount(view(), sleIssuer, 1, j_); + adjustOwnerCount(view(), sleIssuer.mutableSle(), 1, j_); } if (subject == accountID_) @@ -173,7 +175,7 @@ CredentialCreate::doApply() sleCred->setFieldU64(sfSubjectNode, *page); } - view().insert(sleCred); + sleCred.insert(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp b/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp index 6bd4ad54c5..6fcccd7042 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialDelete.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,7 @@ CredentialDelete::doApply() auto const issuer = ctx_.tx[~sfIssuer].value_or(accountID_); auto const credType(ctx_.tx[sfCredentialType]); - auto const sleCred = view().peek(keylet::credential(subject, issuer, credType)); + CredentialEntry sleCred{keylet::credential(subject, issuer, credType), view()}; if (!sleCred) return tefINTERNAL; // LCOV_EXCL_LINE @@ -91,7 +92,7 @@ CredentialDelete::doApply() return tecNO_PERMISSION; } - return deleteSLE(view(), sleCred, j_); + return deleteSLE(view(), sleCred.mutableSle(), j_); } void diff --git a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp index 32a51555b1..3b6674095d 100644 --- a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp +++ b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -72,25 +73,25 @@ DelegateSet::preclaim(PreclaimContext const& ctx) TER DelegateSet::doApply() { - auto const sleOwner = ctx_.view().peek(keylet::account(accountID_)); + AccountRootEntry sleOwner{keylet::account(accountID_), ctx_.view()}; if (!sleOwner) return tefINTERNAL; // LCOV_EXCL_LINE auto const& authAccount = ctx_.tx[sfAuthorize]; auto const delegateKey = keylet::delegate(accountID_, authAccount); - auto sle = ctx_.view().peek(delegateKey); + DelegateEntry sle{delegateKey, ctx_.view()}; if (sle) { auto const& permissions = ctx_.tx.getFieldArray(sfPermissions); if (permissions.empty()) { // if permissions array is empty, delete the ledger object. - return deleteDelegate(view(), sle, j_); + return deleteDelegate(view(), sle.mutableSle(), j_); } sle->setFieldArray(sfPermissions, permissions); - ctx_.view().update(sle); + sle.update(); return tesSUCCESS; } @@ -104,7 +105,7 @@ DelegateSet::doApply() if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; - sle = std::make_shared(delegateKey); + sle.newSLE(); sle->setAccountID(sfAccount, accountID_); sle->setAccountID(sfAuthorize, authAccount); @@ -129,8 +130,8 @@ DelegateSet::doApply() (*sle)[sfDestinationNode] = *destPage; - ctx_.view().insert(sle); - adjustOwnerCount(ctx_.view(), sleOwner, 1, ctx_.journal); + sle.insert(); + adjustOwnerCount(ctx_.view(), sleOwner.mutableSle(), 1, ctx_.journal); return tesSUCCESS; } @@ -166,11 +167,11 @@ DelegateSet::deleteDelegate(ApplyView& view, SLE::ref sle, beast::Journal j) } // Only the delegating account's owner count was incremented on creation - auto const sleOwner = view.peek(keylet::account(delegator)); + AccountRootEntry sleOwner{keylet::account(delegator), view}; if (!sleOwner) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleOwner, -1, j); + adjustOwnerCount(view, sleOwner.mutableSle(), -1, j); view.erase(sle); diff --git a/src/libxrpl/tx/transactors/dex/AMMClawback.cpp b/src/libxrpl/tx/transactors/dex/AMMClawback.cpp index c1ef9f875e..c9249adc4c 100644 --- a/src/libxrpl/tx/transactors/dex/AMMClawback.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMClawback.cpp @@ -268,8 +268,9 @@ AMMClawback::applyGuts(Sandbox& sb) } } + AMMEntry ammEntry{ammSle, sb}; auto const res = - AMMWithdraw::deleteAMMAccountIfEmpty(sb, ammSle, newLPTokenBalance, asset, asset2, j_); + AMMWithdraw::deleteAMMAccountIfEmpty(sb, ammEntry, newLPTokenBalance, asset, asset2, j_); if (!res.second) return res.first; // LCOV_EXCL_LINE diff --git a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp index 66d059c54d..577d4f7431 100644 --- a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -347,8 +348,8 @@ applyCreate(ApplyContext& ctx, Sandbox& sb, AccountID const& account, beast::Jou // Set AMM flag on AMM trustline if (!isXRP(amount)) { - SLE::pointer const sleRippleState = - sb.peek(keylet::trustLine(accountId, issue)); + RippleStateEntry sleRippleState{ + keylet::trustLine(accountId, issue), sb}; if (!sleRippleState) { return tecINTERNAL; // LCOV_EXCL_LINE @@ -356,7 +357,7 @@ applyCreate(ApplyContext& ctx, Sandbox& sb, AccountID const& account, beast::Jou auto const flags = sleRippleState->getFlags(); sleRippleState->setFieldU32(sfFlags, flags | lsfAMMNode); - sb.update(sleRippleState); + sleRippleState.update(); } return tesSUCCESS; }); diff --git a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp index 14ed5a4646..ed8d45f22c 100644 --- a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp @@ -446,8 +446,9 @@ AMMWithdraw::applyGuts(Sandbox& sb) } } + AMMEntry ammEntry{ammSle, sb}; auto const res = deleteAMMAccountIfEmpty( - sb, ammSle, newLPTokenBalance, ctx_.tx[sfAsset], ctx_.tx[sfAsset2], j_); + sb, ammEntry, newLPTokenBalance, ctx_.tx[sfAsset], ctx_.tx[sfAsset2], j_); // LCOV_EXCL_START if (!res.second) return {res.first, false}; @@ -797,7 +798,7 @@ AMMWithdraw::equalWithdrawTokens( std::pair AMMWithdraw::deleteAMMAccountIfEmpty( Sandbox& sb, - SLE::pointer const ammSle, + AMMEntry& ammSle, STAmount const& lpTokenBalance, Asset const& asset1, Asset const& asset2, @@ -817,7 +818,7 @@ AMMWithdraw::deleteAMMAccountIfEmpty( if (updateBalance) { ammSle->setFieldAmount(sfLPTokenBalance, lpTokenBalance); - sb.update(ammSle); + ammSle.update(); } return {ter, true}; diff --git a/src/libxrpl/tx/transactors/did/DIDDelete.cpp b/src/libxrpl/tx/transactors/did/DIDDelete.cpp index 90aa21d8a1..09a8a1c2c1 100644 --- a/src/libxrpl/tx/transactors/did/DIDDelete.cpp +++ b/src/libxrpl/tx/transactors/did/DIDDelete.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -27,11 +28,11 @@ DIDDelete::preflight(PreflightContext const& ctx) TER DIDDelete::deleteSLE(ApplyContext& ctx, Keylet sleKeylet, AccountID const owner) { - auto const sle = ctx.view().peek(sleKeylet); + WritableSLE sle{sleKeylet, ctx.view()}; if (!sle) return tecNO_ENTRY; - return DIDDelete::deleteSLE(ctx.view(), sle, owner, ctx.journal); + return DIDDelete::deleteSLE(ctx.view(), sle.mutableSle(), owner, ctx.journal); } TER @@ -46,12 +47,12 @@ DIDDelete::deleteSLE(ApplyView& view, SLE::pointer sle, AccountID const owner, b // LCOV_EXCL_STOP } - auto const sleOwner = view.peek(keylet::account(owner)); + AccountRootEntry sleOwner{keylet::account(owner), view}; if (!sleOwner) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleOwner, -1, j); - view.update(sleOwner); + adjustOwnerCount(view, sleOwner.mutableSle(), -1, j); + sleOwner.update(); // Remove object from ledger view.erase(sle); diff --git a/src/libxrpl/tx/transactors/did/DIDSet.cpp b/src/libxrpl/tx/transactors/did/DIDSet.cpp index 1392581bb0..a8b716ed71 100644 --- a/src/libxrpl/tx/transactors/did/DIDSet.cpp +++ b/src/libxrpl/tx/transactors/did/DIDSet.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -63,9 +64,9 @@ DIDSet::preflight(PreflightContext const& ctx) } static TER -addSLE(ApplyContext& ctx, SLE::ref sle, AccountID const& owner) +addSLE(ApplyContext& ctx, DIDEntry& sle, AccountID const& owner) { - auto const sleAccount = ctx.view().peek(keylet::account(owner)); + AccountRootEntry sleAccount{keylet::account(owner), ctx.view()}; if (!sleAccount) return tefINTERNAL; // LCOV_EXCL_LINE @@ -79,7 +80,7 @@ addSLE(ApplyContext& ctx, SLE::ref sle, AccountID const& owner) } // Add ledger object to ledger - ctx.view().insert(sle); + sle.insert(); // Add ledger object to owner's page { @@ -89,8 +90,8 @@ addSLE(ApplyContext& ctx, SLE::ref sle, AccountID const& owner) return tecDIR_FULL; // LCOV_EXCL_LINE (*sle)[sfOwnerNode] = *page; } - adjustOwnerCount(ctx.view(), sleAccount, 1, ctx.journal); - ctx.view().update(sleAccount); + adjustOwnerCount(ctx.view(), sleAccount.mutableSle(), 1, ctx.journal); + sleAccount.update(); return tesSUCCESS; } @@ -100,7 +101,8 @@ DIDSet::doApply() { // Edit ledger object if it already exists Keylet const didKeylet = keylet::did(accountID_); - if (auto const sleDID = ctx_.view().peek(didKeylet)) + DIDEntry sleDID{didKeylet, ctx_.view()}; + if (sleDID) { auto update = [&](auto const& sField) { if (auto const field = ctx_.tx[~sField]) @@ -124,12 +126,12 @@ DIDSet::doApply() { return tecEMPTY_DID; } - ctx_.view().update(sleDID); + sleDID.update(); return tesSUCCESS; } // Create new ledger object otherwise - auto const sleDID = std::make_shared(didKeylet); + sleDID.newSLE(); (*sleDID)[sfAccount] = accountID_; auto set = [&](auto const& sField) { diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp index 55a9133e1e..91670f6f48 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,7 @@ escrowCancelPreclaimHelper( // If the mpt does not exist, return tecOBJECT_NOT_FOUND auto const issuanceKey = keylet::mptokenIssuance(amount.get().getMptID()); - auto const sleIssuance = ctx.view.read(issuanceKey); + MPTokenIssuanceEntry sleIssuance{issuanceKey, ctx.view}; if (!sleIssuance) return tecOBJECT_NOT_FOUND; @@ -93,7 +94,7 @@ EscrowCancel::preclaim(PreclaimContext const& ctx) if (ctx.view.rules().enabled(featureTokenEscrow)) { auto const k = keylet::escrow(ctx.tx[sfOwner], ctx.tx[sfOfferSequence]); - auto const slep = ctx.view.read(k); + EscrowEntry slep{k, ctx.view}; if (!slep) return tecNO_TARGET; @@ -118,7 +119,7 @@ TER EscrowCancel::doApply() { auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]); - auto const slep = ctx_.view().peek(k); + EscrowEntry slep{k, ctx_.view()}; if (!slep) { if (ctx_.view().rules().enabled(featureTokenEscrow)) @@ -163,7 +164,7 @@ EscrowCancel::doApply() } } - auto const sle = ctx_.view().peek(keylet::account(account)); + AccountRootEntry sle{keylet::account(account), ctx_.view()}; STAmount const amount = slep->getFieldAmount(sfAmount); // Transfer amount back to the owner @@ -183,7 +184,8 @@ EscrowCancel::doApply() return escrowUnlockApplyHelper( ctx_.view(), kParityRate, - ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle : slep, + ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle.mutableSle() + : slep.mutableSle(), preFeeBalance_, amount, issuer, @@ -209,11 +211,11 @@ EscrowCancel::doApply() } } - adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal); - ctx_.view().update(sle); + adjustOwnerCount(ctx_.view(), sle.mutableSle(), -1, ctx_.journal); + sle.update(); // Remove escrow from ledger - ctx_.view().erase(slep); + slep.erase(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp index 531098bd1c..9c6624ff0e 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -201,14 +202,15 @@ escrowCreatePreclaimHelper( return tecNO_PERMISSION; // If the lsfAllowTrustLineLocking is not enabled, return tecNO_PERMISSION - auto const sleIssuer = ctx.view.read(keylet::account(issuer)); + AccountRootEntry sleIssuer{keylet::account(issuer), ctx.view}; if (!sleIssuer) return tecNO_ISSUER; if (!sleIssuer->isFlag(lsfAllowTrustLineLocking)) return tecNO_PERMISSION; // If the account does not have a trustline to the issuer, return tecNO_LINE - auto const sleRippleState = ctx.view.read(keylet::trustLine(account, issuer, issue.currency)); + RippleStateEntry sleRippleState{ + keylet::trustLine(account, issuer, issue.currency), ctx.view}; if (!sleRippleState) return tecNO_LINE; @@ -272,7 +274,7 @@ escrowCreatePreclaimHelper( // If the mpt does not exist, return tecOBJECT_NOT_FOUND auto const issuanceKey = keylet::mptokenIssuance(amount.get().getMptID()); - auto const sleIssuance = ctx.view.read(issuanceKey); + MPTokenIssuanceEntry sleIssuance{issuanceKey, ctx.view}; if (!sleIssuance) return tecOBJECT_NOT_FOUND; @@ -341,7 +343,7 @@ EscrowCreate::preclaim(PreclaimContext const& ctx) AccountID const account{ctx.tx[sfAccount]}; AccountID const dest{ctx.tx[sfDestination]}; - auto const sled = ctx.view.read(keylet::account(dest)); + AccountRootEntry sled{keylet::account(dest), ctx.view}; if (!sled) return tecNO_DST; @@ -349,7 +351,7 @@ EscrowCreate::preclaim(PreclaimContext const& ctx) // because all writes to pseudo-account discriminator fields **are** // amendment gated, hence the behaviour of this check will always match the // currently active amendments. - if (isPseudoAccount(sled)) + if (isPseudoAccount(sled.sle())) return tecNO_PERMISSION; if (!isXRP(amount)) @@ -427,7 +429,7 @@ EscrowCreate::doApply() if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter])) return tecNO_PERMISSION; - auto const sle = ctx_.view().peek(keylet::account(accountID_)); + AccountRootEntry sle{keylet::account(accountID_), ctx_.view()}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -449,7 +451,7 @@ EscrowCreate::doApply() // Check destination account { - auto const sled = ctx_.view().read(keylet::account(ctx_.tx[sfDestination])); + AccountRootEntry sled{keylet::account(ctx_.tx[sfDestination]), ctx_.view()}; if (!sled) return tecNO_DST; // LCOV_EXCL_LINE if (sled->isFlag(lsfRequireDestTag) && !ctx_.tx[~sfDestinationTag]) @@ -459,7 +461,8 @@ EscrowCreate::doApply() // Create escrow in ledger. Note that we use the value from the // sequence or ticket. For more explanation see comments in SeqProxy.h. Keylet const escrowKeylet = keylet::escrow(accountID_, ctx_.tx.getSeqValue()); - auto const slep = std::make_shared(escrowKeylet); + EscrowEntry slep{escrowKeylet, ctx_.view()}; + slep.newSLE(); (*slep)[sfAmount] = amount; (*slep)[sfAccount] = accountID_; (*slep)[~sfCondition] = ctx_.tx[~sfCondition]; @@ -481,7 +484,7 @@ EscrowCreate::doApply() (*slep)[sfTransferRate] = xferRate.value; } - ctx_.view().insert(slep); + slep.insert(); // Add escrow to sender's owner directory { @@ -535,8 +538,8 @@ EscrowCreate::doApply() } // increment owner count - adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal); - ctx_.view().update(sle); + adjustOwnerCount(ctx_.view(), sle.mutableSle(), 1, ctx_.journal); + sle.update(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp index 7f1f9ec078..02f41bf9b5 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -173,7 +174,7 @@ escrowFinishPreclaimHelper( // If the mpt does not exist, return tecOBJECT_NOT_FOUND auto const issuanceKey = keylet::mptokenIssuance(amount.get().getMptID()); - auto const sleIssuance = ctx.view.read(issuanceKey); + MPTokenIssuanceEntry sleIssuance{issuanceKey, ctx.view}; if (!sleIssuance) return tecOBJECT_NOT_FOUND; @@ -204,7 +205,7 @@ EscrowFinish::preclaim(PreclaimContext const& ctx) if (ctx.view.rules().enabled(featureTokenEscrow)) { auto const k = keylet::escrow(ctx.tx[sfOwner], ctx.tx[sfOfferSequence]); - auto const slep = ctx.view.read(k); + EscrowEntry slep{k, ctx.view}; if (!slep) return tecNO_TARGET; @@ -229,7 +230,7 @@ TER EscrowFinish::doApply() { auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]); - auto const slep = ctx_.view().peek(k); + EscrowEntry slep{k, ctx_.view()}; if (!slep) { if (ctx_.view().rules().enabled(featureTokenEscrow)) @@ -305,12 +306,12 @@ EscrowFinish::doApply() // NOTE: Escrow payments cannot be used to fund accounts. AccountID const destID = (*slep)[sfDestination]; - auto const sled = ctx_.view().peek(keylet::account(destID)); + AccountRootEntry sled{keylet::account(destID), ctx_.view()}; if (!sled) return tecNO_DST; - if (auto err = - verifyDepositPreauth(ctx_.tx, ctx_.view(), accountID_, destID, sled, ctx_.journal); + if (auto err = verifyDepositPreauth( + ctx_.tx, ctx_.view(), accountID_, destID, sled.sle(), ctx_.journal); !isTesSuccess(err)) return err; @@ -361,7 +362,7 @@ EscrowFinish::doApply() return escrowUnlockApplyHelper( ctx_.view(), lockedRate, - sled, + sled.mutableSle(), preFeeBalance_, amount, issuer, @@ -387,15 +388,15 @@ EscrowFinish::doApply() } } - ctx_.view().update(sled); + sled.update(); // Adjust source owner count - auto const sle = ctx_.view().peek(keylet::account(account)); - adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal); - ctx_.view().update(sle); + AccountRootEntry sle{keylet::account(account), ctx_.view()}; + adjustOwnerCount(ctx_.view(), sle.mutableSle(), -1, ctx_.journal); + sle.update(); // Remove escrow from ledger - ctx_.view().erase(slep); + slep.erase(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp b/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp index 14bf3646c0..df82616ee1 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenAcceptOffer.cpp @@ -54,16 +54,16 @@ TER NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx) { auto const checkOffer = - [&ctx](std::optional id) -> std::pair { + [&ctx](std::optional id) -> std::pair, TER> { if (id) { if (id->isZero()) - return {nullptr, tecOBJECT_NOT_FOUND}; + return {NFTokenOfferEntry{nullptr, ctx.view}, tecOBJECT_NOT_FOUND}; - auto offerSLE = ctx.view.read(keylet::nftokenOffer(*id)); + NFTokenOfferEntry offerSLE{keylet::nftokenOffer(*id), ctx.view}; if (!offerSLE) - return {nullptr, tecOBJECT_NOT_FOUND}; + return {NFTokenOfferEntry{nullptr, ctx.view}, tecOBJECT_NOT_FOUND}; if (hasExpired(ctx.view, (*offerSLE)[~sfExpiration])) { @@ -71,16 +71,16 @@ NFTokenAcceptOffer::preclaim(PreclaimContext const& ctx) // leaving them on ledger forever. After the amendment, we allow expired offers to // reach doApply() where they get deleted and tecEXPIRED is returned. if (!ctx.view.rules().enabled(fixCleanup3_1_3)) - return {nullptr, tecEXPIRED}; + return {NFTokenOfferEntry{nullptr, ctx.view}, tecEXPIRED}; // Amendment enabled: return the expired offer to be handled in doApply. } if ((*offerSLE)[sfAmount].negative()) - return {nullptr, temBAD_OFFER}; + return {NFTokenOfferEntry{nullptr, ctx.view}, temBAD_OFFER}; return {std::move(offerSLE), tesSUCCESS}; } - return {nullptr, tesSUCCESS}; + return {NFTokenOfferEntry{nullptr, ctx.view}, tesSUCCESS}; }; auto const [bo, err1] = checkOffer(ctx.tx[~sfNFTokenBuyOffer]); @@ -396,7 +396,7 @@ NFTokenAcceptOffer::transferNFToken( } TER -NFTokenAcceptOffer::acceptOffer(SLE::ref offer) +NFTokenAcceptOffer::acceptOffer(NFTokenOfferEntry const& offer) { bool const isSell = offer->isFlag(lsfSellNFToken); AccountID const owner = (*offer)[sfOwner]; @@ -434,10 +434,9 @@ TER NFTokenAcceptOffer::doApply() { auto const loadToken = [this](std::optional const& id) { - SLE::pointer sle; if (id) - sle = view().peek(keylet::nftokenOffer(*id)); - return sle; + return NFTokenOfferEntry{keylet::nftokenOffer(*id), view()}; + return NFTokenOfferEntry{SLE::pointer{}, view()}; }; auto bo = loadToken(ctx_.tx[~sfNFTokenBuyOffer]); @@ -449,11 +448,12 @@ NFTokenAcceptOffer::doApply() { bool foundExpired = false; - auto const deleteOfferIfExpired = [this, &foundExpired](SLE::ref offer) -> TER { + auto const deleteOfferIfExpired = + [this, &foundExpired](NFTokenOfferEntry& offer) -> TER { if (offer && hasExpired(view(), (*offer)[~sfExpiration])) { JLOG(j_.trace()) << "Offer is expired, deleting: " << offer->key(); - if (!nft::deleteTokenOffer(view(), offer)) + if (!nft::deleteTokenOffer(view(), offer.mutableSle())) { // LCOV_EXCL_START JLOG(j_.fatal()) @@ -476,7 +476,7 @@ NFTokenAcceptOffer::doApply() return tecEXPIRED; } - if (bo && !nft::deleteTokenOffer(view(), bo)) + if (bo && !nft::deleteTokenOffer(view(), bo.mutableSle())) { // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete buy offer '" << to_string(bo->key()) << "': ignoring"; @@ -484,7 +484,7 @@ NFTokenAcceptOffer::doApply() // LCOV_EXCL_STOP } - if (so && !nft::deleteTokenOffer(view(), so)) + if (so && !nft::deleteTokenOffer(view(), so.mutableSle())) { // LCOV_EXCL_START JLOG(j_.fatal()) << "Unable to delete sell offer '" << to_string(so->key()) diff --git a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp index 9a26816155..066a1bcaa0 100644 --- a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -64,13 +65,13 @@ OracleDelete::deleteOracle( // LCOV_EXCL_STOP } - auto const sleOwner = view.peek(keylet::account(account)); + AccountRootEntry sleOwner{keylet::account(account), view}; if (!sleOwner) return tecINTERNAL; // LCOV_EXCL_LINE auto const count = sle->getFieldArray(sfPriceDataSeries).size() > 5 ? -2 : -1; - adjustOwnerCount(view, sleOwner, count, j); + adjustOwnerCount(view, sleOwner.mutableSle(), count, j); view.erase(sle); @@ -80,8 +81,9 @@ OracleDelete::deleteOracle( TER OracleDelete::doApply() { - if (auto sle = ctx_.view().peek(keylet::oracle(accountID_, ctx_.tx[sfOracleDocumentID]))) - return deleteOracle(ctx_.view(), sle, accountID_, j_); + if (OracleEntry sle{ + keylet::oracle(accountID_, ctx_.tx[sfOracleDocumentID]), ctx_.view()}) + return deleteOracle(ctx_.view(), sle.mutableSle(), accountID_, j_); return tecINTERNAL; // LCOV_EXCL_LINE } diff --git a/src/libxrpl/tx/transactors/oracle/OracleSet.cpp b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp index 12d826e54d..6af16a2d95 100644 --- a/src/libxrpl/tx/transactors/oracle/OracleSet.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,7 @@ OracleSet::preflight(PreflightContext const& ctx) TER OracleSet::preclaim(PreclaimContext const& ctx) { - auto const sleSetter = ctx.view.read(keylet::account(ctx.tx.getAccountID(sfAccount))); + AccountRootEntry sleSetter{keylet::account(ctx.tx.getAccountID(sfAccount)), ctx.view}; if (!sleSetter) return terNO_ACCOUNT; // LCOV_EXCL_LINE @@ -80,8 +81,8 @@ OracleSet::preclaim(PreclaimContext const& ctx) lastUpdateTimeEpoch > (closeTime + kMaxLastUpdateTimeDelta)) return tecINVALID_UPDATE_TIME; - auto const sle = - ctx.view.read(keylet::oracle(ctx.tx.getAccountID(sfAccount), ctx.tx[sfOracleDocumentID])); + OracleEntry sle{ + keylet::oracle(ctx.tx.getAccountID(sfAccount), ctx.tx[sfOracleDocumentID]), ctx.view}; // token pairs to add/update std::set> pairs; @@ -181,9 +182,9 @@ OracleSet::preclaim(PreclaimContext const& ctx) static bool adjustOwnerCount(ApplyContext& ctx, int count) { - if (auto const sleAccount = ctx.view().peek(keylet::account(ctx.tx[sfAccount]))) + if (AccountRootEntry sleAccount{keylet::account(ctx.tx[sfAccount]), ctx.view()}) { - adjustOwnerCount(ctx.view(), sleAccount, count, ctx.journal); + adjustOwnerCount(ctx.view(), sleAccount.mutableSle(), count, ctx.journal); return true; } @@ -212,7 +213,8 @@ OracleSet::doApply() priceData.setFieldU8(sfScale, entry.getFieldU8(sfScale)); }; - if (auto sle = ctx_.view().peek(oracleID)) + OracleEntry sle{oracleID, ctx_.view()}; + if (sle) { // update // the token pair that doesn't have their price updated will not @@ -271,13 +273,13 @@ OracleSet::doApply() if (adjust != 0 && !adjustOwnerCount(ctx_, adjust)) return tefINTERNAL; // LCOV_EXCL_LINE - ctx_.view().update(sle); + sle.update(); } else { // create - sle = std::make_shared(oracleID); + sle.newSLE(); sle->setAccountID(sfOwner, ctx_.tx.getAccountID(sfAccount)); if (ctx_.view().rules().enabled(fixIncludeKeyletFields)) { @@ -321,7 +323,7 @@ OracleSet::doApply() if (!adjustOwnerCount(ctx_, count)) return tefINTERNAL; // LCOV_EXCL_LINE - ctx_.view().insert(sle); + sle.insert(); } return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/payment/Payment.cpp b/src/libxrpl/tx/transactors/payment/Payment.cpp index 6e3883572a..6d9b30874a 100644 --- a/src/libxrpl/tx/transactors/payment/Payment.cpp +++ b/src/libxrpl/tx/transactors/payment/Payment.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -460,24 +461,24 @@ Payment::doApply() // Open a ledger for editing. auto const k = keylet::account(dstAccountID); - SLE::pointer sleDst = view().peek(k); + AccountRootEntry sleDst{k, view()}; if (!sleDst) { // Create the account. - sleDst = std::make_shared(k); + sleDst.newSLE(); sleDst->setAccountID(sfAccount, dstAccountID); sleDst->setFieldU32(sfSequence, view().seq()); sleDst->setFieldAmount(sfBalance, XRPAmount(beast::kZero)); - view().insert(sleDst); + sleDst.insert(); } else { // Tell the engine that we are intending to change the destination // account. The source account gets always charged a fee so it's always // marked as modified. - view().update(sleDst); + sleDst.update(); } bool const mpTokensV2 = view().rules().enabled(featureMPTokensV2); @@ -496,7 +497,7 @@ Payment::doApply() // 2. If Account is deposit preauthorized by destination. if (auto err = verifyDepositPreauth( - ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal); + ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst.sle(), ctx_.journal); !isTesSuccess(err)) return err; @@ -566,7 +567,7 @@ Payment::doApply() return ter; if (auto err = verifyDepositPreauth( - ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal); + ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst.sle(), ctx_.journal); !isTesSuccess(err)) return err; @@ -669,7 +670,7 @@ Payment::doApply() // transaction types. Note, this is not amendment-gated because all writes // to pseudo-account discriminator fields **are** amendment gated, hence the // behaviour of this check will always match the active amendments. - if (isPseudoAccount(sleDst)) + if (isPseudoAccount(sleDst.sle())) return tecNO_PERMISSION; // The source account does have enough money. Make sure the @@ -699,7 +700,7 @@ Payment::doApply() if (dstAmount > dstReserve || sleDst->getFieldAmount(sfBalance) > dstReserve) { if (auto err = verifyDepositPreauth( - ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal); + ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst.sle(), ctx_.journal); !isTesSuccess(err)) return err; } diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp index b8118bc49f..4ae9fc7469 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp @@ -110,7 +110,7 @@ TER PaymentChannelClaim::doApply() { Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]); - auto const slep = ctx_.view().peek(k); + PayChannelEntry slep{k, ctx_.view()}; if (!slep) return tecNO_TARGET; @@ -159,12 +159,12 @@ PaymentChannelClaim::doApply() return tecUNFUNDED_PAYMENT; } - auto const sled = ctx_.view().peek(keylet::account(dst)); + AccountRootEntry sled{dst, ctx_.view()}; if (!sled) return tecNO_DST; - if (auto err = - verifyDepositPreauth(ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal); + if (auto err = verifyDepositPreauth( + ctx_.tx, ctx_.view(), txAccount, dst, sled.sle(), ctx_.journal); !isTesSuccess(err)) return err; @@ -173,8 +173,8 @@ PaymentChannelClaim::doApply() XRPL_ASSERT( reqDelta >= beast::kZero, "xrpl::PaymentChannelClaim::doApply : minimum balance delta"); (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta; - ctx_.view().update(sled); - ctx_.view().update(slep); + sled.update(); + slep.update(); } if (ctx_.tx.isFlag(tfRenew)) @@ -182,7 +182,7 @@ PaymentChannelClaim::doApply() if (src != txAccount) return tecNO_PERMISSION; (*slep)[~sfExpiration] = std::nullopt; - ctx_.view().update(slep); + slep.update(); } if (ctx_.tx.isFlag(tfClose)) @@ -199,7 +199,7 @@ PaymentChannelClaim::doApply() if (!curExpiration || *curExpiration > settleExpiration) { (*slep)[~sfExpiration] = settleExpiration; - ctx_.view().update(slep); + slep.update(); } } diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp index 4e3c5dd638..68d2bf1e4b 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp @@ -43,7 +43,7 @@ TER PaymentChannelFund::doApply() { Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]); - auto const slep = ctx_.view().peek(k); + PayChannelEntry slep{k, ctx_.view()}; if (!slep) return tecNO_ENTRY; @@ -78,10 +78,10 @@ PaymentChannelFund::doApply() : TER{temBAD_EXPIRATION}; } (*slep)[~sfExpiration] = *newExpiration; - ctx_.view().update(slep); + slep.update(); } - auto const sle = ctx_.view().peek(keylet::account(txAccount)); + AccountRootEntry sle{txAccount, ctx_.view()}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -104,10 +104,10 @@ PaymentChannelFund::doApply() } (*slep)[sfAmount] = (*slep)[sfAmount] + ctx_.tx[sfAmount]; - ctx_.view().update(slep); + slep.update(); (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount]; - ctx_.view().update(sle); + sle.update(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp index 7eb3f282b9..241b175aa1 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,7 @@ TER PermissionedDomainDelete::preclaim(PreclaimContext const& ctx) { auto const domain = ctx.tx.getFieldH256(sfDomainID); - auto const sleDomain = ctx.view.read(keylet::permissionedDomain(domain)); + PermissionedDomainEntry sleDomain{keylet::permissionedDomain(domain), ctx.view}; if (!sleDomain) return tecNO_ENTRY; @@ -50,7 +51,8 @@ PermissionedDomainDelete::doApply() ctx_.tx.isFieldPresent(sfDomainID), "xrpl::PermissionedDomainDelete::doApply : required field present"); - auto const slePd = view().peek(keylet::permissionedDomain(ctx_.tx.at(sfDomainID))); + PermissionedDomainEntry slePd{ + keylet::permissionedDomain(ctx_.tx.at(sfDomainID)), view()}; auto const page = (*slePd)[sfOwnerNode]; if (!view().dirRemove(keylet::ownerDir(accountID_), page, slePd->key(), true)) @@ -61,12 +63,12 @@ PermissionedDomainDelete::doApply() // LCOV_EXCL_STOP } - auto const ownerSle = view().peek(keylet::account(accountID_)); + AccountRootEntry ownerSle{keylet::account(accountID_), view()}; XRPL_ASSERT( ownerSle && ownerSle->getFieldU32(sfOwnerCount) > 0, "xrpl::PermissionedDomainDelete::doApply : nonzero owner count"); - adjustOwnerCount(view(), ownerSle, -1, ctx_.journal); - view().erase(slePd); + adjustOwnerCount(view(), ownerSle.mutableSle(), -1, ctx_.journal); + slePd.erase(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp index 0e71ceada1..220620fa47 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -62,8 +63,8 @@ PermissionedDomainSet::preclaim(PreclaimContext const& ctx) if (ctx.tx.isFieldPresent(sfDomainID)) { - auto const sleDomain = - ctx.view.read(keylet::permissionedDomain(ctx.tx.getFieldH256(sfDomainID))); + PermissionedDomainEntry sleDomain{ + keylet::permissionedDomain(ctx.tx.getFieldH256(sfDomainID)), ctx.view}; if (!sleDomain) return tecNO_ENTRY; if (sleDomain->getAccountID(sfOwner) != account) @@ -77,7 +78,7 @@ PermissionedDomainSet::preclaim(PreclaimContext const& ctx) TER PermissionedDomainSet::doApply() { - auto const ownerSle = view().peek(keylet::account(accountID_)); + AccountRootEntry ownerSle{keylet::account(accountID_), view()}; if (!ownerSle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -95,11 +96,12 @@ PermissionedDomainSet::doApply() if (ctx_.tx.isFieldPresent(sfDomainID)) { // Modify existing permissioned domain. - auto slePd = view().peek(keylet::permissionedDomain(ctx_.tx.getFieldH256(sfDomainID))); + PermissionedDomainEntry slePd{ + keylet::permissionedDomain(ctx_.tx.getFieldH256(sfDomainID)), view()}; if (!slePd) return tefINTERNAL; // LCOV_EXCL_LINE slePd->peekFieldArray(sfAcceptedCredentials) = std::move(sortedLE); - view().update(slePd); + slePd.update(); } else { @@ -113,7 +115,8 @@ PermissionedDomainSet::doApply() bool const fixEnabled = view().rules().enabled(fixCleanup3_1_3); auto const seq = fixEnabled ? ctx_.tx.getSeqValue() : ctx_.tx.getFieldU32(sfSequence); Keylet const pdKeylet = keylet::permissionedDomain(accountID_, seq); - auto slePd = std::make_shared(pdKeylet); + PermissionedDomainEntry slePd{pdKeylet, view()}; + slePd.newSLE(); slePd->setAccountID(sfOwner, accountID_); slePd->setFieldU32(sfSequence, seq); @@ -125,8 +128,8 @@ PermissionedDomainSet::doApply() slePd->setFieldU64(sfOwnerNode, *page); // If we succeeded, the new entry counts against the creator's reserve. - adjustOwnerCount(view(), ownerSle, 1, ctx_.journal); - view().insert(slePd); + adjustOwnerCount(view(), ownerSle.mutableSle(), 1, ctx_.journal); + slePd.insert(); } return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/system/Change.cpp b/src/libxrpl/tx/transactors/system/Change.cpp index f27855a5c8..efd40f170f 100644 --- a/src/libxrpl/tx/transactors/system/Change.cpp +++ b/src/libxrpl/tx/transactors/system/Change.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -162,14 +163,12 @@ Change::applyAmendment() { uint256 const amendment(ctx_.tx.getFieldH256(sfAmendment)); - auto const k = keylet::amendments(); - - SLE::pointer amendmentObject = view().peek(k); + AmendmentsEntry amendmentObject{view()}; if (!amendmentObject) { - amendmentObject = std::make_shared(k); - view().insert(amendmentObject); + amendmentObject.newSLE(); + amendmentObject.insert(); } STVector256 amendments = amendmentObject->getFieldV256(sfAmendments); @@ -246,7 +245,7 @@ Change::applyAmendment() amendmentObject->setFieldArray(sfMajorities, newMajorities); } - view().update(amendmentObject); + amendmentObject.update(); return tesSUCCESS; } @@ -254,16 +253,14 @@ Change::applyAmendment() TER Change::applyFee() { - auto const k = keylet::feeSettings(); - - SLE::pointer feeObject = view().peek(k); + FeeSettingsEntry feeObject{view()}; if (!feeObject) { - feeObject = std::make_shared(k); - view().insert(feeObject); + feeObject.newSLE(); + feeObject.insert(); } - auto set = [](SLE::pointer& feeObject, STTx const& tx, auto const& field) { + auto set = [](auto& feeObject, STTx const& tx, auto const& field) { feeObject->at(field) = tx[field]; }; if (view().rules().enabled(featureXRPFees)) @@ -285,7 +282,7 @@ Change::applyFee() set(feeObject, ctx_.tx, sfReserveIncrement); } - view().update(feeObject); + feeObject.update(); JLOG(j_.warn()) << "Fees have been changed"; return tesSUCCESS; @@ -326,12 +323,11 @@ Change::applyUNLModify() JLOG(j_.info()) << "N-UNL: applyUNLModify, " << (disabling ? "ToDisable" : "ToReEnable") << " seq=" << seq << " validator data:" << strHex(validator); - auto const k = keylet::negativeUNL(); - SLE::pointer negUnlObject = view().peek(k); + NegativeUNLEntry negUnlObject{view()}; if (!negUnlObject) { - negUnlObject = std::make_shared(k); - view().insert(negUnlObject); + negUnlObject.newSLE(); + negUnlObject.insert(); } bool const found = [&] { @@ -404,7 +400,7 @@ Change::applyUNLModify() negUnlObject->setFieldVL(sfValidatorToReEnable, validator); } - view().update(negUnlObject); + negUnlObject.update(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/system/TicketCreate.cpp b/src/libxrpl/tx/transactors/system/TicketCreate.cpp index 73a72c217d..d4f4fc6a52 100644 --- a/src/libxrpl/tx/transactors/system/TicketCreate.cpp +++ b/src/libxrpl/tx/transactors/system/TicketCreate.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -67,7 +68,7 @@ TicketCreate::preclaim(PreclaimContext const& ctx) TER TicketCreate::doApply() { - SLE::pointer const sleAccountRoot = view().peek(keylet::account(accountID_)); + AccountRootEntry sleAccountRoot{keylet::account(accountID_), view()}; if (!sleAccountRoot) return tefINTERNAL; // LCOV_EXCL_LINE @@ -101,11 +102,12 @@ TicketCreate::doApply() { std::uint32_t const curTicketSeq = firstTicketSeq + i; Keylet const ticketKeylet = keylet::ticket(accountID_, curTicketSeq); - SLE::pointer const sleTicket = std::make_shared(ticketKeylet); + TicketEntry sleTicket{ticketKeylet, view()}; + sleTicket.newSLE(); sleTicket->setAccountID(sfAccount, accountID_); sleTicket->setFieldU32(sfTicketSequence, curTicketSeq); - view().insert(sleTicket); + sleTicket.insert(); auto const page = view().dirInsert( keylet::ownerDir(accountID_), ticketKeylet, describeOwnerDir(accountID_)); @@ -125,7 +127,7 @@ TicketCreate::doApply() sleAccountRoot->setFieldU32(sfTicketCount, oldTicketCount + ticketCount); // Every added Ticket counts against the creator's reserve. - adjustOwnerCount(view(), sleAccountRoot, ticketCount, viewJ); + adjustOwnerCount(view(), sleAccountRoot.mutableSle(), ticketCount, viewJ); // TicketCreate is the only transaction that can cause an account root's // Sequence field to increase by more than one. October 2018. diff --git a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp index 6db37515cb..ce1b0f9a93 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenAuthorize.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -46,8 +47,8 @@ MPTokenAuthorize::preclaim(PreclaimContext const& ctx) // `holderID` is NOT used if (!holderID) { - SLE::const_pointer const sleMpt = - ctx.view.read(keylet::mptoken(ctx.tx[sfMPTokenIssuanceID], accountID)); + MPTokenEntry const sleMpt{ + keylet::mptoken(ctx.tx[sfMPTokenIssuanceID], accountID), ctx.view}; // There is an edge case where all holders have zero balance, issuance // is legally destroyed, then outstanding MPT(s) are deleted afterwards. diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp index d526251069..5f41a369c7 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -301,16 +302,10 @@ MPTokenIssuanceSet::doApply() auto const mptIssuanceID = ctx_.tx[sfMPTokenIssuanceID]; auto const holderID = ctx_.tx[~sfHolder]; auto const domainID = ctx_.tx[~sfDomainID]; - SLE::pointer sle; - - if (holderID) - { - sle = view().peek(keylet::mptoken(mptIssuanceID, *holderID)); - } - else - { - sle = view().peek(keylet::mptokenIssuance(mptIssuanceID)); - } + WritableSLE sle{ + holderID ? keylet::mptoken(mptIssuanceID, *holderID) + : keylet::mptokenIssuance(mptIssuanceID), + view()}; if (!sle) return tecINTERNAL; // LCOV_EXCL_LINE @@ -410,7 +405,7 @@ MPTokenIssuanceSet::doApply() sle->setFieldVL(sfAuditorEncryptionKey, *pubKey); } - view().update(sle); + sle.update(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/token/TrustSet.cpp b/src/libxrpl/tx/transactors/token/TrustSet.cpp index e79e3cad5a..6fa044a849 100644 --- a/src/libxrpl/tx/transactors/token/TrustSet.cpp +++ b/src/libxrpl/tx/transactors/token/TrustSet.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -293,7 +294,7 @@ TrustSet::doApply() // true, if current is high account. bool const bHigh = accountID_ > uDstAccountID; - auto const sle = view().peek(keylet::account(accountID_)); + AccountRootEntry sle{keylet::account(accountID_), view()}; if (!sle) return tefINTERNAL; // LCOV_EXCL_LINE @@ -337,7 +338,7 @@ TrustSet::doApply() auto viewJ = ctx_.registry.get().getJournal("View"); - SLE::pointer const sleDst = view().peek(keylet::account(uDstAccountID)); + AccountRootEntry sleDst{keylet::account(uDstAccountID), view()}; if (!sleDst) { @@ -348,8 +349,8 @@ TrustSet::doApply() STAmount saLimitAllow = saLimitAmount; saLimitAllow.get().account = accountID_; - SLE::pointer const sleRippleState = - view().peek(keylet::trustLine(accountID_, uDstAccountID, currency)); + RippleStateEntry sleRippleState{ + keylet::trustLine(accountID_, uDstAccountID, currency), view()}; if (sleRippleState) { @@ -363,8 +364,8 @@ TrustSet::doApply() std::uint32_t uHighQualityOut = 0; auto const& uLowAccountID = !bHigh ? accountID_ : uDstAccountID; auto const& uHighAccountID = bHigh ? accountID_ : uDstAccountID; - SLE::ref sleLowAccount = !bHigh ? sle : sleDst; - SLE::ref sleHighAccount = bHigh ? sle : sleDst; + AccountRootEntry& sleLowAccount = !bHigh ? sle : sleDst; + AccountRootEntry& sleHighAccount = bHigh ? sle : sleDst; // // Balances @@ -513,7 +514,7 @@ TrustSet::doApply() if (bLowReserveSet && !bLowReserved) { // Set reserve for low account. - adjustOwnerCount(view(), sleLowAccount, 1, viewJ); + adjustOwnerCount(view(), sleLowAccount.mutableSle(), 1, viewJ); uFlagsOut |= lsfLowReserve; if (!bHigh) @@ -523,14 +524,14 @@ TrustSet::doApply() if (bLowReserveClear && bLowReserved) { // Clear reserve for low account. - adjustOwnerCount(view(), sleLowAccount, -1, viewJ); + adjustOwnerCount(view(), sleLowAccount.mutableSle(), -1, viewJ); uFlagsOut &= ~lsfLowReserve; } if (bHighReserveSet && !bHighReserved) { // Set reserve for high account. - adjustOwnerCount(view(), sleHighAccount, 1, viewJ); + adjustOwnerCount(view(), sleHighAccount.mutableSle(), 1, viewJ); uFlagsOut |= lsfHighReserve; if (bHigh) @@ -540,7 +541,7 @@ TrustSet::doApply() if (bHighReserveClear && bHighReserved) { // Clear reserve for high account. - adjustOwnerCount(view(), sleHighAccount, -1, viewJ); + adjustOwnerCount(view(), sleHighAccount.mutableSle(), -1, viewJ); uFlagsOut &= ~lsfHighReserve; } @@ -551,7 +552,8 @@ TrustSet::doApply() { // Delete. - terResult = trustDelete(view(), sleRippleState, uLowAccountID, uHighAccountID, viewJ); + terResult = trustDelete( + view(), sleRippleState.mutableSle(), uLowAccountID, uHighAccountID, viewJ); } // Reserve is not scaled by load. else if (bReserveIncrease && preFeeBalance_ < reserveCreate) @@ -565,7 +567,7 @@ TrustSet::doApply() } else { - view().update(sleRippleState); + sleRippleState.update(); JLOG(j_.trace()) << "Modify ripple line"; } @@ -608,7 +610,7 @@ TrustSet::doApply() accountID_, uDstAccountID, k.key, - sle, + sle.mutableSle(), bSetAuth, bSetNoRipple && !bClearNoRipple, bSetFreeze && !bClearFreeze, diff --git a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp index 541660c98f..ddd070bdf5 100644 --- a/src/libxrpl/tx/transactors/vault/VaultClawback.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultClawback.cpp @@ -60,7 +60,7 @@ VaultClawback::preflight(PreflightContext const& ctx) [[nodiscard]] STAmount clawbackAmount( - SLE::const_ref vault, + VaultEntry const& vault, std::optional const& maybeAmount, AccountID const& account) { @@ -77,7 +77,7 @@ clawbackAmount( TER VaultClawback::preclaim(PreclaimContext const& ctx) { - auto const vault = ctx.view.read(keylet::vault(ctx.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx.tx[sfVaultID]), ctx.view}; if (!vault) return tecNO_ENTRY; @@ -86,7 +86,8 @@ VaultClawback::preclaim(PreclaimContext const& ctx) auto const holder = ctx.tx[sfHolder]; auto const maybeAmount = ctx.tx[~sfAmount]; auto const mptIssuanceID = vault->at(sfShareMPTID); - auto const sleShareIssuance = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry sleShareIssuance{ + keylet::mptokenIssuance(mptIssuanceID), ctx.view}; if (!sleShareIssuance) { // LCOV_EXCL_START @@ -180,8 +181,9 @@ VaultClawback::preclaim(PreclaimContext const& ctx) return vaultAsset.visit( [&](MPTIssue const& issue) -> TER { - auto const mptIssue = ctx.view.read(keylet::mptokenIssuance(issue.getMptID())); - if (mptIssue == nullptr) + MPTokenIssuanceEntry mptIssue{ + keylet::mptokenIssuance(issue.getMptID()), ctx.view}; + if (!mptIssue) return tecOBJECT_NOT_FOUND; if (!mptIssue->isFlag(lsfMPTCanClawback)) @@ -194,7 +196,7 @@ VaultClawback::preclaim(PreclaimContext const& ctx) return tesSUCCESS; }, [&](Issue const&) -> TER { - auto const issuerSle = ctx.view.read(keylet::account(account)); + AccountRootEntry issuerSle{keylet::account(account), ctx.view}; if (!issuerSle) { // LCOV_EXCL_START @@ -220,8 +222,8 @@ VaultClawback::preclaim(PreclaimContext const& ctx) std::expected, TER> VaultClawback::assetsToClawback( - SLE::ref vault, - SLE::const_ref sleShareIssuance, + VaultEntry& vault, + MPTokenIssuanceEntry const& sleShareIssuance, AccountID const& holder, STAmount const& clawbackAmount) { @@ -332,12 +334,12 @@ TER VaultClawback::doApply() { auto const& tx = ctx_.tx; - auto const vault = view().peek(keylet::vault(tx[sfVaultID])); + VaultEntry vault{keylet::vault(tx[sfVaultID]), view()}; if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE auto const mptIssuanceID = *vault->at(sfShareMPTID); - auto const sleIssuance = view().read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry sleIssuance{keylet::mptokenIssuance(mptIssuanceID), view()}; if (!sleIssuance) { // LCOV_EXCL_START @@ -385,7 +387,7 @@ VaultClawback::doApply() assetsTotal -= assetsRecovered; assetsAvailable -= assetsRecovered; - view().update(vault); + vault.update(); auto const& vaultAccount = vault->at(sfAccount); // Transfer shares from holder to vault. diff --git a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp index d262132b6f..a70103b3e9 100644 --- a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -147,8 +148,8 @@ VaultCreate::doApply() auto const& tx = ctx_.tx; auto const sequence = tx.getSeqValue(); - auto const owner = view().peek(keylet::account(accountID_)); - if (owner == nullptr) + AccountRootEntry owner{keylet::account(accountID_), view()}; + if (!owner) return tefINTERNAL; // LCOV_EXCL_LINE auto vault = std::make_shared(keylet::vault(accountID_, sequence)); @@ -156,7 +157,7 @@ VaultCreate::doApply() if (auto ter = dirLink(view(), accountID_, vault)) return ter; // We will create Vault and PseudoAccount, hence increase OwnerCount by 2 - adjustOwnerCount(view(), owner, 2, j_); + adjustOwnerCount(view(), owner.mutableSle(), 2, j_); auto const ownerCount = owner->at(sfOwnerCount); if (preFeeBalance_ < view().fees().accountReserve(ownerCount)) return tecINSUFFICIENT_RESERVE; diff --git a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp index fa38ae278b..a7eeeefd2b 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,7 @@ VaultDelete::preflight(PreflightContext const& ctx) TER VaultDelete::preclaim(PreclaimContext const& ctx) { - auto const vault = ctx.view.read(keylet::vault(ctx.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx.tx[sfVaultID]), ctx.view}; if (!vault) return tecNO_ENTRY; @@ -65,7 +66,8 @@ VaultDelete::preclaim(PreclaimContext const& ctx) } // Verify we can destroy MPTokenIssuance - auto const sleMPT = ctx.view.read(keylet::mptokenIssuance(vault->at(sfShareMPTID))); + MPTokenIssuanceEntry sleMPT{ + keylet::mptokenIssuance(vault->at(sfShareMPTID)), ctx.view}; if (!sleMPT) { @@ -95,7 +97,7 @@ VaultDelete::preclaim(PreclaimContext const& ctx) TER VaultDelete::doApply() { - auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx_.tx[sfVaultID]), view()}; if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE @@ -106,7 +108,7 @@ VaultDelete::doApply() return ter; auto const& pseudoID = vault->at(sfAccount); - auto const pseudoAcct = view().peek(keylet::account(pseudoID)); + AccountRootEntry pseudoAcct{keylet::account(pseudoID), view()}; if (!pseudoAcct) { // LCOV_EXCL_START @@ -118,7 +120,7 @@ VaultDelete::doApply() // Destroy the share issuance. Do not use MPTokenIssuanceDestroy for this, // no special logic needed. First run few checks, duplicated from preclaim. auto const shareMPTID = *vault->at(sfShareMPTID); - auto const mpt = view().peek(keylet::mptokenIssuance(shareMPTID)); + MPTokenIssuanceEntry mpt{keylet::mptokenIssuance(shareMPTID), view()}; if (!mpt) { // LCOV_EXCL_START @@ -128,7 +130,7 @@ VaultDelete::doApply() } // Try to remove MPToken for vault shares for the vault owner if it exists. - if (auto const mptoken = view().peek(keylet::mptoken(shareMPTID, accountID_))) + if (MPTokenEntry mptoken{keylet::mptoken(shareMPTID, accountID_), view()}) { if (auto const ter = removeEmptyHolding(view(), accountID_, MPTIssue(shareMPTID), j_); !isTesSuccess(ter)) @@ -151,16 +153,16 @@ VaultDelete::doApply() return tefBAD_LEDGER; // LCOV_EXCL_STOP } - adjustOwnerCount(view(), pseudoAcct, -1, j_); + adjustOwnerCount(view(), pseudoAcct.mutableSle(), -1, j_); - view().erase(mpt); + mpt.erase(); // The pseudo-account's directory should have been deleted already. - if (view().peek(keylet::ownerDir(pseudoID))) + if (DirectoryNodeEntry{keylet::ownerDir(pseudoID), view()}) return tecHAS_OBLIGATIONS; // LCOV_EXCL_LINE // Destroy the pseudo-account. - auto vaultPseudoSLE = view().peek(keylet::account(pseudoID)); + AccountRootEntry vaultPseudoSLE{keylet::account(pseudoID), view()}; if (!vaultPseudoSLE || vaultPseudoSLE->at(~sfVaultID) != vault->key()) return tefBAD_LEDGER; // LCOV_EXCL_LINE @@ -188,7 +190,7 @@ VaultDelete::doApply() // LCOV_EXCL_STOP } - view().erase(vaultPseudoSLE); + vaultPseudoSLE.erase(); // Remove the vault from its owner's directory. auto const ownerID = vault->at(sfOwner); @@ -200,7 +202,7 @@ VaultDelete::doApply() // LCOV_EXCL_STOP } - auto const owner = view().peek(keylet::account(ownerID)); + AccountRootEntry owner{keylet::account(ownerID), view()}; if (!owner) { // LCOV_EXCL_START @@ -210,10 +212,10 @@ VaultDelete::doApply() } // We are destroying Vault and PseudoAccount, hence decrease by 2 - adjustOwnerCount(view(), owner, -2, j_); + adjustOwnerCount(view(), owner.mutableSle(), -2, j_); // Destroy the vault. - view().erase(vault); + vault.erase(); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp index d5eb80b84d..2c312e0ac4 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDeposit.cpp @@ -29,7 +29,7 @@ namespace xrpl { [[nodiscard]] static STAmount -roundToVaultScale(STAmount const& amount, SLE::const_ref vault) +roundToVaultScale(STAmount const& amount, VaultEntry const& vault) { XRPL_ASSERT(vault && vault->getType() == ltVAULT, "xrpl::roundToVaultScale : valid vault sle"); XRPL_ASSERT( @@ -66,7 +66,7 @@ VaultDeposit::preclaim(PreclaimContext const& ctx) auto const fix320Enabled = ctx.view.rules().enabled(fixCleanup3_2_0); auto const fix330Enabled = ctx.view.rules().enabled(fixCleanup3_3_0); - auto const vault = ctx.view.read(keylet::vault(ctx.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx.tx[sfVaultID]), ctx.view}; if (!vault) return tecNO_ENTRY; @@ -93,7 +93,7 @@ VaultDeposit::preclaim(PreclaimContext const& ctx) // LCOV_EXCL_STOP } - auto const sleIssuance = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry sleIssuance{keylet::mptokenIssuance(mptIssuanceID), ctx.view}; if (!sleIssuance) { // LCOV_EXCL_START @@ -195,7 +195,7 @@ TER VaultDeposit::doApply() { bool const fix320Enabled = view().rules().enabled(fixCleanup3_2_0); - auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx_.tx[sfVaultID]), view()}; if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE auto const vaultAsset = vault->at(sfAsset); @@ -216,7 +216,7 @@ VaultDeposit::doApply() // Make sure the depositor can hold shares. auto const mptIssuanceID = (*vault)[sfShareMPTID]; - auto const sleIssuance = view().read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry sleIssuance{keylet::mptokenIssuance(mptIssuanceID), view()}; if (!sleIssuance) { // LCOV_EXCL_START @@ -310,7 +310,7 @@ VaultDeposit::doApply() vault->at(sfAssetsTotal) += assetsDeposited; vault->at(sfAssetsAvailable) += assetsDeposited; - view().update(vault); + vault.update(); // A deposit must not push the vault over its limit. auto const maximum = *vault->at(sfAssetsMaximum); diff --git a/src/libxrpl/tx/transactors/vault/VaultSet.cpp b/src/libxrpl/tx/transactors/vault/VaultSet.cpp index c71e84858a..048055b364 100644 --- a/src/libxrpl/tx/transactors/vault/VaultSet.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultSet.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ VaultSet::preflight(PreflightContext const& ctx) TER VaultSet::preclaim(PreclaimContext const& ctx) { - auto const vault = ctx.view.read(keylet::vault(ctx.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx.tx[sfVaultID]), ctx.view}; if (!vault) return tecNO_ENTRY; @@ -75,7 +76,7 @@ VaultSet::preclaim(PreclaimContext const& ctx) } auto const mptIssuanceID = (*vault)[sfShareMPTID]; - auto const sleIssuance = ctx.view.read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry sleIssuance{keylet::mptokenIssuance(mptIssuanceID), ctx.view}; if (!sleIssuance) { // LCOV_EXCL_START @@ -95,7 +96,8 @@ VaultSet::preclaim(PreclaimContext const& ctx) if (*domain != beast::kZero) { - auto const sleDomain = ctx.view.read(keylet::permissionedDomain(*domain)); + PermissionedDomainEntry sleDomain{ + keylet::permissionedDomain(*domain), ctx.view}; if (!sleDomain) return tecOBJECT_NOT_FOUND; } @@ -123,14 +125,14 @@ VaultSet::doApply() auto const& tx = ctx_.tx; // Update existing object. - auto vault = view().peek(keylet::vault(tx[sfVaultID])); + VaultEntry vault{keylet::vault(tx[sfVaultID]), view()}; if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE auto const vaultAsset = vault->at(sfAsset); auto const mptIssuanceID = (*vault)[sfShareMPTID]; - auto const sleIssuance = view().peek(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry sleIssuance{keylet::mptokenIssuance(mptIssuanceID), view()}; if (!sleIssuance) { // LCOV_EXCL_START @@ -164,13 +166,13 @@ VaultSet::doApply() { sleIssuance->makeFieldAbsent(sfDomainID); } - view().update(sleIssuance); + sleIssuance.update(); } // Note, we must update Vault object even if only DomainID is being updated // in Issuance object. Otherwise it's really difficult for Vault invariants // to verify the operation. - view().update(vault); + vault.update(); associateAsset(*vault, vaultAsset); diff --git a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp index ad91c55723..7deb864f86 100644 --- a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp @@ -28,7 +28,10 @@ namespace xrpl { static WaiveUnrealizedLoss -shouldWaiveWithdrawal(ReadView const& view, AccountID const& account, SLE::const_ref issuance) +shouldWaiveWithdrawal( + ReadView const& view, + AccountID const& account, + MPTokenIssuanceEntry const& issuance) { XRPL_ASSERT( issuance && issuance->getType() == ltMPTOKEN_ISSUANCE, @@ -69,7 +72,7 @@ VaultWithdraw::preclaim(PreclaimContext const& ctx) auto const fix320Enabled = ctx.view.rules().enabled(fixCleanup3_2_0); auto const fix330Enabled = ctx.view.rules().enabled(fixCleanup3_3_0); - auto const vault = ctx.view.read(keylet::vault(ctx.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx.tx[sfVaultID]), ctx.view}; if (!vault) return tecNO_ENTRY; @@ -109,7 +112,7 @@ VaultWithdraw::preclaim(PreclaimContext const& ctx) // to the equivalent asset amount before checking withdrawal // limits. Pre-amendment the limit check was skipped for // share-denominated withdrawals. - auto const sleIssuance = ctx.view.read(keylet::mptokenIssuance(vaultShare)); + MPTokenIssuanceEntry sleIssuance{keylet::mptokenIssuance(vaultShare), ctx.view}; if (!sleIssuance) { // LCOV_EXCL_START @@ -193,12 +196,12 @@ VaultWithdraw::preclaim(PreclaimContext const& ctx) TER VaultWithdraw::doApply() { - auto const vault = view().peek(keylet::vault(ctx_.tx[sfVaultID])); + VaultEntry vault{keylet::vault(ctx_.tx[sfVaultID]), view()}; if (!vault) return tefINTERNAL; // LCOV_EXCL_LINE auto const mptIssuanceID = *((*vault)[sfShareMPTID]); - auto const sleIssuance = view().read(keylet::mptokenIssuance(mptIssuanceID)); + MPTokenIssuanceEntry sleIssuance{keylet::mptokenIssuance(mptIssuanceID), view()}; if (!sleIssuance) { // LCOV_EXCL_START @@ -346,7 +349,7 @@ VaultWithdraw::doApply() assetsTotal -= assetsWithdrawn; assetsAvailable -= assetsWithdrawn; } - view().update(vault); + vault.update(); auto const& vaultAccount = vault->at(sfAccount); // Transfer shares from depositor to vault. diff --git a/src/test/app/LendingHelpers_test.cpp b/src/test/app/LendingHelpers_test.cpp index ac8e0764fc..2062f69b4e 100644 --- a/src/test/app/LendingHelpers_test.cpp +++ b/src/test/app/LendingHelpers_test.cpp @@ -1525,8 +1525,9 @@ public: for (auto const& tc : testCases) { testcase("canApplyToBrokerCover: " + tc.name); - auto sle = std::make_shared(ltLOAN_BROKER, uint256{1u}); - sle->at(sfCoverAvailable) = tc.coverAvailable; + auto broker = std::make_shared(Keylet{ltLOAN_BROKER, uint256{1u}}); + broker->at(sfCoverAvailable) = tc.coverAvailable; + LoanBrokerEntry sle{broker, *env.current()}; BEAST_EXPECT( canApplyToBrokerCover(*env.current(), sle, iou, tc.amount, env.journal, "test") == tc.expected); @@ -1536,8 +1537,9 @@ public: { testcase("canApplyToBrokerCover: amendment disabled"); Env const envOff{*this, testableAmendments() - fixCleanup3_2_0}; - auto sle = std::make_shared(ltLOAN_BROKER, uint256{1u}); - sle->at(sfCoverAvailable) = Number{10}; + auto broker = std::make_shared(Keylet{ltLOAN_BROKER, uint256{1u}}); + broker->at(sfCoverAvailable) = Number{10}; + LoanBrokerEntry sle{broker, *envOff.current()}; BEAST_EXPECT( canApplyToBrokerCover( *envOff.current(),