mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-21 19:18:22 +00:00
Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16389dcb2e | ||
|
|
97a780b29f | ||
|
|
654edc9a08 | ||
|
|
658d04f694 | ||
|
|
93498952b1 | ||
|
|
269f79e568 | ||
|
|
e7a8e0336a | ||
|
|
1d7e40777a | ||
|
|
7bb43a243b | ||
|
|
d697b7843c | ||
|
|
2de5140f20 | ||
|
|
edf085a697 | ||
|
|
c35ac1339b | ||
|
|
dc1cfbc474 | ||
|
|
3044073401 |
No files matched your search
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
@@ -211,7 +212,7 @@ canWithdraw(
|
||||
ReadView const& view,
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
SLE::ConstRef toSle,
|
||||
AccountRootEntryR const& toSle,
|
||||
STAmount const& amount,
|
||||
bool hasDestinationTag,
|
||||
std::optional<std::vector<UInt256>> const& credentialIDs = std::nullopt);
|
||||
|
||||
@@ -7,9 +7,20 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
struct Adjustment
|
||||
{
|
||||
std::int32_t ownerCountDelta = 0;
|
||||
std::int32_t accountCountDelta = 0;
|
||||
};
|
||||
|
||||
template <typename ViewT>
|
||||
class AccountRootEntry : public SLEBase<ViewT, ltACCOUNT_ROOT>
|
||||
{
|
||||
@@ -27,6 +38,123 @@ public:
|
||||
: Base(keylet::account(id), view, j)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the account reserve, in drops.
|
||||
*
|
||||
* Actual owner count can be adjusted by delta in ownerCountAdj
|
||||
* Actual reserve count can be adjusted by delta in accountCountAdj
|
||||
* The reserve is calculated as:
|
||||
* (ownerCount + "sponsoring object count" - "sponsored object count" + additionalOwnerCount) *
|
||||
* increment + (1 if not sponsored account + sponsoringAccountCount) * "reserve base"
|
||||
*
|
||||
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative
|
||||
* to subtract.
|
||||
* @return The account reserve amount in drops
|
||||
*/
|
||||
[[nodiscard]] XRPAmount
|
||||
reserve(Adjustment adj = {}) const;
|
||||
|
||||
/**
|
||||
* Return number of the objects which reserve is covered by the account (so called "owner
|
||||
* count"). Actual owner count can be adjusted by delta in ownerCountAdj.
|
||||
*
|
||||
* @param ownerCountAdj Adjustment to the owner count (default: 0)
|
||||
* @return The adjusted owner count
|
||||
*/
|
||||
[[nodiscard]] std::uint32_t
|
||||
ownerCount(std::int32_t ownerCountAdj = 0) const;
|
||||
|
||||
/**
|
||||
* Check if this account has sufficient reserve.
|
||||
*
|
||||
* @param ctx The apply-view context (view + tx)
|
||||
* @param accBalance The account's balance
|
||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative
|
||||
* to subtract.
|
||||
* @param insufReserveCode The transaction result code to return if the reserve is
|
||||
* insufficient (default: tecINSUFFICIENT_RESERVE).
|
||||
* @return Transaction result code
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkReserve(
|
||||
ApplyViewContext ctx,
|
||||
XRPAmount accBalance,
|
||||
std::optional<AccountRootEntry<ReadView>> const& sponsorSle,
|
||||
Adjustment adj,
|
||||
TER insufReserveCode = tecINSUFFICIENT_RESERVE) const;
|
||||
|
||||
/**
|
||||
* Check if this account has sufficient reserve, deriving the sponsor internally.
|
||||
*
|
||||
* Equivalent to the overload above, but resolves the sponsor via
|
||||
* getEffectiveTxReserveSponsor(ctx, *this) instead of taking it explicitly. Use this
|
||||
* in the common case where the sponsor is simply the transaction's reserve
|
||||
* sponsor for this account. Callers that must force the account's-own-reserve branch
|
||||
* (passing a null sponsor) or supply a different sponsor should use the
|
||||
* explicit overload above.
|
||||
*
|
||||
* @param ctx The apply-view context (view + tx)
|
||||
* @param accBalance The account's balance
|
||||
* @param adj Reserve adjustments (owner/account count deltas)
|
||||
* @return Transaction result code
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkReserve(ApplyViewContext ctx, XRPAmount accBalance, Adjustment adj) const;
|
||||
|
||||
/**
|
||||
* Increase owner-count fields when the caller supplies the sponsor.
|
||||
*
|
||||
* This helper does not create a ledger object. It updates reserve accounting
|
||||
* after the caller has created/updated an object.
|
||||
* If sponsorSle is provided, this also adjusts the account's sponsored count
|
||||
* and the sponsor's sponsoring count.
|
||||
*
|
||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||
* @param count Amount to add to the owner count
|
||||
*/
|
||||
void
|
||||
increaseOwnerCount(std::optional<AccountRootEntry<ApplyView>>& sponsorSle, std::uint32_t count)
|
||||
requires Base::kIsWritable;
|
||||
|
||||
/**
|
||||
* Increase owner-count fields, deriving the tx reserve sponsor internally.
|
||||
*
|
||||
* Equivalent to the overload above, but resolves the sponsor via
|
||||
* getEffectiveTxReserveSponsor(ctx, *this) instead of taking it explicitly. Use
|
||||
* this when the sponsor is the transaction's reserve sponsor for this account
|
||||
* (the common create path). Deletion paths, which derive the sponsor from an
|
||||
* object's sfSponsor field, should keep using the explicit overload.
|
||||
*
|
||||
* @param ctx The apply-view context (view + tx)
|
||||
* @param count Amount to add to the owner count
|
||||
*/
|
||||
void
|
||||
increaseOwnerCount(ApplyViewContext ctx, std::uint32_t count)
|
||||
requires Base::kIsWritable;
|
||||
|
||||
/**
|
||||
* Decrease owner-count fields when the caller supplies the sponsor.
|
||||
*
|
||||
* This helper does not delete a ledger object. It updates reserve accounting
|
||||
* after the caller has removed an owner-counted reserve, or for special
|
||||
* owner-count changes whose sponsor cannot be derived from an object's
|
||||
* sfSponsor field.
|
||||
*
|
||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||
* @param count Amount to remove from the owner count
|
||||
*/
|
||||
void
|
||||
decreaseOwnerCount(std::optional<AccountRootEntry<ApplyView>>& sponsorSle, std::uint32_t count)
|
||||
requires Base::kIsWritable;
|
||||
|
||||
private:
|
||||
void
|
||||
adjustOwnerCountSigned(
|
||||
std::optional<AccountRootEntry<ApplyView>>& sponsorSle,
|
||||
std::int32_t adjustment)
|
||||
requires Base::kIsWritable;
|
||||
};
|
||||
|
||||
using AccountRootEntryR = AccountRootEntry<ReadView>;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -46,30 +46,55 @@ isGlobalFrozen(ReadView const& view, AccountID const& issuer);
|
||||
[[nodiscard]] XRPAmount
|
||||
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j);
|
||||
|
||||
struct Adjustment
|
||||
{
|
||||
std::int32_t ownerCountDelta = 0;
|
||||
std::int32_t accountCountDelta = 0;
|
||||
};
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Returns the account reserve, in drops.
|
||||
* 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.
|
||||
*
|
||||
* Actual owner count can be adjusted by delta in ownerCountAdj
|
||||
* Actual reserve count can be adjusted by delta in accountCountAdj
|
||||
* The reserve is calculated as:
|
||||
* (ownerCount + "sponsoring object count" - "sponsored object count" + additionalOwnerCount) *
|
||||
* increment + (1 if not sponsored account + sponsoringAccountCount) * "reserve base"
|
||||
* Shared by AccountRootEntry::ownerCount() and the owner-count helpers.
|
||||
*
|
||||
* @param view The ledger view to read from
|
||||
* @param sle The ledger entry for the account
|
||||
* @param currentOwnerCount The owner count before adjustment
|
||||
* @param ownerCountAdj Positive to add to count, negative to reduce count
|
||||
* @param id The account ID to use for error reporting, or std::nullopt to
|
||||
* skip error reporting
|
||||
* @param j Journal for logging
|
||||
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative to
|
||||
* subtract.
|
||||
* @return The account reserve amount in drops
|
||||
* @return The adjusted owner count
|
||||
*/
|
||||
[[nodiscard]] XRPAmount
|
||||
accountReserve(ReadView const& view, SLE::ConstRef sle, beast::Journal j, Adjustment adj = {});
|
||||
std::uint32_t
|
||||
confineOwnerCount(
|
||||
std::uint32_t currentOwnerCount,
|
||||
std::int32_t ownerCountAdj,
|
||||
std::optional<AccountID> const& id = std::nullopt,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||
|
||||
/**
|
||||
* Clamps and writes an owner-count field of sle, then updates sle in view.
|
||||
*
|
||||
* Shared by AccountRootEntry and adjustLoanBrokerOwnerCount().
|
||||
*
|
||||
* @return The adjusted owner count
|
||||
*/
|
||||
std::uint32_t
|
||||
adjustOwnerCountImpl(
|
||||
ApplyView& view,
|
||||
SLE::Ref sle,
|
||||
SF_UINT32 const& sfield,
|
||||
AccountID const& accID,
|
||||
std::int32_t ownerCountAdj,
|
||||
beast::Journal j);
|
||||
|
||||
/**
|
||||
* Returns the number of account reserves funded by this account: 1 for itself
|
||||
* (0 if sponsored by another account) plus the count of accounts it sponsors.
|
||||
* Shared by AccountRootEntry::reserve() and xrpLiquid().
|
||||
*/
|
||||
std::uint32_t
|
||||
accountCountImpl(AccountRootEntryR const& sle, std::int32_t accountCountAdj, beast::Journal j);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* Convenience overload that accepts AccountID instead of SLE.
|
||||
@@ -84,114 +109,9 @@ accountReserve(ReadView const& view, SLE::ConstRef sle, beast::Journal j, Adjust
|
||||
[[nodiscard]] inline XRPAmount
|
||||
accountReserve(ReadView const& view, AccountID const& id, beast::Journal j, Adjustment adj = {})
|
||||
{
|
||||
return accountReserve(view, view.read(keylet::account(id)), j, adj);
|
||||
return AccountRootEntryR(id, view, j).reserve(adj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an account has sufficient reserve.
|
||||
*
|
||||
* @param view The ledger view to read from
|
||||
* @param tx The transaction being processed
|
||||
* @param accSle The account's ledger entry
|
||||
* @param accBalance The account's balance
|
||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||
* @param adj Adjustment to the owner/account count (default: 0/0). Positive to add, negative to
|
||||
* subtract.
|
||||
* @param j Journal for logging (default: null sink)
|
||||
* @param insufReserveCode The transaction result code to return if the reserve is insufficient
|
||||
* (default: tecINSUFFICIENT_RESERVE).
|
||||
* @return Transaction result code
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkReserve(
|
||||
ApplyViewContext ctx,
|
||||
SLE::ConstRef accSle,
|
||||
XRPAmount accBalance,
|
||||
SLE::ConstRef sponsorSle,
|
||||
Adjustment adj,
|
||||
beast::Journal j,
|
||||
TER insufReserveCode = tecINSUFFICIENT_RESERVE);
|
||||
|
||||
/**
|
||||
* Check if an account has sufficient reserve, deriving the sponsor internally.
|
||||
*
|
||||
* Equivalent to the overload above, but resolves the sponsor via
|
||||
* getEffectiveTxReserveSponsor(ctx, accSle) instead of taking it explicitly. Use this
|
||||
* in the common case where the sponsor is simply the transaction's reserve
|
||||
* sponsor for accSle. Callers that must force the account's-own-reserve branch
|
||||
* (passing a null sponsor) or supply a different sponsor should use the
|
||||
* explicit overload above.
|
||||
*
|
||||
* @param ctx The apply-view context (view + tx)
|
||||
* @param accSle The account's ledger entry
|
||||
* @param accBalance The account's balance
|
||||
* @param adj Reserve adjustments (owner/account count deltas)
|
||||
* @param j Journal for logging (default: null sink)
|
||||
* @return Transaction result code
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkReserve(
|
||||
ApplyViewContext ctx,
|
||||
SLE::ConstRef accSle,
|
||||
XRPAmount accBalance,
|
||||
Adjustment adj,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||
|
||||
/**
|
||||
* Return number of the objects which reserve is covered by the account(sle) (so called "owner
|
||||
* count"). Actual owner count can be adjusted by delta in ownerCountAdj.
|
||||
*
|
||||
* @param sle The account's ledger entry
|
||||
* @param j Journal for logging
|
||||
* @param ownerCountAdj Adjustment to the owner count (default: 0)
|
||||
* @return The adjusted owner count
|
||||
*/
|
||||
std::uint32_t
|
||||
ownerCount(SLE::ConstRef sle, beast::Journal j, std::int32_t ownerCountAdj = 0);
|
||||
|
||||
/**
|
||||
* Increase owner-count fields when the caller supplies the sponsor.
|
||||
*
|
||||
* This helper does not create a ledger object. It updates reserve accounting
|
||||
* after the caller has created/updated an object.
|
||||
* If sponsorSle is provided, this also adjusts the account's sponsored count
|
||||
* and the sponsor's sponsoring count.
|
||||
*
|
||||
* @param view The apply view for making changes
|
||||
* @param accountSle The account's ledger entry
|
||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||
* @param count Amount to add to the owner count
|
||||
* @param j Journal for logging
|
||||
*/
|
||||
void
|
||||
increaseOwnerCount(
|
||||
ApplyView& view,
|
||||
SLE::Ref accountSle,
|
||||
SLE::Ref sponsorSle,
|
||||
std::uint32_t count,
|
||||
beast::Journal j);
|
||||
|
||||
/**
|
||||
* Increase owner-count fields, deriving the tx reserve sponsor internally.
|
||||
*
|
||||
* Equivalent to the overload above, but resolves the sponsor via
|
||||
* getEffectiveTxReserveSponsor(ctx, accountSle) instead of taking it explicitly. Use
|
||||
* this when the sponsor is the transaction's reserve sponsor for accountSle
|
||||
* (the common create path). Deletion paths, which derive the sponsor from an
|
||||
* object's sfSponsor field, should keep using the explicit overload.
|
||||
*
|
||||
* @param ctx The apply-view context (view + tx)
|
||||
* @param accountSle The account's ledger entry
|
||||
* @param count Amount to add to the owner count
|
||||
* @param j Journal for logging
|
||||
*/
|
||||
void
|
||||
increaseOwnerCount(
|
||||
ApplyViewContext ctx,
|
||||
SLE::Ref accountSle,
|
||||
std::uint32_t count,
|
||||
beast::Journal j);
|
||||
|
||||
/**
|
||||
* Convenience overload that accepts AccountID instead of SLE references.
|
||||
*
|
||||
@@ -209,36 +129,13 @@ increaseOwnerCount(
|
||||
std::uint32_t count,
|
||||
beast::Journal j)
|
||||
{
|
||||
increaseOwnerCount(
|
||||
view,
|
||||
view.peek(keylet::account(account)),
|
||||
sponsor ? view.peek(keylet::account(*sponsor)) : SLE::pointer(),
|
||||
count,
|
||||
j);
|
||||
AccountRootEntryW accountSle(account, view, j);
|
||||
std::optional<AccountRootEntryW> sponsorSle;
|
||||
if (sponsor)
|
||||
sponsorSle.emplace(*sponsor, view);
|
||||
accountSle.increaseOwnerCount(sponsorSle, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrease owner-count fields when the caller supplies the sponsor.
|
||||
*
|
||||
* This helper does not delete a ledger object. It updates reserve accounting
|
||||
* after the caller has removed an owner-counted reserve, or for special
|
||||
* owner-count changes whose sponsor cannot be derived from an object's
|
||||
* sfSponsor field.
|
||||
*
|
||||
* @param view The apply view for making changes
|
||||
* @param accountSle The account's ledger entry
|
||||
* @param sponsorSle The sponsor's ledger entry (if applicable)
|
||||
* @param count Amount to remove from the owner count
|
||||
* @param j Journal for logging
|
||||
*/
|
||||
void
|
||||
decreaseOwnerCount(
|
||||
ApplyView& view,
|
||||
SLE::Ref accountSle,
|
||||
SLE::Ref sponsorSle,
|
||||
std::uint32_t count,
|
||||
beast::Journal j);
|
||||
|
||||
/**
|
||||
* Convenience overload that accepts AccountID instead of SLE references.
|
||||
*
|
||||
@@ -256,12 +153,11 @@ decreaseOwnerCount(
|
||||
std::uint32_t count,
|
||||
beast::Journal j)
|
||||
{
|
||||
decreaseOwnerCount(
|
||||
view,
|
||||
view.peek(keylet::account(account)),
|
||||
sponsor ? view.peek(keylet::account(*sponsor)) : SLE::pointer(),
|
||||
count,
|
||||
j);
|
||||
AccountRootEntryW accountSle(account, view, j);
|
||||
std::optional<AccountRootEntryW> sponsorSle;
|
||||
if (sponsor)
|
||||
sponsorSle.emplace(*sponsor, view);
|
||||
accountSle.decreaseOwnerCount(sponsorSle, count);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,7 +177,7 @@ decreaseOwnerCount(
|
||||
void
|
||||
decreaseOwnerCountForObject(
|
||||
ApplyView& view,
|
||||
SLE::Ref accountSle,
|
||||
AccountRootEntryW& accountSle,
|
||||
SLE::Ref objectSle,
|
||||
std::uint32_t count,
|
||||
beast::Journal j);
|
||||
@@ -303,7 +199,7 @@ decreaseOwnerCountForObject(
|
||||
std::uint32_t count,
|
||||
beast::Journal j)
|
||||
{
|
||||
SLE::Ref accountSle = view.peek(keylet::account(account));
|
||||
AccountRootEntryW accountSle(account, view);
|
||||
decreaseOwnerCountForObject(view, accountSle, objectSle, count, j);
|
||||
}
|
||||
|
||||
@@ -367,7 +263,7 @@ getPseudoAccountFields();
|
||||
* - null pointer
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount(SLE::const_pointer sleAcct);
|
||||
isPseudoAccount(AccountRootEntryR const& sleAcct);
|
||||
|
||||
/**
|
||||
* Convenience overload that reads the account from the view.
|
||||
@@ -375,7 +271,7 @@ isPseudoAccount(SLE::const_pointer sleAcct);
|
||||
[[nodiscard]] inline bool
|
||||
isPseudoAccount(ReadView const& view, AccountID const& accountId)
|
||||
{
|
||||
return isPseudoAccount(view.read(keylet::account(accountId)));
|
||||
return isPseudoAccount(AccountRootEntryR(accountId, view));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,6 +292,6 @@ createPseudoAccount(ApplyView& view, UInt256 const& pseudoOwnerKey, SField const
|
||||
* - If the SLE requires a destination tag, checks that there is a tag.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkDestinationAndTag(SLE::ConstRef toSle, bool hasDestinationTag);
|
||||
checkDestinationAndTag(AccountRootEntryR const& toSle, bool hasDestinationTag);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -27,6 +27,32 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Before fixCleanup3_2_0, EscrowCancel passes the escrow SLE as sleDest.
|
||||
* Return what the old reserve check returned for it, without adopting a
|
||||
* non-AccountRoot SLE into an AccountRootEntry: the tx reserve sponsor's
|
||||
* error if the escrow owner submitted the tx, else tefINTERNAL.
|
||||
*
|
||||
* @param ctx the apply view context for the escrow transaction.
|
||||
* @param sleDest the non-AccountRoot SLE that was passed as the destination.
|
||||
* @return the tx reserve sponsor's error code if the escrow owner submitted
|
||||
* the tx, else tefINTERNAL.
|
||||
*/
|
||||
inline TER
|
||||
escrowDestNotAccountResult(ApplyViewContext ctx, SLE::ConstRef sleDest)
|
||||
{
|
||||
if (sleDest->getAccountID(sfAccount) == ctx.tx[sfAccount])
|
||||
{
|
||||
if (auto const sponsor = getTxReserveSponsor(ctx); !sponsor)
|
||||
return sponsor.error(); // LCOV_EXCL_LINE
|
||||
}
|
||||
return tefINTERNAL;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <ValidIssueType T>
|
||||
TER
|
||||
escrowUnlockApplyHelper(
|
||||
@@ -70,18 +96,17 @@ escrowUnlockApplyHelper<Issue>(
|
||||
if (!ctx.view.exists(trustLineKey) && createAsset)
|
||||
{
|
||||
// Can the account cover the trust line's reserve?
|
||||
auto const sponsorSle = getEffectiveTxReserveSponsor(ctx, sleDest);
|
||||
if (sleDest->getType() != ltACCOUNT_ROOT)
|
||||
return detail::escrowDestNotAccountResult(ctx, sleDest);
|
||||
auto const destSle = AccountRootEntryR(sleDest, ctx.view, journal);
|
||||
auto sponsorSle = getEffectiveTxReserveSponsor(ctx, destSle);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = checkReserve(
|
||||
ctx,
|
||||
sleDest,
|
||||
xrpBalance,
|
||||
*sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
journal,
|
||||
tecNO_LINE_INSUF_RESERVE);
|
||||
auto& sponsor = *sponsorSle;
|
||||
|
||||
if (auto const ret = destSle.checkReserve(
|
||||
ctx, xrpBalance, sponsor, {.ownerCountDelta = 1}, tecNO_LINE_INSUF_RESERVE);
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
JLOG(journal.trace()) << "Trust line does not exist. "
|
||||
@@ -108,7 +133,7 @@ escrowUnlockApplyHelper<Issue>(
|
||||
Issue(currency, receiver), // limit of zero
|
||||
0, // quality in
|
||||
0, // quality out
|
||||
*sponsorSle, // sponsor
|
||||
sponsor ? sponsor->mutableRawSle() : SLE::pointer(), // sponsor
|
||||
journal); // journal
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
@@ -204,23 +229,29 @@ escrowUnlockApplyHelper<MPTIssue>(
|
||||
auto const mptKeylet = keylet::mptoken(issuanceKey.key, receiver);
|
||||
if (!ctx.view.exists(mptKeylet) && createAsset && !receiverIssuer)
|
||||
{
|
||||
auto const sponsorSle = getEffectiveTxReserveSponsor(ctx, sleDest);
|
||||
if (sleDest->getType() != ltACCOUNT_ROOT)
|
||||
return detail::escrowDestNotAccountResult(ctx, sleDest);
|
||||
auto const destSle = AccountRootEntryR(sleDest, ctx.view, journal);
|
||||
auto sponsorSle = getEffectiveTxReserveSponsor(ctx, destSle);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = checkReserve(
|
||||
ctx, sleDest, xrpBalance, *sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
auto& sponsor = *sponsorSle;
|
||||
|
||||
if (auto const ret = destSle.checkReserve(ctx, xrpBalance, sponsor, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
if (auto const ter = createMPToken(ctx.view, mptID, receiver, *sponsorSle, 0);
|
||||
if (auto const ter = createMPToken(
|
||||
ctx.view, mptID, receiver, sponsor ? sponsor->mutableRawSle() : SLE::pointer(), 0);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// update owner count.
|
||||
increaseOwnerCount(ctx.view, sleDest, *sponsorSle, 1, journal);
|
||||
AccountRootEntryW receiverSle(receiver, ctx.view, journal);
|
||||
receiverSle.increaseOwnerCount(sponsor, 1);
|
||||
}
|
||||
|
||||
if (!ctx.view.exists(mptKeylet) && !receiverIssuer)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -54,11 +55,11 @@ getTxReserveSponsorID(STTx const& tx);
|
||||
* Return a mutable SLE for the transaction's reserve sponsor account.
|
||||
*
|
||||
* @param ctx The apply-view context (view + tx)
|
||||
* @return The sponsor account SLE, a null pointer if the tx is not
|
||||
* @return The sponsor account entry, nullopt if the tx is not
|
||||
* reserve-sponsored, or tecINTERNAL if the sponsor account cannot
|
||||
* be loaded (an already-checked invariant).
|
||||
*/
|
||||
std::expected<SLE::pointer, TER>
|
||||
std::expected<std::optional<AccountRootEntryW>, TER>
|
||||
getTxReserveSponsor(ApplyViewContext ctx);
|
||||
|
||||
/**
|
||||
@@ -66,29 +67,29 @@ getTxReserveSponsor(ApplyViewContext ctx);
|
||||
*
|
||||
* @param view The ledger read view
|
||||
* @param tx The transaction to inspect
|
||||
* @return The sponsor account SLE, a null pointer if the tx is not
|
||||
* @return The sponsor account entry, nullopt if the tx is not
|
||||
* reserve-sponsored, or tecINTERNAL if the sponsor account cannot
|
||||
* be loaded (an already-checked invariant).
|
||||
*/
|
||||
std::expected<SLE::const_pointer, TER>
|
||||
std::expected<std::optional<AccountRootEntryR>, TER>
|
||||
getTxReserveSponsor(ReadView const& view, STTx const& tx);
|
||||
|
||||
/**
|
||||
* The transaction's reserve sponsor for the given account, if applicable.
|
||||
*
|
||||
* A reserve sponsor only covers the transaction submitter's own objects, so
|
||||
* this returns the tx reserve sponsor SLE only when accountSle is the tx's own
|
||||
* (non-pseudo) account; otherwise it returns a null sponsor pointer. This is
|
||||
* this returns the tx reserve sponsor entry only when accountSle is the tx's
|
||||
* own (non-pseudo) account; otherwise it returns nullopt. This is
|
||||
* the single source of truth for the "sponsor applies to tx.Account only" rule
|
||||
* that the sponsor-deriving helper overloads in AccountRootHelpers rely on.
|
||||
*
|
||||
* @param ctx The apply-view context (view + tx)
|
||||
* @param accountSle The account whose sponsor is being resolved
|
||||
* @return The sponsor SLE (nullptr if unsponsored), or tecINTERNAL if the
|
||||
* @return The sponsor entry (nullopt if unsponsored), or tecINTERNAL if the
|
||||
* sponsor account cannot be loaded (an already-checked invariant)
|
||||
*/
|
||||
[[nodiscard]] std::expected<SLE::pointer, TER>
|
||||
getEffectiveTxReserveSponsor(ApplyViewContext ctx, SLE::ConstRef accountSle);
|
||||
[[nodiscard]] std::expected<std::optional<AccountRootEntryW>, TER>
|
||||
getEffectiveTxReserveSponsor(ApplyViewContext ctx, AccountRootEntryR const& accountSle);
|
||||
|
||||
/**
|
||||
* Return the AccountID stored in the given sponsor field of a ledger entry, or nullopt if absent.
|
||||
@@ -105,9 +106,9 @@ getLedgerEntryReserveSponsorID(SLE::ConstRef sle, SF_ACCOUNT const& field = sfSp
|
||||
* @param view The mutable apply view
|
||||
* @param sle The ledger entry whose sponsor field is inspected
|
||||
* @param field The field that holds the sponsor AccountID (defaults to sfSponsor)
|
||||
* @return The sponsor account SLE, or a null pointer if the entry is unsponsored.
|
||||
* @return The sponsor account entry, or nullopt if the entry is unsponsored.
|
||||
*/
|
||||
SLE::pointer
|
||||
std::optional<AccountRootEntryW>
|
||||
getLedgerEntryReserveSponsor(
|
||||
ApplyView& view,
|
||||
SLE::ConstRef sle,
|
||||
|
||||
@@ -27,6 +27,18 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* Returns true if sleAcct is an AccountRoot carrying a pseudo-account field.
|
||||
*
|
||||
* isPseudoAccount() takes a view-bound AccountRootEntry, which is not
|
||||
* available while visiting entries, so invariant checks use this instead.
|
||||
*
|
||||
* @param sleAcct the SLE to check.
|
||||
* @return true if sleAcct is an AccountRoot carrying a pseudo-account field.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccountSle(SLE::ConstRef sleAcct);
|
||||
|
||||
#if GENERATING_DOCS
|
||||
/**
|
||||
* @brief Prototype for invariant check implementations.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -25,7 +26,7 @@ checkFreeze(
|
||||
XRPL_ASSERT(src != dst, "xrpl::checkFreeze : unequal input accounts");
|
||||
|
||||
// check freeze
|
||||
if (auto sle = view.read(keylet::account(dst)))
|
||||
if (auto sle = AccountRootEntryR(dst, view))
|
||||
{
|
||||
if (sle->isFlag(lsfGlobalFreeze))
|
||||
{
|
||||
@@ -49,7 +50,7 @@ checkFreeze(
|
||||
|
||||
if (view.rules().enabled(fixFrozenLPTokenTransfer))
|
||||
{
|
||||
if (auto const sleDst = view.read(keylet::account(dst));
|
||||
if (auto const sleDst = AccountRootEntryR(dst, view);
|
||||
sleDst && sleDst->isFieldPresent(sfAMMID))
|
||||
{
|
||||
auto const sleAmm = view.read(keylet::amm((*sleDst)[sfAMMID]));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -12,6 +13,7 @@
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -56,8 +58,8 @@ private:
|
||||
Keylet const& sponsorshipKeylet,
|
||||
AccountID const& sponsorID,
|
||||
AccountID const& sponseeID,
|
||||
SLE::Ref sponsorAccSle,
|
||||
SLE::Ref reserveSponsorAccSle);
|
||||
AccountRootEntryW& sponsorAccSle,
|
||||
std::optional<AccountRootEntryW>& reserveSponsorAccSle);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
@@ -115,8 +116,8 @@ isVaultPseudoAccountFrozenForIssuance(
|
||||
view, {issuer, account}, assetOfHolding(issuanceSle, *sleHolding), depth + 1);
|
||||
}
|
||||
|
||||
auto const mptIssuer = view.read(keylet::account(issuer));
|
||||
if (mptIssuer == nullptr)
|
||||
auto const mptIssuer = AccountRootEntryR(issuer, view);
|
||||
if (!mptIssuer.exists())
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
UNREACHABLE("xrpl::isVaultPseudoAccountFrozen : null MPToken issuer");
|
||||
@@ -189,7 +190,7 @@ canTransferLPToken(
|
||||
{
|
||||
// Only AMM-issued LPTokens are subject to this check. The LPToken's issuer
|
||||
// is the AMM account; if it is not an AMM, this is not an LPToken.
|
||||
auto const sleIssuer = view.read(keylet::account(lpTokenIssuer));
|
||||
auto const sleIssuer = AccountRootEntryR(lpTokenIssuer, view);
|
||||
if (!sleIssuer || !sleIssuer->isFieldPresent(sfAMMID))
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -466,7 +467,7 @@ canWithdraw(
|
||||
ReadView const& view,
|
||||
AccountID const& from,
|
||||
AccountID const& to,
|
||||
SLE::ConstRef toSle,
|
||||
AccountRootEntryR const& toSle,
|
||||
STAmount const& amount,
|
||||
bool hasDestinationTag,
|
||||
std::optional<std::vector<UInt256>> const& credentialIDs)
|
||||
@@ -516,7 +517,7 @@ canWithdraw(
|
||||
bool hasDestinationTag,
|
||||
std::optional<std::vector<UInt256>> const& credentialIDs)
|
||||
{
|
||||
auto const toSle = view.read(keylet::account(to));
|
||||
auto const toSle = AccountRootEntryR(to, view);
|
||||
|
||||
return canWithdraw(view, from, to, toSle, amount, hasDestinationTag, credentialIDs);
|
||||
}
|
||||
@@ -541,7 +542,7 @@ doWithdraw(
|
||||
STAmount const& amount,
|
||||
beast::Journal j)
|
||||
{
|
||||
auto const dstSle = ctx.view.read(keylet::account(dstAcct));
|
||||
auto dstSle = AccountRootEntryW(dstAcct, ctx.view);
|
||||
|
||||
// Create a trust line or MPToken for a self-destination only when there
|
||||
// is a payout to credit. Post-fixCleanup3_4_0, a zero-value withdraw
|
||||
@@ -559,7 +560,8 @@ doWithdraw(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto err = verifyDepositPreauth(ctx.tx, ctx.view, senderAcct, dstAcct, dstSle, j))
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx.tx, ctx.view, senderAcct, dstAcct, dstSle.rawSle(), j))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -582,14 +584,21 @@ doWithdraw(
|
||||
// sponsor against the destination. accountSend can auto-create a holding
|
||||
// for dstAcct; keying on the destination ensures a third-party destination's
|
||||
// holding is never stamped with the tx's reserve sponsor.
|
||||
auto const sponsorSle = getEffectiveTxReserveSponsor(ctx, dstSle);
|
||||
auto sponsorSle = getEffectiveTxReserveSponsor(ctx, dstSle);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
// Move the funds directly from the broker's pseudo-account to the
|
||||
// dstAcct
|
||||
auto& sponsor = *sponsorSle;
|
||||
return accountSend(
|
||||
ctx.view, sourceAcct, dstAcct, amount, j, *sponsorSle, WaiveTransferFee::Yes);
|
||||
ctx.view,
|
||||
sourceAcct,
|
||||
dstAcct,
|
||||
amount,
|
||||
j,
|
||||
sponsor ? sponsor->mutableRawSle() : SLE::pointer{},
|
||||
WaiveTransferFee::Yes);
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OwnerCounts.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename ViewT>
|
||||
XRPAmount
|
||||
AccountRootEntry<ViewT>::reserve(Adjustment adj) const
|
||||
{
|
||||
auto const& view = this->readView();
|
||||
auto const j = this->journal();
|
||||
|
||||
XRPL_ASSERT(
|
||||
this->exists() && (*this)->getType() == ltACCOUNT_ROOT, "xrpl::accountReserve : valid sle");
|
||||
|
||||
if (!view.rules().enabled(featureSponsor))
|
||||
{
|
||||
XRPL_ASSERT(adj.accountCountDelta == 0, "xrpl::accountReserve : no account count delta");
|
||||
return view.fees().accountReserve(
|
||||
(*this)->getFieldU32(sfOwnerCount) + adj.ownerCountDelta, 1);
|
||||
}
|
||||
std::uint32_t const currentOwnerCount = ownerCount(adj.ownerCountDelta);
|
||||
std::uint32_t const currentAccountCount =
|
||||
detail::accountCountImpl(*this, adj.accountCountDelta, j);
|
||||
|
||||
return view.fees().accountReserve(currentOwnerCount, currentAccountCount);
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
std::uint32_t
|
||||
AccountRootEntry<ViewT>::ownerCount(std::int32_t ownerCountAdj) const
|
||||
{
|
||||
auto const j = this->journal();
|
||||
|
||||
XRPL_ASSERT(
|
||||
this->exists() && (*this)->getType() == ltACCOUNT_ROOT,
|
||||
"xrpl::ownerCount : sle is account root");
|
||||
|
||||
AccountID const id = (*this)->getAccountID(sfAccount);
|
||||
std::uint32_t const currentOwnerCount = (*this)->at(sfOwnerCount);
|
||||
std::uint32_t const sponsoredOwnerCount = (*this)->at(sfSponsoredOwnerCount);
|
||||
std::uint32_t const sponsoringOwnerCount = (*this)->at(sfSponsoringOwnerCount);
|
||||
|
||||
XRPL_ASSERT(
|
||||
currentOwnerCount >= sponsoredOwnerCount,
|
||||
"xrpl::ownerCount : OwnerCount must be greater than or equal to SponsoredOwnerCount");
|
||||
|
||||
std::int64_t deltaCount =
|
||||
static_cast<std::int64_t>(ownerCountAdj) - sponsoredOwnerCount + sponsoringOwnerCount;
|
||||
|
||||
if (deltaCount > std::numeric_limits<std::int32_t>::max())
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
deltaCount = std::numeric_limits<std::int32_t>::max();
|
||||
JLOG(j.fatal()) << "Account " << id << " delta count exceeds max, "
|
||||
<< "adjustment: " << ownerCountAdj
|
||||
<< ", sponsoredCount: " << sponsoredOwnerCount
|
||||
<< ", sponsoringOwnerCount: " << sponsoringOwnerCount;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
else if (deltaCount < std::numeric_limits<std::int32_t>::min())
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
deltaCount = std::numeric_limits<std::int32_t>::min();
|
||||
JLOG(j.fatal()) << "Account " << id << " delta count is below min, "
|
||||
<< "adjustment: " << ownerCountAdj
|
||||
<< ", sponsoredCount: " << sponsoredOwnerCount
|
||||
<< ", sponsoringCount: " << sponsoringOwnerCount;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
return detail::confineOwnerCount(currentOwnerCount, deltaCount);
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
TER
|
||||
AccountRootEntry<ViewT>::checkReserve(
|
||||
ApplyViewContext ctx,
|
||||
XRPAmount accBalance,
|
||||
std::optional<AccountRootEntry<ReadView>> const& sponsorSle,
|
||||
Adjustment adj,
|
||||
TER insufReserveCode) const
|
||||
{
|
||||
// TODO: swap to assert after fixCleanup3_2_0 is retired
|
||||
if (!this->exists() || (*this)->getType() != ltACCOUNT_ROOT)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
XRPL_ASSERT(
|
||||
!isTesSuccess(insufReserveCode), "xrpl::checkReserve : insufReserveCode is not tesSUCCESS");
|
||||
if (ctx.view.rules().enabled(featureSponsor))
|
||||
{
|
||||
if (sponsorSle)
|
||||
{
|
||||
if ((*sponsorSle)->getType() != ltACCOUNT_ROOT)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sle = ctx.view.read(
|
||||
keylet::sponsorship(
|
||||
(*sponsorSle)->getAccountID(sfAccount), (*this)->getAccountID(sfAccount)));
|
||||
|
||||
// A reserve-sponsored tx must carry a sponsor signature
|
||||
// (cosigning path) and/or have a pre-existing sponsorship SLE
|
||||
// (prefunded path). Absence of both is an internal invariant break.
|
||||
if (isReserveSponsored(ctx.tx) && !sle && !ctx.tx.isFieldPresent(sfSponsorSignature))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (sle)
|
||||
{
|
||||
auto const ownerCountAllowed = sle->getFieldU32(sfRemainingOwnerCount);
|
||||
if (adj.ownerCountDelta > 0 &&
|
||||
ownerCountAllowed < static_cast<std::uint32_t>(adj.ownerCountDelta))
|
||||
return insufReserveCode;
|
||||
}
|
||||
|
||||
auto const sponsorBalance = (*sponsorSle)->getFieldAmount(sfBalance).xrp();
|
||||
XRPAmount const sponsorReserve = sponsorSle->reserve(adj);
|
||||
|
||||
if (sponsorBalance < sponsorReserve)
|
||||
return insufReserveCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
XRPAmount const reserve = this->reserve(adj);
|
||||
if (accBalance < reserve)
|
||||
return insufReserveCode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
!sponsorSle,
|
||||
"xrpl::checkReserve : featureSponsor disabled and sponsorSle not provided");
|
||||
XRPL_ASSERT(adj.accountCountDelta == 0, "xrpl::checkReserve : accountCountDelta is 0");
|
||||
auto const reserve = ctx.view.fees().accountReserve(
|
||||
(*this)->getFieldU32(sfOwnerCount) + adj.ownerCountDelta, 1);
|
||||
if (accBalance < reserve)
|
||||
return insufReserveCode;
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
TER
|
||||
AccountRootEntry<ViewT>::checkReserve(ApplyViewContext ctx, XRPAmount accBalance, Adjustment adj)
|
||||
const
|
||||
{
|
||||
auto const sponsorExp = getEffectiveTxReserveSponsor(ctx, *this);
|
||||
if (!sponsorExp)
|
||||
return sponsorExp.error(); // LCOV_EXCL_LINE
|
||||
|
||||
std::optional<AccountRootEntry<ReadView>> sponsorSle;
|
||||
if (*sponsorExp)
|
||||
sponsorSle.emplace(**sponsorExp);
|
||||
return checkReserve(ctx, accBalance, sponsorSle, adj);
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
void
|
||||
AccountRootEntry<ViewT>::adjustOwnerCountSigned(
|
||||
std::optional<AccountRootEntry<ApplyView>>& sponsorSle,
|
||||
std::int32_t adjustment)
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
auto& view = this->applyView();
|
||||
auto const j = this->journal();
|
||||
|
||||
if (view.rules().enabled(featureSponsor))
|
||||
{
|
||||
XRPL_ASSERT(this->exists(), "xrpl::adjustOwnerCountSigned : valid account sle");
|
||||
if (!this->exists())
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
auto const accountID = (*this)->getAccountID(sfAccount);
|
||||
bool const validType = (*this)->getType() == ltACCOUNT_ROOT;
|
||||
XRPL_ASSERT(validType, "xrpl::adjustOwnerCountSigned : valid account sle type");
|
||||
if (!validType)
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
XRPL_ASSERT(adjustment, "xrpl::adjustOwnerCountSigned : nonzero adjustment input");
|
||||
|
||||
OwnerCounts const currentOwnerCount(this->rawSle());
|
||||
OwnerCounts totalOwnerCount(currentOwnerCount);
|
||||
|
||||
if (sponsorSle)
|
||||
{
|
||||
bool const validSponsorType = (*sponsorSle)->getType() == ltACCOUNT_ROOT;
|
||||
XRPL_ASSERT(validSponsorType, "xrpl::adjustOwnerCountSigned : valid sponsor sle type");
|
||||
if (!validSponsorType)
|
||||
return; // LCOV_EXCL_LINE
|
||||
auto const sponsorID = (*sponsorSle)->getAccountID(sfAccount);
|
||||
|
||||
totalOwnerCount.sponsored = detail::adjustOwnerCountImpl(
|
||||
view, this->mutableRawSle(), sfSponsoredOwnerCount, accountID, adjustment, j);
|
||||
|
||||
{
|
||||
OwnerCounts const sponsorCurrent(sponsorSle->rawSle());
|
||||
OwnerCounts sponsorAdjustment(sponsorCurrent);
|
||||
sponsorAdjustment.sponsoring = detail::adjustOwnerCountImpl(
|
||||
view,
|
||||
sponsorSle->mutableRawSle(),
|
||||
sfSponsoringOwnerCount,
|
||||
sponsorID,
|
||||
adjustment,
|
||||
j);
|
||||
view.adjustOwnerCountHook(sponsorID, sponsorCurrent, sponsorAdjustment);
|
||||
}
|
||||
|
||||
auto sponsorshipSle = view.peek(keylet::sponsorship(sponsorID, accountID));
|
||||
if (sponsorshipSle && adjustment > 0)
|
||||
{
|
||||
// Only decrease the pre-funded ReserveCount on Sponsorship if we assign new
|
||||
// objects. Removing/reassigning ownership of the object doesn't increase
|
||||
// RemainingOwnerCount back. Don't call hook because this counter is not something
|
||||
// that requires reserve (like other sf...OwnerCounts do).
|
||||
detail::adjustOwnerCountImpl(
|
||||
view, sponsorshipSle, sfRemainingOwnerCount, sponsorID, -adjustment, j);
|
||||
}
|
||||
}
|
||||
|
||||
totalOwnerCount.owner = detail::adjustOwnerCountImpl(
|
||||
view, this->mutableRawSle(), sfOwnerCount, accountID, adjustment, j);
|
||||
view.adjustOwnerCountHook(accountID, currentOwnerCount, totalOwnerCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
XRPL_ASSERT(this->exists(), "xrpl::adjustOwnerCountSigned : valid account sle");
|
||||
if (!this->exists())
|
||||
return;
|
||||
// the remaining are only asserts to preserve existing behavior
|
||||
XRPL_ASSERT(!sponsorSle, "xrpl::adjustOwnerCountSigned : sponsor not enabled");
|
||||
XRPL_ASSERT(
|
||||
(*this)->getType() == ltACCOUNT_ROOT,
|
||||
"xrpl::adjustOwnerCountSigned : valid account sle type");
|
||||
XRPL_ASSERT(adjustment, "xrpl::adjustOwnerCount : nonzero adjustment input");
|
||||
std::uint32_t const current{(*this)->getFieldU32(sfOwnerCount)};
|
||||
AccountID const id = (**this)[sfAccount];
|
||||
std::uint32_t const adjusted = detail::confineOwnerCount(current, adjustment, id, j);
|
||||
|
||||
OwnerCounts const currentOwnerCount(this->rawSle());
|
||||
OwnerCounts finalOwnerCount(currentOwnerCount);
|
||||
finalOwnerCount.owner = adjusted;
|
||||
|
||||
view.adjustOwnerCountHook(id, currentOwnerCount, finalOwnerCount);
|
||||
(*this)->at(sfOwnerCount) = adjusted;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
void
|
||||
AccountRootEntry<ViewT>::increaseOwnerCount(
|
||||
std::optional<AccountRootEntry<ApplyView>>& sponsorSle,
|
||||
std::uint32_t count)
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
count != 0 && count <= std::numeric_limits<std::int32_t>::max(),
|
||||
"xrpl::increaseOwnerCount : count in signed delta range");
|
||||
if (count == 0 || count > std::numeric_limits<std::int32_t>::max())
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
adjustOwnerCountSigned(sponsorSle, static_cast<std::int32_t>(count));
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
void
|
||||
AccountRootEntry<ViewT>::increaseOwnerCount(ApplyViewContext ctx, std::uint32_t count)
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
auto sponsorExp = getEffectiveTxReserveSponsor(ctx, *this);
|
||||
|
||||
// The sponsor's existence is validated by checkReserve/checkSponsor before
|
||||
// any owner-count mutation, so loading it here cannot fail.
|
||||
XRPL_ASSERT(
|
||||
sponsorExp.has_value(), "xrpl::increaseOwnerCount : sponsor validated before mutation");
|
||||
|
||||
std::optional<AccountRootEntry<ApplyView>> sponsorSle;
|
||||
if (sponsorExp && *sponsorExp)
|
||||
sponsorSle.emplace(std::move(**sponsorExp));
|
||||
|
||||
increaseOwnerCount(sponsorSle, count);
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
void
|
||||
AccountRootEntry<ViewT>::decreaseOwnerCount(
|
||||
std::optional<AccountRootEntry<ApplyView>>& sponsorSle,
|
||||
std::uint32_t count)
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
count != 0 && count <= std::numeric_limits<std::int32_t>::max(),
|
||||
"xrpl::decreaseOwnerCount : count in signed delta range");
|
||||
if (count == 0 || count > std::numeric_limits<std::int32_t>::max())
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
adjustOwnerCountSigned(sponsorSle, -static_cast<std::int32_t>(count));
|
||||
}
|
||||
|
||||
template class AccountRootEntry<ReadView>;
|
||||
template class AccountRootEntry<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -641,7 +642,7 @@ ammAccountHolds(ReadView const& view, AccountID const& ammAccountID, Asset const
|
||||
[&](Issue const& issue) {
|
||||
if (isXRP(issue))
|
||||
{
|
||||
if (auto const sle = view.read(keylet::account(ammAccountID)))
|
||||
if (auto const sle = AccountRootEntryR(ammAccountID, view))
|
||||
return (*sle)[sfBalance];
|
||||
}
|
||||
else if (
|
||||
@@ -757,7 +758,7 @@ deleteAMMAccount(Sandbox& sb, Asset const& asset, Asset const& asset2, beast::Jo
|
||||
}
|
||||
|
||||
auto const ammAccountID = (*ammSle)[sfAccount];
|
||||
auto sleAMMRoot = sb.peek(keylet::account(ammAccountID));
|
||||
auto sleAMMRoot = AccountRootEntryW(ammAccountID, sb);
|
||||
if (!sleAMMRoot)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
@@ -795,7 +796,7 @@ deleteAMMAccount(Sandbox& sb, Asset const& asset, Asset const& asset2, beast::Jo
|
||||
}
|
||||
|
||||
sb.erase(ammSle);
|
||||
sb.erase(sleAMMRoot);
|
||||
sleAMMRoot.erase();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OwnerCounts.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -17,7 +18,6 @@
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
@@ -38,25 +38,19 @@ isGlobalFrozen(ReadView const& view, AccountID const& issuer)
|
||||
{
|
||||
if (isXRP(issuer))
|
||||
return false;
|
||||
if (auto const sle = view.read(keylet::account(issuer)))
|
||||
if (auto const sle = AccountRootEntryR(issuer, view))
|
||||
return sle->isFlag(lsfGlobalFreeze);
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
namespace detail {
|
||||
|
||||
// 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.
|
||||
std::uint32_t
|
||||
confineOwnerCount(
|
||||
std::uint32_t currentOwnerCount,
|
||||
std::int32_t ownerCountAdj,
|
||||
std::optional<AccountID> const& id = std::nullopt,
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()})
|
||||
std::optional<AccountID> const& id,
|
||||
beast::Journal j)
|
||||
{
|
||||
std::uint32_t totalOwnerCount{currentOwnerCount + ownerCountAdj};
|
||||
if (ownerCountAdj > 0)
|
||||
@@ -91,10 +85,8 @@ confineOwnerCount(
|
||||
return totalOwnerCount;
|
||||
}
|
||||
|
||||
// Returns the number of account reserves funded by this account: 1 for itself (0 if sponsored by
|
||||
// another account) plus the count of accounts it sponsors.
|
||||
std::uint32_t
|
||||
accountCountImpl(SLE::ConstRef sle, std::int32_t accountCountAdj, beast::Journal j)
|
||||
accountCountImpl(AccountRootEntryR const& sle, std::int32_t accountCountAdj, beast::Journal j)
|
||||
{
|
||||
bool const isSponsored = sle->isFieldPresent(sfSponsor);
|
||||
std::int64_t const sponsoringAccountCount = sle->getFieldU32(sfSponsoringAccountCount);
|
||||
@@ -131,151 +123,25 @@ adjustOwnerCountImpl(
|
||||
{
|
||||
std::uint32_t const currentOwnerCount = sle->at(sfield);
|
||||
std::uint32_t const totalOwnerCount =
|
||||
confineOwnerCount(currentOwnerCount, ownerCountAdj, accID, j);
|
||||
detail::confineOwnerCount(currentOwnerCount, ownerCountAdj, accID, j);
|
||||
sle->at(sfield) = totalOwnerCount;
|
||||
view.update(sle);
|
||||
return totalOwnerCount;
|
||||
}
|
||||
|
||||
void
|
||||
adjustOwnerCountSigned(
|
||||
ApplyView& view,
|
||||
SLE::Ref accountSle,
|
||||
SLE::Ref sponsorSle,
|
||||
std::int32_t adjustment,
|
||||
beast::Journal j)
|
||||
{
|
||||
if (view.rules().enabled(featureSponsor))
|
||||
{
|
||||
XRPL_ASSERT(accountSle, "xrpl::adjustOwnerCountSigned : valid account sle");
|
||||
if (!accountSle)
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
auto const accountID = accountSle->getAccountID(sfAccount);
|
||||
bool const validType = accountSle->getType() == ltACCOUNT_ROOT;
|
||||
XRPL_ASSERT(validType, "xrpl::adjustOwnerCountSigned : valid account sle type");
|
||||
if (!validType)
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
XRPL_ASSERT(adjustment, "xrpl::adjustOwnerCountSigned : nonzero adjustment input");
|
||||
|
||||
OwnerCounts const currentOwnerCount(accountSle);
|
||||
OwnerCounts totalOwnerCount(currentOwnerCount);
|
||||
|
||||
if (sponsorSle)
|
||||
{
|
||||
bool const validSponsorType = sponsorSle->getType() == ltACCOUNT_ROOT;
|
||||
XRPL_ASSERT(validSponsorType, "xrpl::adjustOwnerCountSigned : valid sponsor sle type");
|
||||
if (!validSponsorType)
|
||||
return; // LCOV_EXCL_LINE
|
||||
auto const sponsorID = sponsorSle->getAccountID(sfAccount);
|
||||
|
||||
totalOwnerCount.sponsored = adjustOwnerCountImpl(
|
||||
view, accountSle, sfSponsoredOwnerCount, accountID, adjustment, j);
|
||||
|
||||
{
|
||||
OwnerCounts const sponsorCurrent(sponsorSle);
|
||||
OwnerCounts sponsorAdjustment(sponsorCurrent);
|
||||
sponsorAdjustment.sponsoring = adjustOwnerCountImpl(
|
||||
view, sponsorSle, sfSponsoringOwnerCount, sponsorID, adjustment, j);
|
||||
view.adjustOwnerCountHook(sponsorID, sponsorCurrent, sponsorAdjustment);
|
||||
}
|
||||
|
||||
auto sponsorshipSle = view.peek(keylet::sponsorship(sponsorID, accountID));
|
||||
if (sponsorshipSle && adjustment > 0)
|
||||
{
|
||||
// Only decrease the pre-funded ReserveCount on Sponsorship if we assign new
|
||||
// objects. Removing/reassigning ownership of the object doesn't increase
|
||||
// RemainingOwnerCount back. Don't call hook because this counter is not something
|
||||
// that requires reserve (like other sf...OwnerCounts do).
|
||||
adjustOwnerCountImpl(
|
||||
view, sponsorshipSle, sfRemainingOwnerCount, sponsorID, -adjustment, j);
|
||||
}
|
||||
}
|
||||
|
||||
totalOwnerCount.owner =
|
||||
adjustOwnerCountImpl(view, accountSle, sfOwnerCount, accountID, adjustment, j);
|
||||
view.adjustOwnerCountHook(accountID, currentOwnerCount, totalOwnerCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
XRPL_ASSERT(accountSle, "xrpl::adjustOwnerCountSigned : valid account sle");
|
||||
if (!accountSle)
|
||||
return;
|
||||
// the remaining are only asserts to preserve existing behavior
|
||||
XRPL_ASSERT(sponsorSle == nullptr, "xrpl::adjustOwnerCountSigned : sponsor not enabled");
|
||||
XRPL_ASSERT(
|
||||
accountSle->getType() == ltACCOUNT_ROOT,
|
||||
"xrpl::adjustOwnerCountSigned : valid account sle type");
|
||||
XRPL_ASSERT(adjustment, "xrpl::adjustOwnerCount : nonzero adjustment input");
|
||||
std::uint32_t const current{accountSle->getFieldU32(sfOwnerCount)};
|
||||
AccountID const id = (*accountSle)[sfAccount];
|
||||
std::uint32_t const adjusted = confineOwnerCount(current, adjustment, id, j);
|
||||
|
||||
OwnerCounts const currentOwnerCount(accountSle);
|
||||
OwnerCounts finalOwnerCount(currentOwnerCount);
|
||||
finalOwnerCount.owner = adjusted;
|
||||
|
||||
view.adjustOwnerCountHook(id, currentOwnerCount, finalOwnerCount);
|
||||
accountSle->at(sfOwnerCount) = adjusted;
|
||||
view.update(accountSle);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::uint32_t
|
||||
ownerCount(SLE::ConstRef sle, beast::Journal j, std::int32_t ownerCountAdj)
|
||||
{
|
||||
XRPL_ASSERT(sle && sle->getType() == ltACCOUNT_ROOT, "xrpl::ownerCount : sle is account root");
|
||||
|
||||
AccountID const id = sle->getAccountID(sfAccount);
|
||||
std::uint32_t const currentOwnerCount = sle->at(sfOwnerCount);
|
||||
std::uint32_t const sponsoredOwnerCount = sle->at(sfSponsoredOwnerCount);
|
||||
std::uint32_t const sponsoringOwnerCount = sle->at(sfSponsoringOwnerCount);
|
||||
|
||||
XRPL_ASSERT(
|
||||
currentOwnerCount >= sponsoredOwnerCount,
|
||||
"xrpl::ownerCount : OwnerCount must be greater than or equal to SponsoredOwnerCount");
|
||||
|
||||
std::int64_t deltaCount =
|
||||
static_cast<std::int64_t>(ownerCountAdj) - sponsoredOwnerCount + sponsoringOwnerCount;
|
||||
|
||||
if (deltaCount > std::numeric_limits<std::int32_t>::max())
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
deltaCount = std::numeric_limits<std::int32_t>::max();
|
||||
JLOG(j.fatal()) << "Account " << id << " delta count exceeds max, "
|
||||
<< "adjustment: " << ownerCountAdj
|
||||
<< ", sponsoredCount: " << sponsoredOwnerCount
|
||||
<< ", sponsoringOwnerCount: " << sponsoringOwnerCount;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
else if (deltaCount < std::numeric_limits<std::int32_t>::min())
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
deltaCount = std::numeric_limits<std::int32_t>::min();
|
||||
JLOG(j.fatal()) << "Account " << id << " delta count is below min, "
|
||||
<< "adjustment: " << ownerCountAdj
|
||||
<< ", sponsoredCount: " << sponsoredOwnerCount
|
||||
<< ", sponsoringCount: " << sponsoringOwnerCount;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
return confineOwnerCount(currentOwnerCount, deltaCount);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
XRPAmount
|
||||
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j)
|
||||
{
|
||||
auto const sle = view.read(keylet::account(id));
|
||||
if (sle == nullptr)
|
||||
auto const sle = AccountRootEntryR(id, view);
|
||||
if (!sle.exists())
|
||||
return beast::kZero;
|
||||
|
||||
// Return balance minus reserve
|
||||
std::uint32_t const currentOwnerCount =
|
||||
confineOwnerCount(view.ownerCountHook(id, OwnerCounts(sle)).count(), ownerCountAdj);
|
||||
std::uint32_t const currentAccountCount = accountCountImpl(sle, 0, j);
|
||||
std::uint32_t const currentOwnerCount = detail::confineOwnerCount(
|
||||
view.ownerCountHook(id, OwnerCounts(sle.rawSle())).count(), ownerCountAdj);
|
||||
std::uint32_t const currentAccountCount = detail::accountCountImpl(sle, 0, j);
|
||||
|
||||
// Pseudo-accounts have no reserve requirement
|
||||
auto const reserve = isPseudoAccount(sle)
|
||||
@@ -300,7 +166,7 @@ xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj,
|
||||
Rate
|
||||
transferRate(ReadView const& view, AccountID const& issuer)
|
||||
{
|
||||
auto const sle = view.read(keylet::account(issuer));
|
||||
auto const sle = AccountRootEntryR(issuer, view);
|
||||
|
||||
if (sle && sle->isFieldPresent(sfTransferRate))
|
||||
return Rate{sle->getFieldU32(sfTransferRate)};
|
||||
@@ -308,57 +174,10 @@ transferRate(ReadView const& view, AccountID const& issuer)
|
||||
return kParityRate;
|
||||
}
|
||||
|
||||
void
|
||||
increaseOwnerCount(
|
||||
ApplyView& view,
|
||||
SLE::Ref accountSle,
|
||||
SLE::Ref sponsorSle,
|
||||
std::uint32_t count,
|
||||
beast::Journal j)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
count != 0 && count <= std::numeric_limits<std::int32_t>::max(),
|
||||
"xrpl::increaseOwnerCount : count in signed delta range");
|
||||
if (count == 0 || count > std::numeric_limits<std::int32_t>::max())
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
adjustOwnerCountSigned(view, accountSle, sponsorSle, static_cast<std::int32_t>(count), j);
|
||||
}
|
||||
|
||||
void
|
||||
increaseOwnerCount(ApplyViewContext ctx, SLE::Ref accountSle, std::uint32_t count, beast::Journal j)
|
||||
{
|
||||
auto const sponsorExp = getEffectiveTxReserveSponsor(ctx, accountSle);
|
||||
|
||||
// The sponsor's existence is validated by checkReserve/checkSponsor before
|
||||
// any owner-count mutation, so loading it here cannot fail.
|
||||
XRPL_ASSERT(
|
||||
sponsorExp.has_value(), "xrpl::increaseOwnerCount : sponsor validated before mutation");
|
||||
|
||||
increaseOwnerCount(ctx.view, accountSle, sponsorExp ? *sponsorExp : SLE::pointer(), count, j);
|
||||
}
|
||||
|
||||
void
|
||||
decreaseOwnerCount(
|
||||
ApplyView& view,
|
||||
SLE::Ref accountSle,
|
||||
SLE::Ref sponsorSle,
|
||||
std::uint32_t count,
|
||||
beast::Journal j)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
count != 0 && count <= std::numeric_limits<std::int32_t>::max(),
|
||||
"xrpl::decreaseOwnerCount : count in signed delta range");
|
||||
if (count == 0 || count > std::numeric_limits<std::int32_t>::max())
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
adjustOwnerCountSigned(view, accountSle, sponsorSle, -static_cast<std::int32_t>(count), j);
|
||||
}
|
||||
|
||||
void
|
||||
decreaseOwnerCountForObject(
|
||||
ApplyView& view,
|
||||
SLE::Ref accountSle,
|
||||
AccountRootEntryW& accountSle,
|
||||
SLE::Ref objectSle,
|
||||
std::uint32_t count,
|
||||
beast::Journal j)
|
||||
@@ -372,8 +191,8 @@ decreaseOwnerCountForObject(
|
||||
if (!validObjectType)
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
SLE::Ref sponsorSle = getLedgerEntryReserveSponsor(view, objectSle);
|
||||
decreaseOwnerCount(view, accountSle, sponsorSle, count, j);
|
||||
auto sponsorSle = getLedgerEntryReserveSponsor(view, objectSle);
|
||||
accountSle.decreaseOwnerCount(sponsorSle, count);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -393,107 +212,10 @@ adjustLoanBrokerOwnerCount(
|
||||
if (delta == 0)
|
||||
return; // LCOV_EXCL_LINE
|
||||
|
||||
adjustOwnerCountImpl(
|
||||
detail::adjustOwnerCountImpl(
|
||||
view, brokerSle, sfOwnerCount, brokerSle->getAccountID(sfAccount), delta, j);
|
||||
}
|
||||
|
||||
XRPAmount
|
||||
accountReserve(ReadView const& view, SLE::ConstRef sle, beast::Journal j, Adjustment adj)
|
||||
{
|
||||
XRPL_ASSERT(sle && sle->getType() == ltACCOUNT_ROOT, "xrpl::accountReserve : valid sle");
|
||||
|
||||
if (!view.rules().enabled(featureSponsor))
|
||||
{
|
||||
XRPL_ASSERT(adj.accountCountDelta == 0, "xrpl::accountReserve : no account count delta");
|
||||
return view.fees().accountReserve(sle->getFieldU32(sfOwnerCount) + adj.ownerCountDelta, 1);
|
||||
}
|
||||
std::uint32_t const currentOwnerCount = ownerCount(sle, j, adj.ownerCountDelta);
|
||||
std::uint32_t const currentAccountCount = accountCountImpl(sle, adj.accountCountDelta, j);
|
||||
|
||||
return view.fees().accountReserve(currentOwnerCount, currentAccountCount);
|
||||
}
|
||||
|
||||
TER
|
||||
checkReserve(
|
||||
ApplyViewContext ctx,
|
||||
SLE::ConstRef accSle,
|
||||
XRPAmount accBalance,
|
||||
SLE::ConstRef sponsorSle,
|
||||
Adjustment adj,
|
||||
beast::Journal j,
|
||||
TER insufReserveCode)
|
||||
{
|
||||
// TODO: swap to assert after fixCleanup3_2_0 is retired
|
||||
if (!accSle || accSle->getType() != ltACCOUNT_ROOT)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
XRPL_ASSERT(
|
||||
!isTesSuccess(insufReserveCode), "xrpl::checkReserve : insufReserveCode is not tesSUCCESS");
|
||||
if (ctx.view.rules().enabled(featureSponsor))
|
||||
{
|
||||
if (sponsorSle)
|
||||
{
|
||||
if (sponsorSle->getType() != ltACCOUNT_ROOT)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sle = ctx.view.read(
|
||||
keylet::sponsorship(
|
||||
sponsorSle->getAccountID(sfAccount), accSle->getAccountID(sfAccount)));
|
||||
|
||||
// A reserve-sponsored tx must carry a sponsor signature
|
||||
// (cosigning path) and/or have a pre-existing sponsorship SLE
|
||||
// (prefunded path). Absence of both is an internal invariant break.
|
||||
if (isReserveSponsored(ctx.tx) && !sle && !ctx.tx.isFieldPresent(sfSponsorSignature))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (sle)
|
||||
{
|
||||
auto const ownerCountAllowed = sle->getFieldU32(sfRemainingOwnerCount);
|
||||
if (adj.ownerCountDelta > 0 &&
|
||||
ownerCountAllowed < static_cast<std::uint32_t>(adj.ownerCountDelta))
|
||||
return insufReserveCode;
|
||||
}
|
||||
|
||||
auto const sponsorBalance = sponsorSle->getFieldAmount(sfBalance).xrp();
|
||||
XRPAmount const sponsorReserve = accountReserve(ctx.view, sponsorSle, j, adj);
|
||||
|
||||
if (sponsorBalance < sponsorReserve)
|
||||
return insufReserveCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
XRPAmount const reserve = accountReserve(ctx.view, accSle, j, adj);
|
||||
if (accBalance < reserve)
|
||||
return insufReserveCode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
!sponsorSle,
|
||||
"xrpl::checkReserve : featureSponsor disabled and sponsorSle not provided");
|
||||
XRPL_ASSERT(adj.accountCountDelta == 0, "xrpl::checkReserve : accountCountDelta is 0");
|
||||
auto const reserve = ctx.view.fees().accountReserve(
|
||||
accSle->getFieldU32(sfOwnerCount) + adj.ownerCountDelta, 1);
|
||||
if (accBalance < reserve)
|
||||
return insufReserveCode;
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
checkReserve(
|
||||
ApplyViewContext ctx,
|
||||
SLE::ConstRef accSle,
|
||||
XRPAmount accBalance,
|
||||
Adjustment adj,
|
||||
beast::Journal j)
|
||||
{
|
||||
auto const sponsorExp = getEffectiveTxReserveSponsor(ctx, accSle);
|
||||
if (!sponsorExp)
|
||||
return sponsorExp.error(); // LCOV_EXCL_LINE
|
||||
return checkReserve(ctx, accSle, accBalance, *sponsorExp, adj, j);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
||||
AccountID
|
||||
@@ -507,7 +229,7 @@ pseudoAccountAddress(ReadView const& view, UInt256 const& pseudoOwnerKey)
|
||||
auto const hash = sha512Half(i, view.header().parentHash, pseudoOwnerKey);
|
||||
rsh(hash.data(), hash.size());
|
||||
AccountID const ret = AccountID::fromRaw(static_cast<RipeshaHasher::result_type>(rsh));
|
||||
if (!view.read(keylet::account(ret)))
|
||||
if (!AccountRootEntryR(ret, view).exists())
|
||||
return ret;
|
||||
}
|
||||
return beast::kZero;
|
||||
@@ -546,7 +268,7 @@ getPseudoAccountFields()
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount(SLE::const_pointer sleAcct)
|
||||
isPseudoAccount(AccountRootEntryR const& sleAcct)
|
||||
{
|
||||
// Intentionally use defensive coding here because it's cheap and makes the
|
||||
// semantics of true return value clean.
|
||||
@@ -599,9 +321,9 @@ createPseudoAccount(ApplyView& view, UInt256 const& pseudoOwnerKey, SField const
|
||||
}
|
||||
|
||||
[[nodiscard]] TER
|
||||
checkDestinationAndTag(SLE::ConstRef toSle, bool hasDestinationTag)
|
||||
checkDestinationAndTag(AccountRootEntryR const& toSle, bool hasDestinationTag)
|
||||
{
|
||||
if (toSle == nullptr)
|
||||
if (!toSle.exists())
|
||||
return tecNO_DST;
|
||||
|
||||
// The tag is basically account-specific information we don't
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -81,7 +82,7 @@ deleteSLE(ApplyView& view, SLE::Ref sleCredential, beast::Journal j)
|
||||
|
||||
auto delSLE = [&view, &sleCredential, j](
|
||||
AccountID const& account, SField const& node, bool isOwner) -> TER {
|
||||
auto const sleAccount = view.peek(keylet::account(account));
|
||||
auto sleAccount = AccountRootEntryW(account, view);
|
||||
if (!sleAccount)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
@@ -206,7 +207,7 @@ authorizeMPToken(
|
||||
std::uint32_t flags,
|
||||
std::optional<AccountID> holderID)
|
||||
{
|
||||
auto const sleAcct = ctx.view.peek(keylet::account(account));
|
||||
auto sleAcct = AccountRootEntryW(account, ctx.view, journal);
|
||||
if (!sleAcct)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -242,10 +243,10 @@ authorizeMPToken(
|
||||
// - create the MPToken object for the holder
|
||||
|
||||
// A reserve sponsor only covers tx.Account's own objects.
|
||||
auto const sponsorExp = getEffectiveTxReserveSponsor(ctx, sleAcct);
|
||||
auto sponsorExp = getEffectiveTxReserveSponsor(ctx, sleAcct);
|
||||
if (!sponsorExp)
|
||||
return sponsorExp.error(); // LCOV_EXCL_LINE
|
||||
auto const sponsorSle = *sponsorExp;
|
||||
auto& sponsorSle = *sponsorExp;
|
||||
|
||||
// The reserve that is required to create the MPToken. Note
|
||||
// that although the reserve increases with every item
|
||||
@@ -255,10 +256,10 @@ authorizeMPToken(
|
||||
// The "free-tier" shortcut (ownerCount < 2) does not apply once a sponsor is on
|
||||
// the tx — the sponsor must always cover the reserve (via balance or prefunded
|
||||
// budget), so this check always runs for sponsored transactions.
|
||||
if (sponsorSle || ownerCount(sleAcct, journal) >= 2)
|
||||
if (sponsorSle || sleAcct.ownerCount() >= 2)
|
||||
{
|
||||
if (auto const ret = checkReserve(
|
||||
ctx, sleAcct, priorBalance, sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
if (auto const ret =
|
||||
sleAcct.checkReserve(ctx, priorBalance, sponsorSle, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
}
|
||||
@@ -285,8 +286,8 @@ authorizeMPToken(
|
||||
ctx.view.insert(mptoken);
|
||||
|
||||
// Update owner count.
|
||||
increaseOwnerCount(ctx.view, sleAcct, sponsorSle, 1, journal);
|
||||
addSponsorToLedgerEntry(mptoken, sponsorSle);
|
||||
sleAcct.increaseOwnerCount(sponsorSle, 1);
|
||||
addSponsorToLedgerEntry(mptoken, sponsorSle ? sponsorSle->rawSle() : SLE::const_pointer{});
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -415,7 +416,7 @@ requireAuth(
|
||||
}
|
||||
|
||||
// requireAuth is recursive if the issuer is a vault pseudo-account
|
||||
auto const sleIssuer = view.read(keylet::account(mptIssuer));
|
||||
auto const sleIssuer = AccountRootEntryR(mptIssuer, view);
|
||||
if (!sleIssuer)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -1020,13 +1021,16 @@ checkCreateMPT(
|
||||
{
|
||||
return err;
|
||||
}
|
||||
auto const sleAcct = view.peek(keylet::account(holder));
|
||||
auto sleAcct = AccountRootEntryW(holder, view, j);
|
||||
if (!sleAcct)
|
||||
{
|
||||
return tecINTERNAL;
|
||||
}
|
||||
|
||||
increaseOwnerCount(view, sleAcct, sponsorSle, 1, j);
|
||||
std::optional<AccountRootEntryW> sponsorAccSle;
|
||||
if (sponsorSle)
|
||||
sponsorAccSle.emplace(sponsorSle->getAccountID(sfAccount), view);
|
||||
sleAcct.increaseOwnerCount(sponsorAccSle, 1);
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
@@ -855,7 +856,7 @@ tokenOfferCreatePreclaim(
|
||||
|
||||
if (nftIssuer != acctID && ((nftFlags & nft::kFlagTransferable) == 0))
|
||||
{
|
||||
auto const root = view.read(keylet::account(nftIssuer));
|
||||
auto const root = AccountRootEntryR(nftIssuer, view);
|
||||
XRPL_ASSERT(root, "xrpl::nft::tokenOfferCreatePreclaim : non-null account");
|
||||
|
||||
if (auto minter = (*root)[~sfNFTokenMinter]; minter != acctID)
|
||||
@@ -886,7 +887,7 @@ tokenOfferCreatePreclaim(
|
||||
{
|
||||
// If a destination is specified, the destination must already be in
|
||||
// the ledger.
|
||||
auto const sleDst = view.read(keylet::account(*dest));
|
||||
auto const sleDst = AccountRootEntryR(*dest, view);
|
||||
|
||||
if (!sleDst)
|
||||
return tecNO_DST;
|
||||
@@ -898,7 +899,7 @@ tokenOfferCreatePreclaim(
|
||||
|
||||
if (owner)
|
||||
{
|
||||
auto const sleOwner = view.read(keylet::account(*owner));
|
||||
auto const sleOwner = AccountRootEntryR(*owner, view);
|
||||
|
||||
// defensively check
|
||||
// it should not be possible to specify owner that doesn't exist
|
||||
@@ -937,9 +938,8 @@ tokenOfferCreateApply(
|
||||
beast::Journal j,
|
||||
std::uint32_t txFlags)
|
||||
{
|
||||
Keylet const acctKeylet = keylet::account(acctID);
|
||||
if (auto const acct = view.read(acctKeylet);
|
||||
priorBalance < accountReserve(view, acct, j, {.ownerCountDelta = 1}))
|
||||
if (auto const acct = AccountRootEntryW(acctID, view, j);
|
||||
priorBalance < acct.reserve({.ownerCountDelta = 1}))
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
auto const offerID = keylet::nftokenOffer(acctID, seqProxy);
|
||||
@@ -1008,7 +1008,7 @@ checkTrustlineAuthorized(
|
||||
|
||||
if (view.rules().enabled(fixEnforceNFTokenTrustlineV2))
|
||||
{
|
||||
auto const issuerAccount = view.read(keylet::account(issue.account));
|
||||
auto const issuerAccount = AccountRootEntryR(issue.account, view);
|
||||
if (!issuerAccount)
|
||||
{
|
||||
JLOG(j.debug()) << "xrpl::nft::checkTrustlineAuthorized: can't "
|
||||
@@ -1060,7 +1060,7 @@ checkTrustlineDeepFrozen(
|
||||
|
||||
if (view.rules().enabled(featureDeepFreeze))
|
||||
{
|
||||
auto const issuerAccount = view.read(keylet::account(issue.account));
|
||||
auto const issuerAccount = AccountRootEntryR(issue.account, view);
|
||||
if (!issuerAccount)
|
||||
{
|
||||
JLOG(j.debug()) << "xrpl::nft::checkTrustlineDeepFrozen: can't "
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -51,7 +52,7 @@ closeChannel(SLE::Ref slep, ApplyView& view, UInt256 const& key, beast::Journal
|
||||
}
|
||||
|
||||
// Transfer amount back to owner, decrement owner count
|
||||
auto const sle = view.peek(keylet::account(src));
|
||||
auto sle = AccountRootEntryW(src, view);
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -59,7 +60,7 @@ closeChannel(SLE::Ref slep, ApplyView& view, UInt256 const& key, beast::Journal
|
||||
(*slep)[sfAmount] >= (*slep)[sfBalance], "xrpl::closeChannel : minimum channel amount");
|
||||
(*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount] - (*slep)[sfBalance];
|
||||
decreaseOwnerCountForObject(view, sle, slep, 1, j);
|
||||
view.update(sle);
|
||||
sle.update();
|
||||
|
||||
// Remove PayChan from ledger
|
||||
view.erase(slep);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -133,14 +134,14 @@ isFrozen(
|
||||
{
|
||||
if (isXRP(currency))
|
||||
return false;
|
||||
auto sle = view.read(keylet::account(issuer));
|
||||
if (sle && sle->isFlag(lsfGlobalFreeze))
|
||||
auto const sleIssuer = AccountRootEntryR(issuer, view);
|
||||
if (sleIssuer && sleIssuer->isFlag(lsfGlobalFreeze))
|
||||
return true;
|
||||
if (issuer != account)
|
||||
{
|
||||
// Check if the issuer froze the line
|
||||
sle = view.read(keylet::trustLine(account, issuer, currency));
|
||||
if (sle && sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze))
|
||||
auto const sleLine = view.read(keylet::trustLine(account, issuer, currency));
|
||||
if (sleLine && sleLine->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -238,7 +239,7 @@ trustCreate(
|
||||
XRPL_ASSERT(
|
||||
sleAccount->getAccountID(sfAccount) == (bSetHigh ? uHighAccountID : uLowAccountID),
|
||||
"xrpl::trustCreate : matching account ID");
|
||||
auto const slePeer = view.peek(keylet::account(bSetHigh ? uLowAccountID : uHighAccountID));
|
||||
auto const slePeer = AccountRootEntryW(bSetHigh ? uLowAccountID : uHighAccountID, view);
|
||||
if (!slePeer)
|
||||
return tecNO_TARGET;
|
||||
|
||||
@@ -283,7 +284,11 @@ trustCreate(
|
||||
}
|
||||
|
||||
sleRippleState->setFieldU32(sfFlags, uFlags);
|
||||
increaseOwnerCount(view, sleAccount, sponsorSle, 1, j);
|
||||
AccountRootEntryW accountSle(bSetHigh ? uHighAccountID : uLowAccountID, view, j);
|
||||
std::optional<AccountRootEntryW> sponsorAccSle;
|
||||
if (sponsorSle)
|
||||
sponsorAccSle.emplace(sponsorSle->getAccountID(sfAccount), view);
|
||||
accountSle.increaseOwnerCount(sponsorAccSle, 1);
|
||||
|
||||
addSponsorToLedgerEntry(sleRippleState, sponsorSle, bSetHigh ? sfHighSponsor : sfLowSponsor);
|
||||
|
||||
@@ -349,7 +354,7 @@ updateTrustLine(
|
||||
if (!state)
|
||||
return false;
|
||||
|
||||
auto sle = view.peek(keylet::account(sender));
|
||||
auto sle = AccountRootEntryW(sender, view, j);
|
||||
if (!sle)
|
||||
return false;
|
||||
|
||||
@@ -376,9 +381,9 @@ updateTrustLine(
|
||||
{
|
||||
// VFALCO Where is the line being deleted?
|
||||
// Clear the reserve of the sender, possibly delete the line!
|
||||
auto const currentSponsor =
|
||||
auto currentSponsor =
|
||||
getLedgerEntryReserveSponsor(view, state, bSenderHigh ? sfHighSponsor : sfLowSponsor);
|
||||
decreaseOwnerCount(view, sle, currentSponsor, 1, j);
|
||||
sle.decreaseOwnerCount(currentSponsor, 1);
|
||||
|
||||
// Clear reserve flag.
|
||||
state->clearFlag(senderReserveFlag);
|
||||
@@ -464,7 +469,7 @@ issueIOU(
|
||||
|
||||
finalBalance.get<Issue>().account = noAccount();
|
||||
|
||||
auto const receiverAccount = view.peek(keylet::account(account));
|
||||
auto receiverAccount = AccountRootEntryW(account, view);
|
||||
if (!receiverAccount)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -476,7 +481,7 @@ issueIOU(
|
||||
issue.account,
|
||||
account,
|
||||
index.key,
|
||||
receiverAccount,
|
||||
receiverAccount.mutableRawSle(),
|
||||
false,
|
||||
noRipple,
|
||||
false,
|
||||
@@ -579,7 +584,7 @@ requireAuth(ReadView const& view, Issue const& issue, AccountID const& account,
|
||||
|
||||
// If this is a weak or legacy check, or if the account has a line, fail if
|
||||
// auth is required and not set on the line
|
||||
if (auto const issuerAccount = view.read(keylet::account(issue.account));
|
||||
if (auto const issuerAccount = AccountRootEntryR(issue.account, view);
|
||||
issuerAccount && issuerAccount->isFlag(lsfRequireAuth))
|
||||
{
|
||||
if (trustLine)
|
||||
@@ -609,8 +614,8 @@ canTransfer(ReadView const& view, Issue const& issue, AccountID const& from, Acc
|
||||
auto const& issuerId = issue.getIssuer();
|
||||
if (issuerId == from || issuerId == to)
|
||||
return tesSUCCESS;
|
||||
auto const sleIssuer = view.read(keylet::account(issuerId));
|
||||
if (sleIssuer == nullptr)
|
||||
auto const sleIssuer = AccountRootEntryR(issuerId, view);
|
||||
if (!sleIssuer.exists())
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const isRippleDisabled = [&](AccountID account) -> bool {
|
||||
@@ -665,8 +670,8 @@ addEmptyHolding(
|
||||
if (isGlobalFrozen(ctx.view, issuerId))
|
||||
return tecFROZEN; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sleSrc = ctx.view.peek(keylet::account(srcId));
|
||||
auto const sleDst = ctx.view.peek(keylet::account(dstId));
|
||||
auto const sleSrc = AccountRootEntryW(srcId, ctx.view);
|
||||
auto sleDst = AccountRootEntryW(dstId, ctx.view, journal);
|
||||
if (!sleDst || !sleSrc)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
// Create path: DefaultRipple is still required. terNO_RIPPLE is
|
||||
@@ -681,20 +686,14 @@ addEmptyHolding(
|
||||
return tecDUPLICATE;
|
||||
|
||||
// A reserve sponsor only covers tx.Account's own objects.
|
||||
auto const sponsorExp = getEffectiveTxReserveSponsor(ctx, sleDst);
|
||||
auto sponsorExp = getEffectiveTxReserveSponsor(ctx, sleDst);
|
||||
if (!sponsorExp)
|
||||
return sponsorExp.error(); // LCOV_EXCL_LINE
|
||||
auto const sponsorSle = *sponsorExp;
|
||||
auto& sponsorSle = *sponsorExp;
|
||||
|
||||
// Can the account cover the trust line reserve ?
|
||||
if (auto const ret = checkReserve(
|
||||
ctx,
|
||||
sleDst,
|
||||
priorBalance,
|
||||
sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
journal,
|
||||
tecNO_LINE_INSUF_RESERVE);
|
||||
if (auto const ret = sleDst.checkReserve(
|
||||
ctx, priorBalance, sponsorSle, {.ownerCountDelta = 1}, tecNO_LINE_INSUF_RESERVE);
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
return ret;
|
||||
@@ -706,7 +705,7 @@ addEmptyHolding(
|
||||
srcId,
|
||||
dstId,
|
||||
index.key,
|
||||
sleDst,
|
||||
sleDst.mutableRawSle(),
|
||||
/*bAuth=*/false,
|
||||
/*bNoRipple=*/true,
|
||||
/*bFreeze=*/false,
|
||||
@@ -715,7 +714,7 @@ addEmptyHolding(
|
||||
/*saLimit=*/STAmount{Issue{currency, dstId}},
|
||||
/*uQualityIn=*/0,
|
||||
/*uQualityOut=*/0,
|
||||
sponsorSle,
|
||||
sponsorSle ? sponsorSle->mutableRawSle() : SLE::pointer{},
|
||||
journal);
|
||||
}
|
||||
|
||||
@@ -728,7 +727,7 @@ removeEmptyHolding(
|
||||
{
|
||||
if (issue.native())
|
||||
{
|
||||
auto const sle = ctx.view.read(keylet::account(accountID));
|
||||
auto const sle = AccountRootEntryW(accountID, ctx.view);
|
||||
if (!sle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -753,13 +752,14 @@ removeEmptyHolding(
|
||||
if (line->isFlag(lsfLowReserve))
|
||||
{
|
||||
// Clear reserve for low account.
|
||||
auto sleLowAccount = ctx.view.peek(keylet::account(line->at(sfLowLimit)->getIssuer()));
|
||||
auto sleLowAccount =
|
||||
AccountRootEntryW(line->at(sfLowLimit)->getIssuer(), ctx.view, journal);
|
||||
if (!sleLowAccount)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const currentLowSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfLowSponsor);
|
||||
auto currentLowSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfLowSponsor);
|
||||
|
||||
decreaseOwnerCount(ctx.view, sleLowAccount, currentLowSponsor, 1, journal);
|
||||
sleLowAccount.decreaseOwnerCount(currentLowSponsor, 1);
|
||||
// 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.
|
||||
@@ -770,13 +770,14 @@ removeEmptyHolding(
|
||||
if (line->isFlag(lsfHighReserve))
|
||||
{
|
||||
// Clear reserve for high account.
|
||||
auto sleHighAccount = ctx.view.peek(keylet::account(line->at(sfHighLimit)->getIssuer()));
|
||||
auto sleHighAccount =
|
||||
AccountRootEntryW(line->at(sfHighLimit)->getIssuer(), ctx.view, journal);
|
||||
if (!sleHighAccount)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const currentHighSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfHighSponsor);
|
||||
auto currentHighSponsor = getLedgerEntryReserveSponsor(ctx.view, line, sfHighSponsor);
|
||||
|
||||
decreaseOwnerCount(ctx.view, sleHighAccount, currentHighSponsor, 1, journal);
|
||||
sleHighAccount.decreaseOwnerCount(currentHighSponsor, 1);
|
||||
// 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.
|
||||
@@ -805,8 +806,8 @@ deleteAMMTrustLine(
|
||||
auto const& [low, high] = std::minmax(
|
||||
sleState->getFieldAmount(sfLowLimit).getIssuer(),
|
||||
sleState->getFieldAmount(sfHighLimit).getIssuer());
|
||||
auto sleLow = view.peek(keylet::account(low));
|
||||
auto sleHigh = view.peek(keylet::account(high));
|
||||
auto sleLow = AccountRootEntryW(low, view, j);
|
||||
auto sleHigh = AccountRootEntryW(high, view, j);
|
||||
if (!sleLow || !sleHigh)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -825,7 +826,7 @@ deleteAMMTrustLine(
|
||||
if (ammAccountID && (low != *ammAccountID && high != *ammAccountID))
|
||||
return terNO_AMM;
|
||||
|
||||
auto const sponsorSle =
|
||||
auto sponsorSle =
|
||||
getLedgerEntryReserveSponsor(view, sleState, !ammLow ? sfLowSponsor : sfHighSponsor);
|
||||
|
||||
if (auto const ter = trustDelete(view, sleState, low, high, j); !isTesSuccess(ter))
|
||||
@@ -838,7 +839,7 @@ deleteAMMTrustLine(
|
||||
if (!sleState->isFlag(uFlags))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
decreaseOwnerCount(view, !ammLow ? sleLow : sleHigh, sponsorSle, 1, j);
|
||||
(!ammLow ? sleLow : sleHigh).decreaseOwnerCount(sponsorSle, 1);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/OracleHelpers.h>
|
||||
#include <xrpl/ledger/helpers/ProposalHelpers.h>
|
||||
@@ -76,7 +77,7 @@ getTxReserveSponsorID(STTx const& tx)
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<SLE::pointer, TER>
|
||||
std::expected<std::optional<AccountRootEntryW>, TER>
|
||||
getTxReserveSponsor(ApplyViewContext ctx)
|
||||
{
|
||||
auto const sponsorID = getTxReserveSponsorID(ctx.tx);
|
||||
@@ -85,17 +86,17 @@ getTxReserveSponsor(ApplyViewContext ctx)
|
||||
XRPL_ASSERT(
|
||||
ctx.view.rules().enabled(featureSponsor),
|
||||
"xrpl::getTxReserveSponsor : sponsor exists + Sponsor enabled");
|
||||
auto sle = ctx.view.peek(keylet::account(*sponsorID));
|
||||
auto sle = AccountRootEntryW(*sponsorID, ctx.view);
|
||||
|
||||
// already checked in Transactor::checkSponsor
|
||||
if (!sle)
|
||||
if (!sle.exists())
|
||||
return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE
|
||||
return sle;
|
||||
}
|
||||
return SLE::pointer();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::expected<SLE::const_pointer, TER>
|
||||
std::expected<std::optional<AccountRootEntryR>, TER>
|
||||
getTxReserveSponsor(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
auto const sponsorID = getTxReserveSponsorID(tx);
|
||||
@@ -104,18 +105,18 @@ getTxReserveSponsor(ReadView const& view, STTx const& tx)
|
||||
XRPL_ASSERT(
|
||||
view.rules().enabled(featureSponsor),
|
||||
"xrpl::getTxReserveSponsor : sponsor exists + Sponsor enabled");
|
||||
auto sle = view.read(keylet::account(*sponsorID));
|
||||
auto sle = AccountRootEntryR(*sponsorID, view);
|
||||
|
||||
// already checked in Transactor::checkSponsor
|
||||
if (!sle)
|
||||
if (!sle.exists())
|
||||
return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE
|
||||
return sle;
|
||||
}
|
||||
return SLE::pointer();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::expected<SLE::pointer, TER>
|
||||
getEffectiveTxReserveSponsor(ApplyViewContext ctx, SLE::ConstRef accountSle)
|
||||
std::expected<std::optional<AccountRootEntryW>, TER>
|
||||
getEffectiveTxReserveSponsor(ApplyViewContext ctx, AccountRootEntryR const& accountSle)
|
||||
{
|
||||
// A reserve sponsor only covers tx.Account's own objects.
|
||||
if (ctx.view.rules().enabled(fixCleanup3_2_0))
|
||||
@@ -133,7 +134,7 @@ getEffectiveTxReserveSponsor(ApplyViewContext ctx, SLE::ConstRef accountSle)
|
||||
}
|
||||
|
||||
if (isPseudoAccount(accountSle) || accountSle->getAccountID(sfAccount) != ctx.tx[sfAccount])
|
||||
return SLE::pointer();
|
||||
return std::nullopt;
|
||||
return getTxReserveSponsor(ctx);
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@ getLedgerEntryReserveSponsorID(SLE::ConstRef sle, SF_ACCOUNT const& field)
|
||||
return {};
|
||||
}
|
||||
|
||||
SLE::pointer
|
||||
std::optional<AccountRootEntryW>
|
||||
getLedgerEntryReserveSponsor(ApplyView& view, SLE::ConstRef sle, SF_ACCOUNT const& field)
|
||||
{
|
||||
auto const sponsorID = getLedgerEntryReserveSponsorID(sle, field);
|
||||
@@ -160,9 +161,9 @@ getLedgerEntryReserveSponsor(ApplyView& view, SLE::ConstRef sle, SF_ACCOUNT cons
|
||||
XRPL_ASSERT(
|
||||
view.rules().enabled(featureSponsor),
|
||||
"xrpl::getLedgerEntryReserveSponsor : sponsor exists + Sponsor enabled");
|
||||
return view.peek(keylet::account(*sponsorID));
|
||||
return AccountRootEntryW(*sponsorID, view);
|
||||
}
|
||||
return {};
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -185,16 +186,16 @@ addSponsorToLedgerEntry(SLE::Ref sle, SLE::ConstRef sponsorSle, SF_ACCOUNT const
|
||||
void
|
||||
addSponsorToLedgerEntry(ApplyViewContext ctx, SLE::Ref sle, SF_ACCOUNT const& field)
|
||||
{
|
||||
// getTxReserveSponsor yields a null pointer when the tx is not
|
||||
// reserve-sponsored, so addSponsorToLedgerEntry becomes a no-op then. The
|
||||
// error case (tecINTERNAL) is an already-checked invariant; skip stamping.
|
||||
// getTxReserveSponsor yields nullopt when the tx is not reserve-sponsored,
|
||||
// so addSponsorToLedgerEntry becomes a no-op then. The error case
|
||||
// (tecINTERNAL) is an already-checked invariant; skip stamping.
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx);
|
||||
if (sponsorSle && *sponsorSle)
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
ctx.view.rules().enabled(featureSponsor),
|
||||
"xrpl::addSponsorToLedgerEntry : sponsor exists + Sponsor enabled");
|
||||
addSponsorToLedgerEntry(sle, *sponsorSle, field);
|
||||
addSponsorToLedgerEntry(sle, (**sponsorSle).rawSle(), field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
@@ -293,7 +294,7 @@ getLineIfUsable(
|
||||
// we need to check if the associated assets have been frozen
|
||||
if (view.rules().enabled(fixFrozenLPTokenTransfer))
|
||||
{
|
||||
auto const sleIssuer = view.read(keylet::account(issuer));
|
||||
auto const sleIssuer = AccountRootEntryR(issuer, view);
|
||||
if (!sleIssuer)
|
||||
{
|
||||
return nullptr; // LCOV_EXCL_LINE
|
||||
@@ -562,7 +563,7 @@ canAddHolding(ReadView const& view, Issue const& issue)
|
||||
return tesSUCCESS; // No special checks for XRP
|
||||
}
|
||||
|
||||
auto const issuer = view.read(keylet::account(issue.getIssuer()));
|
||||
auto const issuer = AccountRootEntryR(issue.getIssuer(), view);
|
||||
if (!issuer)
|
||||
{
|
||||
return terNO_ACCOUNT;
|
||||
@@ -738,6 +739,8 @@ directSendNoFeeIOU(
|
||||
auto const senderFreezeFlag = bSenderHigh ? lsfHighFreeze : lsfLowFreeze;
|
||||
auto const receiverReserveFlag = bSenderHigh ? lsfLowReserve : lsfHighReserve;
|
||||
|
||||
AccountRootEntryW senderSle(uSenderID, view, j);
|
||||
|
||||
// FIXME This NEEDS to be cleaned up and simplified. It's impossible
|
||||
// for anyone to understand.
|
||||
if (saBefore > beast::kZero
|
||||
@@ -746,8 +749,7 @@ directSendNoFeeIOU(
|
||||
// Sender is zero or negative.
|
||||
&& sleRippleState->isFlag(senderReserveFlag)
|
||||
// Sender reserve is set.
|
||||
&& sleRippleState->isFlag(senderNoRippleFlag) !=
|
||||
view.read(keylet::account(uSenderID))->isFlag(lsfDefaultRipple) &&
|
||||
&& sleRippleState->isFlag(senderNoRippleFlag) != senderSle->isFlag(lsfDefaultRipple) &&
|
||||
!sleRippleState->isFlag(senderFreezeFlag) &&
|
||||
!sleRippleState->getFieldAmount(bSenderHigh ? sfHighLimit : sfLowLimit)
|
||||
// Sender trust limit is 0.
|
||||
@@ -758,9 +760,9 @@ directSendNoFeeIOU(
|
||||
// Sender quality out is 0.
|
||||
{
|
||||
// Clear the reserve of the sender, possibly delete the line!
|
||||
auto const currentSponsor = getLedgerEntryReserveSponsor(
|
||||
auto currentSponsor = getLedgerEntryReserveSponsor(
|
||||
view, sleRippleState, !bSenderHigh ? sfLowSponsor : sfHighSponsor);
|
||||
decreaseOwnerCount(view, view.peek(keylet::account(uSenderID)), currentSponsor, 1, j);
|
||||
senderSle.decreaseOwnerCount(currentSponsor, 1);
|
||||
|
||||
removeSponsorFromLedgerEntry(
|
||||
sleRippleState, !bSenderHigh ? sfLowSponsor : sfHighSponsor);
|
||||
@@ -805,7 +807,7 @@ directSendNoFeeIOU(
|
||||
<< to_string(uSenderID) << " -> " << to_string(uReceiverID) << " : "
|
||||
<< saAmount.getFullText();
|
||||
|
||||
auto const sleAccount = view.peek(keylet::account(uReceiverID));
|
||||
auto sleAccount = AccountRootEntryW(uReceiverID, view);
|
||||
if (!sleAccount)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -817,7 +819,7 @@ directSendNoFeeIOU(
|
||||
uSenderID,
|
||||
uReceiverID,
|
||||
index.key,
|
||||
sleAccount,
|
||||
sleAccount.mutableRawSle(),
|
||||
false,
|
||||
noRipple,
|
||||
false,
|
||||
@@ -1010,10 +1012,12 @@ accountSendIOU(
|
||||
*/
|
||||
TER terResult(tesSUCCESS);
|
||||
|
||||
SLE::pointer const sender =
|
||||
uSenderID != beast::kZero ? view.peek(keylet::account(uSenderID)) : SLE::pointer();
|
||||
SLE::pointer const receiver =
|
||||
uReceiverID != beast::kZero ? view.peek(keylet::account(uReceiverID)) : SLE::pointer();
|
||||
SLE::pointer const sender = uSenderID != beast::kZero
|
||||
? AccountRootEntryW(uSenderID, view).mutableRawSle()
|
||||
: SLE::pointer();
|
||||
SLE::pointer const receiver = uReceiverID != beast::kZero
|
||||
? AccountRootEntryW(uReceiverID, view).mutableRawSle()
|
||||
: SLE::pointer();
|
||||
|
||||
if (auto stream = j.trace())
|
||||
{
|
||||
@@ -1106,8 +1110,9 @@ accountSendMultiIOU(
|
||||
* ensure that transfers are balanced.
|
||||
*/
|
||||
|
||||
SLE::pointer const sender =
|
||||
senderID != beast::kZero ? view.peek(keylet::account(senderID)) : SLE::pointer();
|
||||
SLE::pointer const sender = senderID != beast::kZero
|
||||
? AccountRootEntryW(senderID, view).mutableRawSle()
|
||||
: SLE::pointer();
|
||||
|
||||
if (auto stream = j.trace())
|
||||
{
|
||||
@@ -1138,8 +1143,9 @@ accountSendMultiIOU(
|
||||
if (!amount || (senderID == receiverID))
|
||||
continue;
|
||||
|
||||
SLE::pointer const receiver =
|
||||
receiverID != beast::kZero ? view.peek(keylet::account(receiverID)) : SLE::pointer();
|
||||
SLE::pointer const receiver = receiverID != beast::kZero
|
||||
? AccountRootEntryW(receiverID, view).mutableRawSle()
|
||||
: SLE::pointer();
|
||||
|
||||
if (auto stream = j.trace())
|
||||
{
|
||||
@@ -1591,8 +1597,8 @@ transferXRP(
|
||||
XRPL_ASSERT(from != to, "xrpl::transferXRP : sender is not receiver");
|
||||
XRPL_ASSERT(amount.native(), "xrpl::transferXRP : amount is XRP");
|
||||
|
||||
SLE::pointer const sender = view.peek(keylet::account(from));
|
||||
SLE::pointer const receiver = view.peek(keylet::account(to));
|
||||
SLE::pointer const sender = AccountRootEntryW(from, view).mutableRawSle();
|
||||
SLE::pointer const receiver = AccountRootEntryW(to, view).mutableRawSle();
|
||||
if (!sender || !receiver)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <xrpl/json/to_string.h> // IWYU pragma: keep
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DelegateHelpers.h>
|
||||
@@ -586,7 +587,7 @@ Transactor::checkFee(PreclaimContext const& ctx, XRPAmount baseFee)
|
||||
|
||||
if (feePayer.type == FeePayerType::SponsorCoSigned)
|
||||
{
|
||||
auto const sponsorReserve = accountReserve(ctx.view, payerSle, ctx.j);
|
||||
auto const sponsorReserve = accountReserve(ctx.view, feePayer.id, ctx.j);
|
||||
maxSpendable = payerSle->getFieldAmount(sfBalance).xrp() - sponsorReserve;
|
||||
}
|
||||
else
|
||||
@@ -652,7 +653,7 @@ Transactor::payFee()
|
||||
XRPAmount spendable = balance;
|
||||
if (feePayer.type == FeePayerType::SponsorCoSigned)
|
||||
{
|
||||
auto const sponsorReserve = accountReserve(view(), sle, j_);
|
||||
auto const sponsorReserve = accountReserve(view(), feePayer.id, j_);
|
||||
// max(balance - reserve, 0) with overflow handling
|
||||
spendable = balance > sponsorReserve ? balance - sponsorReserve : beast::kZero;
|
||||
}
|
||||
@@ -700,7 +701,7 @@ Transactor::checkSeqProxy(ReadView const& view, STTx const& tx, beast::Journal j
|
||||
{
|
||||
auto const id = tx.getAccountID(sfAccount);
|
||||
|
||||
auto const sle = view.read(keylet::account(id));
|
||||
auto const sle = AccountRootEntryR(id, view);
|
||||
|
||||
if (!sle)
|
||||
{
|
||||
@@ -765,7 +766,7 @@ Transactor::checkPriorTxAndLastLedger(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const id = ctx.tx.getAccountID(sfAccount);
|
||||
|
||||
auto const sle = ctx.view.read(keylet::account(id));
|
||||
auto const sle = AccountRootEntryR(id, ctx.view);
|
||||
|
||||
if (!sle)
|
||||
{
|
||||
@@ -835,7 +836,7 @@ 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));
|
||||
auto sleAccount = AccountRootEntryW(account, view);
|
||||
if (!sleAccount)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
@@ -885,19 +886,19 @@ Transactor::apply()
|
||||
|
||||
// If the transactor requires a valid account and the transaction doesn't
|
||||
// list one, preflight will have already a flagged a failure.
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
auto sle = AccountRootEntryW(accountID_, view());
|
||||
|
||||
// sle must exist except for transactions
|
||||
// that allow zero account.
|
||||
XRPL_ASSERT(
|
||||
sle != nullptr || accountID_ == beast::kZero,
|
||||
sle.exists() || accountID_ == beast::kZero,
|
||||
"xrpl::Transactor::apply : non-null SLE or zero account");
|
||||
|
||||
if (sle)
|
||||
{
|
||||
preFeeBalance_ = STAmount{(*sle)[sfBalance]}.xrp();
|
||||
|
||||
TER result = consumeSeqProxy(sle);
|
||||
TER result = consumeSeqProxy(sle.mutableRawSle());
|
||||
if (!isTesSuccess(result))
|
||||
return result;
|
||||
|
||||
@@ -908,7 +909,7 @@ Transactor::apply()
|
||||
if (sle->isFieldPresent(sfAccountTxnID))
|
||||
sle->setFieldH256(sfAccountTxnID, ctx_.tx.getTransactionID());
|
||||
|
||||
view().update(sle);
|
||||
sle.update();
|
||||
}
|
||||
|
||||
return doApply();
|
||||
@@ -925,7 +926,7 @@ Transactor::checkSign(
|
||||
bool permitUncreatedAccount)
|
||||
{
|
||||
{
|
||||
auto const sle = view.read(keylet::account(idAccount));
|
||||
auto const sle = AccountRootEntryR(idAccount, view);
|
||||
|
||||
if ((view.rules().enabled(featureLendingProtocol) ||
|
||||
view.rules().enabled(featureBatchV1_1) || view.rules().enabled(fixCleanup3_3_0)) &&
|
||||
@@ -991,7 +992,7 @@ Transactor::checkSign(
|
||||
|
||||
// Look up the account.
|
||||
auto const idSigner = calcAccountID(PublicKey(makeSlice(pkSigner)));
|
||||
auto const sleAccount = view.read(keylet::account(idAccount));
|
||||
auto const sleAccount = AccountRootEntryR(idAccount, view);
|
||||
if (!sleAccount)
|
||||
{
|
||||
// An account that does not exist yet can only be authorized by its own
|
||||
@@ -1004,7 +1005,7 @@ Transactor::checkSign(
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
return checkSingleSign(view, idSigner, idAccount, sleAccount, j);
|
||||
return checkSingleSign(view, idSigner, idAccount, sleAccount.rawSle(), j);
|
||||
}
|
||||
|
||||
NotTEC
|
||||
@@ -1153,7 +1154,7 @@ Transactor::checkMultiSign(
|
||||
|
||||
// In any of these cases we need to know whether the account is in
|
||||
// the ledger. Determine that now.
|
||||
auto const sleTxSignerRoot = view.read(keylet::account(txSignerAcctID));
|
||||
auto const sleTxSignerRoot = AccountRootEntryR(txSignerAcctID, view);
|
||||
|
||||
if (signingAcctIDFromPubKey == txSignerAcctID)
|
||||
{
|
||||
@@ -1296,7 +1297,7 @@ Transactor::reset(XRPAmount fee)
|
||||
{
|
||||
ctx_.discard();
|
||||
|
||||
auto const txnAcct = view().peek(keylet::account(ctx_.tx.getAccountID(sfAccount)));
|
||||
auto txnAcct = AccountRootEntryW(ctx_.tx.getAccountID(sfAccount), view());
|
||||
|
||||
// The account should never be missing from the ledger. But if it
|
||||
// is missing then we can't very well charge it a fee, can we?
|
||||
@@ -1331,7 +1332,7 @@ Transactor::reset(XRPAmount fee)
|
||||
XRPAmount spendable = balance;
|
||||
if (feePayer.type == FeePayerType::SponsorCoSigned)
|
||||
{
|
||||
auto const sponsorReserve = accountReserve(view(), payerSle, j_);
|
||||
auto const sponsorReserve = accountReserve(view(), feePayer.id, j_);
|
||||
// max(balance - reserve, 0) with overflow handling
|
||||
spendable = balance > sponsorReserve ? balance - sponsorReserve : beast::kZero;
|
||||
}
|
||||
@@ -1364,13 +1365,13 @@ Transactor::reset(XRPAmount fee)
|
||||
payerSle->setFieldAmount(feePayer.balanceField, feeAmountAfter);
|
||||
}
|
||||
|
||||
TER const ter{consumeSeqProxy(txnAcct)};
|
||||
TER const ter{consumeSeqProxy(txnAcct.mutableRawSle())};
|
||||
XRPL_ASSERT(isTesSuccess(ter), "xrpl::Transactor::reset : result is tesSUCCESS");
|
||||
|
||||
if (isTesSuccess(ter))
|
||||
{
|
||||
view().update(txnAcct);
|
||||
if (payerSle != txnAcct)
|
||||
txnAcct.update();
|
||||
if (payerSle != txnAcct.mutableRawSle())
|
||||
view().update(payerSle);
|
||||
}
|
||||
|
||||
|
||||
@@ -735,6 +735,15 @@ NoDeepFreezeTrustLinesWithoutFreeze::finalize(
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
isPseudoAccountSle(SLE::ConstRef sleAcct)
|
||||
{
|
||||
auto const& fields = getPseudoAccountFields();
|
||||
return sleAcct && sleAcct->getType() == ltACCOUNT_ROOT &&
|
||||
std::ranges::any_of(
|
||||
fields, [&sleAcct](SField const* sf) { return sleAcct->isFieldPresent(*sf); });
|
||||
}
|
||||
|
||||
void
|
||||
ValidNewAccountRoot::visitEntry(bool, SLE::ConstRef before, SLE::ConstRef after)
|
||||
{
|
||||
@@ -742,7 +751,7 @@ ValidNewAccountRoot::visitEntry(bool, SLE::ConstRef before, SLE::ConstRef after)
|
||||
{
|
||||
accountsCreated_++;
|
||||
accountSeq_ = (*after)[sfSequence];
|
||||
pseudoAccount_ = isPseudoAccount(after);
|
||||
pseudoAccount_ = isPseudoAccountSle(after);
|
||||
flags_ = after->getFlags();
|
||||
}
|
||||
}
|
||||
@@ -1020,9 +1029,9 @@ ValidPseudoAccounts::visitEntry(bool isDelete, SLE::ConstRef before, SLE::ConstR
|
||||
if (after && after->getType() == ltACCOUNT_ROOT)
|
||||
{
|
||||
bool const isPseudo = [&]() {
|
||||
// isPseudoAccount checks that any of the pseudo-account fields are
|
||||
// set.
|
||||
if (isPseudoAccount(after))
|
||||
// isPseudoAccountSle checks that any of the pseudo-account fields
|
||||
// are set.
|
||||
if (isPseudoAccountSle(after))
|
||||
return true;
|
||||
// Not all pseudo-accounts have a zero sequence, but all accounts
|
||||
// with a zero sequence had better be pseudo-accounts.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/invariants/InvariantCheck.h>
|
||||
#include <xrpl/tx/invariants/InvariantCheckPrivilege.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -893,7 +894,7 @@ ValidMPTTransfer::visitEntry(
|
||||
// no trace of its pseudo-account status in the post-transaction view
|
||||
// isAuthorized() sees at finalize() time.
|
||||
if (before && before->getType() == ltACCOUNT_ROOT)
|
||||
pseudoAccountsBefore_[before->at(sfAccount)] = isPseudoAccount(before);
|
||||
pseudoAccountsBefore_[before->at(sfAccount)] = isPseudoAccountSle(before);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -740,7 +740,7 @@ ValidVault::finalize(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isPseudoAccount(sleSharesIssuer))
|
||||
if (!isPseudoAccount(AccountRootEntryR(sleSharesIssuer, view)))
|
||||
{
|
||||
JLOG(j.fatal()) //
|
||||
<< "Invariant failed: shares issuer must be a "
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -836,7 +837,7 @@ DirectStepI<TDerived>::check(StrandContext const& ctx) const
|
||||
return temBAD_PATH;
|
||||
}
|
||||
|
||||
auto const sleSrc = ctx.view.read(keylet::account(src_));
|
||||
auto const sleSrc = AccountRootEntryR(src_, ctx.view);
|
||||
if (!sleSrc)
|
||||
{
|
||||
JLOG(j_.warn()) << "DirectStepI: can't receive IOUs from non-existent issuer: " << src_;
|
||||
@@ -902,7 +903,7 @@ DirectStepI<TDerived>::check(StrandContext const& ctx) const
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<TDerived const*>(this)->check(ctx, sleSrc);
|
||||
return static_cast<TDerived const*>(this)->check(ctx, sleSrc.rawSle());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -865,7 +866,7 @@ MPTEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
return temBAD_PATH;
|
||||
}
|
||||
|
||||
auto const sleSrc = ctx.view.read(keylet::account(src_));
|
||||
auto const sleSrc = AccountRootEntryR(src_, ctx.view);
|
||||
if (!sleSrc)
|
||||
{
|
||||
JLOG(j_.warn()) << "MPTEndpointStep: can't receive MPT from non-existent issuer: " << src_;
|
||||
@@ -928,7 +929,7 @@ MPTEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
return temBAD_PATH;
|
||||
}
|
||||
|
||||
return static_cast<TDerived const*>(this)->check(ctx, sleSrc);
|
||||
return static_cast<TDerived const*>(this)->check(ctx, sleSrc.rawSle());
|
||||
}
|
||||
|
||||
template <class TDerived>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -342,7 +343,7 @@ XRPEndpointStep<TDerived>::check(StrandContext const& ctx) const
|
||||
return temBAD_PATH;
|
||||
}
|
||||
|
||||
auto sleAcc = ctx.view.read(keylet::account(acc_));
|
||||
auto sleAcc = AccountRootEntryR(acc_, ctx.view);
|
||||
if (!sleAcc)
|
||||
{
|
||||
JLOG(j_.warn()) << "XRPEndpointStep: can't send or receive XRP from "
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
@@ -224,7 +225,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx)
|
||||
AccountID const account{ctx.tx[sfAccount]};
|
||||
AccountID const dst{ctx.tx[sfDestination]};
|
||||
|
||||
auto sleDst = ctx.view.read(keylet::account(dst));
|
||||
auto sleDst = AccountRootEntryR(dst, ctx.view);
|
||||
|
||||
if (!sleDst)
|
||||
return tecNO_DST;
|
||||
@@ -250,7 +251,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
auto sleAccount = ctx.view.read(keylet::account(account));
|
||||
auto sleAccount = AccountRootEntryR(account, ctx.view);
|
||||
XRPL_ASSERT(sleAccount, "xrpl::AccountDelete::preclaim : non-null account");
|
||||
if (!sleAccount)
|
||||
return terNO_ACCOUNT;
|
||||
@@ -353,11 +354,11 @@ AccountDelete::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
AccountDelete::doApply()
|
||||
{
|
||||
auto src = view().peek(keylet::account(accountID_));
|
||||
auto src = AccountRootEntryW(accountID_, view());
|
||||
XRPL_ASSERT(src, "xrpl::AccountDelete::doApply : non-null source account");
|
||||
|
||||
auto const dstID = ctx_.tx[sfDestination];
|
||||
auto dst = view().peek(keylet::account(dstID));
|
||||
auto dst = AccountRootEntryW(dstID, view());
|
||||
XRPL_ASSERT(dst, "xrpl::AccountDelete::doApply : non-null destination account");
|
||||
|
||||
if (!src || !dst)
|
||||
@@ -365,8 +366,8 @@ AccountDelete::doApply()
|
||||
|
||||
if (ctx_.tx.isFieldPresent(sfCredentialIDs))
|
||||
{
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_.tx, ctx_.view(), accountID_, dstID, dst, ctx_.journal);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), accountID_, dstID, dst.rawSle(), ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
@@ -407,7 +408,7 @@ AccountDelete::doApply()
|
||||
if (src->isFieldPresent(sfSponsor))
|
||||
{
|
||||
auto const sponsorID = src->getAccountID(sfSponsor);
|
||||
auto sponsorSle = view().peek(keylet::account(sponsorID));
|
||||
auto sponsorSle = AccountRootEntryW(sponsorID, view());
|
||||
|
||||
if (!sponsorSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
@@ -425,7 +426,7 @@ AccountDelete::doApply()
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
}
|
||||
sponsorSle->at(sfSponsoringAccountCount) = sponsoringAccountCount - 1;
|
||||
view().update(sponsorSle);
|
||||
sponsorSle.update();
|
||||
|
||||
// Following line might look redundant, but without it, sfSponsor
|
||||
// would end up remaining in after-ltAccountRoot during the
|
||||
@@ -448,8 +449,8 @@ AccountDelete::doApply()
|
||||
if (remainingBalance > XRPAmount(0) && dst->isFlag(lsfPasswordSpent))
|
||||
dst->clearFlag(lsfPasswordSpent);
|
||||
|
||||
view().update(dst);
|
||||
view().erase(src);
|
||||
dst.update();
|
||||
src.erase();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -170,7 +171,7 @@ AccountSet::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const id = ctx.tx[sfAccount];
|
||||
|
||||
auto const sle = ctx.view.read(keylet::account(id));
|
||||
auto const sle = AccountRootEntryR(id, ctx.view);
|
||||
if (!sle)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
@@ -224,7 +225,7 @@ AccountSet::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
AccountSet::doApply()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
auto sle = AccountRootEntryW(accountID_, view());
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -582,7 +583,7 @@ AccountSet::doApply()
|
||||
if (uFlagsIn != uFlagsOut)
|
||||
sle->setFieldU32(sfFlags, uFlagsOut);
|
||||
|
||||
ctx_.view().update(sle);
|
||||
sle.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
@@ -25,7 +26,7 @@ SetRegularKey::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
if (calcAccountID(PublicKey(makeSlice(spk))) == id)
|
||||
{
|
||||
auto const sle = view.read(keylet::account(id));
|
||||
auto const sle = AccountRootEntryR(id, view);
|
||||
|
||||
if (sle && !sle->isFlag(lsfPasswordSpent))
|
||||
{
|
||||
@@ -53,7 +54,7 @@ SetRegularKey::preflight(PreflightContext const& ctx)
|
||||
TER
|
||||
SetRegularKey::doApply()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
auto sle = AccountRootEntryW(accountID_, view());
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -73,7 +74,7 @@ SetRegularKey::doApply()
|
||||
sle->makeFieldAbsent(sfRegularKey);
|
||||
}
|
||||
|
||||
ctx_.view().update(sle);
|
||||
sle.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -213,8 +214,9 @@ removeSignersFromLedger(
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
AccountRootEntryW accountSle(accountKeylet, view);
|
||||
decreaseOwnerCountForObject(
|
||||
view, view.peek(accountKeylet), signers, removeFromOwnerCount, registry.getJournal("View"));
|
||||
view, accountSle, signers, removeFromOwnerCount, registry.getJournal("View"));
|
||||
|
||||
view.erase(signers);
|
||||
|
||||
@@ -309,7 +311,7 @@ SignerListSet::replaceSignerList()
|
||||
ctx_.registry, view(), accountKeylet, ownerDirKeylet, signerListKeylet, j_))
|
||||
return ter;
|
||||
|
||||
auto const sle = view().peek(accountKeylet);
|
||||
auto sle = AccountRootEntryW(accountKeylet, view(), ctx_.journal);
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -319,12 +321,8 @@ SignerListSet::replaceSignerList()
|
||||
// We check the reserve against the starting balance because we want to
|
||||
// allow dipping into the reserve to pay fees. This behavior is consistent
|
||||
// with TicketCreate.
|
||||
if (auto const ret = checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
{.ownerCountDelta = kAddedOwnerCount},
|
||||
ctx_.journal);
|
||||
if (auto const ret = sle.checkReserve(
|
||||
ctx_.getApplyViewContext(), preFeeBalance_, {.ownerCountDelta = kAddedOwnerCount});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -333,7 +331,6 @@ SignerListSet::replaceSignerList()
|
||||
view().insert(signerList);
|
||||
writeSignersToSLE(signerList, flags);
|
||||
|
||||
auto viewJ = ctx_.registry.get().getJournal("View");
|
||||
// Add the signer list to the account's directory.
|
||||
auto const page =
|
||||
ctx_.view().dirInsert(ownerDirKeylet, signerListKeylet, describeOwnerDir(accountID_));
|
||||
@@ -348,7 +345,7 @@ SignerListSet::replaceSignerList()
|
||||
|
||||
// If we succeeded, the new entry counts against the
|
||||
// creator's reserve.
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sle, kAddedOwnerCount, viewJ);
|
||||
sle.increaseOwnerCount(ctx_.getApplyViewContext(), kAddedOwnerCount);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), signerList);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -359,7 +356,7 @@ SignerListSet::destroySignerList()
|
||||
auto const accountKeylet = keylet::account(accountID_);
|
||||
// Destroying the signer list is only allowed if either the master key
|
||||
// is enabled or there is a regular key.
|
||||
SLE::pointer const ledgerEntry = view().peek(accountKeylet);
|
||||
auto const ledgerEntry = AccountRootEntryW(accountKeylet, view());
|
||||
if (!ledgerEntry)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/RawView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -125,8 +126,7 @@ checkAttestationPublicKey(
|
||||
|
||||
AccountID const accountFromPK = calcAccountID(pk);
|
||||
|
||||
if (auto const sleAttestationSigningAccount =
|
||||
view.read(keylet::account(attestationSignerAccount)))
|
||||
if (auto const sleAttestationSigningAccount = AccountRootEntryR(attestationSignerAccount, view))
|
||||
{
|
||||
if (accountFromPK == attestationSignerAccount)
|
||||
{
|
||||
@@ -404,7 +404,7 @@ transferHelper(
|
||||
return tesSUCCESS;
|
||||
|
||||
auto const dstK = keylet::account(dst);
|
||||
if (auto sleDst = psb.read(dstK))
|
||||
if (auto sleDst = AccountRootEntryR(dstK, psb))
|
||||
{
|
||||
// Check dst tag and deposit auth
|
||||
|
||||
@@ -430,13 +430,13 @@ transferHelper(
|
||||
|
||||
if (amt.native())
|
||||
{
|
||||
auto const sleSrc = psb.peek(keylet::account(src));
|
||||
auto sleSrc = AccountRootEntryW(src, psb, j);
|
||||
XRPL_ASSERT(sleSrc, "xrpl::transferHelper : non-null source account");
|
||||
if (!sleSrc)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
{
|
||||
auto const reserve = accountReserve(psb, sleSrc, j);
|
||||
auto const reserve = sleSrc.reserve();
|
||||
|
||||
auto const availableBalance = [&]() -> STAmount {
|
||||
STAmount curBal = (*sleSrc)[sfBalance];
|
||||
@@ -455,7 +455,7 @@ transferHelper(
|
||||
}
|
||||
}
|
||||
|
||||
auto sleDst = psb.peek(dstK);
|
||||
auto sleDst = AccountRootEntryW(dstK, psb);
|
||||
if (!sleDst)
|
||||
{
|
||||
if (canCreate == CanCreateDstPolicy::No)
|
||||
@@ -470,17 +470,17 @@ transferHelper(
|
||||
}
|
||||
|
||||
// Create the account.
|
||||
sleDst = std::make_shared<SLE>(dstK);
|
||||
sleDst.newSLE();
|
||||
sleDst->setAccountID(sfAccount, dst);
|
||||
sleDst->setFieldU32(sfSequence, psb.seq());
|
||||
|
||||
psb.insert(sleDst);
|
||||
sleDst.insert();
|
||||
}
|
||||
|
||||
(*sleSrc)[sfBalance] = (*sleSrc)[sfBalance] - amt;
|
||||
(*sleDst)[sfBalance] = (*sleDst)[sfBalance] + amt;
|
||||
psb.update(sleSrc);
|
||||
psb.update(sleDst);
|
||||
sleSrc.update();
|
||||
sleDst.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -724,7 +724,7 @@ finalizeClaimHelper(
|
||||
auto const cidOwner = (*sleClaimID)[sfAccount];
|
||||
{
|
||||
// Remove the claim id
|
||||
auto const sleOwner = outerSb.peek(keylet::account(cidOwner));
|
||||
auto sleOwner = AccountRootEntryW(cidOwner, outerSb);
|
||||
auto const page = (*sleClaimID)[sfOwnerNode];
|
||||
if (!outerSb.dirRemove(keylet::ownerDir(cidOwner), page, sleClaimID->key(), true))
|
||||
{
|
||||
@@ -759,7 +759,7 @@ getSignersListAndQuorum(ReadView const& view, SLE const& sleBridge, beast::Journ
|
||||
std::uint32_t q = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
AccountID const thisDoor = sleBridge[sfAccount];
|
||||
auto const sleDoor = [&] { return view.read(keylet::account(thisDoor)); }();
|
||||
auto const sleDoor = [&] { return AccountRootEntryR(thisDoor, view); }();
|
||||
|
||||
if (!sleDoor)
|
||||
{
|
||||
@@ -1036,7 +1036,7 @@ applyCreateAccountAttestations(
|
||||
|
||||
// Check reserve
|
||||
auto const balance = (*sleDoor)[sfBalance];
|
||||
auto const reserve = accountReserve(psb, sleDoor, j, {.ownerCountDelta = 1});
|
||||
auto const reserve = AccountRootEntryR(sleDoor, psb, j).reserve({.ownerCountDelta = 1});
|
||||
|
||||
if (balance < reserve)
|
||||
return std::unexpected(tecINSUFFICIENT_RESERVE);
|
||||
@@ -1145,7 +1145,9 @@ applyCreateAccountAttestations(
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Reserve was already checked
|
||||
increaseOwnerCount(psb, sleDoor, {}, 1, j);
|
||||
AccountRootEntryW doorSle(doorK, psb, j);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
doorSle.increaseOwnerCount(noSponsor, 1);
|
||||
psb.insert(createdSleClaimID);
|
||||
psb.update(sleDoor);
|
||||
}
|
||||
@@ -1429,7 +1431,7 @@ XChainCreateBridge::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
if (!isXRP(bridgeSpec.issue(chainType)))
|
||||
{
|
||||
auto const sleIssuer = ctx.view.read(keylet::account(bridgeSpec.issue(chainType).account));
|
||||
auto const sleIssuer = AccountRootEntryR(bridgeSpec.issue(chainType).account, ctx.view);
|
||||
|
||||
if (!sleIssuer)
|
||||
return tecNO_ISSUER;
|
||||
@@ -1442,12 +1444,12 @@ XChainCreateBridge::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
{
|
||||
// Check reserve
|
||||
auto const sleAcc = ctx.view.read(keylet::account(account));
|
||||
auto const sleAcc = AccountRootEntryR(account, ctx.view, ctx.j);
|
||||
if (!sleAcc)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
auto const balance = (*sleAcc)[sfBalance];
|
||||
auto const reserve = accountReserve(ctx.view, sleAcc, ctx.j, {.ownerCountDelta = 1});
|
||||
auto const reserve = sleAcc.reserve({.ownerCountDelta = 1});
|
||||
|
||||
if (balance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
@@ -1464,7 +1466,7 @@ XChainCreateBridge::doApply()
|
||||
auto const reward = ctx_.tx[sfSignatureReward];
|
||||
auto const minAccountCreate = ctx_.tx[~sfMinAccountCreateAmount];
|
||||
|
||||
auto const sleAcct = ctx_.view().peek(keylet::account(account));
|
||||
auto sleAcct = AccountRootEntryW(account, ctx_.view(), ctx_.journal);
|
||||
if (!sleAcct)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -1492,10 +1494,11 @@ XChainCreateBridge::doApply()
|
||||
(*sleBridge)[sfOwnerNode] = *page;
|
||||
}
|
||||
|
||||
increaseOwnerCount(ctx_.view(), sleAcct, {}, 1, ctx_.journal);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
sleAcct.increaseOwnerCount(noSponsor, 1);
|
||||
|
||||
ctx_.view().insert(sleBridge);
|
||||
ctx_.view().update(sleAcct);
|
||||
sleAcct.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -1575,7 +1578,7 @@ BridgeModify::doApply()
|
||||
auto const minAccountCreate = ctx_.tx[~sfMinAccountCreateAmount];
|
||||
bool const clearAccountCreate = ctx_.tx.isFlag(tfClearAccountCreateAmount);
|
||||
|
||||
auto const sleAcct = ctx_.view().peek(keylet::account(account));
|
||||
auto const sleAcct = AccountRootEntryW(account, ctx_.view());
|
||||
if (!sleAcct)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -1633,7 +1636,7 @@ XChainClaim::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_ENTRY;
|
||||
}
|
||||
|
||||
if (!ctx.view.read(keylet::account(ctx.tx[sfDestination])))
|
||||
if (!AccountRootEntryR(ctx.tx[sfDestination], ctx.view))
|
||||
{
|
||||
return tecNO_DST;
|
||||
}
|
||||
@@ -1738,7 +1741,7 @@ XChainClaim::doApply()
|
||||
// `finalizeClaimHelper`. Since `finalizeClaimHelper` can create child
|
||||
// views, it's important that the sle's lifetime doesn't overlap.
|
||||
|
||||
auto const sleAcct = psb.peek(keylet::account(account));
|
||||
auto const sleAcct = AccountRootEntryW(account, psb);
|
||||
auto const sleBridge = peekBridge(psb, bridgeSpec);
|
||||
auto const sleClaimID = psb.peek(claimIDKeylet);
|
||||
|
||||
@@ -1919,7 +1922,7 @@ XChainCommit::doApply()
|
||||
auto const amount = ctx_.tx[sfAmount];
|
||||
auto const bridgeSpec = ctx_.tx[sfXChainBridge];
|
||||
|
||||
auto const sleAccount = psb.read(keylet::account(account));
|
||||
auto const sleAccount = AccountRootEntryR(account, psb);
|
||||
if (!sleAccount)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -1990,12 +1993,12 @@ XChainCreateClaimID::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
{
|
||||
// Check reserve
|
||||
auto const sleAcc = ctx.view.read(keylet::account(account));
|
||||
auto const sleAcc = AccountRootEntryR(account, ctx.view, ctx.j);
|
||||
if (!sleAcc)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
auto const balance = (*sleAcc)[sfBalance];
|
||||
auto const reserve = accountReserve(ctx.view, sleAcc, ctx.j, {.ownerCountDelta = 1});
|
||||
auto const reserve = sleAcc.reserve({.ownerCountDelta = 1});
|
||||
if (balance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
@@ -2011,7 +2014,7 @@ XChainCreateClaimID::doApply()
|
||||
auto const reward = ctx_.tx[sfSignatureReward];
|
||||
auto const otherChainSrc = ctx_.tx[sfOtherChainSource];
|
||||
|
||||
auto const sleAcct = ctx_.view().peek(keylet::account(account));
|
||||
auto sleAcct = AccountRootEntryW(account, ctx_.view(), ctx_.journal);
|
||||
if (!sleAcct)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -2053,11 +2056,12 @@ XChainCreateClaimID::doApply()
|
||||
(*sleClaimID)[sfOwnerNode] = *page;
|
||||
}
|
||||
|
||||
increaseOwnerCount(ctx_.view(), sleAcct, {}, 1, ctx_.journal);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
sleAcct.increaseOwnerCount(noSponsor, 1);
|
||||
|
||||
ctx_.view().insert(sleClaimID);
|
||||
ctx_.view().update(sleBridge);
|
||||
ctx_.view().update(sleAcct);
|
||||
sleAcct.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -2195,7 +2199,7 @@ XChainCreateAccountCommit::doApply()
|
||||
STAmount const reward = ctx_.tx[sfSignatureReward];
|
||||
STXChainBridge const bridge = ctx_.tx[sfXChainBridge];
|
||||
|
||||
auto const sle = psb.peek(keylet::account(account));
|
||||
auto const sle = AccountRootEntryW(account, psb);
|
||||
if (!sle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
@@ -112,8 +113,8 @@ CheckCash::preclaim(PreclaimContext const& ctx)
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
{
|
||||
auto const sleSrc = ctx.view.read(keylet::account(srcId));
|
||||
auto const sleDst = ctx.view.read(keylet::account(dstId));
|
||||
auto const sleSrc = AccountRootEntryR(srcId, ctx.view);
|
||||
auto const sleDst = AccountRootEntryR(dstId, ctx.view);
|
||||
if (!sleSrc || !sleDst)
|
||||
{
|
||||
// If the check exists this should never occur.
|
||||
@@ -201,7 +202,7 @@ CheckCash::preclaim(PreclaimContext const& ctx)
|
||||
auto const sleTrustLine =
|
||||
ctx.view.read(keylet::trustLine(dstId, issuerId, currency));
|
||||
|
||||
auto const sleIssuer = ctx.view.read(keylet::account(issuerId));
|
||||
auto const sleIssuer = AccountRootEntryR(issuerId, ctx.view);
|
||||
if (!sleIssuer)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Can't receive IOUs from "
|
||||
@@ -253,7 +254,7 @@ CheckCash::preclaim(PreclaimContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
},
|
||||
[&](MPTIssue const& issue) -> TER {
|
||||
auto const sleIssuer = ctx.view.read(keylet::account(issuerId));
|
||||
auto const sleIssuer = AccountRootEntryR(issuerId, ctx.view);
|
||||
if (!sleIssuer)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Can't receive MPTs from "
|
||||
@@ -406,23 +407,18 @@ CheckCash::doApply()
|
||||
optDeliverMin ? maxDeliverMin() : ctx_.tx.getFieldAmount(sfAmount)};
|
||||
|
||||
auto applyViewContext = ApplyViewContext({.view = psb, .tx = ctx_.tx});
|
||||
auto const sponsorSle = getTxReserveSponsor(applyViewContext);
|
||||
auto sponsorSle = getTxReserveSponsor(applyViewContext);
|
||||
if (!sponsorSle)
|
||||
return sponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
// Check reserve. Return destination account SLE if enough reserve,
|
||||
// otherwise return nullptr.
|
||||
auto checkDstReserve = [&]() -> SLE::pointer {
|
||||
auto sleDst = psb.peek(keylet::account(accountID_));
|
||||
auto sleDst = AccountRootEntryW(accountID_, psb, j_);
|
||||
|
||||
// Can the account cover the trust line's or MPT reserve?
|
||||
if (auto const ret = checkReserve(
|
||||
applyViewContext,
|
||||
sleDst,
|
||||
preFeeBalance_,
|
||||
*sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
j_);
|
||||
if (auto const ret = sleDst.checkReserve(
|
||||
applyViewContext, preFeeBalance_, *sponsorSle, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
JLOG(j_.trace()) << "Trust line does not exist. "
|
||||
@@ -430,7 +426,7 @@ CheckCash::doApply()
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
return sleDst;
|
||||
return sleDst.mutableRawSle();
|
||||
};
|
||||
|
||||
std::optional<Keylet> trustLineKey;
|
||||
@@ -486,7 +482,9 @@ CheckCash::doApply()
|
||||
Issue(currency, accountID_), // limit of zero
|
||||
0, // quality in
|
||||
0, // quality out
|
||||
*sponsorSle, // sponsor
|
||||
sponsorSle->has_value() // sponsor
|
||||
? (*sponsorSle)->mutableRawSle()
|
||||
: SLE::pointer{},
|
||||
viewJ); // journal
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
@@ -533,8 +531,14 @@ CheckCash::doApply()
|
||||
if (sleDst == nullptr)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
if (auto const err =
|
||||
checkCreateMPT(psb, mptID, accountID_, *sponsorSle, 0, j_);
|
||||
if (auto const err = checkCreateMPT(
|
||||
psb,
|
||||
mptID,
|
||||
accountID_,
|
||||
sponsorSle->has_value() ? (*sponsorSle)->mutableRawSle()
|
||||
: SLE::pointer{},
|
||||
0,
|
||||
j_);
|
||||
!isTesSuccess(err))
|
||||
{
|
||||
return err;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
@@ -79,7 +80,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
AccountID const dstId{ctx.tx[sfDestination]};
|
||||
AccountID const srcId{ctx.tx[sfAccount]};
|
||||
auto const sleDst = ctx.view.read(keylet::account(dstId));
|
||||
auto const sleDst = AccountRootEntryR(dstId, ctx.view);
|
||||
if (!sleDst)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Destination account does not exist.";
|
||||
@@ -187,15 +188,15 @@ CheckCreate::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
CheckCreate::doApply()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
auto sle = AccountRootEntryW(accountID_, view(), ctx_.journal);
|
||||
if (!sle)
|
||||
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.
|
||||
if (auto const ret = checkReserve(
|
||||
ctx_.getApplyViewContext(), sle, preFeeBalance_, {.ownerCountDelta = 1}, ctx_.journal);
|
||||
if (auto const ret =
|
||||
sle.checkReserve(ctx_.getApplyViewContext(), preFeeBalance_, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
// Note that we use the value from the sequence or ticket as the
|
||||
@@ -220,7 +221,6 @@ CheckCreate::doApply()
|
||||
|
||||
view().insert(sleCheck);
|
||||
|
||||
auto viewJ = ctx_.registry.get().getJournal("View");
|
||||
// If it's not a self-send (and it shouldn't be), add Check to the
|
||||
// destination's owner directory.
|
||||
if (dstAccountId != accountID_)
|
||||
@@ -251,7 +251,7 @@ CheckCreate::doApply()
|
||||
}
|
||||
// If we succeeded, the new entry counts against the creator's reserve.
|
||||
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sle, 1, viewJ);
|
||||
sle.increaseOwnerCount(ctx_.getApplyViewContext(), 1);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleCheck);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -87,8 +88,8 @@ CredentialAccept::doApply()
|
||||
AccountID const issuer{ctx_.tx[sfIssuer]};
|
||||
|
||||
// Both exist as credential object exist itself (checked in preclaim)
|
||||
auto const sleSubject = view().peek(keylet::account(accountID_));
|
||||
auto const sleIssuer = view().peek(keylet::account(issuer));
|
||||
auto sleSubject = AccountRootEntryW(accountID_, view(), j_);
|
||||
auto sleIssuer = AccountRootEntryW(issuer, view());
|
||||
|
||||
if (!sleSubject || !sleIssuer)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
@@ -97,13 +98,8 @@ CredentialAccept::doApply()
|
||||
if (!txSponsorSle)
|
||||
return txSponsorSle.error(); // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sleSubject,
|
||||
preFeeBalance_,
|
||||
*txSponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
j_);
|
||||
if (auto const ret = sleSubject.checkReserve(
|
||||
ctx_.getApplyViewContext(), preFeeBalance_, *txSponsorSle, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -130,7 +126,7 @@ CredentialAccept::doApply()
|
||||
removeSponsorFromLedgerEntry(sleCred);
|
||||
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleCred);
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sleSubject, 1, j_);
|
||||
sleSubject.increaseOwnerCount(ctx_.getApplyViewContext(), 1);
|
||||
view().update(sleCred);
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h> // IWYU pragma: keep
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
@@ -84,7 +85,7 @@ CredentialCreate::preclaim(PreclaimContext const& ctx)
|
||||
auto const credType(ctx.tx[sfCredentialType]);
|
||||
auto const subject = ctx.tx[sfSubject];
|
||||
|
||||
auto const subjectSle = ctx.view.read(keylet::account(subject));
|
||||
auto const subjectSle = AccountRootEntryR(subject, ctx.view);
|
||||
|
||||
if (!subjectSle)
|
||||
{
|
||||
@@ -134,12 +135,12 @@ CredentialCreate::doApply()
|
||||
sleCred->setFieldU32(sfExpiration, *optExp);
|
||||
}
|
||||
|
||||
auto const sleIssuer = view().peek(keylet::account(accountID_));
|
||||
auto sleIssuer = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!sleIssuer)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = checkReserve(
|
||||
ctx_.getApplyViewContext(), sleIssuer, preFeeBalance_, {.ownerCountDelta = 1}, j_);
|
||||
if (auto const ret = sleIssuer.checkReserve(
|
||||
ctx_.getApplyViewContext(), preFeeBalance_, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -159,7 +160,7 @@ CredentialCreate::doApply()
|
||||
return tecDIR_FULL;
|
||||
sleCred->setFieldU64(sfIssuerNode, *page);
|
||||
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sleIssuer, 1, j_);
|
||||
sleIssuer.increaseOwnerCount(ctx_.getApplyViewContext(), 1);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleCred);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -52,7 +53,7 @@ DelegateSet::preclaim(PreclaimContext const& ctx)
|
||||
if (!ctx.view.exists(keylet::account(ctx.tx[sfAccount])))
|
||||
return terNO_ACCOUNT; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sleAuthorize = ctx.view.read(keylet::account(ctx.tx[sfAuthorize]));
|
||||
auto const sleAuthorize = AccountRootEntryR(ctx.tx[sfAuthorize], ctx.view);
|
||||
if (!sleAuthorize)
|
||||
return tecNO_TARGET;
|
||||
|
||||
@@ -72,7 +73,7 @@ DelegateSet::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
DelegateSet::doApply()
|
||||
{
|
||||
auto const sleOwner = ctx_.view().peek(keylet::account(accountID_));
|
||||
auto sleOwner = AccountRootEntryW(accountID_, ctx_.view(), ctx_.journal);
|
||||
if (!sleOwner)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -98,12 +99,8 @@ DelegateSet::doApply()
|
||||
if (permissions.empty())
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sleOwner,
|
||||
preFeeBalance_,
|
||||
{.ownerCountDelta = 1},
|
||||
ctx_.journal);
|
||||
if (auto const ret = sleOwner.checkReserve(
|
||||
ctx_.getApplyViewContext(), preFeeBalance_, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -133,7 +130,7 @@ DelegateSet::doApply()
|
||||
(*sle)[sfDestinationNode] = *destPage;
|
||||
|
||||
ctx_.view().insert(sle);
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sleOwner, 1, ctx_.journal);
|
||||
sleOwner.increaseOwnerCount(ctx_.getApplyViewContext(), 1);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sle);
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -170,7 +167,7 @@ DelegateSet::deleteDelegate(ApplyView& view, SLE::Ref sle, beast::Journal j)
|
||||
}
|
||||
|
||||
// Only the delegating account's owner count was incremented on creation
|
||||
auto const sleOwner = view.peek(keylet::account(delegator));
|
||||
auto sleOwner = AccountRootEntryW(delegator, view);
|
||||
if (!sleOwner)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AMMHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -119,7 +120,7 @@ AMMBid::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
for (auto const& account : ctx.tx.getFieldArray(sfAuthAccounts))
|
||||
{
|
||||
if (!ctx.view.read(keylet::account(account[sfAccount])))
|
||||
if (!AccountRootEntryR(account[sfAccount], ctx.view))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: Invalid Account.";
|
||||
return terNO_ACCOUNT;
|
||||
@@ -208,7 +209,7 @@ applyBid(ApplyContext& ctx, Sandbox& sb, AccountID const& account, beast::Journa
|
||||
auto validOwner = [&](AccountID const& account) {
|
||||
// Valid range is 0-19 but the tailing slot pays MinSlotPrice
|
||||
// and doesn't refund so the check is < instead of <= to optimize.
|
||||
return timeSlot && *timeSlot < kTailingSlot && sb.read(keylet::account(account));
|
||||
return timeSlot && *timeSlot < kTailingSlot && AccountRootEntryR(account, sb);
|
||||
};
|
||||
|
||||
auto updateSlot = [&](std::uint32_t fee, Number const& minPrice, Number const& burn) -> TER {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AMMHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -102,11 +103,11 @@ AMMClawback::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const asset = ctx.tx[sfAsset];
|
||||
auto const asset2 = ctx.tx[sfAsset2];
|
||||
auto const sleIssuer = ctx.view.read(keylet::account(ctx.tx[sfAccount]));
|
||||
auto const sleIssuer = AccountRootEntryR(ctx.tx[sfAccount], ctx.view);
|
||||
if (!sleIssuer)
|
||||
return terNO_ACCOUNT; // LCOV_EXCL_LINE
|
||||
|
||||
if (!ctx.view.read(keylet::account(ctx.tx[sfHolder])))
|
||||
if (!AccountRootEntryR(ctx.tx[sfHolder], ctx.view))
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
auto const ammSle = ctx.view.read(keylet::amm(asset, asset2));
|
||||
@@ -178,7 +179,7 @@ AMMClawback::applyGuts(Sandbox& sb)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const ammAccount = (*ammSle)[sfAccount];
|
||||
auto const accountSle = sb.read(keylet::account(ammAccount));
|
||||
auto const accountSle = AccountRootEntryR(ammAccount, sb);
|
||||
if (!accountSle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AMMHelpers.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
@@ -133,7 +134,7 @@ AMMCreate::preclaim(PreclaimContext const& ctx)
|
||||
if (asset.holds<MPTIssue>() || isXRP(asset))
|
||||
return false;
|
||||
|
||||
if (auto const issuerAccount = view.read(keylet::account(asset.getIssuer())))
|
||||
if (auto const issuerAccount = AccountRootEntryR(asset.getIssuer(), view))
|
||||
return !issuerAccount->isFlag(lsfDefaultRipple);
|
||||
|
||||
return false;
|
||||
@@ -173,7 +174,7 @@ AMMCreate::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
|
||||
auto isLPToken = [&](STAmount const& amount) -> bool {
|
||||
if (auto const sle = ctx.view.read(keylet::account(amount.asset().getIssuer())))
|
||||
if (auto const sle = AccountRootEntryR(amount.asset().getIssuer(), ctx.view))
|
||||
return sle->isFieldPresent(sfAMMID);
|
||||
return false;
|
||||
};
|
||||
@@ -237,7 +238,7 @@ AMMCreate::preclaim(PreclaimContext const& ctx)
|
||||
[&](Issue const& issue) -> TER {
|
||||
if (isXRP(issue))
|
||||
return tesSUCCESS;
|
||||
auto const sle = ctx.view.read(keylet::account(issue.account));
|
||||
auto const sle = AccountRootEntryR(issue.account, ctx.view);
|
||||
if (!sle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
if (sle->isFlag(lsfAllowTrustLineClawback))
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AMMHelpers.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -344,7 +344,7 @@ AMMWithdraw::applyGuts(Sandbox& sb)
|
||||
if (!ammSle)
|
||||
return {tecINTERNAL, false}; // LCOV_EXCL_LINE
|
||||
auto const ammAccountID = (*ammSle)[sfAccount];
|
||||
auto const accountSle = sb.read(keylet::account(ammAccountID));
|
||||
auto const accountSle = AccountRootEntryR(ammAccountID, sb);
|
||||
if (!accountSle)
|
||||
return {tecINTERNAL, false}; // LCOV_EXCL_LINE
|
||||
auto const lpTokens = ammLPHolds(ctx_.view(), *ammSle, ctx_.tx[sfAccount], ctx_.journal);
|
||||
@@ -691,16 +691,15 @@ AMMWithdraw::withdraw(
|
||||
reserveHandling == ReserveHandling::IgnoreReserve)
|
||||
return tesSUCCESS;
|
||||
|
||||
auto sleAccount = view.peek(keylet::account(account));
|
||||
auto sleAccount = AccountRootEntryW(account, view, journal);
|
||||
if (!sleAccount)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const balance = (*sleAccount)[sfBalance]->xrp();
|
||||
// See also TrustSet::doApply() and MPTokenAuthorize::authorize()
|
||||
XRPAmount const reserve(
|
||||
(ownerCount(sleAccount, journal) < 2)
|
||||
? XRPAmount(beast::kZero)
|
||||
: accountReserve(view, sleAccount, journal, {.ownerCountDelta = 1}));
|
||||
(sleAccount.ownerCount() < 2) ? XRPAmount(beast::kZero)
|
||||
: sleAccount.reserve({.ownerCountDelta = 1}));
|
||||
|
||||
auto const balanceAdj = std::max(priorBalance, balance);
|
||||
if (balanceAdj < reserve)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <xrpl/tx/transactors/dex/OfferCancel.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/OfferHelpers.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
@@ -33,7 +35,7 @@ OfferCancel::preclaim(PreclaimContext const& ctx)
|
||||
auto const id = ctx.tx[sfAccount];
|
||||
auto const offerSequence = ctx.tx[sfOfferSequence];
|
||||
|
||||
auto const sle = ctx.view.read(keylet::account(id));
|
||||
auto const sle = AccountRootEntryR(id, ctx.view);
|
||||
if (!sle)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
@@ -54,7 +56,7 @@ OfferCancel::doApply()
|
||||
{
|
||||
auto const offerSequence = ctx_.tx[sfOfferSequence];
|
||||
|
||||
auto const sle = view().read(keylet::account(accountID_));
|
||||
auto const sle = AccountRootEntryW(accountID_, view());
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
@@ -181,7 +181,7 @@ OfferCreate::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
auto const cancelSequence = ctx.tx[~sfOfferSequence];
|
||||
|
||||
auto const sleCreator = ctx.view.read(keylet::account(id));
|
||||
auto const sleCreator = AccountRootEntryR(id, ctx.view);
|
||||
if (!sleCreator)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
@@ -288,7 +288,7 @@ OfferCreate::checkAcceptAsset(
|
||||
// Only valid for custom currencies
|
||||
XRPL_ASSERT(!isXRP(asset), "xrpl::OfferCreate::checkAcceptAsset : input is not XRP");
|
||||
|
||||
auto const issuerAccount = view.read(keylet::account(asset.getIssuer()));
|
||||
auto const issuerAccount = AccountRootEntryR(asset.getIssuer(), view);
|
||||
|
||||
if (!issuerAccount)
|
||||
{
|
||||
@@ -707,14 +707,14 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel)
|
||||
// Not XRP or MPT
|
||||
if (!saTakerPays.integral())
|
||||
{
|
||||
auto const sle = sb.read(keylet::account(uPaysIssuerID));
|
||||
auto const sle = AccountRootEntryR(uPaysIssuerID, sb);
|
||||
if (sle && sle->isFieldPresent(sfTickSize))
|
||||
uTickSize = std::min(uTickSize, (*sle)[sfTickSize]);
|
||||
}
|
||||
// Not XRP or MPT
|
||||
if (!saTakerGets.integral())
|
||||
{
|
||||
auto const sle = sb.read(keylet::account(uGetsIssuerID));
|
||||
auto const sle = AccountRootEntryR(uGetsIssuerID, sb);
|
||||
if (sle && sle->isFieldPresent(sfTickSize))
|
||||
uTickSize = std::min(uTickSize, (*sle)[sfTickSize]);
|
||||
}
|
||||
@@ -884,12 +884,12 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel)
|
||||
return {tesSUCCESS, true};
|
||||
}
|
||||
|
||||
auto const sleCreator = sb.peek(keylet::account(accountID_));
|
||||
auto sleCreator = AccountRootEntryW(accountID_, sb, viewJ);
|
||||
if (!sleCreator)
|
||||
return {tefINTERNAL, false};
|
||||
|
||||
{
|
||||
XRPAmount const reserve = accountReserve(sb, sleCreator, viewJ, {.ownerCountDelta = 1});
|
||||
XRPAmount const reserve = sleCreator.reserve({.ownerCountDelta = 1});
|
||||
if (preFeeBalance_ < reserve)
|
||||
{
|
||||
// If we are here, the signing account had an insufficient reserve
|
||||
@@ -923,7 +923,8 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel)
|
||||
}
|
||||
|
||||
// Update owner count.
|
||||
increaseOwnerCount(sb, sleCreator, {}, 1, viewJ);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
sleCreator.increaseOwnerCount(noSponsor, 1);
|
||||
|
||||
JLOG(j_.trace()) << "adding to book: " << to_string(saTakerPays.asset()) << " : "
|
||||
<< to_string(saTakerGets.asset())
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -46,7 +47,7 @@ DIDDelete::deleteSLE(ApplyView& view, SLE::pointer sle, AccountID const owner, b
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const sleOwner = view.peek(keylet::account(owner));
|
||||
auto sleOwner = AccountRootEntryW(owner, view);
|
||||
if (!sleOwner)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -65,15 +66,14 @@ DIDSet::preflight(PreflightContext const& ctx)
|
||||
static TER
|
||||
addSLE(ApplyContext& ctx, SLE::Ref sle, AccountID const& owner)
|
||||
{
|
||||
auto const sleAccount = ctx.view().peek(keylet::account(owner));
|
||||
auto sleAccount = AccountRootEntryW(owner, ctx.view(), ctx.journal);
|
||||
if (!sleAccount)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Check reserve availability for new object creation
|
||||
{
|
||||
auto const balance = STAmount((*sleAccount)[sfBalance]).xrp();
|
||||
auto const reserve =
|
||||
accountReserve(ctx.view(), sleAccount, ctx.journal, {.ownerCountDelta = 1});
|
||||
auto const reserve = sleAccount.reserve({.ownerCountDelta = 1});
|
||||
|
||||
if (balance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
@@ -90,8 +90,9 @@ addSLE(ApplyContext& ctx, SLE::Ref sle, AccountID const& owner)
|
||||
return tecDIR_FULL; // LCOV_EXCL_LINE
|
||||
(*sle)[sfOwnerNode] = *page;
|
||||
}
|
||||
increaseOwnerCount(ctx.view(), sleAccount, {}, 1, ctx.journal);
|
||||
ctx.view().update(sleAccount);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
sleAccount.increaseOwnerCount(noSponsor, 1);
|
||||
sleAccount.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/EscrowHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
@@ -166,7 +167,7 @@ EscrowCancel::doApply()
|
||||
}
|
||||
}
|
||||
|
||||
auto const sle = ctx_.view().peek(keylet::account(account));
|
||||
auto sle = AccountRootEntryW(account, ctx_.view());
|
||||
STAmount const amount = slep->getFieldAmount(sfAmount);
|
||||
|
||||
// The return can re-create a holding the owner deleted while the escrow
|
||||
@@ -192,7 +193,7 @@ EscrowCancel::doApply()
|
||||
return escrowUnlockApplyHelper<T>(
|
||||
ctx_.getApplyViewContext(),
|
||||
kParityRate,
|
||||
ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle : slep,
|
||||
ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle.mutableRawSle() : slep,
|
||||
preFeeBalance_,
|
||||
amount,
|
||||
issuer,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
@@ -207,7 +208,7 @@ escrowCreatePreclaimHelper<Issue>(
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// If the lsfAllowTrustLineLocking is not enabled, return tecNO_PERMISSION
|
||||
auto const sleIssuer = ctx.view.read(keylet::account(issuer));
|
||||
auto const sleIssuer = AccountRootEntryR(issuer, ctx.view);
|
||||
if (!sleIssuer)
|
||||
return tecNO_ISSUER;
|
||||
if (!sleIssuer->isFlag(lsfAllowTrustLineLocking))
|
||||
@@ -347,7 +348,7 @@ EscrowCreate::preclaim(PreclaimContext const& ctx)
|
||||
AccountID const account{ctx.tx[sfAccount]};
|
||||
AccountID const dest{ctx.tx[sfDestination]};
|
||||
|
||||
auto const sled = ctx.view.read(keylet::account(dest));
|
||||
auto const sled = AccountRootEntryR(dest, ctx.view);
|
||||
if (!sled)
|
||||
return tecNO_DST;
|
||||
|
||||
@@ -433,7 +434,7 @@ EscrowCreate::doApply()
|
||||
if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter]))
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const sle = ctx_.view().peek(keylet::account(accountID_));
|
||||
auto sle = AccountRootEntryW(accountID_, ctx_.view(), j_);
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -447,7 +448,7 @@ EscrowCreate::doApply()
|
||||
// unsponsored this hits the source branch and validates the
|
||||
// source's pre-lock balance against base + (currentOC+1)*increment.
|
||||
if (auto const ret =
|
||||
checkReserve(ctx_.getApplyViewContext(), sle, balance, {.ownerCountDelta = 1}, j_);
|
||||
sle.checkReserve(ctx_.getApplyViewContext(), balance, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -464,15 +465,15 @@ EscrowCreate::doApply()
|
||||
// - sponsored: 0 — sponsor covers the new owner increment, so the
|
||||
// source only owes reserve for its current owners.
|
||||
// - unsponsored: 1 — source owes reserve including the new increment.
|
||||
auto const sourceReserve = accountReserve(
|
||||
ctx_.view(), sle, j_, {.ownerCountDelta = getTxReserveSponsorID(ctx_.tx) ? 0 : 1});
|
||||
auto const sourceReserve =
|
||||
sle.reserve({.ownerCountDelta = getTxReserveSponsorID(ctx_.tx) ? 0 : 1});
|
||||
if (balance - STAmount(amount).xrp() < sourceReserve)
|
||||
return tecUNFUNDED;
|
||||
}
|
||||
|
||||
// Check destination account
|
||||
{
|
||||
auto const sled = ctx_.view().read(keylet::account(ctx_.tx[sfDestination]));
|
||||
auto const sled = AccountRootEntryW(ctx_.tx[sfDestination], ctx_.view());
|
||||
if (!sled)
|
||||
return tecNO_DST; // LCOV_EXCL_LINE
|
||||
if (sled->isFlag(lsfRequireDestTag) && !ctx_.tx[~sfDestinationTag])
|
||||
@@ -558,9 +559,9 @@ EscrowCreate::doApply()
|
||||
}
|
||||
|
||||
// increment owner count
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sle, 1, ctx_.journal);
|
||||
sle.increaseOwnerCount(ctx_.getApplyViewContext(), 1);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), slep);
|
||||
ctx_.view().update(sle);
|
||||
sle.update();
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/EscrowHelpers.h>
|
||||
@@ -314,12 +315,12 @@ EscrowFinish::doApply()
|
||||
|
||||
// NOTE: Escrow payments cannot be used to fund accounts.
|
||||
AccountID const destID = (*slep)[sfDestination];
|
||||
auto const sled = ctx_.view().peek(keylet::account(destID));
|
||||
auto sled = AccountRootEntryW(destID, ctx_.view());
|
||||
if (!sled)
|
||||
return tecNO_DST;
|
||||
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_.tx, ctx_.view(), accountID_, destID, sled, ctx_.journal);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), accountID_, destID, sled.rawSle(), ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -378,7 +379,7 @@ EscrowFinish::doApply()
|
||||
return escrowUnlockApplyHelper<T>(
|
||||
ctx_.getApplyViewContext(),
|
||||
lockedRate,
|
||||
sled,
|
||||
sled.mutableRawSle(),
|
||||
preFeeBalance_,
|
||||
amount,
|
||||
issuer,
|
||||
@@ -404,7 +405,7 @@ EscrowFinish::doApply()
|
||||
}
|
||||
}
|
||||
|
||||
ctx_.view().update(sled);
|
||||
sled.update();
|
||||
|
||||
if (!recycleReserve)
|
||||
decreaseOwnerCountForObject(ctx_.view(), account, slep, 1, ctx_.journal);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/LendingHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -108,7 +109,7 @@ determineBrokerID(ReadView const& view, STTx const& tx)
|
||||
// Thus, Amount.issuer _should_ be the loan broker's
|
||||
// pseudo-account, but we don't know yet whether it is.
|
||||
auto const maybePseudo = dstAmount->getIssuer();
|
||||
auto const sle = view.read(keylet::account(maybePseudo));
|
||||
auto const sle = AccountRootEntryR(maybePseudo, view);
|
||||
|
||||
// If the account was not found, the transaction can't go further.
|
||||
if (!sle)
|
||||
@@ -319,7 +320,7 @@ LoanBrokerCoverClawback::preclaim(PreclaimContext const& ctx)
|
||||
return tecINTERNAL; // tecINSUFFICIENT_FUNDS; LCOV_EXCL_LINE
|
||||
|
||||
// Check if the vault asset issuer has the correct flags
|
||||
auto const sleIssuer = ctx.view.read(keylet::account(vaultAsset.getIssuer()));
|
||||
auto const sleIssuer = AccountRootEntryR(vaultAsset.getIssuer(), ctx.view);
|
||||
if (!sleIssuer)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/LendingHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -161,7 +162,7 @@ LoanBrokerDelete::doApply()
|
||||
if (auto ter = removeEmptyHolding(ctx_.getApplyViewContext(), brokerPseudoID, vaultAsset, j_))
|
||||
return ter;
|
||||
|
||||
auto brokerPseudoSLE = view().peek(keylet::account(brokerPseudoID));
|
||||
auto brokerPseudoSLE = AccountRootEntryW(brokerPseudoID, view());
|
||||
if (!brokerPseudoSLE)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -183,10 +184,10 @@ LoanBrokerDelete::doApply()
|
||||
return tecHAS_OBLIGATIONS; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
view().erase(brokerPseudoSLE);
|
||||
brokerPseudoSLE.erase();
|
||||
|
||||
{
|
||||
auto owner = view().peek(keylet::account(accountID_));
|
||||
auto owner = AccountRootEntryW(accountID_, view());
|
||||
if (!owner)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/LendingHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -236,7 +238,7 @@ LoanBrokerSet::doApply()
|
||||
auto const vaultAsset = sleVault->at(sfAsset);
|
||||
auto const sequence = tx.getSeqProxy();
|
||||
|
||||
auto owner = view.peek(keylet::account(accountID_));
|
||||
auto owner = AccountRootEntryW(accountID_, view, j_);
|
||||
if (!owner)
|
||||
{
|
||||
// This should be impossible
|
||||
@@ -254,8 +256,9 @@ LoanBrokerSet::doApply()
|
||||
|
||||
// Increases the owner count by two: one for the LoanBroker object, and
|
||||
// one for the pseudo-account.
|
||||
increaseOwnerCount(view, owner, {}, 2, j_);
|
||||
if (preFeeBalance_ < accountReserve(view, owner, j_))
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
owner.increaseOwnerCount(noSponsor, 2);
|
||||
if (preFeeBalance_ < owner.reserve())
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
auto maybePseudo = createPseudoAccount(view, broker->key(), sfLoanBrokerID);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/basics/Number.h> // IWYU pragma: keep
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/LendingHelpers.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -80,7 +81,7 @@ LoanDelete::doApply()
|
||||
if (!loanSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
auto const borrower = loanSle->at(sfBorrower);
|
||||
auto const borrowerSle = view.peek(keylet::account(borrower));
|
||||
auto borrowerSle = AccountRootEntryW(borrower, view);
|
||||
if (!borrowerSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/LendingHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -56,7 +57,7 @@ conservationBalance(ReadView const& view, AccountID const& id, Asset const& asse
|
||||
{
|
||||
if (isXRP(asset))
|
||||
{
|
||||
auto const sle = view.read(keylet::account(id));
|
||||
auto const sle = AccountRootEntryR(id, view);
|
||||
if (!sle)
|
||||
return STAmount{asset}; // LCOV_EXCL_LINE
|
||||
return view.balanceHookIOU(id, xrpAccount(), sle->getFieldAmount(sfBalance));
|
||||
@@ -391,7 +392,7 @@ LoanPay::doApply()
|
||||
}();
|
||||
|
||||
auto const brokerPayee = sendBrokerFeeToOwner ? brokerOwner : brokerPseudoAccount;
|
||||
auto const brokerPayeeSle = view.peek(keylet::account(brokerPayee));
|
||||
auto const brokerPayeeSle = AccountRootEntryW(brokerPayee, view);
|
||||
if (!sendBrokerFeeToOwner)
|
||||
{
|
||||
// If we can't send the fee to the owner, and the pseudo-account is
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/LendingHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -305,7 +306,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 borrowerSle = AccountRootEntryR(borrower, ctx.view); !borrowerSle)
|
||||
{
|
||||
// It may not be possible to hit this case, because it'll fail the
|
||||
// signature check with terNO_ACCOUNT.
|
||||
@@ -443,7 +444,7 @@ LoanSet::doApply()
|
||||
if (!brokerSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
auto const brokerOwner = brokerSle->at(sfOwner);
|
||||
auto const brokerOwnerSle = view.peek(keylet::account(brokerOwner));
|
||||
auto const brokerOwnerSle = AccountRootEntryW(brokerOwner, view);
|
||||
if (!brokerOwnerSle)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -455,14 +456,14 @@ LoanSet::doApply()
|
||||
|
||||
auto const counterparty = tx[~sfCounterparty].value_or(brokerOwner);
|
||||
auto const borrower = counterparty == brokerOwner ? accountID_ : counterparty;
|
||||
auto const borrowerSle = view.peek(keylet::account(borrower));
|
||||
auto borrowerSle = AccountRootEntryW(borrower, view, j_);
|
||||
if (!borrowerSle)
|
||||
{
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
auto const brokerPseudo = brokerSle->at(sfAccount);
|
||||
auto const brokerPseudoSle = view.peek(keylet::account(brokerPseudo));
|
||||
auto const brokerPseudoSle = AccountRootEntryW(brokerPseudo, view);
|
||||
if (!brokerPseudoSle)
|
||||
{
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
@@ -581,12 +582,13 @@ LoanSet::doApply()
|
||||
}
|
||||
}
|
||||
|
||||
increaseOwnerCount(view, borrowerSle, {}, 1, j_);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
borrowerSle.increaseOwnerCount(noSponsor, 1);
|
||||
|
||||
{
|
||||
auto const balance =
|
||||
accountID_ == borrower ? preFeeBalance_ : borrowerSle->at(sfBalance).value().xrp();
|
||||
if (balance < accountReserve(view, borrowerSle, j_))
|
||||
if (balance < borrowerSle.reserve())
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
@@ -376,7 +376,7 @@ NFTokenAcceptOffer::transferNFToken(
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
auto const sleBuyer = view().read(keylet::account(buyer));
|
||||
auto const sleBuyer = AccountRootEntryW(buyer, view(), j_);
|
||||
if (!sleBuyer)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -397,7 +397,7 @@ NFTokenAcceptOffer::transferNFToken(
|
||||
auto const buyerOwnerCountAfter = sleBuyer->getFieldU32(sfOwnerCount);
|
||||
if (buyerOwnerCountAfter > buyerOwnerCountBefore)
|
||||
{
|
||||
if (buyerBalance < accountReserve(view(), sleBuyer, j_))
|
||||
if (buyerBalance < sleBuyer.reserve())
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <xrpl/tx/transactors/nft/NFTokenBurn.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
@@ -43,7 +45,7 @@ NFTokenBurn::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
if (auto const issuer = nft::getIssuer(ctx.tx[sfNFTokenID]); issuer != account)
|
||||
{
|
||||
if (auto const sle = ctx.view.read(keylet::account(issuer)); sle)
|
||||
if (auto const sle = AccountRootEntryR(issuer, ctx.view); sle)
|
||||
{
|
||||
if (auto const minter = (*sle)[~sfNFTokenMinter]; minter != account)
|
||||
return tecNO_PERMISSION;
|
||||
@@ -68,10 +70,10 @@ NFTokenBurn::doApply()
|
||||
if (!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
if (auto issuer = view().peek(keylet::account(nft::getIssuer(ctx_.tx[sfNFTokenID]))))
|
||||
if (auto issuer = AccountRootEntryW(nft::getIssuer(ctx_.tx[sfNFTokenID]), view()))
|
||||
{
|
||||
(*issuer)[~sfBurnedNFTokens] = (*issuer)[~sfBurnedNFTokens].valueOr(0) + 1;
|
||||
view().update(issuer);
|
||||
issuer.update();
|
||||
}
|
||||
|
||||
// Delete up to 500 offers in total.
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/InnerObjectFormats.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
@@ -186,7 +186,7 @@ NFTokenMint::preclaim(PreclaimContext const& ctx)
|
||||
// transaction. Check that and verify that this is allowed:
|
||||
if (auto issuer = ctx.tx[~sfIssuer])
|
||||
{
|
||||
auto const sle = ctx.view.read(keylet::account(*issuer));
|
||||
auto const sle = AccountRootEntryR(*issuer, ctx.view);
|
||||
|
||||
if (!sle)
|
||||
return tecNO_ISSUER;
|
||||
@@ -225,8 +225,8 @@ NFTokenMint::doApply()
|
||||
auto const issuer = ctx_.tx[~sfIssuer].value_or(accountID_);
|
||||
|
||||
auto const tokenSeq = [this, &issuer]() -> std::expected<std::uint32_t, TER> {
|
||||
auto const root = view().peek(keylet::account(issuer));
|
||||
if (root == nullptr)
|
||||
auto root = AccountRootEntryW(issuer, view());
|
||||
if (!root)
|
||||
{
|
||||
// Should not happen. Checked in preclaim.
|
||||
return std::unexpected(tecNO_ISSUER);
|
||||
@@ -271,7 +271,7 @@ NFTokenMint::doApply()
|
||||
if (tokenSeq + 1u == 0u || tokenSeq < offset)
|
||||
return std::unexpected(tecMAX_SEQUENCE_REACHED);
|
||||
|
||||
ctx_.view().update(root);
|
||||
root.update();
|
||||
return tokenSeq;
|
||||
}();
|
||||
|
||||
@@ -279,7 +279,7 @@ NFTokenMint::doApply()
|
||||
return (tokenSeq.error());
|
||||
|
||||
std::uint32_t const ownerCountBefore =
|
||||
view().read(keylet::account(accountID_))->getFieldU32(sfOwnerCount);
|
||||
AccountRootEntryW(accountID_, view())->getFieldU32(sfOwnerCount);
|
||||
|
||||
// Assemble the new NFToken.
|
||||
SOTemplate const* nfTokenTemplate =
|
||||
@@ -332,14 +332,14 @@ NFTokenMint::doApply()
|
||||
// allows NFTs to be added to the page (and burn fees) without
|
||||
// requiring the reserve to be met each time. The reserve is
|
||||
// only managed when a new NFT page or sell offer is added.
|
||||
auto const sleAccount = view().read(keylet::account(accountID_));
|
||||
auto const sleAccount = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!sleAccount)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ownerCountAfter = sleAccount->getFieldU32(sfOwnerCount);
|
||||
ownerCountAfter > ownerCountBefore)
|
||||
{
|
||||
if (preFeeBalance_ < accountReserve(view(), sleAccount, j_))
|
||||
if (preFeeBalance_ < sleAccount.reserve())
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -47,7 +48,7 @@ NFTokenModify::preclaim(PreclaimContext const& ctx)
|
||||
// Verify permissions for the issuer
|
||||
if (AccountID const issuer = nft::getIssuer(ctx.tx[sfNFTokenID]); issuer != account)
|
||||
{
|
||||
auto const sle = ctx.view.read(keylet::account(issuer));
|
||||
auto const sle = AccountRootEntryR(issuer, ctx.view);
|
||||
if (!sle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
if (auto const minter = (*sle)[~sfNFTokenMinter]; minter != account)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/OracleHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -67,7 +68,7 @@ OracleDelete::deleteOracle(
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const sleOwner = view.peek(keylet::account(account));
|
||||
auto sleOwner = AccountRootEntryW(account, view);
|
||||
if (!sleOwner)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/OracleHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
@@ -64,7 +65,7 @@ OracleSet::preflight(PreflightContext const& ctx)
|
||||
TER
|
||||
OracleSet::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const sleSetter = ctx.view.read(keylet::account(ctx.tx.getAccountID(sfAccount)));
|
||||
auto const sleSetter = AccountRootEntryR(ctx.tx.getAccountID(sfAccount), ctx.view, ctx.j);
|
||||
if (!sleSetter)
|
||||
return terNO_ACCOUNT; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -172,8 +173,7 @@ OracleSet::preclaim(PreclaimContext const& ctx)
|
||||
if (pairs.size() > kMaxOracleDataSeries)
|
||||
return tecARRAY_TOO_LARGE;
|
||||
|
||||
auto const reserve =
|
||||
accountReserve(ctx.view, sleSetter, ctx.j, {.ownerCountDelta = adjustReserve});
|
||||
auto const reserve = sleSetter.reserve({.ownerCountDelta = adjustReserve});
|
||||
auto const& balance = sleSetter->getFieldAmount(sfBalance);
|
||||
|
||||
if (balance < reserve)
|
||||
@@ -187,22 +187,20 @@ adjustOracleOwnerCount(ApplyContext& ctx, int count)
|
||||
{
|
||||
XRPL_ASSERT(std::abs(count) <= 2, "xrpl::adjustOracleOwnerCount abs(counter) <= 2");
|
||||
|
||||
if (auto const sleAccount = ctx.view().peek(keylet::account(ctx.tx[sfAccount])))
|
||||
{
|
||||
auto sleAccount = AccountRootEntryW(ctx.tx[sfAccount], ctx.view(), ctx.journal);
|
||||
if (!sleAccount)
|
||||
return false; // LCOV_EXCL_LINE
|
||||
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
if (count > 0)
|
||||
{
|
||||
increaseOwnerCount(
|
||||
ctx.view(), sleAccount, {}, static_cast<std::uint32_t>(count), ctx.journal);
|
||||
sleAccount.increaseOwnerCount(noSponsor, static_cast<std::uint32_t>(count));
|
||||
}
|
||||
else if (count < 0)
|
||||
{
|
||||
decreaseOwnerCount(
|
||||
ctx.view(), sleAccount, {}, static_cast<std::uint32_t>(-count), ctx.journal);
|
||||
sleAccount.decreaseOwnerCount(noSponsor, static_cast<std::uint32_t>(-count));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
@@ -103,7 +104,7 @@ DepositPreauth::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
// Verify that the Authorize account is present in the ledger.
|
||||
AccountID const auth{ctx.tx[sfAuthorize]};
|
||||
auto const sleAuth = ctx.view.read(keylet::account(auth));
|
||||
auto const sleAuth = AccountRootEntryR(auth, ctx.view);
|
||||
if (!sleAuth)
|
||||
return tecNO_TARGET;
|
||||
|
||||
@@ -161,15 +162,15 @@ DepositPreauth::doApply()
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
if (ctx_.tx.isFieldPresent(sfAuthorize))
|
||||
{
|
||||
auto const sleOwner = view().peek(keylet::account(accountID_));
|
||||
auto sleOwner = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!sleOwner)
|
||||
return {tefINTERNAL};
|
||||
|
||||
// A preauth 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.
|
||||
if (auto const ret = checkReserve(
|
||||
applyViewContext, sleOwner, preFeeBalance_, {.ownerCountDelta = 1}, j_);
|
||||
if (auto const ret =
|
||||
sleOwner.checkReserve(applyViewContext, preFeeBalance_, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -195,7 +196,7 @@ DepositPreauth::doApply()
|
||||
slePreauth->setFieldU64(sfOwnerNode, *page);
|
||||
|
||||
// If we succeeded, the new entry counts against the creator's reserve.
|
||||
increaseOwnerCount(applyViewContext, sleOwner, 1, j_);
|
||||
sleOwner.increaseOwnerCount(applyViewContext, 1);
|
||||
addSponsorToLedgerEntry(applyViewContext, slePreauth);
|
||||
}
|
||||
else if (ctx_.tx.isFieldPresent(sfUnauthorize))
|
||||
@@ -206,15 +207,15 @@ DepositPreauth::doApply()
|
||||
}
|
||||
else if (ctx_.tx.isFieldPresent(sfAuthorizeCredentials))
|
||||
{
|
||||
auto const sleOwner = view().peek(keylet::account(accountID_));
|
||||
auto sleOwner = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!sleOwner)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// A preauth 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.
|
||||
if (auto const ret = checkReserve(
|
||||
applyViewContext, sleOwner, preFeeBalance_, {.ownerCountDelta = 1}, j_);
|
||||
if (auto const ret =
|
||||
sleOwner.checkReserve(applyViewContext, preFeeBalance_, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -254,7 +255,7 @@ DepositPreauth::doApply()
|
||||
slePreauth->setFieldU64(sfOwnerNode, *page);
|
||||
|
||||
// If we succeeded, the new entry counts against the creator's reserve.
|
||||
increaseOwnerCount(applyViewContext, sleOwner, 1, j_);
|
||||
sleOwner.increaseOwnerCount(applyViewContext, 1);
|
||||
addSponsorToLedgerEntry(applyViewContext, slePreauth);
|
||||
}
|
||||
else if (ctx_.tx.isFieldPresent(sfUnauthorizeCredentials))
|
||||
@@ -289,7 +290,7 @@ 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));
|
||||
auto sleOwner = AccountRootEntryW(account, view);
|
||||
if (!sleOwner)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
@@ -386,7 +387,7 @@ Payment::preclaim(PreclaimContext const& ctx)
|
||||
STAmount const dstAmount(ctx.tx[sfAmount]);
|
||||
|
||||
auto const k = keylet::account(dstAccountID);
|
||||
auto const sleDst = ctx.view.read(k);
|
||||
auto const sleDst = AccountRootEntryR(k, ctx.view);
|
||||
|
||||
if (!sleDst)
|
||||
{
|
||||
@@ -564,19 +565,19 @@ Payment::doApply()
|
||||
|
||||
// Open a ledger for editing.
|
||||
auto const k = keylet::account(dstAccountID);
|
||||
SLE::pointer sleDst = view().peek(k);
|
||||
AccountRootEntryW sleDst(k, view());
|
||||
|
||||
if (!sleDst)
|
||||
{
|
||||
// Create the account.
|
||||
sleDst = std::make_shared<SLE>(k);
|
||||
sleDst.newSLE();
|
||||
sleDst->setAccountID(sfAccount, dstAccountID);
|
||||
sleDst->setFieldU32(sfSequence, view().seq());
|
||||
sleDst->setFieldAmount(sfBalance, XRPAmount(beast::kZero));
|
||||
|
||||
if (ctx_.tx.isFlag(tfSponsorCreatedAccount))
|
||||
{
|
||||
auto const sponsor = view().peek(keylet::account(accountID_));
|
||||
auto sponsor = AccountRootEntryW(accountID_, view());
|
||||
if (!sponsor)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const currentSponsoringAccountCount =
|
||||
@@ -591,18 +592,18 @@ Payment::doApply()
|
||||
}
|
||||
sponsor->setFieldU32(sfSponsoringAccountCount, currentSponsoringAccountCount + 1);
|
||||
|
||||
addSponsorToLedgerEntry(sleDst, sponsor);
|
||||
view().update(sponsor);
|
||||
addSponsorToLedgerEntry(sleDst.mutableRawSle(), sponsor.rawSle());
|
||||
sponsor.update();
|
||||
}
|
||||
|
||||
view().insert(sleDst);
|
||||
sleDst.insert();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tell the engine that we are intending to change the destination
|
||||
// account. The source account gets always charged a fee so it's always
|
||||
// marked as modified.
|
||||
view().update(sleDst);
|
||||
sleDst.update();
|
||||
}
|
||||
|
||||
bool const mpTokensV2 = view().rules().enabled(featureMPTokensV2);
|
||||
@@ -621,7 +622,12 @@ Payment::doApply()
|
||||
// 2. If Account is deposit preauthorized by destination.
|
||||
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal);
|
||||
ctx_.tx,
|
||||
ctx_.view(),
|
||||
accountID_,
|
||||
dstAccountID,
|
||||
sleDst.mutableRawSle(),
|
||||
ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -691,7 +697,12 @@ Payment::doApply()
|
||||
return ter;
|
||||
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal);
|
||||
ctx_.tx,
|
||||
ctx_.view(),
|
||||
accountID_,
|
||||
dstAccountID,
|
||||
sleDst.mutableRawSle(),
|
||||
ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -757,13 +768,13 @@ Payment::doApply()
|
||||
|
||||
// Direct XRP payment.
|
||||
|
||||
auto const sleSrc = view().peek(keylet::account(accountID_));
|
||||
auto sleSrc = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!sleSrc)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// the number of reserves in this ledger for this account that require a
|
||||
// reserve.
|
||||
auto const reserve = accountReserve(view(), sleSrc, j_);
|
||||
auto const reserve = sleSrc.reserve();
|
||||
|
||||
// In a delegated / fee sponsored payment, the fee payer is not the source account (accountID_).
|
||||
bool const accountIsPayer = ctx_.tx.getFeePayerID() == accountID_;
|
||||
@@ -820,7 +831,12 @@ Payment::doApply()
|
||||
if (dstAmount > dstReserve || sleDst->getFieldAmount(sfBalance) > dstReserve)
|
||||
{
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal);
|
||||
ctx_.tx,
|
||||
ctx_.view(),
|
||||
accountID_,
|
||||
dstAccountID,
|
||||
sleDst.mutableRawSle(),
|
||||
ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/PaymentChannelHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/PayChan.h>
|
||||
@@ -159,12 +159,12 @@ PaymentChannelClaim::doApply()
|
||||
return tecUNFUNDED_PAYMENT;
|
||||
}
|
||||
|
||||
auto const sled = ctx_.view().peek(keylet::account(dst));
|
||||
auto sled = AccountRootEntryW(dst, ctx_.view());
|
||||
if (!sled)
|
||||
return tecNO_DST;
|
||||
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), txAccount, dst, sled.rawSle(), ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -173,7 +173,7 @@ PaymentChannelClaim::doApply()
|
||||
XRPL_ASSERT(
|
||||
reqDelta >= beast::kZero, "xrpl::PaymentChannelClaim::doApply : minimum balance delta");
|
||||
(*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta;
|
||||
ctx_.view().update(sled);
|
||||
sled.update();
|
||||
ctx_.view().update(slep);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -73,7 +74,7 @@ TER
|
||||
PaymentChannelCreate::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const account = ctx.tx[sfAccount];
|
||||
auto const sle = ctx.view.read(keylet::account(account));
|
||||
auto const sle = AccountRootEntryR(account, ctx.view);
|
||||
if (!sle)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
@@ -94,7 +95,7 @@ PaymentChannelCreate::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
{
|
||||
// Check destination account
|
||||
auto const sled = ctx.view.read(keylet::account(dst));
|
||||
auto const sled = AccountRootEntryR(dst, ctx.view);
|
||||
if (!sled)
|
||||
return tecNO_DST;
|
||||
|
||||
@@ -122,7 +123,7 @@ TER
|
||||
PaymentChannelCreate::doApply()
|
||||
{
|
||||
auto const account = ctx_.tx[sfAccount];
|
||||
auto const sle = ctx_.view().peek(keylet::account(account));
|
||||
auto sle = AccountRootEntryW(account, ctx_.view(), j_);
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -140,8 +141,8 @@ PaymentChannelCreate::doApply()
|
||||
// validates the sponsor's reserve + remaining credit. When
|
||||
// unsponsored this hits the source branch and validates the
|
||||
// source's pre-lock balance against base + (currentOC+1)*increment.
|
||||
if (auto const ret = checkReserve(
|
||||
ctx_.getApplyViewContext(), sle, preFeeBalance_, {.ownerCountDelta = 1}, j_);
|
||||
if (auto const ret = sle.checkReserve(
|
||||
ctx_.getApplyViewContext(), preFeeBalance_, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -157,8 +158,8 @@ PaymentChannelCreate::doApply()
|
||||
// - sponsored: 0 — sponsor covers the new owner increment, so
|
||||
// the source only owes reserve for its current owners.
|
||||
// - unsponsored: 1 — source owes reserve including the new increment.
|
||||
auto const sourceReserve = accountReserve(
|
||||
ctx_.view(), sle, j_, {.ownerCountDelta = getTxReserveSponsorID(ctx_.tx) ? 0 : 1});
|
||||
auto const sourceReserve =
|
||||
sle.reserve({.ownerCountDelta = getTxReserveSponsorID(ctx_.tx) ? 0 : 1});
|
||||
if (preFeeBalance_ - ctx_.tx[sfAmount].xrp() < sourceReserve)
|
||||
return tecUNFUNDED;
|
||||
}
|
||||
@@ -210,9 +211,9 @@ PaymentChannelCreate::doApply()
|
||||
|
||||
// Deduct owner's balance, increment owner count
|
||||
(*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sle, 1, ctx_.journal);
|
||||
sle.increaseOwnerCount(ctx_.getApplyViewContext(), 1);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), slep);
|
||||
ctx_.view().update(sle);
|
||||
sle.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/PaymentChannelHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
@@ -82,14 +81,14 @@ PaymentChannelFund::doApply()
|
||||
ctx_.view().update(slep);
|
||||
}
|
||||
|
||||
auto const sle = ctx_.view().peek(keylet::account(txAccount));
|
||||
auto sle = AccountRootEntryW(txAccount, ctx_.view(), j_);
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
{
|
||||
// Check reserve and funds availability
|
||||
STAmount const balance = (*sle)[sfBalance];
|
||||
if (auto const ret = checkReserve(ctx_.getApplyViewContext(), sle, balance.xrp(), {}, j_);
|
||||
if (auto const ret = sle.checkReserve(ctx_.getApplyViewContext(), balance.xrp(), {});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -99,12 +98,12 @@ PaymentChannelFund::doApply()
|
||||
// when a sponsor is present and would ignore the source's post-lock
|
||||
// balance entirely. Funding an existing channel adds no owned object,
|
||||
// so there is no owner-count delta.
|
||||
if (balance < accountReserve(ctx_.view(), sle, j_) + ctx_.tx[sfAmount])
|
||||
if (balance < sle.reserve() + ctx_.tx[sfAmount])
|
||||
return tecUNFUNDED;
|
||||
}
|
||||
|
||||
// do not allow adding funds if dst does not exist
|
||||
if (AccountID const dst = (*slep)[sfDestination]; !ctx_.view().read(keylet::account(dst)))
|
||||
if (AccountID const dst = (*slep)[sfDestination]; !AccountRootEntryW(dst, ctx_.view()))
|
||||
{
|
||||
return tecNO_DST;
|
||||
}
|
||||
@@ -113,7 +112,7 @@ PaymentChannelFund::doApply()
|
||||
ctx_.view().update(slep);
|
||||
|
||||
(*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
|
||||
ctx_.view().update(sle);
|
||||
sle.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
@@ -63,7 +64,7 @@ PermissionedDomainDelete::doApply()
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const ownerSle = view().peek(keylet::account(accountID_));
|
||||
auto ownerSle = AccountRootEntryW(accountID_, view());
|
||||
XRPL_ASSERT(
|
||||
ownerSle && ownerSle->getFieldU32(sfOwnerCount) > 0,
|
||||
"xrpl::PermissionedDomainDelete::doApply : nonzero owner count");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -80,7 +81,7 @@ PermissionedDomainSet::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
PermissionedDomainSet::doApply()
|
||||
{
|
||||
auto const ownerSle = view().peek(keylet::account(accountID_));
|
||||
auto ownerSle = AccountRootEntryW(accountID_, view(), ctx_.journal);
|
||||
if (!ownerSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -109,8 +110,7 @@ PermissionedDomainSet::doApply()
|
||||
// Create new permissioned domain.
|
||||
// Check reserve availability for new object creation
|
||||
auto const balance = STAmount((*ownerSle)[sfBalance]).xrp();
|
||||
auto const reserve =
|
||||
accountReserve(ctx_.view(), ownerSle, ctx_.journal, {.ownerCountDelta = 1});
|
||||
auto const reserve = ownerSle.reserve({.ownerCountDelta = 1});
|
||||
if (balance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
@@ -130,7 +130,8 @@ PermissionedDomainSet::doApply()
|
||||
|
||||
slePd->setFieldU64(sfOwnerNode, *page);
|
||||
// If we succeeded, the new entry counts against the creator's reserve.
|
||||
increaseOwnerCount(view(), ownerSle, {}, 1, ctx_.journal);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
ownerSle.increaseOwnerCount(noSponsor, 1);
|
||||
view().insert(slePd);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/ProposalHelpers.h>
|
||||
@@ -159,7 +160,7 @@ TransactionProposalCreate::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
|
||||
AccountID const target = proposedTx.getAccountID(sfAccount);
|
||||
auto const sleTarget = ctx.view.read(keylet::account(target));
|
||||
auto const sleTarget = AccountRootEntryR(target, ctx.view);
|
||||
if (!sleTarget)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "TransactionProposalCreate: target account "
|
||||
@@ -297,7 +298,7 @@ TransactionProposalCreate::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
TransactionProposalCreate::doApply()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
auto sle = AccountRootEntryW(accountID_, view(), ctx_.journal);
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -307,12 +308,10 @@ TransactionProposalCreate::doApply()
|
||||
// The proposal holds a full transaction plus its collected signatures, so
|
||||
// it reserves more than a typical ledger entry (5 increments; 10 for a
|
||||
// proposed Batch).
|
||||
if (auto const ret = checkReserve(
|
||||
if (auto const ret = sle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
{.ownerCountDelta = static_cast<int>(ownerCount)},
|
||||
ctx_.journal);
|
||||
{.ownerCountDelta = static_cast<int>(ownerCount)});
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -327,7 +326,6 @@ TransactionProposalCreate::doApply()
|
||||
|
||||
view().insert(sleProposal);
|
||||
|
||||
auto viewJ = ctx_.registry.get().getJournal("View");
|
||||
{
|
||||
auto const page = view().dirInsert(
|
||||
keylet::ownerDir(accountID_), proposalKeylet, describeOwnerDir(accountID_));
|
||||
@@ -336,7 +334,7 @@ TransactionProposalCreate::doApply()
|
||||
sleProposal->setFieldU64(sfOwnerNode, *page);
|
||||
}
|
||||
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sle, ownerCount, viewJ);
|
||||
sle.increaseOwnerCount(ctx_.getApplyViewContext(), ownerCount);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleProposal);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -164,11 +165,11 @@ SponsorshipSet::preclaim(PreclaimContext const& ctx)
|
||||
if (sponseeID == sponsorID)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sponsorAccSle = ctx.view.read(keylet::account(sponsorID));
|
||||
auto const sponsorAccSle = AccountRootEntryR(sponsorID, ctx.view);
|
||||
if (!sponsorAccSle)
|
||||
return tecNO_DST;
|
||||
|
||||
auto const sponseeSle = ctx.view.read(keylet::account(sponseeID));
|
||||
auto const sponseeSle = AccountRootEntryR(sponseeID, ctx.view);
|
||||
if (!sponseeSle)
|
||||
return tecNO_DST;
|
||||
|
||||
@@ -212,7 +213,7 @@ deleteSponsorship(ApplyView& view, SLE::Ref sle, beast::Journal j)
|
||||
|
||||
// The sponsor owns the Sponsorship object, so deletion releases the
|
||||
// sponsor's owner reserve.
|
||||
auto sponsorAccSle = view.peek(keylet::account(sponsorID));
|
||||
auto sponsorAccSle = AccountRootEntryW(sponsorID, view);
|
||||
if (!sponsorAccSle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -237,7 +238,7 @@ deleteSponsorship(ApplyView& view, SLE::Ref sle, beast::Journal j)
|
||||
if (sle->isFieldPresent(sfFeeAmount))
|
||||
{
|
||||
(*sponsorAccSle)[sfBalance] += sle->getFieldAmount(sfFeeAmount);
|
||||
view.update(sponsorAccSle);
|
||||
sponsorAccSle.update();
|
||||
}
|
||||
|
||||
view.erase(sle);
|
||||
@@ -250,8 +251,8 @@ SponsorshipSet::createSponsorship(
|
||||
Keylet const& sponsorshipKeylet,
|
||||
AccountID const& sponsorID,
|
||||
AccountID const& sponseeID,
|
||||
SLE::Ref sponsorAccSle,
|
||||
SLE::Ref reserveSponsorAccSle)
|
||||
AccountRootEntryW& sponsorAccSle,
|
||||
std::optional<AccountRootEntryW>& reserveSponsorAccSle)
|
||||
{
|
||||
auto const feeAmountDelta = ctx_.tx[~sfFeeAmountDelta];
|
||||
auto const maxFee = ctx_.tx[~sfMaxFee];
|
||||
@@ -276,13 +277,11 @@ SponsorshipSet::createSponsorship(
|
||||
if (hasPositiveFeeAmount)
|
||||
sponsorBalanceAfterFee -= *feeAmountDelta;
|
||||
|
||||
if (auto const ret = checkReserve(
|
||||
if (auto const ret = sponsorAccSle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sponsorAccSle,
|
||||
sponsorBalanceAfterFee.xrp(),
|
||||
reserveSponsorAccSle,
|
||||
{.ownerCountDelta = 1},
|
||||
ctx_.journal,
|
||||
tecUNFUNDED);
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
@@ -323,8 +322,9 @@ SponsorshipSet::createSponsorship(
|
||||
(*newSle)[sfSponseeNode] = *sponseePage;
|
||||
|
||||
// NOLINTNEXTLINE(readability-suspicious-call-argument)
|
||||
increaseOwnerCount(view(), sponsorAccSle, reserveSponsorAccSle, 1, ctx_.journal);
|
||||
addSponsorToLedgerEntry(newSle, reserveSponsorAccSle);
|
||||
sponsorAccSle.increaseOwnerCount(reserveSponsorAccSle, 1);
|
||||
if (reserveSponsorAccSle.has_value())
|
||||
addSponsorToLedgerEntry(newSle, reserveSponsorAccSle->rawSle());
|
||||
|
||||
ctx_.view().insert(newSle);
|
||||
return tesSUCCESS;
|
||||
@@ -339,7 +339,7 @@ SponsorshipSet::doApply()
|
||||
if (sponseeID == sponsorID)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const sponsorAccSle = ctx_.view().peek(keylet::account(sponsorID));
|
||||
auto sponsorAccSle = AccountRootEntryW(sponsorID, ctx_.view(), ctx_.journal);
|
||||
if (!sponsorAccSle)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -388,13 +388,11 @@ SponsorshipSet::doApply()
|
||||
// object.
|
||||
(*sponsorAccSle)[sfBalance] -= actualDelta;
|
||||
|
||||
if (auto const ret = checkReserve(
|
||||
if (auto const ret = sponsorAccSle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sponsorAccSle,
|
||||
(*sponsorAccSle)[sfBalance]->xrp(),
|
||||
*reserveSponsorAccSle,
|
||||
{},
|
||||
ctx_.journal,
|
||||
tecUNFUNDED);
|
||||
!isTesSuccess(ret))
|
||||
{
|
||||
@@ -413,7 +411,7 @@ SponsorshipSet::doApply()
|
||||
{
|
||||
(*sponsorshipSle)[sfFeeAmount] = newFee;
|
||||
}
|
||||
ctx_.view().update(sponsorAccSle);
|
||||
sponsorAccSle.update();
|
||||
}
|
||||
|
||||
if (maxFee)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -20,17 +20,13 @@
|
||||
#include <bit>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Increment an uint32 sponsor count field and update the SLE.
|
||||
static TER
|
||||
incrementSponsorCount(
|
||||
ApplyView& view,
|
||||
SLE::Ref sle,
|
||||
SF_UINT32 const& field,
|
||||
std::uint32_t const delta)
|
||||
incrementSponsorCount(AccountRootEntryW& sle, SF_UINT32 const& field, std::uint32_t const delta)
|
||||
{
|
||||
auto const currentValue = sle->getFieldU32(field);
|
||||
if (std::numeric_limits<std::uint32_t>::max() - currentValue < delta)
|
||||
@@ -42,17 +38,13 @@ incrementSponsorCount(
|
||||
}
|
||||
|
||||
sle->at(field) = currentValue + delta;
|
||||
view.update(sle);
|
||||
sle.update();
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// Decrement an uint32 sponsor count field and update the SLE.
|
||||
static TER
|
||||
decrementSponsorCount(
|
||||
ApplyView& view,
|
||||
SLE::Ref sle,
|
||||
SF_UINT32 const& field,
|
||||
std::uint32_t const delta)
|
||||
decrementSponsorCount(AccountRootEntryW& sle, SF_UINT32 const& field, std::uint32_t const delta)
|
||||
{
|
||||
auto const currentValue = sle->getFieldU32(field);
|
||||
if (currentValue < delta)
|
||||
@@ -64,7 +56,7 @@ decrementSponsorCount(
|
||||
}
|
||||
|
||||
sle->at(field) = currentValue - delta;
|
||||
view.update(sle);
|
||||
sle.update();
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -232,7 +224,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
auto const account = ctx.tx[sfAccount];
|
||||
auto const sponseeID = ctx.tx[~sfSponsee].value_or(account);
|
||||
auto const sponseeSle = ctx.view.read(keylet::account(sponseeID));
|
||||
auto const sponseeSle = AccountRootEntryR(sponseeID, ctx.view);
|
||||
if (!sponseeSle)
|
||||
{
|
||||
// If it is ending sponsorship, sfSponsee is user input, return terNO_ACCOUNT if it does not
|
||||
@@ -248,7 +240,7 @@ SponsorshipTransfer::preclaim(PreclaimContext const& ctx)
|
||||
// Default setup with an account sponsorship transfer. If it is an object transfer, they will be
|
||||
// overridden to the object SLE and its type-specific sponsor field:
|
||||
// sfHighSponsor/sfLowSponsor for a RippleState, sfSponsor for other object types.
|
||||
SLE::const_pointer targetSle = sponseeSle;
|
||||
SLE::const_pointer targetSle = sponseeSle.rawSle();
|
||||
auto const* sponsorField = &sfSponsor;
|
||||
|
||||
if (objectID.has_value())
|
||||
@@ -313,7 +305,7 @@ SponsorshipTransfer::doApply()
|
||||
auto const objectID = ctx_.tx[~sfObjectID];
|
||||
|
||||
auto const sponseeID = ctx_.tx[~sfSponsee].value_or(accountID_);
|
||||
auto const sponseeSle = view().peek(keylet::account(sponseeID));
|
||||
auto sponseeSle = AccountRootEntryW(sponseeID, view(), ctx_.journal);
|
||||
if (!sponseeSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -337,7 +329,7 @@ SponsorshipTransfer::doApply()
|
||||
if (!isLedgerEntryOwner(view(), *objectSle, sponseeID))
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const ownerSle = view().peek(keylet::account(sponseeID));
|
||||
auto ownerSle = AccountRootEntryW(sponseeID, view());
|
||||
if (!ownerSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -355,27 +347,25 @@ SponsorshipTransfer::doApply()
|
||||
if (!newSponsor)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const newSponsorID = *newSponsor;
|
||||
auto const newSponsorSle = view().peek(keylet::account(newSponsorID));
|
||||
auto newSponsorSle = AccountRootEntryW(newSponsorID, view());
|
||||
if (!newSponsorSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Check if new sponsor has sufficient balance
|
||||
// NOLINTNEXTLINE(readability-suspicious-call-argument)
|
||||
if (auto const ter = checkReserve(
|
||||
if (auto const ter = sponseeSle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance).xrp(),
|
||||
newSponsorSle,
|
||||
{.ownerCountDelta = ownerCountDelta},
|
||||
ctx_.journal);
|
||||
std::optional<AccountRootEntryR>{newSponsorSle},
|
||||
{.ownerCountDelta = ownerCountDelta});
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
if (isCreate)
|
||||
{
|
||||
// Update owner's sponsored count
|
||||
if (auto const ter = incrementSponsorCount(
|
||||
view(), ownerSle, sfSponsoredOwnerCount, ownerCountDelta);
|
||||
if (auto const ter =
|
||||
incrementSponsorCount(ownerSle, sfSponsoredOwnerCount, ownerCountDelta);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
@@ -384,20 +374,20 @@ SponsorshipTransfer::doApply()
|
||||
auto const oldSponsorID = objectSle->getAccountID(sponsorField);
|
||||
if (!oldSponsorID)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const oldSponsorSle = view().peek(keylet::account(oldSponsorID));
|
||||
auto oldSponsorSle = AccountRootEntryW(oldSponsorID, view());
|
||||
if (!oldSponsorSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Decrement old sponsor's sponsoring count
|
||||
if (auto const ter = decrementSponsorCount(
|
||||
view(), oldSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
|
||||
oldSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// Increment new sponsor's sponsoring count
|
||||
if (auto const ter = incrementSponsorCount(
|
||||
view(), newSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
|
||||
if (auto const ter =
|
||||
incrementSponsorCount(newSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -421,7 +411,7 @@ SponsorshipTransfer::doApply()
|
||||
auto const oldSponsorID = objectSle->getAccountID(sponsorField);
|
||||
if (!oldSponsorID)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const oldSponsorSle = view().peek(keylet::account(oldSponsorID));
|
||||
auto oldSponsorSle = AccountRootEntryW(oldSponsorID, view());
|
||||
if (!oldSponsorSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -433,26 +423,24 @@ SponsorshipTransfer::doApply()
|
||||
// steps in (Reassign), or the object/account is deleted.
|
||||
if (view().rules().enabled(fixCleanup3_4_0))
|
||||
{
|
||||
if (auto const ter = checkReserve(
|
||||
if (auto const ter = sponseeSle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
balanceBeforeFee(sponseeSle),
|
||||
SLE::pointer(),
|
||||
{.ownerCountDelta = ownerCountDelta},
|
||||
ctx_.journal);
|
||||
balanceBeforeFee(sponseeSle.rawSle()),
|
||||
std::nullopt,
|
||||
{.ownerCountDelta = ownerCountDelta});
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
}
|
||||
|
||||
// Decrement sponsored count
|
||||
if (auto const ter = decrementSponsorCount(
|
||||
view(), sponseeSle, sfSponsoredOwnerCount, ownerCountDelta);
|
||||
if (auto const ter =
|
||||
decrementSponsorCount(sponseeSle, sfSponsoredOwnerCount, ownerCountDelta);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
|
||||
// Decrement old sponsoring count
|
||||
if (auto const ter = decrementSponsorCount(
|
||||
view(), oldSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
|
||||
if (auto const ter =
|
||||
decrementSponsorCount(oldSponsorSle, sfSponsoringOwnerCount, ownerCountDelta);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -475,17 +463,15 @@ SponsorshipTransfer::doApply()
|
||||
if (!newSponsor)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const newSponsorID = *newSponsor;
|
||||
auto const newSponsorSle = view().peek(keylet::account(newSponsorID));
|
||||
auto newSponsorSle = AccountRootEntryW(newSponsorID, view());
|
||||
if (!newSponsorSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ter = checkReserve(
|
||||
if (auto const ter = sponseeSle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
sponseeSle->getFieldAmount(sfBalance).xrp(),
|
||||
newSponsorSle,
|
||||
{.accountCountDelta = 1},
|
||||
ctx_.journal);
|
||||
std::optional<AccountRootEntryR>{newSponsorSle},
|
||||
{.accountCountDelta = 1});
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
@@ -494,26 +480,25 @@ SponsorshipTransfer::doApply()
|
||||
auto const oldSponsorID = sponseeSle->getAccountID(sfSponsor);
|
||||
if (!oldSponsorID)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const oldSponsorSle = view().peek(keylet::account(oldSponsorID));
|
||||
auto oldSponsorSle = AccountRootEntryW(oldSponsorID, view());
|
||||
if (!oldSponsorSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Decrement old sponsoring count
|
||||
if (auto const ter =
|
||||
decrementSponsorCount(view(), oldSponsorSle, sfSponsoringAccountCount, 1);
|
||||
decrementSponsorCount(oldSponsorSle, sfSponsoringAccountCount, 1);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// Increment new sponsoring count
|
||||
if (auto const ter =
|
||||
incrementSponsorCount(view(), newSponsorSle, sfSponsoringAccountCount, 1);
|
||||
if (auto const ter = incrementSponsorCount(newSponsorSle, sfSponsoringAccountCount, 1);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
|
||||
// Account is now sponsored by new sponsor
|
||||
sponseeSle->setAccountID(sfSponsor, newSponsorID);
|
||||
view().update(sponseeSle);
|
||||
sponseeSle.update();
|
||||
}
|
||||
else if (ctx_.tx.isFlag(tfSponsorshipEnd))
|
||||
{
|
||||
@@ -521,28 +506,25 @@ SponsorshipTransfer::doApply()
|
||||
auto const oldSponsorID = sponseeSle->getAccountID(sfSponsor);
|
||||
if (!oldSponsorID)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
auto const oldSponsorSle = view().peek(keylet::account(oldSponsorID));
|
||||
auto oldSponsorSle = AccountRootEntryW(oldSponsorID, view());
|
||||
if (!oldSponsorSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// The sponsee must be able to hold its own account reserve after
|
||||
// the sponsorship is removed.
|
||||
if (auto const ter = checkReserve(
|
||||
if (auto const ter = sponseeSle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sponseeSle,
|
||||
balanceBeforeFee(sponseeSle),
|
||||
SLE::pointer(),
|
||||
{.accountCountDelta = 1},
|
||||
ctx_.journal);
|
||||
balanceBeforeFee(sponseeSle.rawSle()),
|
||||
std::optional<AccountRootEntryR>{},
|
||||
{.accountCountDelta = 1});
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
sponseeSle->makeFieldAbsent(sfSponsor);
|
||||
view().update(sponseeSle);
|
||||
sponseeSle.update();
|
||||
|
||||
// Decrement account sponsoring count
|
||||
if (auto const ter =
|
||||
decrementSponsorCount(view(), oldSponsorSle, sfSponsoringAccountCount, 1);
|
||||
if (auto const ter = decrementSponsorCount(oldSponsorSle, sfSponsoringAccountCount, 1);
|
||||
!isTesSuccess(ter))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -96,7 +97,7 @@ LedgerStateFix::preclaim(PreclaimContext const& ctx)
|
||||
if (static_cast<FixType>(ctx.tx[sfLedgerFixType]) == FixType::NfTokenPageLink)
|
||||
{
|
||||
AccountID const owner{ctx.tx[sfOwner]};
|
||||
if (!ctx.view.read(keylet::account(owner)))
|
||||
if (!AccountRootEntryR(owner, ctx.view))
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
@@ -18,6 +19,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -42,7 +44,7 @@ TER
|
||||
TicketCreate::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const id = ctx.tx[sfAccount];
|
||||
auto const sleAccountRoot = ctx.view.read(keylet::account(id));
|
||||
auto const sleAccountRoot = AccountRootEntryR(id, ctx.view);
|
||||
if (!sleAccountRoot)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
@@ -67,7 +69,7 @@ TicketCreate::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
TicketCreate::doApply()
|
||||
{
|
||||
SLE::pointer const sleAccountRoot = view().peek(keylet::account(accountID_));
|
||||
auto sleAccountRoot = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!sleAccountRoot)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -75,15 +77,10 @@ TicketCreate::doApply()
|
||||
// check the starting balance because we want to allow dipping into the
|
||||
// reserve to pay fees.
|
||||
std::uint32_t const ticketCount = ctx_.tx[sfTicketCount];
|
||||
if (preFeeBalance_ < accountReserve(
|
||||
view(),
|
||||
sleAccountRoot,
|
||||
j_,
|
||||
{.ownerCountDelta = static_cast<std::int32_t>(ticketCount)}))
|
||||
if (preFeeBalance_ <
|
||||
sleAccountRoot.reserve({.ownerCountDelta = static_cast<std::int32_t>(ticketCount)}))
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
beast::Journal const viewJ{ctx_.registry.get().getJournal("View")};
|
||||
|
||||
// The starting ticket sequence is the same as the current account
|
||||
// root sequence. Before we got here to doApply(), the transaction
|
||||
// machinery already incremented the account root sequence if that
|
||||
@@ -125,7 +122,8 @@ TicketCreate::doApply()
|
||||
sleAccountRoot->setFieldU32(sfTicketCount, oldTicketCount + ticketCount);
|
||||
|
||||
// Every added Ticket counts against the creator's reserve.
|
||||
increaseOwnerCount(view(), sleAccountRoot, {}, ticketCount, viewJ);
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
sleAccountRoot.increaseOwnerCount(noSponsor, ticketCount);
|
||||
|
||||
// TicketCreate is the only transaction that can cause an account root's
|
||||
// Sequence field to increase by more than one. October 2018.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -186,8 +187,8 @@ Clawback::preclaim(PreclaimContext const& ctx)
|
||||
auto const clawAmount = ctx.tx[sfAmount];
|
||||
AccountID const holder = clawAmount.holds<Issue>() ? clawAmount.getIssuer() : ctx.tx[sfHolder];
|
||||
|
||||
auto const sleIssuer = ctx.view.read(keylet::account(issuer));
|
||||
auto const sleHolder = ctx.view.read(keylet::account(holder));
|
||||
auto const sleIssuer = AccountRootEntryR(issuer, ctx.view);
|
||||
auto const sleHolder = AccountRootEntryR(holder, ctx.view);
|
||||
if (!sleIssuer || !sleHolder)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/ConfidentialTransfer.h>
|
||||
@@ -167,7 +168,7 @@ ConfidentialMPTSend::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// Check if destination account exists
|
||||
auto const destination = ctx.tx[sfDestination];
|
||||
auto const sleDst = ctx.view.read(keylet::account(destination));
|
||||
auto const sleDst = AccountRootEntryR(destination, ctx.view);
|
||||
if (!sleDst)
|
||||
return tecNO_TARGET;
|
||||
|
||||
@@ -292,7 +293,7 @@ ConfidentialMPTSend::preclaim(PreclaimContext const& ctx)
|
||||
// Check deposit preauth before the expensive ZK proof verification.
|
||||
// Uses read-only view.
|
||||
auto const preauthErr =
|
||||
checkDepositPreauth(ctx.tx, ctx.view, account, destination, sleDst, ctx.j);
|
||||
checkDepositPreauth(ctx.tx, ctx.view, account, destination, sleDst.rawSle(), ctx.j);
|
||||
if (!isTesSuccess(preauthErr))
|
||||
return preauthErr;
|
||||
|
||||
@@ -309,7 +310,7 @@ ConfidentialMPTSend::doApply()
|
||||
auto sleDestinationMPToken = view().peek(keylet::mptoken(mptIssuanceID, destination));
|
||||
auto const sleIssuance = view().read(keylet::mptokenIssuance(mptIssuanceID));
|
||||
|
||||
auto const sleDestAcct = view().read(keylet::account(destination));
|
||||
auto const sleDestAcct = AccountRootEntryW(destination, view());
|
||||
|
||||
if (!sleSenderMPToken || !sleDestinationMPToken || !sleIssuance || !sleDestAcct)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <xrpl/tx/transactors/token/MPTokenAuthorize.h>
|
||||
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -120,7 +121,7 @@ MPTokenAuthorize::preclaim(PreclaimContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
auto const sleHolder = ctx.view.read(keylet::account(*holderID));
|
||||
auto const sleHolder = AccountRootEntryR(*holderID, ctx.view);
|
||||
if (!sleHolder)
|
||||
return tecNO_DST;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -125,20 +125,20 @@ MPTokenIssuanceCreate::create(
|
||||
beast::Journal journal,
|
||||
MPTCreateArgs const& args)
|
||||
{
|
||||
auto const acct = ctx.view.peek(keylet::account(args.account));
|
||||
auto acct = AccountRootEntryW(args.account, ctx.view, journal);
|
||||
if (!acct)
|
||||
return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
// A reserve sponsor only covers tx.Account's own objects.
|
||||
auto const sponsorExp = getEffectiveTxReserveSponsor(ctx, acct);
|
||||
auto sponsorExp = getEffectiveTxReserveSponsor(ctx, acct);
|
||||
if (!sponsorExp)
|
||||
return std::unexpected(sponsorExp.error()); // LCOV_EXCL_LINE
|
||||
auto const sponsorSle = *sponsorExp;
|
||||
auto& sponsorSle = *sponsorExp;
|
||||
|
||||
if (args.priorBalance)
|
||||
{
|
||||
if (auto const ret = checkReserve(
|
||||
ctx, acct, *(args.priorBalance), sponsorSle, {.ownerCountDelta = 1}, journal);
|
||||
if (auto const ret =
|
||||
acct.checkReserve(ctx, *(args.priorBalance), sponsorSle, {.ownerCountDelta = 1});
|
||||
!isTesSuccess(ret))
|
||||
return std::unexpected(ret);
|
||||
}
|
||||
@@ -195,13 +195,14 @@ MPTokenIssuanceCreate::create(
|
||||
(*mptIssuance)[sfReferenceHolding] = *args.referenceHolding;
|
||||
}
|
||||
|
||||
addSponsorToLedgerEntry(mptIssuance, sponsorSle);
|
||||
if (sponsorSle)
|
||||
addSponsorToLedgerEntry(mptIssuance, sponsorSle->rawSle());
|
||||
|
||||
ctx.view.insert(mptIssuance);
|
||||
}
|
||||
|
||||
// Update owner count.
|
||||
increaseOwnerCount(ctx.view, acct, sponsorSle, 1, journal);
|
||||
acct.increaseOwnerCount(sponsorSle, 1);
|
||||
|
||||
return mptId;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -26,6 +27,7 @@
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace {
|
||||
@@ -157,7 +159,7 @@ TrustSet::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
auto const id = ctx.tx[sfAccount];
|
||||
|
||||
auto const sle = ctx.view.read(keylet::account(id));
|
||||
auto const sle = AccountRootEntryR(id, ctx.view);
|
||||
if (!sle)
|
||||
return terNO_ACCOUNT;
|
||||
|
||||
@@ -178,9 +180,9 @@ TrustSet::preclaim(PreclaimContext const& ctx)
|
||||
return temDST_IS_SRC;
|
||||
|
||||
// This might be nullptr
|
||||
auto const sleDst = ctx.view.read(keylet::account(uDstAccountID));
|
||||
auto const sleDst = AccountRootEntryR(uDstAccountID, ctx.view);
|
||||
if ((ammEnabled(ctx.view.rules()) || ctx.view.rules().enabled(featureSingleAssetVault)) &&
|
||||
sleDst == nullptr)
|
||||
!sleDst)
|
||||
return tecNO_DST;
|
||||
|
||||
// If the destination has opted to disallow incoming trustlines
|
||||
@@ -294,7 +296,7 @@ TrustSet::doApply()
|
||||
// true, if current is high account.
|
||||
bool const bHigh = accountID_ > uDstAccountID;
|
||||
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
auto sle = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -316,23 +318,24 @@ TrustSet::doApply()
|
||||
// well. A person with no intention of using the gateway
|
||||
// could use the extra XRP for their own purposes.
|
||||
|
||||
auto const sponsorExp = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
auto sponsorExp = getTxReserveSponsor(ctx_.getApplyViewContext());
|
||||
if (!sponsorExp)
|
||||
return sponsorExp.error(); // LCOV_EXCL_LINE
|
||||
auto const sponsorSle = *sponsorExp;
|
||||
auto& sponsorSle = *sponsorExp;
|
||||
|
||||
auto getSponsor = [&sponsorSle, this](AccountID const& account) {
|
||||
return (sponsorSle && account == accountID_) ? sponsorSle : SLE::pointer();
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
auto getSponsor = [&sponsorSle, &noSponsor, this](
|
||||
AccountID const& account) -> std::optional<AccountRootEntryW>& {
|
||||
return (sponsorSle && account == accountID_) ? sponsorSle : noSponsor;
|
||||
};
|
||||
|
||||
// The "free-tier" shortcut (ownerCount < 2) only applies when there is no sponsor.
|
||||
// With any sponsor on the tx, the sponsor must cover the reserve (via balance or
|
||||
// prefunded budget), so the reserve check always runs.
|
||||
bool const freeTrustLine = !sponsorSle && (ownerCount(sle, j_) < 2);
|
||||
std::uint32_t const uOwnerCount = ownerCount(sle, j_);
|
||||
bool const freeTrustLine = !sponsorSle && (sle.ownerCount() < 2);
|
||||
std::uint32_t const uOwnerCount = sle.ownerCount();
|
||||
XRPAmount const reserveCreate(
|
||||
(uOwnerCount < 2) ? XRPAmount(beast::kZero)
|
||||
: accountReserve(view(), sle, j_, {.ownerCountDelta = 1}));
|
||||
(uOwnerCount < 2) ? XRPAmount(beast::kZero) : sle.reserve({.ownerCountDelta = 1}));
|
||||
|
||||
std::uint32_t const uQualityIn(bQualityIn ? ctx_.tx.getFieldU32(sfQualityIn) : 0);
|
||||
std::uint32_t uQualityOut(bQualityOut ? ctx_.tx.getFieldU32(sfQualityOut) : 0);
|
||||
@@ -350,7 +353,7 @@ TrustSet::doApply()
|
||||
|
||||
auto viewJ = ctx_.registry.get().getJournal("View");
|
||||
|
||||
SLE::pointer const sleDst = view().peek(keylet::account(uDstAccountID));
|
||||
auto sleDst = AccountRootEntryW(uDstAccountID, view(), j_);
|
||||
|
||||
if (!sleDst)
|
||||
{
|
||||
@@ -376,8 +379,8 @@ TrustSet::doApply()
|
||||
std::uint32_t uHighQualityOut = 0;
|
||||
auto const& uLowAccountID = !bHigh ? accountID_ : uDstAccountID;
|
||||
auto const& uHighAccountID = bHigh ? accountID_ : uDstAccountID;
|
||||
SLE::Ref sleLowAccount = !bHigh ? sle : sleDst;
|
||||
SLE::Ref sleHighAccount = bHigh ? sle : sleDst;
|
||||
AccountRootEntryW& sleLowAccount = !bHigh ? sle : sleDst;
|
||||
AccountRootEntryW& sleHighAccount = bHigh ? sle : sleDst;
|
||||
|
||||
//
|
||||
// Balances
|
||||
@@ -518,10 +521,9 @@ TrustSet::doApply()
|
||||
|
||||
bool bReserveIncrease = false;
|
||||
|
||||
auto const currentHighSponsor =
|
||||
auto currentHighSponsor =
|
||||
getLedgerEntryReserveSponsor(view(), sleRippleState, sfHighSponsor);
|
||||
auto const currentLowSponsor =
|
||||
getLedgerEntryReserveSponsor(view(), sleRippleState, sfLowSponsor);
|
||||
auto currentLowSponsor = getLedgerEntryReserveSponsor(view(), sleRippleState, sfLowSponsor);
|
||||
|
||||
if (bSetAuth)
|
||||
{
|
||||
@@ -530,17 +532,15 @@ TrustSet::doApply()
|
||||
|
||||
if (bLowReserveSet && !bLowReserved)
|
||||
{
|
||||
SLE::pointer const lowSponsor = getSponsor(uLowAccountID);
|
||||
auto& lowSponsor = getSponsor(uLowAccountID);
|
||||
|
||||
if (view().rules().enabled(featureSponsor))
|
||||
{
|
||||
if (auto const ret = checkReserve(
|
||||
if (auto const ret = sleLowAccount.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sleLowAccount,
|
||||
preFeeBalance_,
|
||||
lowSponsor,
|
||||
{.ownerCountDelta = 1},
|
||||
j_,
|
||||
tecINSUF_RESERVE_LINE);
|
||||
lowSponsor && !isTesSuccess(ret))
|
||||
{
|
||||
@@ -549,10 +549,11 @@ TrustSet::doApply()
|
||||
}
|
||||
|
||||
// Set reserve for low account.
|
||||
increaseOwnerCount(view(), sleLowAccount, lowSponsor, 1, viewJ);
|
||||
sleLowAccount.increaseOwnerCount(lowSponsor, 1);
|
||||
uFlagsOut |= lsfLowReserve;
|
||||
|
||||
addSponsorToLedgerEntry(sleRippleState, lowSponsor, sfLowSponsor);
|
||||
if (lowSponsor)
|
||||
addSponsorToLedgerEntry(sleRippleState, lowSponsor->rawSle(), sfLowSponsor);
|
||||
|
||||
if (!bHigh)
|
||||
bReserveIncrease = true;
|
||||
@@ -561,7 +562,7 @@ TrustSet::doApply()
|
||||
if (bLowReserveClear && bLowReserved)
|
||||
{
|
||||
// Clear reserve for low account.
|
||||
decreaseOwnerCount(view(), sleLowAccount, currentLowSponsor, 1, viewJ);
|
||||
sleLowAccount.decreaseOwnerCount(currentLowSponsor, 1);
|
||||
uFlagsOut &= ~lsfLowReserve;
|
||||
|
||||
removeSponsorFromLedgerEntry(sleRippleState, sfLowSponsor);
|
||||
@@ -569,20 +570,18 @@ TrustSet::doApply()
|
||||
|
||||
if (bHighReserveSet && !bHighReserved)
|
||||
{
|
||||
SLE::pointer const highSponsor = getSponsor(uHighAccountID);
|
||||
auto& highSponsor = getSponsor(uHighAccountID);
|
||||
|
||||
// should be checked PreFunded Sponsor before increaseOwnerCount()
|
||||
// For PreFunded sponsors, we need to check if there are sufficient reserves before
|
||||
// calling increaseOwnerCount().
|
||||
if (view().rules().enabled(featureSponsor))
|
||||
{
|
||||
if (auto const ret = checkReserve(
|
||||
if (auto const ret = sleHighAccount.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sleHighAccount,
|
||||
preFeeBalance_,
|
||||
highSponsor,
|
||||
{.ownerCountDelta = 1},
|
||||
j_,
|
||||
tecINSUF_RESERVE_LINE);
|
||||
highSponsor && !isTesSuccess(ret))
|
||||
{
|
||||
@@ -591,10 +590,11 @@ TrustSet::doApply()
|
||||
}
|
||||
|
||||
// Set reserve for high account.
|
||||
increaseOwnerCount(view(), sleHighAccount, highSponsor, 1, viewJ);
|
||||
sleHighAccount.increaseOwnerCount(highSponsor, 1);
|
||||
uFlagsOut |= lsfHighReserve;
|
||||
|
||||
addSponsorToLedgerEntry(sleRippleState, highSponsor, sfHighSponsor);
|
||||
if (highSponsor)
|
||||
addSponsorToLedgerEntry(sleRippleState, highSponsor->rawSle(), sfHighSponsor);
|
||||
|
||||
if (bHigh)
|
||||
bReserveIncrease = true;
|
||||
@@ -603,7 +603,7 @@ TrustSet::doApply()
|
||||
if (bHighReserveClear && bHighReserved)
|
||||
{
|
||||
// Clear reserve for high account.
|
||||
decreaseOwnerCount(view(), sleHighAccount, currentHighSponsor, 1, viewJ);
|
||||
sleHighAccount.decreaseOwnerCount(currentHighSponsor, 1);
|
||||
uFlagsOut &= ~lsfHighReserve;
|
||||
|
||||
removeSponsorFromLedgerEntry(sleRippleState, sfHighSponsor);
|
||||
@@ -623,13 +623,11 @@ TrustSet::doApply()
|
||||
}
|
||||
// Reserve is not scaled by load
|
||||
else if (
|
||||
auto const ret = checkReserve(
|
||||
auto const ret = sle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
sponsorSle,
|
||||
{},
|
||||
j_,
|
||||
tecINSUF_RESERVE_LINE);
|
||||
!freeTrustLine && bReserveIncrease && !isTesSuccess(ret))
|
||||
{
|
||||
@@ -697,13 +695,11 @@ TrustSet::doApply()
|
||||
terResult = tecNO_LINE_INSUF_RESERVE;
|
||||
}
|
||||
else if (
|
||||
auto const ret = checkReserve(
|
||||
auto const ret = sle.checkReserve(
|
||||
ctx_.getApplyViewContext(),
|
||||
sle,
|
||||
preFeeBalance_,
|
||||
sponsorSle,
|
||||
{.ownerCountDelta = 1},
|
||||
j_,
|
||||
tecNO_LINE_INSUF_RESERVE);
|
||||
view().rules().enabled(featureSponsor) && !freeTrustLine &&
|
||||
!isTesSuccess(ret)) // Reserve is not scaled by load.
|
||||
@@ -731,7 +727,7 @@ TrustSet::doApply()
|
||||
accountID_,
|
||||
uDstAccountID,
|
||||
k.key,
|
||||
sle,
|
||||
sle.mutableRawSle(),
|
||||
bSetAuth,
|
||||
bSetNoRipple && !bClearNoRipple,
|
||||
bSetFreeze && !bClearFreeze,
|
||||
@@ -740,7 +736,7 @@ TrustSet::doApply()
|
||||
saLimitAllow, // Limit for who is being charged.
|
||||
uQualityIn,
|
||||
uQualityOut,
|
||||
sponsorSle,
|
||||
sponsorSle ? sponsorSle->mutableRawSle() : SLE::pointer{},
|
||||
viewJ);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/VaultHelpers.h>
|
||||
@@ -206,7 +207,7 @@ VaultClawback::preclaim(PreclaimContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
},
|
||||
[&](Issue const&) -> TER {
|
||||
auto const issuerSle = ctx.view.read(keylet::account(account));
|
||||
auto const issuerSle = AccountRootEntryR(account, ctx.view);
|
||||
if (!issuerSle)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -181,8 +182,8 @@ VaultCreate::doApply()
|
||||
auto const& tx = ctx_.tx;
|
||||
auto applyViewContext = ctx_.getApplyViewContext();
|
||||
auto const sequence = tx.getSeqProxy();
|
||||
auto const owner = view().peek(keylet::account(accountID_));
|
||||
if (owner == nullptr)
|
||||
auto owner = AccountRootEntryW(accountID_, view(), j_);
|
||||
if (!owner)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto vault = std::make_shared<SLE>(keylet::vault(accountID_, sequence));
|
||||
@@ -190,8 +191,9 @@ VaultCreate::doApply()
|
||||
if (auto ter = dirLink(view(), accountID_, vault))
|
||||
return ter;
|
||||
// We will create Vault and PseudoAccount, hence increase OwnerCount by 2
|
||||
increaseOwnerCount(view(), owner, {}, 2, j_);
|
||||
if (preFeeBalance_ < accountReserve(view(), owner, j_))
|
||||
std::optional<AccountRootEntryW> noSponsor;
|
||||
owner.increaseOwnerCount(noSponsor, 2);
|
||||
if (preFeeBalance_ < owner.reserve())
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
auto maybePseudo = createPseudoAccount(view(), vault->key(), sfVaultID);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -109,7 +110,7 @@ VaultDelete::doApply()
|
||||
return ter;
|
||||
|
||||
auto const& pseudoID = vault->at(sfAccount);
|
||||
auto const pseudoAcct = view().peek(keylet::account(pseudoID));
|
||||
auto pseudoAcct = AccountRootEntryW(pseudoID, view());
|
||||
if (!pseudoAcct)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
@@ -164,7 +165,7 @@ VaultDelete::doApply()
|
||||
return tecHAS_OBLIGATIONS; // LCOV_EXCL_LINE
|
||||
|
||||
// Destroy the pseudo-account.
|
||||
auto vaultPseudoSLE = view().peek(keylet::account(pseudoID));
|
||||
auto vaultPseudoSLE = AccountRootEntryW(pseudoID, view());
|
||||
if (!vaultPseudoSLE || vaultPseudoSLE->at(~sfVaultID) != vault->key())
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -192,7 +193,7 @@ VaultDelete::doApply()
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
view().erase(vaultPseudoSLE);
|
||||
vaultPseudoSLE.erase();
|
||||
|
||||
// Remove the vault from its owner's directory.
|
||||
auto const ownerID = vault->at(sfOwner);
|
||||
@@ -204,7 +205,7 @@ VaultDelete::doApply()
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const owner = view().peek(keylet::account(ownerID));
|
||||
auto owner = AccountRootEntryW(ownerID, view());
|
||||
if (!owner)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/AmountConversions.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -446,7 +447,7 @@ public:
|
||||
// here and the end of the test all the effort will be lost.
|
||||
env.app().getOpenLedger().modify([&gw, transferRate](OpenView& view, beast::Journal j) {
|
||||
// Get the account root we want to hijack.
|
||||
auto const sle = view.read(keylet::account(gw.id()));
|
||||
auto const sle = AccountRootEntryR(gw.id(), view);
|
||||
if (!sle)
|
||||
return false; // This would be really surprising!
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ApplyViewImpl.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -1128,10 +1129,10 @@ struct Credentials_test : public beast::unit_test::Suite
|
||||
ApplyViewImpl av(&*open, TapNone);
|
||||
|
||||
// Erase the issuer's account to simulate ledger corruption
|
||||
auto sleIssuer = av.peek(keylet::account(issuer.id()));
|
||||
auto sleIssuer = AccountRootEntryW(issuer.id(), av);
|
||||
if (!BEAST_EXPECT(sleIssuer))
|
||||
return;
|
||||
av.erase(sleIssuer);
|
||||
sleIssuer.erase();
|
||||
BEAST_EXPECT(!av.exists(keylet::account(issuer.id())));
|
||||
|
||||
// Credential still exists before removeExpired
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/ApiVersion.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -450,7 +451,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite
|
||||
// here and the end of the test all the effort will be lost.
|
||||
env.app().getOpenLedger().modify([&alice](OpenView& view, beast::Journal j) {
|
||||
// Get the account root we want to hijack.
|
||||
auto const sle = view.read(keylet::account(alice.id()));
|
||||
auto const sle = AccountRootEntryR(alice.id(), view);
|
||||
if (!sle)
|
||||
return false; // This would be really surprising!
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/Dir.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/ApiVersion.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -69,7 +70,7 @@ struct PayChan_test : public beast::unit_test::Suite
|
||||
static std::pair<UInt256, SLE::const_pointer>
|
||||
channelKeyAndSle(ReadView const& view, jtx::Account const& account, jtx::Account const& dst)
|
||||
{
|
||||
auto const sle = view.read(keylet::account(account));
|
||||
auto const sle = AccountRootEntryR(account, view);
|
||||
if (!sle)
|
||||
return {};
|
||||
auto const k =
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -4294,7 +4295,7 @@ public:
|
||||
// restore the owner's OwnerCount to the legacy weight.
|
||||
env.app().getOpenLedger().modify([&](OpenView& view, beast::Journal) -> bool {
|
||||
auto signerList = std::make_shared<SLE>(*view.read(signerListKeylet));
|
||||
auto account = std::make_shared<SLE>(*view.read(keylet::account(alice.id())));
|
||||
auto account = std::make_shared<SLE>(*AccountRootEntryR(alice.id(), view));
|
||||
signerList->clearFlag(lsfOneOwnerCount);
|
||||
account->setFieldU32(sfOwnerCount, legacyWeight);
|
||||
view.rawReplace(signerList);
|
||||
|
||||
@@ -176,7 +176,7 @@ class InvariantsMisc_test : public InvariantsBase
|
||||
// check.
|
||||
sleA1->at(sfBalance) = beast::kZero;
|
||||
BEAST_EXPECT(sleA1->at(sfOwnerCount) == 0);
|
||||
increaseOwnerCount(ac.view(), sleA1, {}, 1, ac.journal);
|
||||
increaseOwnerCount(ac.view(), a1, {}, 1, ac.journal);
|
||||
|
||||
ac.view().erase(sleA1);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <xrpl/ledger/OwnerCounts.h>
|
||||
#include <xrpl/ledger/PaymentSandbox.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -417,10 +418,10 @@ class PaymentSandbox_test : public beast::unit_test::Suite
|
||||
|
||||
// Test basic owner count hook without sponsor
|
||||
{
|
||||
auto const aliceSle = sb.peek(keylet::account(alice));
|
||||
auto const aliceSle = AccountRootEntryW(alice, sb);
|
||||
BEAST_EXPECT(aliceSle);
|
||||
|
||||
OwnerCounts const initial(aliceSle);
|
||||
OwnerCounts const initial(aliceSle.rawSle());
|
||||
OwnerCounts updated = initial;
|
||||
updated.owner = initial.owner + 2;
|
||||
|
||||
@@ -436,10 +437,10 @@ class PaymentSandbox_test : public beast::unit_test::Suite
|
||||
|
||||
// Test owner count hook with sponsor-related counts
|
||||
{
|
||||
auto const sponsorSle = sb.peek(keylet::account(sponsor));
|
||||
auto const sponsorSle = AccountRootEntryW(sponsor, sb);
|
||||
BEAST_EXPECT(sponsorSle);
|
||||
|
||||
OwnerCounts const sponsorInitial(sponsorSle);
|
||||
OwnerCounts const sponsorInitial(sponsorSle.rawSle());
|
||||
OwnerCounts sponsorUpdated = sponsorInitial;
|
||||
sponsorUpdated.owner = sponsorInitial.owner + 1;
|
||||
sponsorUpdated.sponsoring = sponsorInitial.sponsoring + 1;
|
||||
@@ -469,8 +470,8 @@ class PaymentSandbox_test : public beast::unit_test::Suite
|
||||
|
||||
// Test that max logic works correctly
|
||||
{
|
||||
auto const aliceSle = sb.peek(keylet::account(alice));
|
||||
OwnerCounts const current(aliceSle);
|
||||
auto const aliceSle = AccountRootEntryW(alice, sb);
|
||||
OwnerCounts const current(aliceSle.rawSle());
|
||||
OwnerCounts lower = current;
|
||||
lower.owner = (current.owner > 0) ? current.owner - 1 : 0;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <xrpl/ledger/entries/XChainOwnedClaimIDEntry.h> // IWYU pragma: keep
|
||||
#include <xrpl/ledger/entries/XChainOwnedCreateAccountClaimIDEntry.h> // IWYU pragma: keep
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -76,12 +77,22 @@ template class SLEBase<ApplyView>;
|
||||
#pragma push_macro("LEDGER_ENTRY")
|
||||
#undef LEDGER_ENTRY
|
||||
|
||||
// No explicit instantiation here, neither a definition nor a declaration.
|
||||
// A definition would instantiate an entry a second time once its member
|
||||
// bodies live in its own .cpp (MSVC rejects that with C4661 under /WX), and a
|
||||
// declaration (`extern template`) stops clang from emitting the inline
|
||||
// constructors of the header-only entries at -O0, which leaves them undefined
|
||||
// at link time in the debug builds. Naming the class in a static_assert is
|
||||
// enough to instantiate its definition, which is all this exhaustiveness
|
||||
// check needs; the per-type suites exercise the members.
|
||||
#define LEDGER_ENTRY(tag, value, name, ...) \
|
||||
template class name##Entry<ReadView>; \
|
||||
template class name##Entry<ApplyView>; \
|
||||
static_assert( \
|
||||
name##Entry<ReadView>::kEntryType == tag && name##Entry<ApplyView>::kEntryType == tag, \
|
||||
#name "Entry must be bound to " #tag);
|
||||
#name "Entry must be bound to " #tag); \
|
||||
static_assert( \
|
||||
std::is_constructible_v<name##Entry<ReadView>, Keylet const&, ReadView const&> && \
|
||||
std::is_constructible_v<name##Entry<ApplyView>, Keylet const&, ApplyView&>, \
|
||||
#name "Entry must be constructible from a Keylet and a view");
|
||||
|
||||
#include <xrpl/protocol/detail/ledger_entries.macro>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/ledger/CanonicalTXSet.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
@@ -143,7 +144,7 @@ public:
|
||||
return true;
|
||||
|
||||
AccountID const acctID = txn.getAccount();
|
||||
auto const sleAcct = view.read(keylet::account(acctID));
|
||||
auto const sleAcct = AccountRootEntryR(acctID, view);
|
||||
|
||||
if (!sleAcct)
|
||||
return false;
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/OrderBookDB.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
@@ -4510,7 +4511,7 @@ NetworkOPsImp::subAccountHistoryStart(
|
||||
}
|
||||
if (accountId == kGenesisAccountId)
|
||||
{
|
||||
if (auto const sleAcct = ledger->read(accountKeylet); sleAcct)
|
||||
if (auto const sleAcct = AccountRootEntryR(accountKeylet, *ledger); sleAcct)
|
||||
{
|
||||
if (sleAcct->getFieldU32(sfSequence) == 1)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <xrpl/ledger/ApplyViewImpl.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -790,7 +791,7 @@ TxQ::apply(
|
||||
// If the account is not currently in the ledger, don't queue its tx.
|
||||
auto const account = (*tx)[sfAccount];
|
||||
Keylet const accountKey{keylet::account(account)};
|
||||
auto const sleAccount = view.read(accountKey);
|
||||
auto const sleAccount = AccountRootEntryR(accountKey, view);
|
||||
if (!sleAccount)
|
||||
return {terNO_ACCOUNT, false};
|
||||
|
||||
@@ -1007,8 +1008,8 @@ TxQ::apply(
|
||||
{
|
||||
// If the transaction is queueable, create the multiTxn
|
||||
// object to hold the info we need to adjust for prior txns.
|
||||
TER const ter{
|
||||
canBeHeld(*tx, flags, view, sleAccount, accountIter, replacedTxIter, lock)};
|
||||
TER const ter{canBeHeld(
|
||||
*tx, flags, view, sleAccount.rawSle(), accountIter, replacedTxIter, lock)};
|
||||
if (!isTesSuccess(ter))
|
||||
return {ter, false};
|
||||
|
||||
@@ -1063,7 +1064,8 @@ TxQ::apply(
|
||||
// front of this one in the queue. Make sure the current
|
||||
// transaction fits in proper sequence order with the
|
||||
// previous transaction or is a ticket.
|
||||
if (txSeqProx.isSeq() && nextQueuableSeqImpl(sleAccount, lock) != txSeqProx)
|
||||
if (txSeqProx.isSeq() &&
|
||||
nextQueuableSeqImpl(sleAccount.rawSle(), lock) != txSeqProx)
|
||||
return {telCAN_NOT_QUEUE, false};
|
||||
}
|
||||
|
||||
@@ -1153,7 +1155,7 @@ TxQ::apply(
|
||||
// Create the test view from the current view.
|
||||
multiTxn.emplace(view, flags);
|
||||
|
||||
auto const sleBump = multiTxn->applyView.peek(accountKey);
|
||||
auto sleBump = AccountRootEntryW(accountKey, multiTxn->applyView);
|
||||
if (!sleBump)
|
||||
return {tefINTERNAL, false};
|
||||
|
||||
@@ -1174,7 +1176,7 @@ TxQ::apply(
|
||||
// to the most successful case.
|
||||
sleBump->at(sfSequence) = txSeqProx.isSeq()
|
||||
? txSeqProx.value()
|
||||
: nextQueuableSeqImpl(sleAccount, lock).value();
|
||||
: nextQueuableSeqImpl(sleAccount.rawSle(), lock).value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1249,7 +1251,8 @@ TxQ::apply(
|
||||
// If `multiTxn` has a value, then `canBeHeld` has already been verified
|
||||
if (!multiTxn)
|
||||
{
|
||||
TER const ter{canBeHeld(*tx, flags, view, sleAccount, accountIter, replacedTxIter, lock)};
|
||||
TER const ter{
|
||||
canBeHeld(*tx, flags, view, sleAccount.rawSle(), accountIter, replacedTxIter, lock)};
|
||||
if (!isTesSuccess(ter))
|
||||
{
|
||||
// Bail, transaction cannot be held
|
||||
@@ -1692,7 +1695,7 @@ TxQ::tryDirectApply(
|
||||
beast::Journal j)
|
||||
{
|
||||
auto const account = (*tx)[sfAccount];
|
||||
auto const sleAccount = view.read(keylet::account(account));
|
||||
auto const sleAccount = AccountRootEntryR(account, view);
|
||||
|
||||
// Don't attempt to direct apply if the account is not in the ledger.
|
||||
if (!sleAccount)
|
||||
@@ -1820,10 +1823,10 @@ TxQ::getTxRequiredFeeAndSeq(OpenView const& view, std::shared_ptr<STTx const> co
|
||||
auto const baseFee = *maybeBaseFee;
|
||||
auto const fee = FeeMetrics::scaleFeeLevel(snapshot, view);
|
||||
|
||||
auto const sle = view.read(keylet::account(account));
|
||||
auto const sle = AccountRootEntryR(account, view);
|
||||
|
||||
std::uint32_t const accountSeq = sle ? (*sle)[sfSequence] : 0;
|
||||
std::uint32_t const availableSeq = nextQueuableSeqImpl(sle, lock).value();
|
||||
std::uint32_t const availableSeq = nextQueuableSeqImpl(sle.rawSle(), lock).value();
|
||||
return FeeAndSeq{
|
||||
.fee = mulDiv(fee, baseFee, kBaseLevel)
|
||||
.value_or(XRPAmount(std::numeric_limits<std::int64_t>::max())),
|
||||
|
||||
Reference in new issue
Block a user