diff --git a/src/ripple/app/tx/impl/DepositPreauth.cpp b/src/ripple/app/tx/impl/DepositPreauth.cpp index 1a81ea691eb..b35c44d0d40 100644 --- a/src/ripple/app/tx/impl/DepositPreauth.cpp +++ b/src/ripple/app/tx/impl/DepositPreauth.cpp @@ -126,7 +126,7 @@ DepositPreauth::doApply() // Preclaim already verified that the Preauth entry does not yet exist. // Create and populate the Preauth entry. AccountID const auth{ctx_.tx[sfAuthorize]}; - Keylet const preauthKeylet = keylet::depositPreauth(account_, auth); + auto const preauthKeylet = keylet::depositPreauth(account_, auth); auto slePreauth = std::make_shared(preauthKeylet); slePreauth->setAccountID(sfAccount, account_); @@ -171,16 +171,16 @@ DepositPreauth::removeFromLedger( { // Verify that the Preauth entry they asked to remove is // in the ledger. - std::shared_ptr const slePreauth{ - view.peekSLE(keylet::depositPreauth(preauthIndex))}; - if (!slePreauth) + std::optional> preAuth{ + view.peek(keylet::depositPreauth(preauthIndex))}; + if (!preAuth) { JLOG(j.warn()) << "Selected DepositPreauth does not exist."; return tecNO_ENTRY; } - AccountID const account{(*slePreauth)[sfAccount]}; - std::uint64_t const page{(*slePreauth)[sfOwnerNode]}; + AccountID const account{preAuth->accountID()}; + std::uint64_t const page{preAuth->getOwner()}; if (!view.dirRemove(keylet::ownerDir(account), page, preauthIndex, false)) { JLOG(j.fatal()) << "Unable to delete DepositPreauth from owner."; @@ -195,7 +195,7 @@ DepositPreauth::removeFromLedger( adjustOwnerCount(view, *ownerAcctRoot, -1, app.journal("View")); // Remove DepositPreauth from ledger. - view.erase(slePreauth); + view.erase(*preAuth); return tesSUCCESS; } diff --git a/src/ripple/ledger/ApplyView.h b/src/ripple/ledger/ApplyView.h index f7578411a23..e75405e8e2d 100644 --- a/src/ripple/ledger/ApplyView.h +++ b/src/ripple/ledger/ApplyView.h @@ -343,7 +343,7 @@ class ApplyView : public ReadView std::optional dirInsert( Keylet const& directory, - Keylet const& key, + KeyletBase const& key, std::function const&)> const& describe) { return dirAdd(false, directory, key.key, describe); diff --git a/src/ripple/protocol/AcctRoot.h b/src/ripple/protocol/AcctRoot.h index c9e27fd4b3e..4aab36c44d1 100644 --- a/src/ripple/protocol/AcctRoot.h +++ b/src/ripple/protocol/AcctRoot.h @@ -48,6 +48,25 @@ class AcctRootImpl final : public LedgerEntryWrapper friend class ApplyView; public: + AcctRootImpl(AcctRootImpl const&) = default; + AcctRootImpl(AcctRootImpl&&) = default; + + AcctRootImpl& + operator=(AcctRootImpl const& rhs) + { + Base::operator=(rhs); + return *this; + } + + AcctRootImpl& + operator=(AcctRootImpl&& rhs) + { + Base::operator=(std::move(rhs)); + return *this; + } + + ~AcctRootImpl() = default; + // Conversion operator from AcctRootImpl to AcctRootImpl. operator AcctRootImpl() const { diff --git a/src/ripple/protocol/DPAuth.h b/src/ripple/protocol/DPAuth.h new file mode 100644 index 00000000000..853b1c824f4 --- /dev/null +++ b/src/ripple/protocol/DPAuth.h @@ -0,0 +1,67 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2021 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include + +namespace ripple { + +// Wrapper class for DepositPreAuth Ledger Object. +// This class encapsulates the std::shared_ptr to the actual ledger object. +template +class DPAuthImpl final : public LedgerEntryWrapper +{ +private: + using Base = LedgerEntryWrapper; + using SleT = typename Base::SleT; + using Base::wrapped_; + + DPAuthImpl(std::shared_ptr&& w) : Base(std::move(w)) + { + } + + // Friend declarations of factory functions. + // + // For classes that contain factories we must declare the entire class + // as a friend unless the class declaration is visible at this point. + friend class ReadView; + friend class ApplyView; + +public: + // Conversion operator from DPAuthImpl to DPAuthImpl. + operator DPAuthImpl() const + { + return DPAuthImpl( + std::const_pointer_cast>( + wrapped_)); + } + + [[nodiscard]] AccountID + accountID() const + { + return wrapped_->at(sfAccount); + } + + [[nodiscard]] std::uint64_t + getOwner() const + { + return wrapped_->at(sfOwnerNode); + } +}; +} \ No newline at end of file diff --git a/src/ripple/protocol/Indexes.h b/src/ripple/protocol/Indexes.h index e7170eff7cc..afef353d585 100644 --- a/src/ripple/protocol/Indexes.h +++ b/src/ripple/protocol/Indexes.h @@ -184,13 +184,13 @@ check(uint256 const& key) noexcept /** A DepositPreauth */ /** @{ */ -Keylet +DPAuthKeylet depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept; -inline Keylet +inline DPAuthKeylet depositPreauth(uint256 const& key) noexcept { - return {ltDEPOSIT_PREAUTH, key}; + return DPAuthKeylet(key); } /** @} */ diff --git a/src/ripple/protocol/Keylet.h b/src/ripple/protocol/Keylet.h index c34b484a150..d9e2562d1a7 100644 --- a/src/ripple/protocol/Keylet.h +++ b/src/ripple/protocol/Keylet.h @@ -22,6 +22,7 @@ #include #include +#include #include namespace ripple { @@ -95,6 +96,20 @@ static_assert(std::is_move_assignable_v); static_assert(std::is_nothrow_destructible_v); #endif +template +class DPAuthImpl; + +struct DPAuthKeylet final : public KeyletBase { + template + using TWrapped = DPAuthImpl; + + using KeyletBase::check; + + explicit DPAuthKeylet(uint256 const& key) : KeyletBase(ltDEPOSIT_PREAUTH, key) + { + } +}; + template class AcctRootImpl; diff --git a/src/ripple/protocol/impl/Indexes.cpp b/src/ripple/protocol/impl/Indexes.cpp index 2cc80ff41e6..2bf72eb71a6 100644 --- a/src/ripple/protocol/impl/Indexes.cpp +++ b/src/ripple/protocol/impl/Indexes.cpp @@ -283,12 +283,10 @@ check(AccountID const& id, std::uint32_t seq) noexcept return {ltCHECK, indexHash(LedgerNameSpace::CHECK, id, seq)}; } -Keylet +DPAuthKeylet depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept { - return { - ltDEPOSIT_PREAUTH, - indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, preauthorized)}; + return DPAuthKeylet((indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, preauthorized))); } //------------------------------------------------------------------------------ diff --git a/src/ripple/rpc/handlers/DepositAuthorized.cpp b/src/ripple/rpc/handlers/DepositAuthorized.cpp index 44064a82541..a4177faa807 100644 --- a/src/ripple/rpc/handlers/DepositAuthorized.cpp +++ b/src/ripple/rpc/handlers/DepositAuthorized.cpp @@ -101,9 +101,8 @@ doDepositAuthorized(RPC::JsonContext& context) if (destAcctRoot->isFlag(lsfDepositAuth)) { // See if a preauthorization entry is in the ledger. - auto const sleDepositAuth = - ledger->readSLE(keylet::depositPreauth(dstAcct, srcAcct)); - depositAuthorized = static_cast(sleDepositAuth); + auto const depositAuthorized = + ledger->read(keylet::depositPreauth(dstAcct, srcAcct)).has_value(); } } result[jss::source_account] = params[jss::source_account].asString();