mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-09 03:36:49 +00:00
refactor: Replace SLE helper inheritance with view-parameterized templates
This commit is contained in:
@@ -19,6 +19,11 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Forward declarations for SLE wrappers
|
||||
template <typename ViewT>
|
||||
class AccountRoot;
|
||||
using ReadOnlyAccountRoot = AccountRoot<ReadView>;
|
||||
|
||||
enum class SkipEntry : bool { No = false, Yes };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -157,7 +162,7 @@ canWithdraw(
|
||||
ReadView const& view,
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
AccountRoot const& toWrapped,
|
||||
ReadOnlyAccountRoot const& toWrapped,
|
||||
STAmount const& amount,
|
||||
bool hasDestinationTag);
|
||||
|
||||
|
||||
@@ -18,27 +18,60 @@
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* Read-only wrapper for AccountRoot ledger entries.
|
||||
* View-parameterized wrapper for AccountRoot ledger entries.
|
||||
*
|
||||
* Provides read-only access to account data.
|
||||
* AccountRoot<ReadView> — read-only access to account data
|
||||
* AccountRoot<ApplyView> — read-write access, with insert/update/erase
|
||||
* and domain-specific write methods
|
||||
*/
|
||||
class AccountRoot : public ReadOnlySLE
|
||||
template <typename ViewT>
|
||||
class AccountRoot : public SLEBase<ViewT>
|
||||
{
|
||||
protected:
|
||||
static constexpr bool is_writable = SLEBase<ViewT>::is_writable;
|
||||
|
||||
AccountID const id_;
|
||||
|
||||
public:
|
||||
/** Constructor for read-only context */
|
||||
AccountRoot(AccountID const& id, ReadView const& view)
|
||||
: ReadOnlySLE(view.read(keylet::account(id)), view), id_(id)
|
||||
requires(!is_writable)
|
||||
: SLEBase<ViewT>(view.read(keylet::account(id)), view), id_(id)
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for writable context */
|
||||
AccountRoot(AccountID const& id, ApplyView& view)
|
||||
requires is_writable
|
||||
: SLEBase<ViewT>(keylet::account(id), view), id_(id)
|
||||
{
|
||||
}
|
||||
|
||||
/** Converting constructor: writable → read-only. */
|
||||
template <WritableView OtherViewT>
|
||||
AccountRoot(AccountRoot<OtherViewT> const& other)
|
||||
requires(!is_writable)
|
||||
: SLEBase<ViewT>(other), id_(other.id())
|
||||
{
|
||||
}
|
||||
|
||||
/** Create an AccountRoot backed by a brand-new SLE
|
||||
* (not yet inserted into the view).
|
||||
*/
|
||||
[[nodiscard]] static AccountRoot
|
||||
makeNew(AccountID const& id, ApplyView& view)
|
||||
requires is_writable
|
||||
{
|
||||
return AccountRoot(id, view, std::make_shared<SLE>(keylet::account(id)));
|
||||
}
|
||||
|
||||
AccountID const&
|
||||
id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
// --- Read-only domain methods (available on both specializations) ---
|
||||
|
||||
/** Check if the issuer has the global freeze flag set.
|
||||
@return true if the account has global freeze set
|
||||
*/
|
||||
@@ -94,52 +127,36 @@ public:
|
||||
{
|
||||
return id_ == other;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Writable wrapper for AccountRoot ledger entries.
|
||||
*
|
||||
* Provides read-write access to account data.
|
||||
* Inherits from AccountRoot to reuse read-only methods,
|
||||
* and adds write capabilities.
|
||||
*/
|
||||
class WritableAccountRoot : public AccountRoot, public WritableSLE
|
||||
{
|
||||
public:
|
||||
WritableAccountRoot(AccountID const& id, ApplyView& view)
|
||||
: AccountRoot(id, view), WritableSLE(keylet::account(id), view)
|
||||
{
|
||||
}
|
||||
|
||||
/** Create a WritableAccountRoot backed by a brand-new SLE
|
||||
* (not yet inserted into the view).
|
||||
*/
|
||||
[[nodiscard]] static WritableAccountRoot
|
||||
makeNew(AccountID const& id, ApplyView& view)
|
||||
{
|
||||
return WritableAccountRoot(id, view, std::make_shared<SLE>(keylet::account(id)));
|
||||
}
|
||||
|
||||
private:
|
||||
// This is a private constructor only used by `makeNew`
|
||||
WritableAccountRoot(AccountID const& id, ApplyView& view, std::shared_ptr<SLE> sle)
|
||||
: AccountRoot(id, view), WritableSLE(std::move(sle), view)
|
||||
{
|
||||
insert();
|
||||
}
|
||||
|
||||
public:
|
||||
// Resolve ambiguity: use writable operator-> for non-const, read-only for const
|
||||
using WritableSLE::operator->;
|
||||
using AccountRoot::operator->;
|
||||
using WritableSLE::operator*;
|
||||
using AccountRoot::operator*;
|
||||
// --- Write-only domain methods (compile-time gated) ---
|
||||
|
||||
/** Adjust the owner count up or down. */
|
||||
void
|
||||
adjustOwnerCount(std::int32_t amount, beast::Journal j);
|
||||
adjustOwnerCount(std::int32_t amount, beast::Journal j)
|
||||
requires is_writable;
|
||||
|
||||
private:
|
||||
// Private constructor only used by `makeNew`
|
||||
AccountRoot(AccountID const& id, ApplyView& view, std::shared_ptr<SLE> sle)
|
||||
requires is_writable
|
||||
: SLEBase<ViewT>(std::move(sle), view), id_(id)
|
||||
{
|
||||
this->insert();
|
||||
}
|
||||
};
|
||||
|
||||
// CTAD deduction guide — bare AccountRoot(id, view) always deduces read-only.
|
||||
// For writable access, use WritableAccountRoot(id, applyView) explicitly.
|
||||
AccountRoot(AccountID const&, ReadView const&) -> AccountRoot<ReadView>;
|
||||
|
||||
// Backward-compatible aliases
|
||||
using ReadOnlyAccountRoot = AccountRoot<ReadView>;
|
||||
using WritableAccountRoot = AccountRoot<ApplyView>;
|
||||
|
||||
// Explicit instantiation declarations (definitions in .cpp)
|
||||
extern template class AccountRoot<ReadView>;
|
||||
extern template class AccountRoot<ApplyView>;
|
||||
|
||||
/** Generate a pseudo-account address from a pseudo owner key.
|
||||
@param pseudoOwnerKey The key to generate the address from
|
||||
@return The generated account ID
|
||||
@@ -177,7 +194,7 @@ isPseudoAccount(
|
||||
AccountID const& accountId,
|
||||
std::set<SField const*> const& pseudoFieldFilter = {})
|
||||
{
|
||||
AccountRoot const acct(accountId, view);
|
||||
AccountRoot<ReadView> const acct(accountId, view);
|
||||
if (!acct)
|
||||
return false;
|
||||
return acct.isPseudoAccount(pseudoFieldFilter);
|
||||
|
||||
@@ -74,7 +74,7 @@ verifyDepositPreauth(
|
||||
STTx const& tx,
|
||||
ApplyView& view,
|
||||
AccountID const& src,
|
||||
AccountRoot const& dst,
|
||||
ReadOnlyAccountRoot const& dst,
|
||||
beast::Journal j);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -4,33 +4,53 @@
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Concept to distinguish read-only vs writable view types
|
||||
template <typename V>
|
||||
concept WritableView = std::derived_from<V, ApplyView>;
|
||||
|
||||
/**
|
||||
* Read-only base class for all ledger entry view classes.
|
||||
* View-parameterized base class for all ledger entry wrappers.
|
||||
*
|
||||
* Provides common functionality for existence checking and raw SLE read access.
|
||||
* Supports read-only (ReadView) contexts.
|
||||
* SLEBase<ReadView> — read-only: holds shared_ptr<SLE const> + ReadView const&
|
||||
* SLEBase<ApplyView> — writable: holds shared_ptr<SLE> + ApplyView& + Keylet,
|
||||
* plus insert/update/erase operations
|
||||
*
|
||||
* Write-only members are gated by `requires` clauses, providing compile-time
|
||||
* guarantees that read-only wrappers cannot mutate state.
|
||||
*
|
||||
* Derived classes should provide domain-specific accessors that hide
|
||||
* implementation details of the underlying ledger entry format.
|
||||
*/
|
||||
class ReadOnlySLE
|
||||
template <typename ViewT>
|
||||
class SLEBase
|
||||
{
|
||||
public:
|
||||
virtual ~ReadOnlySLE() = default;
|
||||
static constexpr bool is_writable = WritableView<ViewT>;
|
||||
|
||||
// Copy/move constructors are fine (reference can be initialized from another)
|
||||
ReadOnlySLE(ReadOnlySLE const&) = default;
|
||||
ReadOnlySLE(ReadOnlySLE&&) = default;
|
||||
// Assignment operators are deleted (cannot rebind reference members)
|
||||
ReadOnlySLE&
|
||||
operator=(ReadOnlySLE const&) = delete;
|
||||
ReadOnlySLE&
|
||||
operator=(ReadOnlySLE&&) = delete;
|
||||
// SLE pointer type: mutable for writable views, const for read-only
|
||||
using sle_ptr_type =
|
||||
std::conditional_t<is_writable, std::shared_ptr<SLE>, std::shared_ptr<SLE const>>;
|
||||
|
||||
// View reference type: ApplyView& for writable, ReadView const& for read-only
|
||||
using view_ref_type = std::conditional_t<is_writable, ApplyView&, ReadView const&>;
|
||||
|
||||
virtual ~SLEBase() = default;
|
||||
|
||||
SLEBase(SLEBase const&) = default;
|
||||
SLEBase(SLEBase&&) = default;
|
||||
SLEBase&
|
||||
operator=(SLEBase const&) = delete;
|
||||
SLEBase&
|
||||
operator=(SLEBase&&) = delete;
|
||||
|
||||
// --- Common interface (always available) ---
|
||||
|
||||
/** Returns true if the ledger entry exists */
|
||||
bool
|
||||
@@ -46,155 +66,163 @@ public:
|
||||
return exists();
|
||||
}
|
||||
|
||||
/** Returns the underlying SLE for read access (always available) */
|
||||
std::shared_ptr<SLE const> const&
|
||||
/** Returns the underlying SLE for read access */
|
||||
std::shared_ptr<SLE const>
|
||||
sle() const
|
||||
{
|
||||
return sle_;
|
||||
}
|
||||
|
||||
/** Returns the read view (always available) */
|
||||
/** Returns the read view (always available; ApplyView inherits ReadView) */
|
||||
ReadView const&
|
||||
readView() const
|
||||
{
|
||||
return readView_;
|
||||
return view_;
|
||||
}
|
||||
|
||||
/** Const dereference operators (always available) */
|
||||
STLedgerEntry const*
|
||||
operator->() const
|
||||
{
|
||||
XRPL_ASSERT(exists(), "xrpl::ReadOnlySLE::operator-> : exists");
|
||||
XRPL_ASSERT(exists(), "xrpl::SLEBase::operator-> : exists");
|
||||
return sle_.get();
|
||||
}
|
||||
|
||||
STLedgerEntry const&
|
||||
operator*() const
|
||||
{
|
||||
XRPL_ASSERT(exists(), "xrpl::ReadOnlySLE::operator* : exists");
|
||||
XRPL_ASSERT(exists(), "xrpl::SLEBase::operator* : exists");
|
||||
return *sle_;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Default constructor is deleted (cannot leave reference uninitialized)
|
||||
ReadOnlySLE() = delete;
|
||||
|
||||
/** Constructor for read-only context (ReadView) */
|
||||
explicit ReadOnlySLE(std::shared_ptr<SLE const> sle, ReadView const& view)
|
||||
: sle_(std::move(sle)), readView_(view)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<SLE const> sle_; // Always valid (const view)
|
||||
ReadView const& readView_; // Always valid
|
||||
};
|
||||
|
||||
/**
|
||||
* Writable base class for all ledger entry view classes.
|
||||
*
|
||||
* Extends ReadOnlySLE with write access capabilities.
|
||||
* Supports read-write (ApplyView) contexts.
|
||||
*
|
||||
* Derived classes should provide domain-specific accessors that hide
|
||||
* implementation details of the underlying ledger entry format.
|
||||
*/
|
||||
class WritableSLE
|
||||
{
|
||||
public:
|
||||
virtual ~WritableSLE() = default;
|
||||
|
||||
// Copy/move constructors are fine (reference can be initialized from another)
|
||||
WritableSLE(WritableSLE const&) = default;
|
||||
WritableSLE(WritableSLE&&) = default;
|
||||
// Assignment operators are deleted (cannot rebind reference members)
|
||||
WritableSLE&
|
||||
operator=(WritableSLE const&) = delete;
|
||||
WritableSLE&
|
||||
operator=(WritableSLE&&) = delete;
|
||||
// --- Writable interface (compile-time gated) ---
|
||||
|
||||
/** Returns a mutable SLE for write operations */
|
||||
std::shared_ptr<SLE> const&
|
||||
sle_ptr_type const&
|
||||
mutableSle() const
|
||||
requires is_writable
|
||||
{
|
||||
return mutableSle_;
|
||||
return sle_;
|
||||
}
|
||||
|
||||
/** Returns true if this wrapper supports write operations */
|
||||
bool
|
||||
canModify() const
|
||||
requires is_writable
|
||||
{
|
||||
return mutableSle_ != nullptr;
|
||||
return sle_ != nullptr;
|
||||
}
|
||||
|
||||
/** Returns the apply view for write operations */
|
||||
ApplyView&
|
||||
applyView() const
|
||||
requires is_writable
|
||||
{
|
||||
return applyView_;
|
||||
return view_;
|
||||
}
|
||||
|
||||
/** Mutable dereference operators */
|
||||
STLedgerEntry*
|
||||
operator->()
|
||||
requires is_writable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::operator-> : can modify");
|
||||
return mutableSle_.get();
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::operator-> : can modify");
|
||||
return sle_.get();
|
||||
}
|
||||
|
||||
STLedgerEntry&
|
||||
operator*()
|
||||
requires is_writable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::operator* : can modify");
|
||||
return *mutableSle_;
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::operator* : can modify");
|
||||
return *sle_;
|
||||
}
|
||||
|
||||
void
|
||||
insert()
|
||||
requires is_writable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::insert : can modify");
|
||||
applyView_.insert(mutableSle_);
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::insert : can modify");
|
||||
view_.insert(sle_);
|
||||
}
|
||||
|
||||
void
|
||||
erase()
|
||||
requires is_writable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::erase : can modify");
|
||||
applyView_.erase(mutableSle_);
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::erase : can modify");
|
||||
view_.erase(sle_);
|
||||
}
|
||||
|
||||
void
|
||||
update()
|
||||
requires is_writable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::update : can modify");
|
||||
applyView_.update(mutableSle_);
|
||||
XRPL_ASSERT(canModify(), "xrpl::SLEBase::update : can modify");
|
||||
view_.update(sle_);
|
||||
}
|
||||
|
||||
void
|
||||
newSLE()
|
||||
requires is_writable
|
||||
{
|
||||
XRPL_ASSERT(!canModify(), "xrpl::WritableSLE::newSLE : mutableSle_ is not null");
|
||||
mutableSle_ = std::make_shared<SLE>(key_);
|
||||
XRPL_ASSERT(!canModify(), "xrpl::SLEBase::newSLE : sle_ is not null");
|
||||
sle_ = std::make_shared<SLE>(key_);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Default constructor is deleted (cannot leave reference uninitialized)
|
||||
WritableSLE() = delete;
|
||||
SLEBase() = delete;
|
||||
|
||||
/** Constructor for read-write context (ApplyView) */
|
||||
explicit WritableSLE(std::shared_ptr<SLE> sle, ApplyView& view)
|
||||
: applyView_(view)
|
||||
/** Constructor for read-only context */
|
||||
explicit SLEBase(std::shared_ptr<SLE const> sle, ReadView const& view)
|
||||
requires(!is_writable)
|
||||
: view_(view), sle_(std::move(sle))
|
||||
{
|
||||
}
|
||||
|
||||
/** Converting constructor: writable → read-only.
|
||||
* Enables implicit conversion from SLEBase<ApplyView> to
|
||||
* SLEBase<ReadView>, so functions taking ReadOnlySLE const& can
|
||||
* accept WritableSLE.
|
||||
*/
|
||||
template <WritableView OtherViewT>
|
||||
SLEBase(SLEBase<OtherViewT> const& other)
|
||||
requires(!is_writable)
|
||||
: view_(other.readView()), sle_(other.sle())
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for writable context (from existing SLE) */
|
||||
explicit SLEBase(std::shared_ptr<SLE> sle, ApplyView& view)
|
||||
requires is_writable
|
||||
: view_(view)
|
||||
, key_(sle ? Keylet(sle->getType(), sle->key()) : Keylet(ltANY, uint256{}))
|
||||
, mutableSle_(std::move(sle))
|
||||
, sle_(std::move(sle))
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for read-write context (ApplyView) */
|
||||
explicit WritableSLE(Keylet const& key, ApplyView& view)
|
||||
: applyView_(view), key_(key), mutableSle_(applyView_.peek(key))
|
||||
/** Constructor for writable context (peek from view by keylet) */
|
||||
explicit SLEBase(Keylet const& key, ApplyView& view)
|
||||
requires is_writable
|
||||
: view_(view), key_(key), sle_(view_.peek(key))
|
||||
{
|
||||
}
|
||||
|
||||
ApplyView& applyView_; // ApplyView for write contexts (first for init order)
|
||||
Keylet const key_;
|
||||
std::shared_ptr<SLE> mutableSle_; // Mutable SLE for write contexts
|
||||
view_ref_type view_;
|
||||
|
||||
// Keylet is only meaningful for writable views, but we conditionally
|
||||
// include it to avoid wasting space in read-only wrappers.
|
||||
struct Empty
|
||||
{
|
||||
};
|
||||
[[no_unique_address]]
|
||||
std::conditional_t<is_writable, Keylet, Empty> key_{};
|
||||
|
||||
sle_ptr_type sle_;
|
||||
};
|
||||
|
||||
// Backward-compatible aliases
|
||||
using ReadOnlySLE = SLEBase<ReadView>;
|
||||
using WritableSLE = SLEBase<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -357,7 +357,7 @@ canWithdraw(
|
||||
ReadView const& view,
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
AccountRoot const& toWrapped,
|
||||
ReadOnlyAccountRoot const& toWrapped,
|
||||
STAmount const& amount,
|
||||
bool hasDestinationTag)
|
||||
{
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename ViewT>
|
||||
bool
|
||||
AccountRoot::isGlobalFrozen() const
|
||||
AccountRoot<ViewT>::isGlobalFrozen() const
|
||||
{
|
||||
if (!exists())
|
||||
if (!this->exists())
|
||||
return false;
|
||||
return sle_->isFlag(lsfGlobalFreeze);
|
||||
return this->sle_->isFlag(lsfGlobalFreeze);
|
||||
}
|
||||
|
||||
// An owner count cannot be negative. If adjustment would cause a negative
|
||||
@@ -61,23 +62,24 @@ confineOwnerCount(
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
XRPAmount
|
||||
AccountRoot::xrpLiquid(std::int32_t ownerCountAdj, beast::Journal j) const
|
||||
AccountRoot<ViewT>::xrpLiquid(std::int32_t ownerCountAdj, beast::Journal j) const
|
||||
{
|
||||
if (!exists())
|
||||
if (!this->exists())
|
||||
return beast::zero;
|
||||
|
||||
// Return balance minus reserve
|
||||
std::uint32_t const ownerCount = confineOwnerCount(
|
||||
readView_.ownerCountHook(id_, sle_->getFieldU32(sfOwnerCount)), ownerCountAdj);
|
||||
this->readView().ownerCountHook(id_, this->sle_->getFieldU32(sfOwnerCount)), ownerCountAdj);
|
||||
|
||||
// Pseudo-accounts have no reserve requirement
|
||||
auto const reserve =
|
||||
isPseudoAccount() ? XRPAmount{0} : readView_.fees().accountReserve(ownerCount);
|
||||
this->isPseudoAccount() ? XRPAmount{0} : this->readView().fees().accountReserve(ownerCount);
|
||||
|
||||
auto const fullBalance = sle_->getFieldAmount(sfBalance);
|
||||
auto const fullBalance = this->sle_->getFieldAmount(sfBalance);
|
||||
|
||||
auto const balance = readView_.balanceHook(id_, xrpAccount(), fullBalance);
|
||||
auto const balance = this->readView().balanceHook(id_, xrpAccount(), fullBalance);
|
||||
|
||||
STAmount const amount = (balance < reserve) ? STAmount{0} : balance - reserve;
|
||||
|
||||
@@ -90,26 +92,29 @@ AccountRoot::xrpLiquid(std::int32_t ownerCountAdj, beast::Journal j) const
|
||||
return amount.xrp();
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
Rate
|
||||
AccountRoot::transferRate() const
|
||||
AccountRoot<ViewT>::transferRate() const
|
||||
{
|
||||
if (sle_ && sle_->isFieldPresent(sfTransferRate))
|
||||
return Rate{sle_->getFieldU32(sfTransferRate)};
|
||||
if (this->sle_ && this->sle_->isFieldPresent(sfTransferRate))
|
||||
return Rate{this->sle_->getFieldU32(sfTransferRate)};
|
||||
|
||||
return parityRate;
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
void
|
||||
WritableAccountRoot::adjustOwnerCount(std::int32_t amount, beast::Journal j)
|
||||
AccountRoot<ViewT>::adjustOwnerCount(std::int32_t amount, beast::Journal j)
|
||||
requires is_writable
|
||||
{
|
||||
XRPL_ASSERT(canModify(), "xrpl::adjustOwnerCount : can modify");
|
||||
XRPL_ASSERT(this->canModify(), "xrpl::adjustOwnerCount : can modify");
|
||||
XRPL_ASSERT(amount, "xrpl::adjustOwnerCount : nonzero amount input");
|
||||
std::uint32_t const current{mutableSle_->getFieldU32(sfOwnerCount)};
|
||||
AccountID const id = (*mutableSle_)[sfAccount];
|
||||
std::uint32_t const current{this->sle_->getFieldU32(sfOwnerCount)};
|
||||
AccountID const id = (*this->sle_)[sfAccount];
|
||||
std::uint32_t const adjusted = confineOwnerCount(current, amount, id, j);
|
||||
applyView_.adjustOwnerCountHook(id_, current, adjusted);
|
||||
mutableSle_->at(sfOwnerCount) = adjusted;
|
||||
update();
|
||||
this->applyView().adjustOwnerCountHook(id_, current, adjusted);
|
||||
this->sle_->at(sfOwnerCount) = adjusted;
|
||||
this->update();
|
||||
}
|
||||
|
||||
AccountID
|
||||
@@ -161,17 +166,18 @@ getPseudoAccountFields()
|
||||
return pseudoFields;
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
[[nodiscard]] bool
|
||||
AccountRoot::isPseudoAccount(std::set<SField const*> const& pseudoFieldFilter) const
|
||||
AccountRoot<ViewT>::isPseudoAccount(std::set<SField const*> const& pseudoFieldFilter) const
|
||||
{
|
||||
auto const& fields = getPseudoAccountFields();
|
||||
|
||||
// Intentionally use defensive coding here because it's cheap and makes the
|
||||
// semantics of true return value clean.
|
||||
return sle_ && sle_->getType() == ltACCOUNT_ROOT &&
|
||||
return this->sle_ && this->sle_->getType() == ltACCOUNT_ROOT &&
|
||||
std::count_if(
|
||||
fields.begin(), fields.end(), [this, &pseudoFieldFilter](SField const* sf) -> bool {
|
||||
return sle_->isFieldPresent(*sf) &&
|
||||
return this->sle_->isFieldPresent(*sf) &&
|
||||
(pseudoFieldFilter.empty() || pseudoFieldFilter.contains(sf));
|
||||
}) > 0;
|
||||
}
|
||||
@@ -235,18 +241,23 @@ createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const
|
||||
return account;
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
[[nodiscard]] TER
|
||||
AccountRoot::checkDestinationAndTag(bool hasDestinationTag) const
|
||||
AccountRoot<ViewT>::checkDestinationAndTag(bool hasDestinationTag) const
|
||||
{
|
||||
if (sle_ == nullptr)
|
||||
if (this->sle_ == nullptr)
|
||||
return tecNO_DST;
|
||||
|
||||
// The tag is basically account-specific information we don't
|
||||
// understand, but we can require someone to fill it in.
|
||||
if (sle_->isFlag(lsfRequireDestTag) && !hasDestinationTag)
|
||||
if (this->sle_->isFlag(lsfRequireDestTag) && !hasDestinationTag)
|
||||
return tecDST_TAG_NEEDED; // Cannot send without a tag
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// Explicit template instantiations
|
||||
template class AccountRoot<ReadView>;
|
||||
template class AccountRoot<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -321,7 +321,7 @@ verifyDepositPreauth(
|
||||
STTx const& tx,
|
||||
ApplyView& view,
|
||||
AccountID const& src,
|
||||
AccountRoot const& dst,
|
||||
ReadOnlyAccountRoot const& dst,
|
||||
beast::Journal j)
|
||||
{
|
||||
// If depositPreauth is enabled, then an account that requires
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static error_code_i
|
||||
acctMatchesPubKey(AccountRoot const& account, PublicKey const& publicKey)
|
||||
acctMatchesPubKey(ReadOnlyAccountRoot const& account, PublicKey const& publicKey)
|
||||
{
|
||||
auto const publicKeyAcctID = calcAccountID(publicKey);
|
||||
bool const isMasterKey = publicKeyAcctID == account.id();
|
||||
@@ -457,7 +457,7 @@ transactionPreProcessImpl(
|
||||
if (!verify && !tx_json.isMember(jss::Sequence))
|
||||
return RPC::missing_field_error("tx_json.Sequence");
|
||||
|
||||
std::optional<AccountRoot> acctSrc;
|
||||
std::optional<ReadOnlyAccountRoot> acctSrc;
|
||||
if (verify)
|
||||
acctSrc.emplace(srcAddressID, *app.openLedger().current());
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace xrpl {
|
||||
* If the entry is not an account root, sets the 'Invalid' field to true.
|
||||
*/
|
||||
void
|
||||
injectSLE(Json::Value& jv, AccountRoot const& account)
|
||||
injectSLE(Json::Value& jv, ReadOnlyAccountRoot const& account)
|
||||
{
|
||||
jv = account->getJson(JsonOptions::none);
|
||||
if (account->isFieldPresent(sfEmailHash))
|
||||
|
||||
Reference in New Issue
Block a user