This commit is contained in:
Mayukha Vadari
2026-03-23 09:59:13 -07:00
parent 8a1adc4ec9
commit 8e218a6285
6 changed files with 18 additions and 223 deletions

View File

@@ -1,200 +0,0 @@
#pragma once
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <memory>
#include <stdexcept>
namespace xrpl {
/**
* Read-only base class for all ledger entry view classes.
*
* Provides common functionality for existence checking and raw SLE read access.
* Supports read-only (ReadView) contexts.
*
* Derived classes should provide domain-specific accessors that hide
* implementation details of the underlying ledger entry format.
*/
class ReadOnlySLE
{
public:
virtual ~ReadOnlySLE() = default;
// 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;
/** Returns true if the ledger entry exists */
bool
exists() const
{
return sle_ != nullptr;
}
/** Explicit conversion to bool for convenient existence checking */
explicit
operator bool() const
{
return exists();
}
/** Returns the underlying SLE for read access (always available) */
std::shared_ptr<SLE const> const&
sle() const
{
return sle_;
}
/** Returns the read view (always available) */
ReadView const&
readView() const
{
return readView_;
}
STLedgerEntry const*
operator->() const
{
XRPL_ASSERT(exists(), "xrpl::ReadOnlySLE::operator-> : exists");
return sle_.get();
}
STLedgerEntry const&
operator*() const
{
XRPL_ASSERT(exists(), "xrpl::ReadOnlySLE::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;
/** Returns a mutable SLE for write operations */
std::shared_ptr<SLE> const&
mutableSle() const
{
return mutableSle_;
}
/** Returns true if this wrapper supports write operations */
bool
canModify() const
{
return mutableSle_ != nullptr;
}
/** Returns the apply view for write operations */
ApplyView&
applyView() const
{
return applyView_;
}
STLedgerEntry*
operator->()
{
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::operator-> : can modify");
return mutableSle_.get();
}
STLedgerEntry&
operator*()
{
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::operator* : can modify");
return *mutableSle_;
}
void
insert()
{
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::insert : can modify");
applyView_.insert(mutableSle_);
}
void
erase()
{
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::erase : can modify");
applyView_.erase(mutableSle_);
}
void
update()
{
XRPL_ASSERT(canModify(), "xrpl::WritableSLE::update : can modify");
applyView_.update(mutableSle_);
}
void
newSLE()
{
XRPL_ASSERT(!canModify(), "xrpl::WritableSLE::newSLE : mutableSle_ is not null");
mutableSle_ = std::make_shared<SLE>(key_);
}
protected:
// Default constructor is deleted (cannot leave reference uninitialized)
WritableSLE() = delete;
/** Constructor for read-write context (ApplyView) */
explicit WritableSLE(std::shared_ptr<SLE> sle, ApplyView& view)
: applyView_(view)
, key_(sle ? Keylet(sle->getType(), sle->key()) : Keylet(ltANY, uint256{}))
, mutableSle_(std::move(sle))
{
}
/** Constructor for read-write context (ApplyView) */
explicit WritableSLE(Keylet const& key, ApplyView& view)
: applyView_(view), key_(key), mutableSle_(applyView_.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
};
} // namespace xrpl

View File

@@ -330,11 +330,10 @@ SignerListSet::destroySignerList()
{
// Destroying the signer list is only allowed if either the master key
// is enabled or there is a regular key.
WritableAccountRoot wrappedAcct(accountID_, view());
if (!wrappedAcct)
if (!account_)
return tefINTERNAL; // LCOV_EXCL_LINE
if ((wrappedAcct->isFlag(lsfDisableMaster)) && (!wrappedAcct->isFieldPresent(sfRegularKey)))
if ((account_->isFlag(lsfDisableMaster)) && (!account_->isFieldPresent(sfRegularKey)))
return tecNO_ALTERNATIVE_KEY;
return removeSignersFromLedger(ctx_.registry, view(), accountID_, j_);

View File

@@ -132,8 +132,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx)
TER
CheckCreate::doApply()
{
WritableAccountRoot wrappedAcct(accountID_, view());
if (!wrappedAcct)
if (!account_)
return tefINTERNAL; // LCOV_EXCL_LINE
// A check counts against the reserve of the issuing account, but we
@@ -141,7 +140,7 @@ CheckCreate::doApply()
// reserve to pay fees.
{
STAmount const reserve{
view().fees().accountReserve(wrappedAcct->getFieldU32(sfOwnerCount) + 1)};
view().fees().accountReserve(account_->getFieldU32(sfOwnerCount) + 1)};
if (preFeeBalance_ < reserve)
return tecINSUFFICIENT_RESERVE;
@@ -199,7 +198,7 @@ CheckCreate::doApply()
sleCheck->setFieldU64(sfOwnerNode, *page);
}
// If we succeeded, the new entry counts against the creator's reserve.
wrappedAcct.adjustOwnerCount(1, viewJ);
account_.adjustOwnerCount(1, viewJ);
return tesSUCCESS;
}

View File

@@ -456,7 +456,6 @@ AMMDeposit::deposit(
{
// Check account has sufficient funds.
// Return true if it does, false otherwise.
WritableAccountRoot wrappedAcct(accountID_, view);
auto checkBalance = [&](auto const& depositAmount) -> TER {
if (depositAmount <= beast::zero)
return temBAD_AMOUNT;
@@ -465,7 +464,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(accountID_, lpIssue.account, lpIssue.currency));
if (wrappedAcct.xrpLiquid(!sle, j_) >= depositAmount)
if (account_.xrpLiquid(!sle, j_) >= depositAmount)
return tesSUCCESS;
}
else if (

View File

@@ -386,16 +386,15 @@ EscrowCreate::doApply()
if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter]))
return tecNO_PERMISSION;
WritableAccountRoot wrappedAcct(accountID_, ctx_.view());
if (!wrappedAcct)
if (!account_)
return tefINTERNAL; // LCOV_EXCL_LINE
// Check reserve and funds availability
STAmount const amount{ctx_.tx[sfAmount]};
auto const reserve = ctx_.view().fees().accountReserve((*wrappedAcct)[sfOwnerCount] + 1);
auto const reserve = ctx_.view().fees().accountReserve((*account_)[sfOwnerCount] + 1);
auto const balance = wrappedAcct->getFieldAmount(sfBalance).xrp();
auto const balance = account_->getFieldAmount(sfBalance).xrp();
if (balance < reserve)
return tecINSUFFICIENT_RESERVE;
@@ -478,7 +477,7 @@ EscrowCreate::doApply()
// Deduct owner's balance
if (isXRP(amount))
{
(*wrappedAcct)[sfBalance] = (*wrappedAcct)[sfBalance] - amount;
(*account_)[sfBalance] = (*account_)[sfBalance] - amount;
}
else
{
@@ -494,8 +493,8 @@ EscrowCreate::doApply()
}
// increment owner count
wrappedAcct.adjustOwnerCount(1, ctx_.journal);
wrappedAcct.update();
account_.adjustOwnerCount(1, ctx_.journal);
account_.update();
return tesSUCCESS;
}

