From a8987cf271aa4dc84c6bc4f5af02f9f84e53c2fe Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 16 Mar 2026 21:48:12 -0400 Subject: [PATCH] fix all the build issues --- include/xrpl/ledger/View.h | 2 +- .../xrpl/ledger/helpers/AccountRootHelpers.h | 24 ++++-- .../xrpl/ledger/helpers/RippleStateHelpers.h | 21 ++--- include/xrpl/ledger/helpers/WrappedSLEBase.h | 47 +++++++++-- .../tx/transactors/lending/LendingHelpers.h | 11 +++ src/libxrpl/ledger/View.cpp | 10 +-- .../ledger/helpers/AccountRootHelpers.cpp | 23 +++--- .../ledger/helpers/CredentialHelpers.cpp | 6 +- src/libxrpl/ledger/helpers/MPTokenHelpers.cpp | 10 +-- src/libxrpl/ledger/helpers/OfferHelpers.cpp | 3 +- .../ledger/helpers/RippleStateHelpers.cpp | 78 ++++++++++--------- src/libxrpl/ledger/helpers/TokenHelpers.cpp | 29 ++++--- src/libxrpl/tx/Transactor.cpp | 10 +-- .../tx/transactors/account/SignerListSet.cpp | 46 ++++------- .../tx/transactors/bridge/XChainBridge.cpp | 26 +++---- .../tx/transactors/check/CheckCancel.cpp | 4 +- .../tx/transactors/check/CheckCash.cpp | 16 ++-- .../tx/transactors/check/CheckCreate.cpp | 14 ++-- .../credentials/CredentialAccept.cpp | 12 +-- .../credentials/CredentialCreate.cpp | 8 +- .../tx/transactors/delegate/DelegateSet.cpp | 14 ++-- src/libxrpl/tx/transactors/dex/AMMCreate.cpp | 3 +- src/libxrpl/tx/transactors/dex/AMMDeposit.cpp | 8 +- .../tx/transactors/dex/OfferCreate.cpp | 15 ++-- src/libxrpl/tx/transactors/did/DIDDelete.cpp | 8 +- src/libxrpl/tx/transactors/did/DIDSet.cpp | 12 +-- .../tx/transactors/escrow/EscrowCancel.cpp | 10 +-- .../tx/transactors/escrow/EscrowCreate.cpp | 12 +-- .../tx/transactors/escrow/EscrowFinish.cpp | 6 +- .../tx/transactors/escrow/EscrowHelpers.h | 32 +++++--- .../tx/transactors/lending/LendingHelpers.cpp | 64 +++++++++++++++ .../transactors/lending/LoanBrokerDelete.cpp | 6 +- .../tx/transactors/lending/LoanBrokerSet.cpp | 4 +- .../tx/transactors/lending/LoanDelete.cpp | 8 +- .../tx/transactors/lending/LoanSet.cpp | 16 ++-- .../tx/transactors/nft/NFTokenUtils.cpp | 35 +++------ .../tx/transactors/oracle/OracleDelete.cpp | 6 +- .../tx/transactors/oracle/OracleSet.cpp | 4 +- .../tx/transactors/payment/DepositPreauth.cpp | 22 +++--- .../payment_channel/PaymentChannelCreate.cpp | 17 ++-- .../payment_channel/PaymentChannelHelpers.cpp | 10 ++- .../PermissionedDomainDelete.cpp | 6 +- .../PermissionedDomainSet.cpp | 10 +-- .../tx/transactors/system/TicketCreate.cpp | 16 ++-- .../token/MPTokenIssuanceCreate.cpp | 4 +- .../token/MPTokenIssuanceDestroy.cpp | 3 +- src/libxrpl/tx/transactors/token/TrustSet.cpp | 30 +++---- .../tx/transactors/vault/VaultCreate.cpp | 6 +- .../tx/transactors/vault/VaultDelete.cpp | 8 +- 49 files changed, 466 insertions(+), 329 deletions(-) diff --git a/include/xrpl/ledger/View.h b/include/xrpl/ledger/View.h index 55be01d677..7b2874985c 100644 --- a/include/xrpl/ledger/View.h +++ b/include/xrpl/ledger/View.h @@ -157,7 +157,7 @@ canWithdraw( ReadView const& view, AccountID const& from, AccountID const& to, - SLE::const_ref toSle, + WrappedAccountRoot const& toWrapped, STAmount const& amount, bool hasDestinationTag); diff --git a/include/xrpl/ledger/helpers/AccountRootHelpers.h b/include/xrpl/ledger/helpers/AccountRootHelpers.h index 1f4c1c80f0..30e988c04a 100644 --- a/include/xrpl/ledger/helpers/AccountRootHelpers.h +++ b/include/xrpl/ledger/helpers/AccountRootHelpers.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -22,20 +22,34 @@ protected: AccountID const id_; public: - WrappedAccountRoot() = default; + WrappedAccountRoot(AccountID const& id, ReadView const* view) + : WrappedSLEBase(view->read(keylet::account(id)), view), id_(sle_ ? (*sle_)[sfAccount] : id) + { + } + + WrappedAccountRoot(AccountID const& id, ApplyView* view) + : WrappedSLEBase(view->peek(keylet::account(id)), view), id_(sle_ ? (*sle_)[sfAccount] : id) + { + } + + AccountID const& + id() const + { + return id_; + } /** Check if the issuer has the global freeze flag set. @return true if the account has global freeze set */ [[nodiscard]] bool - isGlobalFrozen(); + isGlobalFrozen() const; /** Returns IOU issuer transfer fee as Rate. Rate specifies * the fee as fractions of 1 billion. For example, 1% transfer rate * is represented as 1,010,000,000. */ [[nodiscard]] Rate - transferRate(); + transferRate() const; // Calculate liquid XRP balance for an account. // This function may be used to calculate the amount of XRP that @@ -59,7 +73,7 @@ public: - If the SLE requires a destination tag, checks that there is a tag. */ [[nodiscard]] TER - checkDestinationAndTag(SLE::const_ref toSle, bool hasDestinationTag); + checkDestinationAndTag(bool hasDestinationTag) const; }; /** Generate a pseudo-account address from a pseudo owner key. diff --git a/include/xrpl/ledger/helpers/RippleStateHelpers.h b/include/xrpl/ledger/helpers/RippleStateHelpers.h index 3feba59d1f..1ab9fafd17 100644 --- a/include/xrpl/ledger/helpers/RippleStateHelpers.h +++ b/include/xrpl/ledger/helpers/RippleStateHelpers.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -137,16 +138,16 @@ trustCreate( bool const bSrcHigh, AccountID const& uSrcAccountID, AccountID const& uDstAccountID, - uint256 const& uIndex, // --> ripple state entry - SLE::ref sleAccount, // --> the account being set. - bool const bAuth, // --> authorize account. - bool const bNoRipple, // --> others cannot ripple through - bool const bFreeze, // --> funds cannot leave - bool bDeepFreeze, // --> can neither receive nor send funds - STAmount const& saBalance, // --> balance of account being set. - // Issuer should be noAccount() - STAmount const& saLimit, // --> limit for account being set. - // Issuer should be the account being set. + uint256 const& uIndex, // --> ripple state entry + WrappedAccountRoot const& wrappedAcct, // --> the account being set. + bool const bAuth, // --> authorize account. + bool const bNoRipple, // --> others cannot ripple through + bool const bFreeze, // --> funds cannot leave + bool bDeepFreeze, // --> can neither receive nor send funds + STAmount const& saBalance, // --> balance of account being set. + // Issuer should be noAccount() + STAmount const& saLimit, // --> limit for account being set. + // Issuer should be the account being set. std::uint32_t uQualityIn, std::uint32_t uQualityOut, beast::Journal j); diff --git a/include/xrpl/ledger/helpers/WrappedSLEBase.h b/include/xrpl/ledger/helpers/WrappedSLEBase.h index 12b63636d6..72864bd8ac 100644 --- a/include/xrpl/ledger/helpers/WrappedSLEBase.h +++ b/include/xrpl/ledger/helpers/WrappedSLEBase.h @@ -24,6 +24,14 @@ class WrappedSLEBase public: virtual ~WrappedSLEBase() = default; + // Explicitly default copy/move operations + WrappedSLEBase(WrappedSLEBase const&) = default; + WrappedSLEBase(WrappedSLEBase&&) = default; + WrappedSLEBase& + operator=(WrappedSLEBase const&) = default; + WrappedSLEBase& + operator=(WrappedSLEBase&&) = default; + /** Returns true if the ledger entry exists */ bool exists() const @@ -38,13 +46,27 @@ public: return exists(); } - /** Returns the underlying SLE for raw access when needed */ + /** Returns the underlying SLE for read access (always available) */ std::shared_ptr const& sle() const { return sle_; } + /** Returns a mutable SLE for write operations + * + * @throws std::logic_error if called in a read-only context + */ + std::shared_ptr const& + mutableSle() const + { + if (!mutableSle_) + { + throw std::logic_error("Cannot modify SLE in read-only context"); + } + return mutableSle_; + } + /** Returns the read view (always available) */ ReadView const* readView() const @@ -73,12 +95,24 @@ public: return applyView_; } + STLedgerEntry* + operator->() + { + return mutableSle_.get(); + } + STLedgerEntry const* operator->() const { return sle_.get(); } + STLedgerEntry& + operator*() + { + return *mutableSle_; + } + STLedgerEntry const& operator*() const { @@ -95,15 +129,16 @@ protected: } /** Constructor for read-write context (ApplyView) */ - explicit WrappedSLEBase(std::shared_ptr sle, ApplyView* view) - : sle_(std::move(sle)), readView_(view), applyView_(view) + explicit WrappedSLEBase(std::shared_ptr sle, ApplyView* view) + : sle_(sle), mutableSle_(std::move(sle)), readView_(view), applyView_(view) { // ApplyView inherits from ReadView, so we can use it for both } - std::shared_ptr sle_; - ReadView const* readView_; - ApplyView* applyView_; // nullptr for read-only contexts + std::shared_ptr sle_; // Always valid (const view) + std::shared_ptr mutableSle_; // nullptr for read-only contexts + ReadView const* readView_; // Always valid + ApplyView* applyView_; // nullptr for read-only contexts }; } // namespace xrpl diff --git a/include/xrpl/tx/transactors/lending/LendingHelpers.h b/include/xrpl/tx/transactors/lending/LendingHelpers.h index 4057c9c173..7676c758a7 100644 --- a/include/xrpl/tx/transactors/lending/LendingHelpers.h +++ b/include/xrpl/tx/transactors/lending/LendingHelpers.h @@ -475,4 +475,15 @@ loanMakePayment( LoanPaymentType const paymentType, beast::Journal j); +// LoanBroker-specific `adjustOwnerCount` function (temporary, while the Wrapped classes are WIP) +// Assert will check the type, so that we ensure it's not used by anything else +// Order of parameters is different from the old `adjustOwnerCount` function to avoid anything +// accidentally calling this with the wrong type. +void +adjustOwnerCount( + std::shared_ptr const& sle, + ApplyView& view, + std::int32_t amount, + beast::Journal j); + } // namespace xrpl diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index ef6a66744d..4800dc81ab 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -357,17 +357,17 @@ canWithdraw( ReadView const& view, AccountID const& from, AccountID const& to, - SLE::const_ref toSle, + WrappedAccountRoot const& toWrapped, STAmount const& amount, bool hasDestinationTag) { - if (auto const ret = checkDestinationAndTag(toSle, hasDestinationTag)) + if (auto const ret = toWrapped.checkDestinationAndTag(hasDestinationTag)) return ret; if (from == to) return tesSUCCESS; - if (toSle->isFlag(lsfDepositAuth)) + if (toWrapped->isFlag(lsfDepositAuth)) { if (!view.exists(keylet::depositPreauth(to, from))) return tecNO_PERMISSION; @@ -384,9 +384,9 @@ canWithdraw( STAmount const& amount, bool hasDestinationTag) { - auto const toSle = view.read(keylet::account(to)); + auto const toWrapped = WrappedAccountRoot(to, &view); - return canWithdraw(view, from, to, toSle, amount, hasDestinationTag); + return canWithdraw(view, from, to, toWrapped, amount, hasDestinationTag); } [[nodiscard]] TER diff --git a/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp index fcd36a49ef..b13705efe7 100644 --- a/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp +++ b/src/libxrpl/ledger/helpers/AccountRootHelpers.cpp @@ -12,7 +12,7 @@ namespace xrpl { bool -WrappedAccountRoot::isGlobalFrozen() +WrappedAccountRoot::isGlobalFrozen() const { if (isXRP(id_)) return false; @@ -66,19 +66,19 @@ WrappedAccountRoot::xrpLiquid(std::int32_t ownerCountAdj, beast::Journal j) { // Return balance minus reserve std::uint32_t const ownerCount = confineOwnerCount( - readView_.ownerCountHook(id, sle_->getFieldU32(sfOwnerCount)), ownerCountAdj); + readView_->ownerCountHook(id_, sle_->getFieldU32(sfOwnerCount)), ownerCountAdj); // Pseudo-accounts have no reserve requirement auto const reserve = - isPseudoAccount(sle_) ? XRPAmount{0} : readView_.fees().accountReserve(ownerCount); + isPseudoAccount(sle_) ? XRPAmount{0} : readView_->fees().accountReserve(ownerCount); auto const fullBalance = sle_->getFieldAmount(sfBalance); - auto const balance = readView_.balanceHook(id, xrpAccount(), fullBalance); + auto const balance = readView_->balanceHook(id_, xrpAccount(), fullBalance); STAmount const amount = (balance < reserve) ? STAmount{0} : balance - reserve; - JLOG(j.trace()) << "accountHolds:" << " account=" << to_string(id) + JLOG(j.trace()) << "accountHolds:" << " account=" << to_string(id_) << " amount=" << amount.getFullText() << " fullBalance=" << fullBalance.getFullText() << " balance=" << balance.getFullText() << " reserve=" << reserve @@ -88,7 +88,7 @@ WrappedAccountRoot::xrpLiquid(std::int32_t ownerCountAdj, beast::Journal j) } Rate -WrappedAccountRoot::transferRate() +WrappedAccountRoot::transferRate() const { if (sle_ && sle_->isFieldPresent(sfTransferRate)) return Rate{sle_->getFieldU32(sfTransferRate)}; @@ -99,15 +99,16 @@ WrappedAccountRoot::transferRate() void WrappedAccountRoot::adjustOwnerCount(std::int32_t amount, beast::Journal j) { - if (!sle) + if (!sle_) return; XRPL_ASSERT(amount, "xrpl::adjustOwnerCount : nonzero amount input"); std::uint32_t const current{sle_->getFieldU32(sfOwnerCount)}; AccountID const id = (*sle_)[sfAccount]; std::uint32_t const adjusted = confineOwnerCount(current, amount, id, j); - view.adjustOwnerCountHook(id, current, adjusted); - sle_->at(sfOwnerCount) = adjusted; - view.update(sle_); + applyView_->adjustOwnerCountHook(id_, current, adjusted); + auto mutable_sle = mutableSle(); + mutable_sle->at(sfOwnerCount) = adjusted; + applyView_->update(mutable_sle); } AccountID @@ -219,7 +220,7 @@ createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const } [[nodiscard]] TER -WrappedAccountRoot::checkDestinationAndTag(bool hasDestinationTag) +WrappedAccountRoot::checkDestinationAndTag(bool hasDestinationTag) const { if (sle_ == nullptr) return tecNO_DST; diff --git a/src/libxrpl/ledger/helpers/CredentialHelpers.cpp b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp index 32db285f1e..6b67b14e3f 100644 --- a/src/libxrpl/ledger/helpers/CredentialHelpers.cpp +++ b/src/libxrpl/ledger/helpers/CredentialHelpers.cpp @@ -51,8 +51,8 @@ deleteSLE(ApplyView& view, std::shared_ptr const& sleCredential, beast::Jou auto delSLE = [&view, &sleCredential, j]( AccountID const& account, SField const& node, bool isOwner) -> TER { - auto const sleAccount = view.peek(keylet::account(account)); - if (!sleAccount) + WrappedAccountRoot wrappedAccount(account, &view); + if (!wrappedAccount) { // LCOV_EXCL_START JLOG(j.fatal()) << "Internal error: can't retrieve Owner account."; @@ -71,7 +71,7 @@ deleteSLE(ApplyView& view, std::shared_ptr const& sleCredential, beast::Jou } if (isOwner) - adjustOwnerCount(view, sleAccount, -1, j); + wrappedAccount.adjustOwnerCount(-1, j); return tesSUCCESS; }; diff --git a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp index cbf37a06a8..78f0bc908a 100644 --- a/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/MPTokenHelpers.cpp @@ -137,8 +137,8 @@ authorizeMPToken( std::uint32_t flags, std::optional holderID) { - auto const sleAcct = view.peek(keylet::account(account)); - if (!sleAcct) + WrappedAccountRoot wrappedAcct(account, &view); + if (!wrappedAcct) return tecINTERNAL; // LCOV_EXCL_LINE // If the account that submitted the tx is a holder @@ -160,7 +160,7 @@ authorizeMPToken( keylet::ownerDir(account), (*sleMpt)[sfOwnerNode], sleMpt->key(), false)) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleAcct, -1, journal); + wrappedAcct.adjustOwnerCount(-1, journal); view.erase(sleMpt); return tesSUCCESS; @@ -175,7 +175,7 @@ authorizeMPToken( // an account owns, in the case of MPTokens we only // *enforce* a reserve if the user owns more than two // items. This is similar to the reserve requirements of trust lines. - std::uint32_t const uOwnerCount = sleAcct->getFieldU32(sfOwnerCount); + std::uint32_t const uOwnerCount = wrappedAcct->getFieldU32(sfOwnerCount); XRPAmount const reserveCreate( (uOwnerCount < 2) ? XRPAmount(beast::zero) : view.fees().accountReserve(uOwnerCount + 1)); @@ -205,7 +205,7 @@ authorizeMPToken( view.insert(mptoken); // Update owner count. - adjustOwnerCount(view, sleAcct, 1, journal); + wrappedAcct.adjustOwnerCount(1, journal); return tesSUCCESS; } diff --git a/src/libxrpl/ledger/helpers/OfferHelpers.cpp b/src/libxrpl/ledger/helpers/OfferHelpers.cpp index 9422153b10..a7be07e0d8 100644 --- a/src/libxrpl/ledger/helpers/OfferHelpers.cpp +++ b/src/libxrpl/ledger/helpers/OfferHelpers.cpp @@ -48,7 +48,8 @@ offerDelete(ApplyView& view, std::shared_ptr const& sle, beast::Journal j) } } - adjustOwnerCount(view, view.peek(keylet::account(owner)), -1, j); + WrappedAccountRoot wrappedOwner(owner, &view); + wrappedOwner.adjustOwnerCount(-1, j); view.erase(sle); diff --git a/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp index e88afe0cfb..21fe4f604b 100644 --- a/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp +++ b/src/libxrpl/ledger/helpers/RippleStateHelpers.cpp @@ -158,16 +158,16 @@ trustCreate( bool const bSrcHigh, AccountID const& uSrcAccountID, AccountID const& uDstAccountID, - uint256 const& uIndex, // --> ripple state entry - SLE::ref sleAccount, // --> the account being set. - bool const bAuth, // --> authorize account. - bool const bNoRipple, // --> others cannot ripple through - bool const bFreeze, // --> funds cannot leave - bool bDeepFreeze, // --> can neither receive nor send funds - STAmount const& saBalance, // --> balance of account being set. - // Issuer should be noAccount() - STAmount const& saLimit, // --> limit for account being set. - // Issuer should be the account being set. + uint256 const& uIndex, // --> ripple state entry + WrappedAccountRoot& wrappedAcct, // --> the account being set. + bool const bAuth, // --> authorize account. + bool const bNoRipple, // --> others cannot ripple through + bool const bFreeze, // --> funds cannot leave + bool bDeepFreeze, // --> can neither receive nor send funds + STAmount const& saBalance, // --> balance of account being set. + // Issuer should be noAccount() + STAmount const& saLimit, // --> limit for account being set. + // Issuer should be the account being set. std::uint32_t uQualityIn, std::uint32_t uQualityOut, beast::Journal j) @@ -204,12 +204,12 @@ trustCreate( bool const bSetDst = saLimit.getIssuer() == uDstAccountID; bool const bSetHigh = bSrcHigh ^ bSetDst; - XRPL_ASSERT(sleAccount, "xrpl::trustCreate : non-null SLE"); - if (!sleAccount) + XRPL_ASSERT(wrappedAcct, "xrpl::trustCreate : non-null SLE"); + if (!wrappedAcct) return tefINTERNAL; // LCOV_EXCL_LINE XRPL_ASSERT( - sleAccount->getAccountID(sfAccount) == (bSetHigh ? uHighAccountID : uLowAccountID), + wrappedAcct->getAccountID(sfAccount) == (bSetHigh ? uHighAccountID : uLowAccountID), "xrpl::trustCreate : matching account ID"); auto const slePeer = view.peek(keylet::account(bSetHigh ? uLowAccountID : uHighAccountID)); if (!slePeer) @@ -256,7 +256,7 @@ trustCreate( } sleRippleState->setFieldU32(sfFlags, uFlags); - adjustOwnerCount(view, sleAccount, 1, j); + wrappedAcct.adjustOwnerCount(1, j); // ONLY: Create ripple balance. sleRippleState->setFieldAmount(sfBalance, bSetHigh ? -saBalance : saBalance); @@ -318,8 +318,8 @@ updateTrustLine( return false; std::uint32_t const flags(state->getFieldU32(sfFlags)); - auto sle = view.peek(keylet::account(sender)); - if (!sle) + WrappedAccountRoot wrappedAcct(sender, &view); + if (!wrappedAcct) return false; // YYY Could skip this if rippling in reverse. @@ -330,7 +330,7 @@ updateTrustLine( && (flags & (!bSenderHigh ? lsfLowReserve : lsfHighReserve)) // Sender reserve is set. && static_cast(flags & (!bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple)) != - static_cast(sle->getFlags() & lsfDefaultRipple) && + static_cast(wrappedAcct->getFlags() & lsfDefaultRipple) && !(flags & (!bSenderHigh ? lsfLowFreeze : lsfHighFreeze)) && !state->getFieldAmount(!bSenderHigh ? sfLowLimit : sfHighLimit) // Sender trust limit is 0. @@ -341,7 +341,7 @@ updateTrustLine( { // VFALCO Where is the line being deleted? // Clear the reserve of the sender, possibly delete the line! - adjustOwnerCount(view, sle, -1, j); + wrappedAcct.adjustOwnerCount(-1, j); // Clear reserve flag. state->setFieldU32(sfFlags, flags & (!bSenderHigh ? ~lsfLowReserve : ~lsfHighReserve)); @@ -424,7 +424,7 @@ issueIOU( final_balance.setIssuer(noAccount()); - auto const receiverAccount = view.peek(keylet::account(account)); + WrappedAccountRoot const receiverAccount(account, &view); if (!receiverAccount) return tefINTERNAL; // LCOV_EXCL_LINE @@ -605,25 +605,26 @@ addEmptyHolding( auto const& issuerId = issue.getIssuer(); auto const& currency = issue.currency; - if (isGlobalFrozen(view, issuerId)) + WrappedAccountRoot wrappedIssuer(issuerId, &view); + if (wrappedIssuer.isGlobalFrozen()) return tecFROZEN; // LCOV_EXCL_LINE auto const& srcId = issuerId; auto const& dstId = accountID; auto const high = srcId > dstId; auto const index = keylet::line(srcId, dstId, currency); - auto const sleSrc = view.peek(keylet::account(srcId)); - auto const sleDst = view.peek(keylet::account(dstId)); - if (!sleDst || !sleSrc) + WrappedAccountRoot wrappedSrc(srcId, &view); + WrappedAccountRoot wrappedDst(dstId, &view); + if (!wrappedDst || !wrappedSrc) return tefINTERNAL; // LCOV_EXCL_LINE - if (!sleSrc->isFlag(lsfDefaultRipple)) + if (!wrappedSrc->isFlag(lsfDefaultRipple)) return tecINTERNAL; // LCOV_EXCL_LINE // If the line already exists, don't create it again. if (view.read(index)) return tecDUPLICATE; // Can the account cover the trust line reserve ? - std::uint32_t const ownerCount = sleDst->at(sfOwnerCount); + std::uint32_t const ownerCount = wrappedDst->at(sfOwnerCount); if (priorBalance < view.fees().accountReserve(ownerCount + 1)) return tecNO_LINE_INSUF_RESERVE; @@ -633,7 +634,7 @@ addEmptyHolding( srcId, dstId, index.key, - sleDst, + wrappedDst, /*bAuth=*/false, /*bNoRipple=*/true, /*bFreeze=*/false, @@ -679,11 +680,11 @@ removeEmptyHolding( if (line->isFlag(lsfLowReserve)) { // Clear reserve for low account. - auto sleLowAccount = view.peek(keylet::account(line->at(sfLowLimit)->getIssuer())); - if (!sleLowAccount) + WrappedAccountRoot wrappedLow(line->at(sfLowLimit)->getIssuer(), &view); + if (!wrappedLow) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleLowAccount, -1, journal); + wrappedLow.adjustOwnerCount(-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. @@ -693,11 +694,11 @@ removeEmptyHolding( if (line->isFlag(lsfHighReserve)) { // Clear reserve for high account. - auto sleHighAccount = view.peek(keylet::account(line->at(sfHighLimit)->getIssuer())); - if (!sleHighAccount) + WrappedAccountRoot wrappedHigh(line->at(sfHighLimit)->getIssuer(), &view); + if (!wrappedHigh) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleHighAccount, -1, journal); + wrappedHigh.adjustOwnerCount(-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. @@ -721,13 +722,13 @@ 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)); - if (!sleLow || !sleHigh) + WrappedAccountRoot wrappedLow(low, &view); + WrappedAccountRoot wrappedHigh(high, &view); + if (!wrappedLow || !wrappedHigh) return tecINTERNAL; // LCOV_EXCL_LINE - bool const ammLow = sleLow->isFieldPresent(sfAMMID); - bool const ammHigh = sleHigh->isFieldPresent(sfAMMID); + bool const ammLow = wrappedLow->isFieldPresent(sfAMMID); + bool const ammHigh = wrappedHigh->isFieldPresent(sfAMMID); // can't both be AMM if (ammLow && ammHigh) @@ -751,7 +752,8 @@ deleteAMMTrustLine( if (!(sleState->getFlags() & uFlags)) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, !ammLow ? sleLow : sleHigh, -1, j); + WrappedAccountRoot wrappedHolder = !ammLow ? wrappedLow : wrappedHigh; + wrappedHolder.adjustOwnerCount(-1, j); return tesSUCCESS; } diff --git a/src/libxrpl/ledger/helpers/TokenHelpers.cpp b/src/libxrpl/ledger/helpers/TokenHelpers.cpp index 7a98445b0a..1dc26c1405 100644 --- a/src/libxrpl/ledger/helpers/TokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/TokenHelpers.cpp @@ -39,7 +39,8 @@ isGlobalFrozen(ReadView const& view, Asset const& asset) [&](TIss const& issue) { if constexpr (std::is_same_v) { - return isGlobalFrozen(view, issue.getIssuer()); + WrappedAccountRoot issuer(issue.getIssuer(), &view); + return issuer.isGlobalFrozen(); } else { @@ -256,7 +257,8 @@ accountHolds( STAmount amount; if (isXRP(currency)) { - return {xrpLiquid(view, account, 0, j)}; + WrappedAccountRoot accountRoot(account, &view); + return {accountRoot.xrpLiquid(0, j)}; } bool const returnSpendable = (includeFullBalance == shFULL_BALANCE); @@ -402,7 +404,8 @@ transferRate(ReadView const& view, STAmount const& amount) [&](TIss const& issue) { if constexpr (std::is_same_v) { - return transferRate(view, issue.getIssuer()); + WrappedAccountRoot issuer(issue.getIssuer(), &view); + return issuer.transferRate(); } else { @@ -584,7 +587,8 @@ rippleCreditIOU( // Sender quality out is 0. { // Clear the reserve of the sender, possibly delete the line! - adjustOwnerCount(view, view.peek(keylet::account(uSenderID)), -1, j); + WrappedAccountRoot wrappedSender(uSenderID, &view); + wrappedSender.adjustOwnerCount(-1, j); // Clear reserve flag. sleRippleState->setFieldU32( @@ -627,11 +631,11 @@ rippleCreditIOU( << to_string(uSenderID) << " -> " << to_string(uReceiverID) << " : " << saAmount.getFullText(); - auto const sleAccount = view.peek(keylet::account(uReceiverID)); - if (!sleAccount) + WrappedAccountRoot wrappedAccount(uReceiverID, &view); + if (!wrappedAccount) return tefINTERNAL; // LCOV_EXCL_LINE - bool const noRipple = (sleAccount->getFlags() & lsfDefaultRipple) == 0; + bool const noRipple = (wrappedAccount->getFlags() & lsfDefaultRipple) == 0; return trustCreate( view, @@ -639,7 +643,7 @@ rippleCreditIOU( uSenderID, uReceiverID, index.key, - sleAccount, + wrappedAccount, false, noRipple, false, @@ -685,8 +689,10 @@ rippleSendIOU( // Calculate the amount to transfer accounting // for any transfer fees if the fee is not waived: - saActual = (waiveFee == WaiveTransferFee::Yes) ? saAmount - : multiply(saAmount, transferRate(view, issuer)); + WrappedAccountRoot wrappedIssuer(issuer, &view); + saActual = (waiveFee == WaiveTransferFee::Yes) + ? saAmount + : multiply(saAmount, wrappedIssuer.transferRate()); JLOG(j.debug()) << "rippleSendIOU> " << to_string(uSenderID) << " - > " << to_string(uReceiverID) << " : deliver=" << saAmount.getFullText() @@ -751,9 +757,10 @@ rippleSendMultiIOU( // Calculate the amount to transfer accounting // for any transfer fees if the fee is not waived: + WrappedAccountRoot wrappedIssuer(issuer, &view); STAmount actualSend = (waiveFee == WaiveTransferFee::Yes) ? amount - : multiply(amount, transferRate(view, issuer)); + : multiply(amount, wrappedIssuer.transferRate()); actual += actualSend; takeFromSender += actualSend; diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index d579d26c67..ecbcaf5e7a 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -540,8 +540,8 @@ Transactor::ticketDelete( // Update the account root's TicketCount. If the ticket count drops to // zero remove the (optional) field. - auto sleAccount = view.peek(keylet::account(account)); - if (!sleAccount) + WrappedAccountRoot wrappedAcct(account, &view); + if (!wrappedAcct) { // LCOV_EXCL_START JLOG(j.fatal()) << "Could not find Ticket owner account root."; @@ -549,11 +549,11 @@ Transactor::ticketDelete( // LCOV_EXCL_STOP } - if (auto ticketCount = (*sleAccount)[~sfTicketCount]) + if (auto ticketCount = (*wrappedAcct)[~sfTicketCount]) { if (*ticketCount == 1) { - sleAccount->makeFieldAbsent(sfTicketCount); + wrappedAcct->makeFieldAbsent(sfTicketCount); } else { @@ -569,7 +569,7 @@ Transactor::ticketDelete( } // Update the Ticket owner's reserve. - adjustOwnerCount(view, sleAccount, -1, j); + wrappedAcct.adjustOwnerCount(-1, j); // Remove Ticket from ledger. view.erase(sleTicket); diff --git a/src/libxrpl/tx/transactors/account/SignerListSet.cpp b/src/libxrpl/tx/transactors/account/SignerListSet.cpp index fcc74a6b2c..43b7f323f4 100644 --- a/src/libxrpl/tx/transactors/account/SignerListSet.cpp +++ b/src/libxrpl/tx/transactors/account/SignerListSet.cpp @@ -161,11 +161,11 @@ static TER removeSignersFromLedger( ServiceRegistry& registry, ApplyView& view, - Keylet const& accountKeylet, - Keylet const& ownerDirKeylet, - Keylet const& signerListKeylet, + AccountID const& account, beast::Journal j) { + auto const ownerDirKeylet = keylet::ownerDir(account); + auto const signerListKeylet = keylet::signers(account); // We have to examine the current SignerList so we know how much to // reduce the OwnerCount. SLE::pointer signers = view.peek(signerListKeylet); @@ -196,8 +196,8 @@ removeSignersFromLedger( // LCOV_EXCL_STOP } - adjustOwnerCount( - view, view.peek(accountKeylet), removeFromOwnerCount, registry.journal("View")); + WrappedAccountRoot wrappedAcct(account, &view); + wrappedAcct.adjustOwnerCount(removeFromOwnerCount, registry.journal("View")); view.erase(signers); @@ -211,12 +211,7 @@ SignerListSet::removeFromLedger( AccountID const& account, beast::Journal j) { - auto const accountKeylet = keylet::account(account); - auto const ownerDirKeylet = keylet::ownerDir(account); - auto const signerListKeylet = keylet::signers(account); - - return removeSignersFromLedger( - registry, view, accountKeylet, ownerDirKeylet, signerListKeylet, j); + return removeSignersFromLedger(registry, view, account, j); } NotTEC @@ -281,23 +276,18 @@ SignerListSet::validateQuorumAndSignerEntries( TER SignerListSet::replaceSignerList() { - auto const accountKeylet = keylet::account(account_); - auto const ownerDirKeylet = keylet::ownerDir(account_); - auto const signerListKeylet = keylet::signers(account_); - // This may be either a create or a replace. Preemptively remove any // old signer list. May reduce the reserve, so this is done before // checking the reserve. - if (TER const ter = removeSignersFromLedger( - ctx_.registry, view(), accountKeylet, ownerDirKeylet, signerListKeylet, j_)) + if (TER const ter = removeSignersFromLedger(ctx_.registry, view(), account_, j_)) return ter; - auto const sle = view().peek(accountKeylet); - if (!sle) + WrappedAccountRoot wrappedAcct(account_, &view()); + if (!wrappedAcct) return tefINTERNAL; // LCOV_EXCL_LINE // Compute new reserve. Verify the account has funds to meet the reserve. - std::uint32_t const oldOwnerCount{(*sle)[sfOwnerCount]}; + std::uint32_t const oldOwnerCount{(*wrappedAcct)[sfOwnerCount]}; constexpr int addedOwnerCount = 1; std::uint32_t flags{lsfOneOwnerCount}; @@ -311,6 +301,8 @@ SignerListSet::replaceSignerList() return tecINSUFFICIENT_RESERVE; // Everything's ducky. Add the ltSIGNER_LIST to the ledger. + Keylet const ownerDirKeylet = keylet::ownerDir(account_); + Keylet const signerListKeylet = keylet::signers(account_); auto signerList = std::make_shared(signerListKeylet); view().insert(signerList); writeSignersToSLE(signerList, flags); @@ -330,27 +322,23 @@ SignerListSet::replaceSignerList() // If we succeeded, the new entry counts against the // creator's reserve. - adjustOwnerCount(view(), sle, addedOwnerCount, viewJ); + wrappedAcct.adjustOwnerCount(addedOwnerCount, viewJ); return tesSUCCESS; } TER SignerListSet::destroySignerList() { - auto const accountKeylet = keylet::account(account_); // Destroying the signer list is only allowed if either the master key // is enabled or there is a regular key. - SLE::pointer ledgerEntry = view().peek(accountKeylet); - if (!ledgerEntry) + WrappedAccountRoot wrappedAcct(account_, &view()); + if (!wrappedAcct) return tefINTERNAL; // LCOV_EXCL_LINE - if ((ledgerEntry->isFlag(lsfDisableMaster)) && (!ledgerEntry->isFieldPresent(sfRegularKey))) + if ((wrappedAcct->isFlag(lsfDisableMaster)) && (!wrappedAcct->isFieldPresent(sfRegularKey))) return tecNO_ALTERNATIVE_KEY; - auto const ownerDirKeylet = keylet::ownerDir(account_); - auto const signerListKeylet = keylet::signers(account_); - return removeSignersFromLedger( - ctx_.registry, view(), accountKeylet, ownerDirKeylet, signerListKeylet, j_); + return removeSignersFromLedger(ctx_.registry, view(), account_, j_); } void diff --git a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp index 8c09fefe5a..05e24b0c06 100644 --- a/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp +++ b/src/libxrpl/tx/transactors/bridge/XChainBridge.cpp @@ -695,7 +695,7 @@ finalizeClaimHelper( auto const cidOwner = (*sleClaimID)[sfAccount]; { // Remove the claim id - auto const sleOwner = outerSb.peek(keylet::account(cidOwner)); + WrappedAccountRoot wrappedOwner(cidOwner, &outerSb); auto const page = (*sleClaimID)[sfOwnerNode]; if (!outerSb.dirRemove(keylet::ownerDir(cidOwner), page, sleClaimID->key(), true)) { @@ -707,7 +707,7 @@ finalizeClaimHelper( // Remove the claim id from the ledger outerSb.erase(sleClaimID); - adjustOwnerCount(outerSb, sleOwner, -1, j); + wrappedOwner.adjustOwnerCount(-1, j); } } @@ -1111,14 +1111,13 @@ applyCreateAccountAttestations( return tecDIR_FULL; // LCOV_EXCL_LINE (*createdSleClaimID)[sfOwnerNode] = *page; - auto const sleDoor = psb.peek(doorK); - if (!sleDoor) + WrappedAccountRoot wrappedDoor(doorAccount, &psb); + if (!wrappedDoor) return tecINTERNAL; // LCOV_EXCL_LINE // Reserve was already checked - adjustOwnerCount(psb, sleDoor, 1, j); + wrappedDoor.adjustOwnerCount(1, j); psb.insert(createdSleClaimID); - psb.update(sleDoor); } psb.apply(rawView); @@ -1431,8 +1430,8 @@ XChainCreateBridge::doApply() auto const reward = ctx_.tx[sfSignatureReward]; auto const minAccountCreate = ctx_.tx[~sfMinAccountCreateAmount]; - auto const sleAcct = ctx_.view().peek(keylet::account(account)); - if (!sleAcct) + WrappedAccountRoot wrappedAcct(account, &ctx_.view()); + if (!wrappedAcct) return tecINTERNAL; // LCOV_EXCL_LINE STXChainBridge::ChainType const chainType = @@ -1459,10 +1458,10 @@ XChainCreateBridge::doApply() (*sleBridge)[sfOwnerNode] = *page; } - adjustOwnerCount(ctx_.view(), sleAcct, 1, ctx_.journal); + wrappedAcct.adjustOwnerCount(1, ctx_.journal); ctx_.view().insert(sleBridge); - ctx_.view().update(sleAcct); + ctx_.view().update(wrappedAcct.mutableSle()); return tesSUCCESS; } @@ -1977,8 +1976,8 @@ XChainCreateClaimID::doApply() auto const reward = ctx_.tx[sfSignatureReward]; auto const otherChainSrc = ctx_.tx[sfOtherChainSource]; - auto const sleAcct = ctx_.view().peek(keylet::account(account)); - if (!sleAcct) + WrappedAccountRoot wrappedAcct(account, &ctx_.view()); + if (!wrappedAcct) return tecINTERNAL; // LCOV_EXCL_LINE auto const sleBridge = peekBridge(ctx_.view(), bridgeSpec); @@ -2019,11 +2018,10 @@ XChainCreateClaimID::doApply() (*sleClaimID)[sfOwnerNode] = *page; } - adjustOwnerCount(ctx_.view(), sleAcct, 1, ctx_.journal); + wrappedAcct.adjustOwnerCount(1, ctx_.journal); ctx_.view().insert(sleClaimID); ctx_.view().update(sleBridge); - ctx_.view().update(sleAcct); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/check/CheckCancel.cpp b/src/libxrpl/tx/transactors/check/CheckCancel.cpp index 2d08b2f1b0..15c0b3ff1e 100644 --- a/src/libxrpl/tx/transactors/check/CheckCancel.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCancel.cpp @@ -85,8 +85,8 @@ CheckCancel::doApply() } // If we succeeded, update the check owner's reserve. - auto const sleSrc = view().peek(keylet::account(srcId)); - adjustOwnerCount(view(), sleSrc, -1, viewJ); + WrappedAccountRoot wrappedSrc(srcId, &view()); + wrappedSrc.adjustOwnerCount(-1, viewJ); // Remove check from ledger. view().erase(sleCheck); diff --git a/src/libxrpl/tx/transactors/check/CheckCash.cpp b/src/libxrpl/tx/transactors/check/CheckCash.cpp index 2546c2635c..fed76604db 100644 --- a/src/libxrpl/tx/transactors/check/CheckCash.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCash.cpp @@ -251,7 +251,8 @@ CheckCash::doApply() // from src's directory, we allow them to send that additional // incremental reserve amount in the transfer. Hence the -1 // argument. - STAmount const srcLiquid{xrpLiquid(psb, srcId, -1, viewJ)}; + WrappedAccountRoot wrappedSrc(srcId, &psb); + STAmount const srcLiquid{wrappedSrc.xrpLiquid(-1, viewJ)}; // Now, how much do they need in order to be successful? STAmount const xrpDeliver{ @@ -310,10 +311,10 @@ CheckCash::doApply() // a. this (destination) account and // b. issuing account (not sending account). - auto const sleDst = psb.peek(keylet::account(account_)); + WrappedAccountRoot wrappedDst(account_, &psb); // Can the account cover the trust line's reserve? - if (std::uint32_t const ownerCount = {sleDst->at(sfOwnerCount)}; + if (std::uint32_t const ownerCount = {wrappedDst->at(sfOwnerCount)}; preFeeBalance_ < psb.fees().accountReserve(ownerCount + 1)) { JLOG(j_.trace()) << "Trust line does not exist. " @@ -333,9 +334,9 @@ CheckCash::doApply() issuer, // source account_, // destination trustLineKey.key, // ledger index - sleDst, // Account to add to + wrappedDst, // Account to add to false, // authorize account - (sleDst->getFlags() & lsfDefaultRipple) == 0, + (wrappedDst->getFlags() & lsfDefaultRipple) == 0, false, // freeze trust line false, // deep freeze trust line initialBalance, // zero initial balance @@ -349,7 +350,7 @@ CheckCash::doApply() } // clang-format on - psb.update(sleDst); + psb.update(wrappedDst.mutableSle()); // Note that we _don't_ need to be careful about destroying // the trust line if the check cashing fails. The transaction @@ -440,7 +441,8 @@ CheckCash::doApply() } // If we succeeded, update the check owner's reserve. - adjustOwnerCount(psb, psb.peek(keylet::account(srcId)), -1, viewJ); + WrappedAccountRoot wrappedSrc(srcId, &psb); + wrappedSrc.adjustOwnerCount(-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 1aa4ac15ba..fc132ca14d 100644 --- a/src/libxrpl/tx/transactors/check/CheckCreate.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCreate.cpp @@ -86,8 +86,9 @@ CheckCreate::preclaim(PreclaimContext const& ctx) if (!sendMax.native()) { // The currency may not be globally frozen - AccountID const& issuerId{sendMax.getIssuer()}; - if (isGlobalFrozen(ctx.view, issuerId)) + AccountID const issuerId{sendMax.getIssuer()}; + WrappedAccountRoot wrappedIssuer(issuerId, &ctx.view); + if (wrappedIssuer.isGlobalFrozen()) { JLOG(ctx.j.warn()) << "Creating a check for frozen asset"; return tecFROZEN; @@ -133,15 +134,16 @@ CheckCreate::preclaim(PreclaimContext const& ctx) TER CheckCreate::doApply() { - auto const sle = view().peek(keylet::account(account_)); - if (!sle) + WrappedAccountRoot wrappedAcct(account_, &view()); + if (!wrappedAcct) return tefINTERNAL; // LCOV_EXCL_LINE // A check counts against the reserve of the issuing account, but we // check the starting balance because we want to allow dipping into the // reserve to pay fees. { - STAmount const reserve{view().fees().accountReserve(sle->getFieldU32(sfOwnerCount) + 1)}; + STAmount const reserve{ + view().fees().accountReserve(wrappedAcct->getFieldU32(sfOwnerCount) + 1)}; if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; @@ -199,7 +201,7 @@ CheckCreate::doApply() sleCheck->setFieldU64(sfOwnerNode, *page); } // If we succeeded, the new entry counts against the creator's reserve. - adjustOwnerCount(view(), sle, 1, viewJ); + wrappedAcct.adjustOwnerCount(1, viewJ); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp index 9c0018a647..f0188cc2f5 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialAccept.cpp @@ -76,15 +76,15 @@ 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(account_)); - auto const sleIssuer = view().peek(keylet::account(issuer)); + WrappedAccountRoot wrappedSubject(account_, &view()); + WrappedAccountRoot wrappedIssuer(issuer, &view()); - if (!sleSubject || !sleIssuer) + if (!wrappedSubject || !wrappedIssuer) return tefINTERNAL; // LCOV_EXCL_LINE { STAmount const reserve{ - view().fees().accountReserve(sleSubject->getFieldU32(sfOwnerCount) + 1)}; + view().fees().accountReserve(wrappedSubject->getFieldU32(sfOwnerCount) + 1)}; if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; } @@ -104,8 +104,8 @@ CredentialAccept::doApply() sleCred->setFieldU32(sfFlags, lsfAccepted); view().update(sleCred); - adjustOwnerCount(view(), sleIssuer, -1, j_); - adjustOwnerCount(view(), sleSubject, 1, j_); + wrappedIssuer.adjustOwnerCount(-1, j_); + wrappedSubject.adjustOwnerCount(1, j_); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp index f8f0f01b63..9f989fe85d 100644 --- a/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp +++ b/src/libxrpl/tx/transactors/credentials/CredentialCreate.cpp @@ -111,13 +111,13 @@ CredentialCreate::doApply() sleCred->setFieldU32(sfExpiration, *optExp); } - auto const sleIssuer = view().peek(keylet::account(account_)); - if (!sleIssuer) + WrappedAccountRoot wrappedIssuer(account_, &view()); + if (!wrappedIssuer) return tefINTERNAL; // LCOV_EXCL_LINE { STAmount const reserve{ - view().fees().accountReserve(sleIssuer->getFieldU32(sfOwnerCount) + 1)}; + view().fees().accountReserve(wrappedIssuer->getFieldU32(sfOwnerCount) + 1)}; if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; } @@ -138,7 +138,7 @@ CredentialCreate::doApply() return tecDIR_FULL; sleCred->setFieldU64(sfIssuerNode, *page); - adjustOwnerCount(view(), sleIssuer, 1, j_); + wrappedIssuer.adjustOwnerCount(1, j_); } if (subject == account_) diff --git a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp index 9fb17c4d1f..bf7ab2855c 100644 --- a/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp +++ b/src/libxrpl/tx/transactors/delegate/DelegateSet.cpp @@ -56,8 +56,8 @@ DelegateSet::preclaim(PreclaimContext const& ctx) TER DelegateSet::doApply() { - auto const sleOwner = ctx_.view().peek(keylet::account(account_)); - if (!sleOwner) + WrappedAccountRoot wrappedOwner(account_, &ctx_.view()); + if (!wrappedOwner) return tefINTERNAL; // LCOV_EXCL_LINE auto const& authAccount = ctx_.tx[sfAuthorize]; @@ -83,7 +83,7 @@ DelegateSet::doApply() return tecINTERNAL; // LCOV_EXCL_LINE STAmount const reserve{ - ctx_.view().fees().accountReserve(sleOwner->getFieldU32(sfOwnerCount) + 1)}; + ctx_.view().fees().accountReserve(wrappedOwner->getFieldU32(sfOwnerCount) + 1)}; if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; @@ -101,7 +101,7 @@ DelegateSet::doApply() (*sle)[sfOwnerNode] = *page; ctx_.view().insert(sle); - adjustOwnerCount(ctx_.view(), sleOwner, 1, ctx_.journal); + wrappedOwner.adjustOwnerCount(1, ctx_.journal); return tesSUCCESS; } @@ -124,11 +124,11 @@ DelegateSet::deleteDelegate( // LCOV_EXCL_STOP } - auto const sleOwner = view.peek(keylet::account(account)); - if (!sleOwner) + WrappedAccountRoot wrappedOwner(account, &view); + if (!wrappedOwner) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleOwner, -1, j); + wrappedOwner.adjustOwnerCount(-1, j); view.erase(sle); diff --git a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp index dd717948b3..4a3e72524f 100644 --- a/src/libxrpl/tx/transactors/dex/AMMCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMCreate.cpp @@ -110,7 +110,8 @@ AMMCreate::preclaim(PreclaimContext const& ctx) } // Check the reserve for LPToken trustline - STAmount const xrpBalance = xrpLiquid(ctx.view, accountID, 1, ctx.j); + WrappedAccountRoot wrappedAcct(accountID, &ctx.view); + STAmount const xrpBalance = wrappedAcct.xrpLiquid(1, ctx.j); // Insufficient reserve if (xrpBalance <= beast::zero) { diff --git a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp index eb3e61e80b..0419db1c2b 100644 --- a/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMDeposit.cpp @@ -187,6 +187,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) // Have to check again in deposit() because // amounts might be derived based on tokens or // limits. + WrappedAccountRoot wrappedAcct(accountID, &ctx.view); auto balance = [&](auto const& deposit) -> TER { if (isXRP(deposit)) { @@ -194,7 +195,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) // Adjust the reserve if LP doesn't have LPToken trustline auto const sle = ctx.view.read(keylet::line(accountID, lpIssue.account, lpIssue.currency)); - if (xrpLiquid(ctx.view, accountID, !sle, ctx.j) >= deposit) + if (wrappedAcct.xrpLiquid(!sle, ctx.j) >= deposit) return TER(tesSUCCESS); if (sle) return tecUNFUNDED_AMM; @@ -311,7 +312,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx) // We checked above but need to check again if depositing IOU only. if (ammLPHolds(ctx.view, *ammSle, accountID, ctx.j) == beast::zero) { - STAmount const xrpBalance = xrpLiquid(ctx.view, accountID, 1, ctx.j); + STAmount const xrpBalance = wrappedAcct.xrpLiquid(1, ctx.j); // Insufficient reserve if (xrpBalance <= beast::zero) { @@ -456,6 +457,7 @@ AMMDeposit::deposit( { // Check account has sufficient funds. // Return true if it does, false otherwise. + WrappedAccountRoot wrappedAcct(account_, &view); auto checkBalance = [&](auto const& depositAmount) -> TER { if (depositAmount <= beast::zero) return temBAD_AMOUNT; @@ -464,7 +466,7 @@ AMMDeposit::deposit( auto const& lpIssue = lpTokensDeposit.issue(); // Adjust the reserve if LP doesn't have LPToken trustline auto const sle = view.read(keylet::line(account_, lpIssue.account, lpIssue.currency)); - if (xrpLiquid(view, account_, !sle, j_) >= depositAmount) + if (wrappedAcct.xrpLiquid(!sle, j_) >= depositAmount) return tesSUCCESS; } else if ( diff --git a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp index 17dd2d2c57..b28494e5de 100644 --- a/src/libxrpl/tx/transactors/dex/OfferCreate.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp @@ -145,8 +145,10 @@ OfferCreate::preclaim(PreclaimContext const& ctx) std::uint32_t const uAccountSequence = sleCreator->getFieldU32(sfSequence); auto viewJ = ctx.registry.journal("View"); + WrappedAccountRoot wrappedPays(uPaysIssuerID, &ctx.view); + WrappedAccountRoot wrappedGets(uGetsIssuerID, &ctx.view); - if (isGlobalFrozen(ctx.view, uPaysIssuerID) || isGlobalFrozen(ctx.view, uGetsIssuerID)) + if (wrappedPays.isGlobalFrozen() || wrappedGets.isGlobalFrozen()) { JLOG(ctx.j.debug()) << "Offer involves frozen asset"; return tecFROZEN; @@ -296,7 +298,8 @@ OfferCreate::flowCross( STAmount sendMax = takerAmount.in; if (!sendMax.native() && (account_ != sendMax.getIssuer())) { - gatewayXferRate = transferRate(psb, sendMax.getIssuer()); + WrappedAccountRoot wrappedAcct(sendMax.getIssuer(), &psb); + gatewayXferRate = wrappedAcct.transferRate(); if (gatewayXferRate.value != QUALITY_ONE) { sendMax = @@ -732,12 +735,12 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel) return {tesSUCCESS, true}; } - auto const sleCreator = sb.peek(keylet::account(account_)); - if (!sleCreator) + WrappedAccountRoot wrappedCreator(account_, &sb); + if (!wrappedCreator) return {tefINTERNAL, false}; { - XRPAmount reserve = sb.fees().accountReserve(sleCreator->getFieldU32(sfOwnerCount) + 1); + XRPAmount reserve = sb.fees().accountReserve(wrappedCreator->getFieldU32(sfOwnerCount) + 1); if (preFeeBalance_ < reserve) { @@ -772,7 +775,7 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel) } // Update owner count. - adjustOwnerCount(sb, sleCreator, 1, viewJ); + wrappedCreator.adjustOwnerCount(1, viewJ); JLOG(j_.trace()) << "adding to book: " << to_string(saTakerPays.issue()) << " : " << to_string(saTakerGets.issue()) diff --git a/src/libxrpl/tx/transactors/did/DIDDelete.cpp b/src/libxrpl/tx/transactors/did/DIDDelete.cpp index 0d5b63635f..b0530bb847 100644 --- a/src/libxrpl/tx/transactors/did/DIDDelete.cpp +++ b/src/libxrpl/tx/transactors/did/DIDDelete.cpp @@ -38,12 +38,12 @@ DIDDelete::deleteSLE( // LCOV_EXCL_STOP } - auto const sleOwner = view.peek(keylet::account(owner)); - if (!sleOwner) + WrappedAccountRoot wrappedOwner(owner, &view); + if (!wrappedOwner) return tecINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleOwner, -1, j); - view.update(sleOwner); + wrappedOwner.adjustOwnerCount(-1, j); + view.update(wrappedOwner.mutableSle()); // 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 cd5c9bbc96..11e5e7a282 100644 --- a/src/libxrpl/tx/transactors/did/DIDSet.cpp +++ b/src/libxrpl/tx/transactors/did/DIDSet.cpp @@ -51,14 +51,14 @@ DIDSet::preflight(PreflightContext const& ctx) static TER addSLE(ApplyContext& ctx, std::shared_ptr const& sle, AccountID const& owner) { - auto const sleAccount = ctx.view().peek(keylet::account(owner)); - if (!sleAccount) + WrappedAccountRoot wrappedAcct(owner, &ctx.view()); + if (!wrappedAcct) return tefINTERNAL; // LCOV_EXCL_LINE // Check reserve availability for new object creation { - auto const balance = STAmount((*sleAccount)[sfBalance]).xrp(); - auto const reserve = ctx.view().fees().accountReserve((*sleAccount)[sfOwnerCount] + 1); + auto const balance = STAmount((*wrappedAcct)[sfBalance]).xrp(); + auto const reserve = ctx.view().fees().accountReserve((*wrappedAcct)[sfOwnerCount] + 1); if (balance < reserve) return tecINSUFFICIENT_RESERVE; @@ -75,8 +75,8 @@ addSLE(ApplyContext& ctx, std::shared_ptr const& sle, AccountID const& owne return tecDIR_FULL; // LCOV_EXCL_LINE (*sle)[sfOwnerNode] = *page; } - adjustOwnerCount(ctx.view(), sleAccount, 1, ctx.journal); - ctx.view().update(sleAccount); + wrappedAcct.adjustOwnerCount(1, ctx.journal); + ctx.view().update(wrappedAcct.mutableSle()); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp index 1250d950cd..e7657500d9 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCancel.cpp @@ -149,13 +149,13 @@ EscrowCancel::doApply() } } - auto const sle = ctx_.view().peek(keylet::account(account)); + WrappedAccountRoot wrappedAcct(account, &ctx_.view()); STAmount const amount = slep->getFieldAmount(sfAmount); // Transfer amount back to the owner if (isXRP(amount)) { - (*sle)[sfBalance] = (*sle)[sfBalance] + amount; + (*wrappedAcct)[sfBalance] = (*wrappedAcct)[sfBalance] + amount; } else { @@ -169,7 +169,7 @@ EscrowCancel::doApply() return escrowUnlockApplyHelper( ctx_.view(), parityRate, - slep, + slep, // Bug: should be wrappedAcct, will be fixed by amendment in #6171 preFeeBalance_, amount, issuer, @@ -195,8 +195,8 @@ EscrowCancel::doApply() } } - adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal); - ctx_.view().update(sle); + wrappedAcct.adjustOwnerCount(-1, ctx_.journal); + ctx_.view().update(wrappedAcct.mutableSle()); // Remove escrow from ledger ctx_.view().erase(slep); diff --git a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp index 634b9b3a06..fbdf37dfdb 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowCreate.cpp @@ -389,14 +389,14 @@ EscrowCreate::doApply() if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter])) return tecNO_PERMISSION; - auto const sle = ctx_.view().peek(keylet::account(account_)); - if (!sle) + WrappedAccountRoot wrappedAcct(account_, &ctx_.view()); + if (!wrappedAcct) return tefINTERNAL; // LCOV_EXCL_LINE // Check reserve and funds availability STAmount const amount{ctx_.tx[sfAmount]}; - auto const reserve = ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + 1); + auto const reserve = ctx_.view().fees().accountReserve((*wrappedAcct)[sfOwnerCount] + 1); auto const balance = sle->getFieldAmount(sfBalance).xrp(); if (balance < reserve) @@ -481,7 +481,7 @@ EscrowCreate::doApply() // Deduct owner's balance if (isXRP(amount)) { - (*sle)[sfBalance] = (*sle)[sfBalance] - amount; + (*wrappedAcct)[sfBalance] = (*wrappedAcct)[sfBalance] - amount; } else { @@ -497,8 +497,8 @@ EscrowCreate::doApply() } // increment owner count - adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal); - ctx_.view().update(sle); + wrappedAcct.adjustOwnerCount(1, ctx_.journal); + ctx_.view().update(wrappedAcct.mutableSle()); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp index 8a05b2b160..6cf082076c 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp +++ b/src/libxrpl/tx/transactors/escrow/EscrowFinish.cpp @@ -373,9 +373,9 @@ EscrowFinish::doApply() ctx_.view().update(sled); // Adjust source owner count - auto const sle = ctx_.view().peek(keylet::account(account)); - adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal); - ctx_.view().update(sle); + WrappedAccountRoot wrappedAcct(account, &ctx_.view()); + wrappedAcct.adjustOwnerCount(-1, ctx_.journal); + ctx_.view().update(wrappedAcct.mutableSle()); // Remove escrow from ledger ctx_.view().erase(slep); diff --git a/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h b/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h index 5fdc43c359..204c4c3d8f 100644 --- a/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h +++ b/src/libxrpl/tx/transactors/escrow/EscrowHelpers.h @@ -12,6 +12,8 @@ #include #include +#include + namespace xrpl { template @@ -19,7 +21,7 @@ TER escrowUnlockApplyHelper( ApplyView& view, Rate lockedRate, - std::shared_ptr const& sleDest, + std::variant, WrappedAccountRoot> sleDest, STAmount const& xrpBalance, STAmount const& amount, AccountID const& issuer, @@ -33,7 +35,7 @@ inline TER escrowUnlockApplyHelper( ApplyView& view, Rate lockedRate, - std::shared_ptr const& sleDest, + std::variant, WrappedAccountRoot> sleDest, STAmount const& xrpBalance, STAmount const& amount, AccountID const& issuer, @@ -55,8 +57,14 @@ escrowUnlockApplyHelper( if (!view.exists(trustLineKey) && createAsset) { + // For backwards compatibility: if sleDest is not WrappedAccountRoot, return error + if (!std::holds_alternative(sleDest)) + return tefEXCEPTION; + + auto& wrappedDest = std::get(sleDest); + // Can the account cover the trust line's reserve? - if (std::uint32_t const ownerCount = {sleDest->at(sfOwnerCount)}; + if (std::uint32_t const ownerCount = {wrappedDest->at(sfOwnerCount)}; xrpBalance < view.fees().accountReserve(ownerCount + 1)) { JLOG(journal.trace()) << "Trust line does not exist. " @@ -76,9 +84,9 @@ escrowUnlockApplyHelper( issuer, // source receiver, // destination trustLineKey.key, // ledger index - sleDest, // Account to add to + wrappedDest, // Account to add to false, // authorize account - (sleDest->getFlags() & lsfDefaultRipple) == 0, + (wrappedDest->getFlags() & lsfDefaultRipple) == 0, false, // freeze trust line false, // deep freeze trust line initialBalance, // zero initial balance @@ -92,7 +100,7 @@ escrowUnlockApplyHelper( } // clang-format on - view.update(sleDest); + view.update(wrappedDest.mutableSle()); } if (!view.exists(trustLineKey) && !receiverIssuer) @@ -163,7 +171,7 @@ inline TER escrowUnlockApplyHelper( ApplyView& view, Rate lockedRate, - std::shared_ptr const& sleDest, + std::variant, WrappedAccountRoot> sleDest, STAmount const& xrpBalance, STAmount const& amount, AccountID const& issuer, @@ -179,7 +187,13 @@ escrowUnlockApplyHelper( auto const issuanceKey = keylet::mptIssuance(mptID); if (!view.exists(keylet::mptoken(issuanceKey.key, receiver)) && createAsset && !receiverIssuer) { - if (std::uint32_t const ownerCount = {sleDest->at(sfOwnerCount)}; + // For backwards compatibility: if sleDest is not WrappedAccountRoot, return error + if (!std::holds_alternative(sleDest)) + return tefEXCEPTION; + + auto& wrappedDest = std::get(sleDest); + + if (std::uint32_t const ownerCount = {wrappedDest->at(sfOwnerCount)}; xrpBalance < view.fees().accountReserve(ownerCount + 1)) { return tecINSUFFICIENT_RESERVE; @@ -192,7 +206,7 @@ escrowUnlockApplyHelper( } // update owner count. - adjustOwnerCount(view, sleDest, 1, journal); + wrappedDest.adjustOwnerCount(1, journal); } if (!view.exists(keylet::mptoken(issuanceKey.key, receiver)) && !receiverIssuer) diff --git a/src/libxrpl/tx/transactors/lending/LendingHelpers.cpp b/src/libxrpl/tx/transactors/lending/LendingHelpers.cpp index ad4cd8440d..158f6c9e27 100644 --- a/src/libxrpl/tx/transactors/lending/LendingHelpers.cpp +++ b/src/libxrpl/tx/transactors/lending/LendingHelpers.cpp @@ -1900,4 +1900,68 @@ loanMakePayment( "xrpl::loanMakePayment : fee paid is valid"); return totalParts; } + +// An owner count cannot be negative. If adjustment would cause a negative +// owner count, clamp the owner count at 0. Similarly for overflow. This +// adjustment allows the ownerCount to be adjusted up or down in multiple steps. +// If id != std::nullopt, then do error reporting. +// +// Returns adjusted owner count. +static std::uint32_t +confineOwnerCount( + std::uint32_t current, + std::int32_t adjustment, + std::optional const& id = std::nullopt, + beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) +{ + std::uint32_t adjusted{current + adjustment}; + if (adjustment > 0) + { + // Overflow is well defined on unsigned + if (adjusted < current) + { + if (id) + { + JLOG(j.fatal()) << "Account " << *id << " owner count exceeds max!"; + } + adjusted = std::numeric_limits::max(); + } + } + else + { + // Underflow is well defined on unsigned + if (adjusted > current) + { + if (id) + { + JLOG(j.fatal()) << "Account " << *id << " owner count set below 0!"; + } + adjusted = 0; + XRPL_ASSERT(!id, "xrpl::confineOwnerCount : id is not set"); + } + } + return adjusted; +} + +void +adjustOwnerCount( + std::shared_ptr const& sle, + ApplyView& view, + std::int32_t amount, + beast::Journal j) +{ + // This function is only used for LoanBrokers, so assert that + // AccountRoot should use WrappedAccountRoot.adjustOwnerCount instead + XRPL_ASSERT(sle->getType() == ltLOAN_BROKER, "xrpl::adjustOwnerCount : sle is loan broker"); + if (!sle) + return; + XRPL_ASSERT(amount, "xrpl::adjustOwnerCount : nonzero amount input"); + std::uint32_t const current{sle->getFieldU32(sfOwnerCount)}; + AccountID const id = (*sle)[sfAccount]; + std::uint32_t const adjusted = confineOwnerCount(current, amount, id, j); + view.adjustOwnerCountHook(id, current, adjusted); + sle->at(sfOwnerCount) = adjusted; + view.update(sle); +} + } // namespace xrpl diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp index a755db7942..82710fd6b6 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerDelete.cpp @@ -162,13 +162,13 @@ LoanBrokerDelete::doApply() view().erase(broker); { - auto owner = view().peek(keylet::account(account_)); - if (!owner) + WrappedAccountRoot wrappedOwner(account_, &view()); + if (!wrappedOwner) return tefBAD_LEDGER; // LCOV_EXCL_LINE // Decreases the owner count by two: one for the LoanBroker object, and // one for the pseudo-account. - adjustOwnerCount(view(), owner, -2, j_); + wrappedOwner.adjustOwnerCount(-2, j_); } associateAsset(*broker, vaultAsset); diff --git a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp index f8813ddbef..138287d4dc 100644 --- a/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanBrokerSet.cpp @@ -202,7 +202,7 @@ LoanBrokerSet::doApply() auto const vaultAsset = sleVault->at(sfAsset); auto const sequence = tx.getSeqValue(); - auto owner = view.peek(keylet::account(account_)); + WrappedAccountRoot owner(account_, &view); if (!owner) { // This should be impossible @@ -220,7 +220,7 @@ LoanBrokerSet::doApply() // Increases the owner count by two: one for the LoanBroker object, and // one for the pseudo-account. - adjustOwnerCount(view, owner, 2, j_); + owner.adjustOwnerCount(2, j_); auto const ownerCount = owner->at(sfOwnerCount); if (preFeeBalance_ < view.fees().accountReserve(ownerCount)) return tecINSUFFICIENT_RESERVE; diff --git a/src/libxrpl/tx/transactors/lending/LoanDelete.cpp b/src/libxrpl/tx/transactors/lending/LoanDelete.cpp index 39b28f5110..2bcf9a6720 100644 --- a/src/libxrpl/tx/transactors/lending/LoanDelete.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanDelete.cpp @@ -68,8 +68,8 @@ LoanDelete::doApply() if (!loanSle) return tefBAD_LEDGER; // LCOV_EXCL_LINE auto const borrower = loanSle->at(sfBorrower); - auto const borrowerSle = view.peek(keylet::account(borrower)); - if (!borrowerSle) + WrappedAccountRoot wrappedBorrower(borrower, &view); + if (!wrappedBorrower) return tefBAD_LEDGER; // LCOV_EXCL_LINE auto const brokerID = loanSle->at(sfLoanBrokerID); @@ -97,7 +97,7 @@ LoanDelete::doApply() // Decrement the LoanBroker's owner count. // The broker's owner count is solely for the number of outstanding loans, // and is distinct from the broker's pseudo-account's owner count - adjustOwnerCount(view, brokerSle, -1, j_); + adjustOwnerCount(brokerSle, view, -1, j_); // If there are no loans left, then any remaining debt must be forgiven, // because there is no other way to pay it back. if (brokerSle->at(sfOwnerCount) == 0) @@ -117,7 +117,7 @@ LoanDelete::doApply() } } // Decrement the borrower's owner count - adjustOwnerCount(view, borrowerSle, -1, j_); + wrappedBorrower.adjustOwnerCount(-1, j_); // These associations shouldn't do anything, but do them just to be safe associateAsset(*loanSle, vaultAsset); diff --git a/src/libxrpl/tx/transactors/lending/LoanSet.cpp b/src/libxrpl/tx/transactors/lending/LoanSet.cpp index f046a24961..8ca8f00c8d 100644 --- a/src/libxrpl/tx/transactors/lending/LoanSet.cpp +++ b/src/libxrpl/tx/transactors/lending/LoanSet.cpp @@ -258,7 +258,7 @@ LoanSet::preclaim(PreclaimContext const& ctx) auto const brokerPseudo = brokerSle->at(sfAccount); auto const borrower = counterparty == brokerOwner ? account : counterparty; - if (auto const borrowerSle = ctx.view.read(keylet::account(borrower)); !borrowerSle) + if (auto const wrappedBorrower = WrappedAccountRoot(borrower, &ctx.view); !wrappedBorrower) { // It may not be possible to hit this case, because it'll fail the // signature check with terNO_ACCOUNT. @@ -360,8 +360,8 @@ LoanSet::doApply() auto const counterparty = tx[~sfCounterparty].value_or(brokerOwner); auto const borrower = counterparty == brokerOwner ? account_ : counterparty; - auto const borrowerSle = view.peek(keylet::account(borrower)); - if (!borrowerSle) + WrappedAccountRoot wrappedBorrower(borrower, &view); + if (!wrappedBorrower) { return tefBAD_LEDGER; // LCOV_EXCL_LINE } @@ -474,11 +474,11 @@ LoanSet::doApply() } } - adjustOwnerCount(view, borrowerSle, 1, j_); + wrappedBorrower.adjustOwnerCount(1, j_); { - auto const ownerCount = borrowerSle->at(sfOwnerCount); + auto const ownerCount = wrappedBorrower->at(sfOwnerCount); auto const balance = - account_ == borrower ? preFeeBalance_ : borrowerSle->at(sfBalance).value().xrp(); + account_ == borrower ? preFeeBalance_ : wrappedBorrower->at(sfBalance).value().xrp(); if (balance < view.fees().accountReserve(ownerCount)) return tecINSUFFICIENT_RESERVE; } @@ -494,7 +494,7 @@ LoanSet::doApply() "xrpl::LoanSet::doApply", "borrower signed transaction"); if (auto const ter = addEmptyHolding( - view, borrower, borrowerSle->at(sfBalance).value().xrp(), vaultAsset, j_); + view, borrower, wrappedBorrower->at(sfBalance).value().xrp(), vaultAsset, j_); ter && ter != tecDUPLICATE) { // ignore tecDUPLICATE. That means the holding already exists, and @@ -595,7 +595,7 @@ LoanSet::doApply() adjustImpreciseNumber(brokerSle->at(sfDebtTotal), newDebtDelta, vaultAsset, vaultScale); // The broker's owner count is solely for the number of outstanding loans, // and is distinct from the broker's pseudo-account's owner count - adjustOwnerCount(view, brokerSle, 1, j_); + adjustOwnerCount(brokerSle, view, 1, j_); loanSequenceProxy += 1; // The sequence should be extremely unlikely to roll over, but fail if it // does diff --git a/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp b/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp index 84826314e7..44a975034e 100644 --- a/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp +++ b/src/libxrpl/tx/transactors/nft/NFTokenUtils.cpp @@ -247,11 +247,8 @@ insertToken(ApplyView& view, AccountID owner, STObject&& nft) // the NFT. std::shared_ptr page = getPageForToken(view, owner, nft[sfNFTokenID], [](ApplyView& view, AccountID const& owner) { - adjustOwnerCount( - view, - view.peek(keylet::account(owner)), - 1, - beast::Journal{beast::Journal::getNullSink()}); + WrappedAccountRoot wrappedOwner(owner, &view); + wrappedOwner.adjustOwnerCount(1, beast::Journal{beast::Journal::getNullSink()}); }); if (!page) @@ -409,11 +406,8 @@ removeToken( if (cnt != 0) { - adjustOwnerCount( - view, - view.peek(keylet::account(owner)), - cnt, - beast::Journal{beast::Journal::getNullSink()}); + WrappedAccountRoot wrappedOwner(owner, &view); + wrappedOwner.adjustOwnerCount(cnt, beast::Journal{beast::Journal::getNullSink()}); } return tesSUCCESS; @@ -448,11 +442,8 @@ removeToken( curr->makeFieldAbsent(sfPreviousPageMin); } - adjustOwnerCount( - view, - view.peek(keylet::account(owner)), - -1, - beast::Journal{beast::Journal::getNullSink()}); + WrappedAccountRoot wrappedOwner(owner, &view); + wrappedOwner.adjustOwnerCount(-1, beast::Journal{beast::Journal::getNullSink()}); view.update(curr); view.erase(prev); @@ -507,11 +498,8 @@ removeToken( view.peek(Keylet(ltNFTOKEN_PAGE, next->key())))) cnt++; - adjustOwnerCount( - view, - view.peek(keylet::account(owner)), - -1 * cnt, - beast::Journal{beast::Journal::getNullSink()}); + WrappedAccountRoot wrappedOwner(owner, &view); + wrappedOwner.adjustOwnerCount(-1 * cnt, beast::Journal{beast::Journal::getNullSink()}); return tesSUCCESS; } @@ -654,8 +642,8 @@ deleteTokenOffer(ApplyView& view, std::shared_ptr const& offer) false)) return false; - adjustOwnerCount( - view, view.peek(keylet::account(owner)), -1, beast::Journal{beast::Journal::getNullSink()}); + WrappedAccountRoot wrappedOwner(owner, &view); + wrappedOwner.adjustOwnerCount(-1, beast::Journal{beast::Journal::getNullSink()}); view.erase(offer); return true; @@ -998,7 +986,8 @@ tokenOfferCreateApply( } // Update owner count. - adjustOwnerCount(view, view.peek(acctKeylet), 1, j); + WrappedAccountRoot wrappedOwner(acctID, &view); + wrappedOwner.adjustOwnerCount(1, j); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp index bde403f821..ab29b53b93 100644 --- a/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp @@ -56,13 +56,13 @@ OracleDelete::deleteOracle( // LCOV_EXCL_STOP } - auto const sleOwner = view.peek(keylet::account(account)); - if (!sleOwner) + WrappedAccountRoot wrappedOwner(account, &view); + if (!wrappedOwner) return tecINTERNAL; // LCOV_EXCL_LINE auto const count = sle->getFieldArray(sfPriceDataSeries).size() > 5 ? -2 : -1; - adjustOwnerCount(view, sleOwner, count, j); + wrappedOwner.adjustOwnerCount(count, j); view.erase(sle); diff --git a/src/libxrpl/tx/transactors/oracle/OracleSet.cpp b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp index 061dd16b0c..feb6383af6 100644 --- a/src/libxrpl/tx/transactors/oracle/OracleSet.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp @@ -162,9 +162,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 (auto wrappedAccount = WrappedAccountRoot(ctx.tx.getAccountID(sfAccount), &ctx.view())) { - adjustOwnerCount(ctx.view(), sleAccount, count, ctx.journal); + wrappedAccount.adjustOwnerCount(count, ctx.journal); return true; } diff --git a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp index 0f4681a3ad..2974312f2f 100644 --- a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp +++ b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp @@ -135,8 +135,8 @@ DepositPreauth::doApply() { if (ctx_.tx.isFieldPresent(sfAuthorize)) { - auto const sleOwner = view().peek(keylet::account(account_)); - if (!sleOwner) + WrappedAccountRoot wrappedOwner(account_, &view()); + if (!wrappedOwner) return {tefINTERNAL}; // A preauth counts against the reserve of the issuing account, but we @@ -144,7 +144,7 @@ DepositPreauth::doApply() // reserve to pay fees. { STAmount const reserve{ - view().fees().accountReserve(sleOwner->getFieldU32(sfOwnerCount) + 1)}; + view().fees().accountReserve(wrappedOwner->getFieldU32(sfOwnerCount) + 1)}; if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; @@ -172,7 +172,7 @@ DepositPreauth::doApply() slePreauth->setFieldU64(sfOwnerNode, *page); // If we succeeded, the new entry counts against the creator's reserve. - adjustOwnerCount(view(), sleOwner, 1, j_); + wrappedOwner.adjustOwnerCount(1, j_); } else if (ctx_.tx.isFieldPresent(sfUnauthorize)) { @@ -182,8 +182,8 @@ DepositPreauth::doApply() } else if (ctx_.tx.isFieldPresent(sfAuthorizeCredentials)) { - auto const sleOwner = view().peek(keylet::account(account_)); - if (!sleOwner) + WrappedAccountRoot wrappedOwner(account_, &view()); + if (!wrappedOwner) return tefINTERNAL; // LCOV_EXCL_LINE // A preauth counts against the reserve of the issuing account, but we @@ -191,7 +191,7 @@ DepositPreauth::doApply() // reserve to pay fees. { STAmount const reserve{ - view().fees().accountReserve(sleOwner->getFieldU32(sfOwnerCount) + 1)}; + view().fees().accountReserve(wrappedOwner->getFieldU32(sfOwnerCount) + 1)}; if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; @@ -233,7 +233,7 @@ DepositPreauth::doApply() slePreauth->setFieldU64(sfOwnerNode, *page); // If we succeeded, the new entry counts against the creator's reserve. - adjustOwnerCount(view(), sleOwner, 1, j_); + wrappedOwner.adjustOwnerCount(1, j_); } else if (ctx_.tx.isFieldPresent(sfUnauthorizeCredentials)) { @@ -267,11 +267,11 @@ DepositPreauth::removeFromLedger(ApplyView& view, uint256 const& preauthIndex, b } // If we succeeded, update the DepositPreauth owner's reserve. - auto const sleOwner = view.peek(keylet::account(account)); - if (!sleOwner) + WrappedAccountRoot wrappedOwner(account, &view); + if (!wrappedOwner) return tefINTERNAL; // LCOV_EXCL_LINE - adjustOwnerCount(view, sleOwner, -1, j); + wrappedOwner.adjustOwnerCount(-1, j); // Remove DepositPreauth from ledger. view.erase(slePreauth); diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp index c12169fc0e..efae5efd7a 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp @@ -107,9 +107,8 @@ PaymentChannelCreate::preclaim(PreclaimContext const& ctx) TER PaymentChannelCreate::doApply() { - auto const account = ctx_.tx[sfAccount]; - auto const sle = ctx_.view().peek(keylet::account(account)); - if (!sle) + WrappedAccountRoot wrappedOwner(account_, &ctx_.view()); + if (!wrappedOwner) return tefINTERNAL; // LCOV_EXCL_LINE if (ctx_.view().rules().enabled(fixPayChanCancelAfter)) @@ -125,14 +124,14 @@ PaymentChannelCreate::doApply() // // Note that we we use the value from the sequence or ticket as the // payChan sequence. For more explanation see comments in SeqProxy.h. - Keylet const payChanKeylet = keylet::payChan(account, dst, ctx_.tx.getSeqValue()); + Keylet const payChanKeylet = keylet::payChan(account_, dst, ctx_.tx.getSeqValue()); auto const slep = std::make_shared(payChanKeylet); // Funds held in this channel (*slep)[sfAmount] = ctx_.tx[sfAmount]; // Amount channel has already paid (*slep)[sfBalance] = ctx_.tx[sfAmount].zeroed(); - (*slep)[sfAccount] = account; + (*slep)[sfAccount] = account_; (*slep)[sfDestination] = dst; (*slep)[sfSettleDelay] = ctx_.tx[sfSettleDelay]; (*slep)[sfPublicKey] = ctx_.tx[sfPublicKey]; @@ -149,7 +148,7 @@ PaymentChannelCreate::doApply() // Add PayChan to owner directory { auto const page = ctx_.view().dirInsert( - keylet::ownerDir(account), payChanKeylet, describeOwnerDir(account)); + keylet::ownerDir(account_), payChanKeylet, describeOwnerDir(account_)); if (!page) return tecDIR_FULL; // LCOV_EXCL_LINE (*slep)[sfOwnerNode] = *page; @@ -165,9 +164,9 @@ PaymentChannelCreate::doApply() } // Deduct owner's balance, increment owner count - (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount]; - adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal); - ctx_.view().update(sle); + (*wrappedOwner)[sfBalance] = (*wrappedOwner)[sfBalance] - ctx_.tx[sfAmount]; + wrappedOwner.adjustOwnerCount(1, ctx_.journal); + ctx_.view().update(wrappedOwner.mutableSle()); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp index 176b920e6b..7fe21f226c 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp @@ -42,14 +42,16 @@ closeChannel( // Transfer amount back to owner, decrement owner count auto const sle = view.peek(keylet::account(src)); - if (!sle) + WrappedAccountRoot wrappedOwner(src, &view); + if (!wrappedOwner) 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); + (*wrappedOwner)[sfBalance] = + (*wrappedOwner)[sfBalance] + (*slep)[sfAmount] - (*slep)[sfBalance]; + wrappedOwner.adjustOwnerCount(-1, j); + view.update(wrappedOwner.mutableSle()); // Remove PayChan from ledger view.erase(slep); diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp index 565631b3fd..bd9b06a117 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.cpp @@ -52,11 +52,11 @@ PermissionedDomainDelete::doApply() // LCOV_EXCL_STOP } - auto const ownerSle = view().peek(keylet::account(account_)); + auto wrappedOwner = WrappedAccountRoot(account_, &view()); XRPL_ASSERT( - ownerSle && ownerSle->getFieldU32(sfOwnerCount) > 0, + wrappedOwner && wrappedOwner->getFieldU32(sfOwnerCount) > 0, "xrpl::PermissionedDomainDelete::doApply : nonzero owner count"); - adjustOwnerCount(view(), ownerSle, -1, ctx_.journal); + wrappedOwner.adjustOwnerCount(-1, ctx_.journal); view().erase(slePd); return tesSUCCESS; diff --git a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp index e8df51c9d9..8dff718944 100644 --- a/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp +++ b/src/libxrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.cpp @@ -64,8 +64,8 @@ PermissionedDomainSet::preclaim(PreclaimContext const& ctx) TER PermissionedDomainSet::doApply() { - auto const ownerSle = view().peek(keylet::account(account_)); - if (!ownerSle) + WrappedAccountRoot wrappedOwner(account_, &view()); + if (!wrappedOwner) return tefINTERNAL; // LCOV_EXCL_LINE auto const sortedTxCredentials = @@ -92,8 +92,8 @@ PermissionedDomainSet::doApply() { // Create new permissioned domain. // Check reserve availability for new object creation - auto const balance = STAmount((*ownerSle)[sfBalance]).xrp(); - auto const reserve = ctx_.view().fees().accountReserve((*ownerSle)[sfOwnerCount] + 1); + auto const balance = STAmount((*wrappedOwner)[sfBalance]).xrp(); + auto const reserve = ctx_.view().fees().accountReserve((*wrappedOwner)[sfOwnerCount] + 1); if (balance < reserve) return tecINSUFFICIENT_RESERVE; @@ -113,7 +113,7 @@ PermissionedDomainSet::doApply() slePd->setFieldU64(sfOwnerNode, *page); // If we succeeded, the new entry counts against the creator's reserve. - adjustOwnerCount(view(), ownerSle, 1, ctx_.journal); + wrappedOwner.adjustOwnerCount(1, ctx_.journal); view().insert(slePd); } diff --git a/src/libxrpl/tx/transactors/system/TicketCreate.cpp b/src/libxrpl/tx/transactors/system/TicketCreate.cpp index a064c158d1..4692d8efb2 100644 --- a/src/libxrpl/tx/transactors/system/TicketCreate.cpp +++ b/src/libxrpl/tx/transactors/system/TicketCreate.cpp @@ -55,8 +55,8 @@ TicketCreate::preclaim(PreclaimContext const& ctx) TER TicketCreate::doApply() { - SLE::pointer const sleAccountRoot = view().peek(keylet::account(account_)); - if (!sleAccountRoot) + WrappedAccountRoot wrappedOwner(account_, &view()); + if (!wrappedOwner) return tefINTERNAL; // LCOV_EXCL_LINE // Each ticket counts against the reserve of the issuing account, but we @@ -65,7 +65,7 @@ TicketCreate::doApply() std::uint32_t const ticketCount = ctx_.tx[sfTicketCount]; { XRPAmount const reserve = - view().fees().accountReserve(sleAccountRoot->getFieldU32(sfOwnerCount) + ticketCount); + view().fees().accountReserve(wrappedOwner->getFieldU32(sfOwnerCount) + ticketCount); if (preFeeBalance_ < reserve) return tecINSUFFICIENT_RESERVE; @@ -77,7 +77,7 @@ TicketCreate::doApply() // root sequence. Before we got here to doApply(), the transaction // machinery already incremented the account root sequence if that // was appropriate. - std::uint32_t const firstTicketSeq = (*sleAccountRoot)[sfSequence]; + std::uint32_t const firstTicketSeq = (*wrappedOwner)[sfSequence]; // Sanity check that the transaction machinery really did already // increment the account root Sequence. @@ -108,16 +108,16 @@ TicketCreate::doApply() } // Update the record of the number of Tickets this account owns. - std::uint32_t const oldTicketCount = (*(sleAccountRoot))[~sfTicketCount].value_or(0u); + std::uint32_t const oldTicketCount = (*(wrappedOwner))[~sfTicketCount].value_or(0u); - sleAccountRoot->setFieldU32(sfTicketCount, oldTicketCount + ticketCount); + wrappedOwner->setFieldU32(sfTicketCount, oldTicketCount + ticketCount); // Every added Ticket counts against the creator's reserve. - adjustOwnerCount(view(), sleAccountRoot, ticketCount, viewJ); + wrappedOwner.adjustOwnerCount(ticketCount, viewJ); // TicketCreate is the only transaction that can cause an account root's // Sequence field to increase by more than one. October 2018. - sleAccountRoot->setFieldU32(sfSequence, firstTicketSeq + ticketCount); + wrappedOwner->setFieldU32(sfSequence, firstTicketSeq + ticketCount); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp index 6bcb1175e8..77adabb928 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceCreate.cpp @@ -79,7 +79,7 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) Expected MPTokenIssuanceCreate::create(ApplyView& view, beast::Journal journal, MPTCreateArgs const& args) { - auto const acct = view.peek(keylet::account(args.account)); + WrappedAccountRoot acct(args.account, &view); if (!acct) return Unexpected(tecINTERNAL); // LCOV_EXCL_LINE @@ -127,7 +127,7 @@ MPTokenIssuanceCreate::create(ApplyView& view, beast::Journal journal, MPTCreate } // Update owner count. - adjustOwnerCount(view, acct, 1, journal); + acct.adjustOwnerCount(1, journal); return mptId; } diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp index 8ec1f37886..6ef798204b 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceDestroy.cpp @@ -46,7 +46,8 @@ MPTokenIssuanceDestroy::doApply() view().erase(mpt); - adjustOwnerCount(view(), view().peek(keylet::account(account_)), -1, j_); + WrappedAccountRoot acct(account_, &view()); + acct.adjustOwnerCount(-1, j_); return tesSUCCESS; } diff --git a/src/libxrpl/tx/transactors/token/TrustSet.cpp b/src/libxrpl/tx/transactors/token/TrustSet.cpp index 918620c3de..dfebcdb74a 100644 --- a/src/libxrpl/tx/transactors/token/TrustSet.cpp +++ b/src/libxrpl/tx/transactors/token/TrustSet.cpp @@ -324,11 +324,11 @@ TrustSet::doApply() // true, if current is high account. bool const bHigh = account_ > uDstAccountID; - auto const sle = view().peek(keylet::account(account_)); - if (!sle) + WrappedAccountRoot wrappedAccount(account_, &view()); + if (!wrappedAccount) return tefINTERNAL; // LCOV_EXCL_LINE - std::uint32_t const uOwnerCount = sle->getFieldU32(sfOwnerCount); + std::uint32_t const uOwnerCount = wrappedAccount->getFieldU32(sfOwnerCount); // The reserve that is required to create the line. Note // that although the reserve increases with every item @@ -369,9 +369,9 @@ TrustSet::doApply() auto viewJ = ctx_.registry.journal("View"); - SLE::pointer sleDst = view().peek(keylet::account(uDstAccountID)); + WrappedAccountRoot wrappedDst(uDstAccountID, &view()); - if (!sleDst) + if (!wrappedDst) { JLOG(j_.trace()) << "Delay transaction: Destination account does not exist."; return tecNO_DST; @@ -394,8 +394,8 @@ TrustSet::doApply() std::uint32_t uHighQualityOut = 0; auto const& uLowAccountID = !bHigh ? account_ : uDstAccountID; auto const& uHighAccountID = bHigh ? account_ : uDstAccountID; - SLE::ref sleLowAccount = !bHigh ? sle : sleDst; - SLE::ref sleHighAccount = bHigh ? sle : sleDst; + auto lowAcct = !bHigh ? wrappedAccount : wrappedDst; + auto highAcct = bHigh ? wrappedAccount : wrappedDst; // // Balances @@ -500,7 +500,7 @@ TrustSet::doApply() } // Have to use lsfNoFreeze to maintain pre-deep freeze behavior - bool const bNoFreeze = sle->isFlag(lsfNoFreeze); + bool const bNoFreeze = wrappedAccount->isFlag(lsfNoFreeze); uFlagsOut = computeFreezeFlags( uFlagsOut, bHigh, @@ -516,8 +516,8 @@ TrustSet::doApply() if (QUALITY_ONE == uHighQualityOut) uHighQualityOut = 0; - bool const bLowDefRipple = (sleLowAccount->getFlags() & lsfDefaultRipple) != 0u; - bool const bHighDefRipple = (sleHighAccount->getFlags() & lsfDefaultRipple) != 0u; + bool const bLowDefRipple = lowAcct->getFlags() & lsfDefaultRipple; + bool const bHighDefRipple = highAcct->getFlags() & lsfDefaultRipple; bool const bLowReserveSet = (uLowQualityIn != 0u) || (uLowQualityOut != 0u) || ((uFlagsOut & lsfLowNoRipple) == 0) != bLowDefRipple || @@ -544,7 +544,7 @@ TrustSet::doApply() if (bLowReserveSet && !bLowReserved) { // Set reserve for low account. - adjustOwnerCount(view(), sleLowAccount, 1, viewJ); + lowAcct.adjustOwnerCount(1, viewJ); uFlagsOut |= lsfLowReserve; if (!bHigh) @@ -554,14 +554,14 @@ TrustSet::doApply() if (bLowReserveClear && bLowReserved) { // Clear reserve for low account. - adjustOwnerCount(view(), sleLowAccount, -1, viewJ); + lowAcct.adjustOwnerCount(-1, viewJ); uFlagsOut &= ~lsfLowReserve; } if (bHighReserveSet && !bHighReserved) { // Set reserve for high account. - adjustOwnerCount(view(), sleHighAccount, 1, viewJ); + highAcct.adjustOwnerCount(1, viewJ); uFlagsOut |= lsfHighReserve; if (bHigh) @@ -571,7 +571,7 @@ TrustSet::doApply() if (bHighReserveClear && bHighReserved) { // Clear reserve for high account. - adjustOwnerCount(view(), sleHighAccount, -1, viewJ); + highAcct.adjustOwnerCount(-1, viewJ); uFlagsOut &= ~lsfHighReserve; } @@ -639,7 +639,7 @@ TrustSet::doApply() account_, uDstAccountID, k.key, - sle, + wrappedAccount, bSetAuth, bSetNoRipple && !bClearNoRipple, bSetFreeze && !bClearFreeze, diff --git a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp index 02f8ecb57b..0b2a1f3c7b 100644 --- a/src/libxrpl/tx/transactors/vault/VaultCreate.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultCreate.cpp @@ -133,8 +133,8 @@ VaultCreate::doApply() auto const& tx = ctx_.tx; auto const sequence = tx.getSeqValue(); - auto const owner = view().peek(keylet::account(account_)); - if (owner == nullptr) + WrappedAccountRoot owner(account_, &view()); + if (!owner) return tefINTERNAL; // LCOV_EXCL_LINE auto vault = std::make_shared(keylet::vault(account_, sequence)); @@ -142,7 +142,7 @@ VaultCreate::doApply() if (auto ter = dirLink(view(), account_, vault)) return ter; // We will create Vault and PseudoAccount, hence increase OwnerCount by 2 - adjustOwnerCount(view(), owner, 2, j_); + owner.adjustOwnerCount(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 1e2e46e165..f8817520a5 100644 --- a/src/libxrpl/tx/transactors/vault/VaultDelete.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultDelete.cpp @@ -91,7 +91,7 @@ VaultDelete::doApply() return ter; auto const& pseudoID = vault->at(sfAccount); - auto const pseudoAcct = view().peek(keylet::account(pseudoID)); + WrappedAccountRoot pseudoAcct(pseudoID, &view()); if (!pseudoAcct) { // LCOV_EXCL_START @@ -136,7 +136,7 @@ VaultDelete::doApply() return tefBAD_LEDGER; // LCOV_EXCL_STOP } - adjustOwnerCount(view(), pseudoAcct, -1, j_); + pseudoAcct.adjustOwnerCount(-1, j_); view().erase(mpt); @@ -185,7 +185,7 @@ VaultDelete::doApply() // LCOV_EXCL_STOP } - auto const owner = view().peek(keylet::account(ownerID)); + WrappedAccountRoot owner(ownerID, &view()); if (!owner) { // LCOV_EXCL_START @@ -195,7 +195,7 @@ VaultDelete::doApply() } // We are destroying Vault and PseudoAccount, hence decrease by 2 - adjustOwnerCount(view(), owner, -2, j_); + owner.adjustOwnerCount(-2, j_); // Destroy the vault. view().erase(vault);