View File

@@ -323,11 +323,10 @@ TrustSet::doApply()
// true, if current is high account.
bool const bHigh = accountID_ > uDstAccountID;
WritableAccountRoot wrappedAccount(accountID_, view());
if (!wrappedAccount)
if (!account_)
return tefINTERNAL; // LCOV_EXCL_LINE
std::uint32_t const uOwnerCount = wrappedAccount->getFieldU32(sfOwnerCount);
std::uint32_t const uOwnerCount = account_->getFieldU32(sfOwnerCount);
// The reserve that is required to create the line. Note
// that although the reserve increases with every item
@@ -393,8 +392,8 @@ TrustSet::doApply()
std::uint32_t uHighQualityOut = 0;
auto const& uLowAccountID = !bHigh ? accountID_ : uDstAccountID;
auto const& uHighAccountID = bHigh ? accountID_ : uDstAccountID;
auto lowAcct = !bHigh ? wrappedAccount : wrappedDst;
auto highAcct = bHigh ? wrappedAccount : wrappedDst;
auto lowAcct = !bHigh ? account_ : wrappedDst;
auto highAcct = bHigh ? account_ : wrappedDst;
//
// Balances
@@ -499,7 +498,7 @@ TrustSet::doApply()
}
// Have to use lsfNoFreeze to maintain pre-deep freeze behavior
bool const bNoFreeze = wrappedAccount->isFlag(lsfNoFreeze);
bool const bNoFreeze = account_->isFlag(lsfNoFreeze);
uFlagsOut = computeFreezeFlags(
uFlagsOut,
bHigh,
@@ -638,7 +637,7 @@ TrustSet::doApply()
accountID_,
uDstAccountID,
k.key,
wrappedAccount,
account_,
bSetAuth,
bSetNoRipple && !bClearNoRipple,
bSetFreeze && !bClearFreeze,