mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-12 06:38:01 +00:00
Compare commits
11 Commits
mvadari/re
...
mvadari/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51401e1f57 | ||
|
|
8891288bf1 | ||
|
|
821567f4ad | ||
|
|
dcd32a6f6a | ||
|
|
14368cf1f3 | ||
|
|
95323edaf3 | ||
|
|
8940046ca8 | ||
|
|
f27581a6bb | ||
|
|
b0a1f81256 | ||
|
|
d21cf46021 | ||
|
|
b3e0936504 |
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -7,10 +8,13 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -103,6 +107,87 @@ public:
|
||||
[[nodiscard]] TER
|
||||
checkReserve(ApplyViewContext ctx, XRPAmount accBalance, Adjustment adj) const;
|
||||
|
||||
/**
|
||||
* Returns true if and only if this entry is a pseudo-account of any kind
|
||||
* (i.e. carries at least one field flagged with SField::kSmdPseudoAccount).
|
||||
*
|
||||
* Returns false if the entry:
|
||||
* - is NOT a pseudo-account OR
|
||||
* - is NOT a ltACCOUNT_ROOT OR
|
||||
* - does not exist
|
||||
*
|
||||
* @return true if and only if this entry is a pseudo-account of any kind.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount() const;
|
||||
|
||||
/**
|
||||
* Calculate the liquid XRP balance of this account.
|
||||
*
|
||||
* This is the amount of XRP that the holder is able to freely spend. It
|
||||
* subtracts reserve requirements. Returns zero if the entry does not exist.
|
||||
*
|
||||
* ownerCountAdj adjusts the owner count in case the caller calculates
|
||||
* before ledger entries are added or removed. Positive to add, negative
|
||||
* to subtract.
|
||||
*
|
||||
* @param ownerCountAdj Positive to add to count, negative to reduce count
|
||||
* @return The liquid XRP amount available to the account
|
||||
*/
|
||||
[[nodiscard]] XRPAmount
|
||||
xrpLiquid(std::int32_t ownerCountAdj = 0) const;
|
||||
|
||||
/**
|
||||
* Returns true if this account has the global freeze flag set.
|
||||
*
|
||||
* @return true if this account has the global freeze flag set.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isGlobalFrozen() const
|
||||
{
|
||||
return (*this)->isFlag(lsfGlobalFreeze);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this account's IOU transfer fee as Rate, or kParityRate if it
|
||||
* sets none. Rate specifies the fee as fractions of 1 billion. For
|
||||
* example, 1% transfer rate is represented as 1,010,000,000.
|
||||
*
|
||||
* @return This account's IOU transfer fee, or kParityRate if it sets none.
|
||||
*/
|
||||
[[nodiscard]] Rate
|
||||
transferRate() const
|
||||
{
|
||||
if ((*this)->isFieldPresent(sfTransferRate))
|
||||
return Rate{(*this)->getFieldU32(sfTransferRate)};
|
||||
return kParityRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the destination and tag.
|
||||
*
|
||||
* - Checks that the entry exists.
|
||||
* - If the entry requires a destination tag, checks that there is a tag.
|
||||
*
|
||||
* @param hasDestinationTag Whether the transaction supplies a destination tag
|
||||
* @return tecNO_DST if the entry does not exist; tecDST_TAG_NEEDED if the
|
||||
* entry requires a destination tag and hasDestinationTag is false;
|
||||
* tesSUCCESS otherwise
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkDestinationAndTag(bool hasDestinationTag) const
|
||||
{
|
||||
if (!this->exists())
|
||||
return tecNO_DST;
|
||||
|
||||
// The tag is basically account-specific information we don't
|
||||
// understand, but we can require someone to fill it in.
|
||||
if ((*this)->isFlag(lsfRequireDestTag) && !hasDestinationTag)
|
||||
return tecDST_TAG_NEEDED; // Cannot send without a tag
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase owner-count fields when the caller supplies the sponsor.
|
||||
*
|
||||
@@ -149,6 +234,25 @@ public:
|
||||
decreaseOwnerCount(std::optional<AccountRootEntry<ApplyView>>& sponsorSle, std::uint32_t count)
|
||||
requires Base::kIsWritable;
|
||||
|
||||
/**
|
||||
* Create pseudo-account, storing pseudoOwnerKey into ownerField.
|
||||
*
|
||||
* The list of valid ownerField is maintained in AccountRootHelpers.cpp and
|
||||
* the caller to this function must perform necessary amendment check(s)
|
||||
* before using a field. The amendment check is **not** performed in
|
||||
* createPseudoAccount.
|
||||
*
|
||||
* @param view The ledger view to create the pseudo-account in
|
||||
* @param pseudoOwnerKey The key of the object that owns the pseudo-account,
|
||||
* stored into ownerField
|
||||
* @param ownerField The field linking the pseudo-account to its owner
|
||||
* @return The newly created pseudo-account, or tecDUPLICATE if an account
|
||||
* already exists at the derived pseudo-account address
|
||||
*/
|
||||
[[nodiscard]] static std::expected<AccountRootEntry<ApplyView>, TER>
|
||||
createPseudoAccount(ApplyView& view, UInt256 const& pseudoOwnerKey, SField const& ownerField)
|
||||
requires Base::kIsWritable;
|
||||
|
||||
private:
|
||||
void
|
||||
adjustOwnerCountSigned(
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
#include <xrpl/protocol/Rate.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
@@ -43,8 +41,11 @@ isGlobalFrozen(ReadView const& view, AccountID const& issuer);
|
||||
* @param j Journal for logging
|
||||
* @return The liquid XRP amount available to the account
|
||||
*/
|
||||
[[nodiscard]] XRPAmount
|
||||
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j);
|
||||
[[nodiscard]] inline XRPAmount
|
||||
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j)
|
||||
{
|
||||
return AccountRootEntryR(id, view, j).xrpLiquid(ownerCountAdj);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -253,45 +254,13 @@ pseudoAccountAddress(ReadView const& view, UInt256 const& pseudoOwnerKey);
|
||||
[[nodiscard]] std::vector<SField const*> const&
|
||||
getPseudoAccountFields();
|
||||
|
||||
/**
|
||||
* Returns true if and only if sleAcct is a pseudo-account of any kind
|
||||
* (i.e. carries at least one field flagged with SField::kSmdPseudoAccount).
|
||||
*
|
||||
* Returns false if sleAcct is:
|
||||
* - NOT a pseudo-account OR
|
||||
* - NOT a ltACCOUNT_ROOT OR
|
||||
* - null pointer
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount(AccountRootEntryR const& sleAcct);
|
||||
|
||||
/**
|
||||
* Convenience overload that reads the account from the view.
|
||||
*/
|
||||
[[nodiscard]] inline bool
|
||||
isPseudoAccount(ReadView const& view, AccountID const& accountId)
|
||||
{
|
||||
return isPseudoAccount(AccountRootEntryR(accountId, view));
|
||||
return AccountRootEntryR(accountId, view).isPseudoAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create pseudo-account, storing pseudoOwnerKey into ownerField.
|
||||
*
|
||||
* The list of valid ownerField is maintained in AccountRootHelpers.cpp and
|
||||
* the caller to this function must perform necessary amendment check(s)
|
||||
* before using a field. The amendment check is **not** performed in
|
||||
* createPseudoAccount.
|
||||
*/
|
||||
[[nodiscard]] std::expected<SLE::pointer, TER>
|
||||
createPseudoAccount(ApplyView& view, UInt256 const& pseudoOwnerKey, SField const& ownerField);
|
||||
|
||||
/**
|
||||
* Checks the destination and tag.
|
||||
*
|
||||
* - Checks that the SLE is not null.
|
||||
* - If the SLE requires a destination tag, checks that there is a tag.
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
checkDestinationAndTag(AccountRootEntryR const& toSle, bool hasDestinationTag);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#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>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
@@ -472,7 +471,7 @@ canWithdraw(
|
||||
bool hasDestinationTag,
|
||||
std::optional<std::vector<UInt256>> const& credentialIDs)
|
||||
{
|
||||
if (auto const ret = checkDestinationAndTag(toSle, hasDestinationTag))
|
||||
if (auto const ret = toSle.checkDestinationAndTag(hasDestinationTag))
|
||||
return ret;
|
||||
|
||||
if (from == to)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/OwnerCounts.h>
|
||||
@@ -16,7 +18,9 @@
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
@@ -173,6 +177,54 @@ AccountRootEntry<ViewT>::checkReserve(ApplyViewContext ctx, XRPAmount accBalance
|
||||
return checkReserve(ctx, accBalance, sponsorSle, adj);
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
XRPAmount
|
||||
AccountRootEntry<ViewT>::xrpLiquid(std::int32_t ownerCountAdj) const
|
||||
{
|
||||
if (!this->exists())
|
||||
return beast::kZero;
|
||||
|
||||
auto const& view = this->readView();
|
||||
auto const j = this->journal();
|
||||
AccountID const id = (*this)->getAccountID(sfAccount);
|
||||
|
||||
// Return balance minus reserve
|
||||
std::uint32_t const currentOwnerCount = detail::confineOwnerCount(
|
||||
view.ownerCountHook(id, OwnerCounts(this->rawSle())).count(), ownerCountAdj);
|
||||
std::uint32_t const currentAccountCount = detail::accountCountImpl(*this, 0, j);
|
||||
|
||||
// Pseudo-accounts have no reserve requirement
|
||||
auto const reserve = isPseudoAccount()
|
||||
? XRPAmount{0}
|
||||
: view.fees().accountReserve(currentOwnerCount, currentAccountCount);
|
||||
|
||||
auto const fullBalance = (*this)->getFieldAmount(sfBalance);
|
||||
|
||||
auto const balance = view.balanceHookIOU(id, xrpAccount(), fullBalance);
|
||||
|
||||
STAmount const amount = (balance < reserve) ? STAmount{0} : balance - reserve;
|
||||
|
||||
JLOG(j.trace()) << "accountHolds:" << " account=" << to_string(id)
|
||||
<< " amount=" << amount.getFullText()
|
||||
<< " fullBalance=" << fullBalance.getFullText()
|
||||
<< " balance=" << balance.getFullText() << " reserve=" << reserve
|
||||
<< " ownerCount=" << currentOwnerCount << " ownerCountAdj=" << ownerCountAdj;
|
||||
|
||||
return amount.xrp();
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
bool
|
||||
AccountRootEntry<ViewT>::isPseudoAccount() const
|
||||
{
|
||||
// Intentionally use defensive coding here because it's cheap and makes the
|
||||
// semantics of true return value clean.
|
||||
return this->exists() && (*this)->getType() == ltACCOUNT_ROOT &&
|
||||
std::ranges::any_of(getPseudoAccountFields(), [this](SField const* sf) {
|
||||
return (*this)->isFieldPresent(*sf);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
void
|
||||
AccountRootEntry<ViewT>::adjustOwnerCountSigned(
|
||||
@@ -316,6 +368,54 @@ AccountRootEntry<ViewT>::decreaseOwnerCount(
|
||||
adjustOwnerCountSigned(sponsorSle, -static_cast<std::int32_t>(count));
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
std::expected<AccountRootEntry<ApplyView>, TER>
|
||||
AccountRootEntry<ViewT>::createPseudoAccount(
|
||||
ApplyView& view,
|
||||
UInt256 const& pseudoOwnerKey,
|
||||
SField const& ownerField)
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
[[maybe_unused]]
|
||||
auto const& fields = getPseudoAccountFields();
|
||||
XRPL_ASSERT(
|
||||
std::count_if(
|
||||
fields.begin(),
|
||||
fields.end(),
|
||||
[&ownerField](SField const* sf) -> bool { return *sf == ownerField; }) == 1,
|
||||
"xrpl::createPseudoAccount : valid owner field");
|
||||
|
||||
auto const accountId = pseudoAccountAddress(view, pseudoOwnerKey);
|
||||
if (accountId == beast::kZero)
|
||||
return std::unexpected(tecDUPLICATE);
|
||||
|
||||
// Create pseudo-account.
|
||||
AccountRootEntry<ApplyView> account(accountId, view);
|
||||
account.newSLE();
|
||||
account->setAccountID(sfAccount, accountId);
|
||||
account->setFieldAmount(sfBalance, STAmount{});
|
||||
|
||||
// Pseudo-accounts can't submit transactions, so set the sequence number
|
||||
// to 0 to make them easier to spot and verify, and add an extra level
|
||||
// of protection.
|
||||
std::uint32_t const seqno = //
|
||||
view.rules().enabled(featureSingleAssetVault) || //
|
||||
view.rules().enabled(featureLendingProtocol) //
|
||||
? 0 //
|
||||
: view.seq();
|
||||
account->setFieldU32(sfSequence, seqno);
|
||||
// Ignore reserves requirement, disable the master key, allow default
|
||||
// rippling, and enable deposit authorization to prevent payments into
|
||||
// pseudo-account.
|
||||
account->setFieldU32(sfFlags, lsfDisableMaster | lsfDefaultRipple | lsfDepositAuth);
|
||||
// Link the pseudo-account with its owner object.
|
||||
account->setFieldH256(ownerField, pseudoOwnerKey);
|
||||
|
||||
account.insert();
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
template class AccountRootEntry<ReadView>;
|
||||
template class AccountRootEntry<ApplyView>;
|
||||
|
||||
|
||||
@@ -7,24 +7,17 @@
|
||||
#include <xrpl/beast/utility/Zero.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/entries/AccountRootEntry.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/Rate.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -39,7 +32,7 @@ isGlobalFrozen(ReadView const& view, AccountID const& issuer)
|
||||
if (isXRP(issuer))
|
||||
return false;
|
||||
if (auto const sle = AccountRootEntryR(issuer, view))
|
||||
return sle->isFlag(lsfGlobalFreeze);
|
||||
return sle.isGlobalFrozen();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -131,45 +124,13 @@ adjustOwnerCountImpl(
|
||||
|
||||
} // namespace detail
|
||||
|
||||
XRPAmount
|
||||
xrpLiquid(ReadView const& view, AccountID const& id, std::int32_t ownerCountAdj, beast::Journal j)
|
||||
{
|
||||
auto const sle = AccountRootEntryR(id, view);
|
||||
if (!sle.exists())
|
||||
return beast::kZero;
|
||||
|
||||
// Return balance minus reserve
|
||||
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)
|
||||
? XRPAmount{0}
|
||||
: view.fees().accountReserve(currentOwnerCount, currentAccountCount);
|
||||
|
||||
auto const fullBalance = sle->getFieldAmount(sfBalance);
|
||||
|
||||
auto const balance = view.balanceHookIOU(id, xrpAccount(), fullBalance);
|
||||
|
||||
STAmount const amount = (balance < reserve) ? STAmount{0} : balance - reserve;
|
||||
|
||||
JLOG(j.trace()) << "accountHolds:" << " account=" << to_string(id)
|
||||
<< " amount=" << amount.getFullText()
|
||||
<< " fullBalance=" << fullBalance.getFullText()
|
||||
<< " balance=" << balance.getFullText() << " reserve=" << reserve
|
||||
<< " ownerCount=" << currentOwnerCount << " ownerCountAdj=" << ownerCountAdj;
|
||||
|
||||
return amount.xrp();
|
||||
}
|
||||
|
||||
Rate
|
||||
transferRate(ReadView const& view, AccountID const& issuer)
|
||||
{
|
||||
auto const sle = AccountRootEntryR(issuer, view);
|
||||
|
||||
if (sle && sle->isFieldPresent(sfTransferRate))
|
||||
return Rate{sle->getFieldU32(sfTransferRate)};
|
||||
if (sle)
|
||||
return sle.transferRate();
|
||||
|
||||
return kParityRate;
|
||||
}
|
||||
@@ -267,71 +228,4 @@ getPseudoAccountFields()
|
||||
return kPseudoFields;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
isPseudoAccount(AccountRootEntryR const& sleAcct)
|
||||
{
|
||||
// Intentionally use defensive coding here because it's cheap and makes the
|
||||
// semantics of true return value clean.
|
||||
return sleAcct && sleAcct->getType() == ltACCOUNT_ROOT &&
|
||||
std::ranges::any_of(getPseudoAccountFields(), [&sleAcct](SField const* sf) {
|
||||
return sleAcct->isFieldPresent(*sf);
|
||||
});
|
||||
}
|
||||
|
||||
std::expected<SLE::pointer, TER>
|
||||
createPseudoAccount(ApplyView& view, UInt256 const& pseudoOwnerKey, SField const& ownerField)
|
||||
{
|
||||
[[maybe_unused]]
|
||||
auto const& fields = getPseudoAccountFields();
|
||||
XRPL_ASSERT(
|
||||
std::count_if(
|
||||
fields.begin(),
|
||||
fields.end(),
|
||||
[&ownerField](SField const* sf) -> bool { return *sf == ownerField; }) == 1,
|
||||
"xrpl::createPseudoAccount : valid owner field");
|
||||
|
||||
auto const accountId = pseudoAccountAddress(view, pseudoOwnerKey);
|
||||
if (accountId == beast::kZero)
|
||||
return std::unexpected(tecDUPLICATE);
|
||||
|
||||
// Create pseudo-account.
|
||||
auto account = std::make_shared<SLE>(keylet::account(accountId));
|
||||
account->setAccountID(sfAccount, accountId);
|
||||
account->setFieldAmount(sfBalance, STAmount{});
|
||||
|
||||
// Pseudo-accounts can't submit transactions, so set the sequence number
|
||||
// to 0 to make them easier to spot and verify, and add an extra level
|
||||
// of protection.
|
||||
std::uint32_t const seqno = //
|
||||
view.rules().enabled(featureSingleAssetVault) || //
|
||||
view.rules().enabled(featureLendingProtocol) //
|
||||
? 0 //
|
||||
: view.seq();
|
||||
account->setFieldU32(sfSequence, seqno);
|
||||
// Ignore reserves requirement, disable the master key, allow default
|
||||
// rippling, and enable deposit authorization to prevent payments into
|
||||
// pseudo-account.
|
||||
account->setFieldU32(sfFlags, lsfDisableMaster | lsfDefaultRipple | lsfDepositAuth);
|
||||
// Link the pseudo-account with its owner object.
|
||||
account->setFieldH256(ownerField, pseudoOwnerKey);
|
||||
|
||||
view.insert(account);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
[[nodiscard]] TER
|
||||
checkDestinationAndTag(AccountRootEntryR const& toSle, bool hasDestinationTag)
|
||||
{
|
||||
if (!toSle.exists())
|
||||
return tecNO_DST;
|
||||
|
||||
// The tag is basically account-specific information we don't
|
||||
// understand, but we can require someone to fill it in.
|
||||
if (toSle->isFlag(lsfRequireDestTag) && !hasDestinationTag)
|
||||
return tecDST_TAG_NEEDED; // Cannot send without a tag
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#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>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -133,7 +132,7 @@ getEffectiveTxReserveSponsor(ApplyViewContext ctx, AccountRootEntryR const& acco
|
||||
"xrpl::getEffectiveTxReserveSponsor : accountSle exists and is account type");
|
||||
}
|
||||
|
||||
if (isPseudoAccount(accountSle) || accountSle->getAccountID(sfAccount) != ctx.tx[sfAccount])
|
||||
if (accountSle.isPseudoAccount() || accountSle->getAccountID(sfAccount) != ctx.tx[sfAccount])
|
||||
return std::nullopt;
|
||||
return getTxReserveSponsor(ctx);
|
||||
}
|
||||
|
||||
@@ -930,7 +930,7 @@ Transactor::checkSign(
|
||||
|
||||
if ((view.rules().enabled(featureLendingProtocol) ||
|
||||
view.rules().enabled(featureBatchV1_1) || view.rules().enabled(fixCleanup3_3_0)) &&
|
||||
isPseudoAccount(sle))
|
||||
sle.isPseudoAccount())
|
||||
{
|
||||
// Pseudo-accounts can't sign transactions. This check is gated on a
|
||||
// few different amendments so that it takes effect as soon as any of
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/AccountRootEntry.h>
|
||||
#include <xrpl/ledger/helpers/VaultHelpers.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -740,7 +740,7 @@ ValidVault::finalize(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isPseudoAccount(AccountRootEntryR(sleSharesIssuer, view)))
|
||||
if (!AccountRootEntryR(sleSharesIssuer, view).isPseudoAccount())
|
||||
{
|
||||
JLOG(j.fatal()) //
|
||||
<< "Invariant failed: shares issuer must be a "
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#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>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -95,7 +94,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx)
|
||||
// because all writes to pseudo-account discriminator fields **are**
|
||||
// amendment gated, hence the behaviour of this check will always match the
|
||||
// currently active amendments.
|
||||
if (isPseudoAccount(sleDst))
|
||||
if (sleDst.isPseudoAccount())
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
if (sleDst->isFlag(lsfRequireDestTag) && !ctx.tx.isFieldPresent(sfDestinationTag))
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#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>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -99,7 +98,7 @@ CredentialCreate::preclaim(PreclaimContext const& ctx)
|
||||
return tecDUPLICATE;
|
||||
}
|
||||
|
||||
if (ctx.view.rules().enabled(fixCleanup3_3_0) && isPseudoAccount(subjectSle))
|
||||
if (ctx.view.rules().enabled(fixCleanup3_3_0) && subjectSle.isPseudoAccount())
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Subject is a pseudo-account.";
|
||||
return tecPSEUDO_ACCOUNT;
|
||||
|
||||
@@ -57,7 +57,7 @@ DelegateSet::preclaim(PreclaimContext const& ctx)
|
||||
if (!sleAuthorize)
|
||||
return tecNO_TARGET;
|
||||
|
||||
if (isPseudoAccount(sleAuthorize))
|
||||
if (sleAuthorize.isPseudoAccount())
|
||||
return tecPSEUDO_ACCOUNT;
|
||||
|
||||
// Deleting the delegate object is invalid if it doesn’t exist.
|
||||
|
||||
@@ -264,7 +264,7 @@ applyCreate(ApplyContext& ctx, Sandbox& sb, AccountID const& account, beast::Jou
|
||||
auto const ammKeylet = keylet::amm(amount.asset(), amount2.asset());
|
||||
|
||||
// Mitigate same account exists possibility
|
||||
auto const maybeAccount = createPseudoAccount(sb, ammKeylet.key, sfAMMID);
|
||||
auto const maybeAccount = AccountRootEntryW::createPseudoAccount(sb, ammKeylet.key, sfAMMID);
|
||||
// AMM account already exists (should not happen)
|
||||
if (!maybeAccount)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#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>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
@@ -356,7 +355,7 @@ EscrowCreate::preclaim(PreclaimContext const& ctx)
|
||||
// because all writes to pseudo-account discriminator fields **are**
|
||||
// amendment gated, hence the behaviour of this check will always match the
|
||||
// currently active amendments.
|
||||
if (isPseudoAccount(sled))
|
||||
if (sled.isPseudoAccount())
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
if (!isXRP(amount))
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#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>
|
||||
#include <xrpl/ledger/helpers/VaultHelpers.h>
|
||||
@@ -261,7 +260,8 @@ LoanBrokerSet::doApply()
|
||||
if (preFeeBalance_ < owner.reserve())
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
auto maybePseudo = createPseudoAccount(view, broker->key(), sfLoanBrokerID);
|
||||
auto maybePseudo =
|
||||
AccountRootEntryW::createPseudoAccount(view, broker->key(), sfLoanBrokerID);
|
||||
if (!maybePseudo)
|
||||
return maybePseudo.error(); // LCOV_EXCL_LINE
|
||||
auto& pseudo = *maybePseudo;
|
||||
|
||||
@@ -108,7 +108,7 @@ DepositPreauth::preclaim(PreclaimContext const& ctx)
|
||||
if (!sleAuth)
|
||||
return tecNO_TARGET;
|
||||
|
||||
if (ctx.view.rules().enabled(fixCleanup3_3_0) && isPseudoAccount(sleAuth))
|
||||
if (ctx.view.rules().enabled(fixCleanup3_3_0) && sleAuth.isPseudoAccount())
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "Authorized account is a pseudo-account.";
|
||||
return tecPSEUDO_ACCOUNT;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#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>
|
||||
#include <xrpl/ledger/helpers/PermissionedDEXHelpers.h>
|
||||
@@ -801,7 +800,7 @@ Payment::doApply()
|
||||
// transaction types. Note, this is not amendment-gated because all writes
|
||||
// to pseudo-account discriminator fields **are** amendment gated, hence the
|
||||
// behaviour of this check will always match the active amendments.
|
||||
if (isPseudoAccount(sleDst))
|
||||
if (sleDst.isPseudoAccount())
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// The source account does have enough money. Make sure the
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#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>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -112,7 +111,7 @@ PaymentChannelCreate::preclaim(PreclaimContext const& ctx)
|
||||
// writes to pseudo-account discriminator fields **are** amendment
|
||||
// gated, hence the behaviour of this check will always match the
|
||||
// currently active amendments.
|
||||
if (isPseudoAccount(sled))
|
||||
if (sled.isPseudoAccount())
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#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>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
@@ -169,7 +168,7 @@ TransactionProposalCreate::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
|
||||
// A pseudo-account cannot authorize a transaction through a SignerList.
|
||||
if (isPseudoAccount(sleTarget))
|
||||
if (sleTarget.isPseudoAccount())
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// Only the target account itself, an account on its SignerList, or (if
|
||||
|
||||
@@ -174,7 +174,7 @@ SponsorshipSet::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_DST;
|
||||
|
||||
// Pseudo-accounts cannot participate in sponsorship.
|
||||
if (isPseudoAccount(sponsorAccSle) || isPseudoAccount(sponseeSle))
|
||||
if (sponsorAccSle.isPseudoAccount() || sponseeSle.isPseudoAccount())
|
||||
return tecPSEUDO_ACCOUNT;
|
||||
|
||||
auto const sponsorshipSle = ctx.view.read(keylet::sponsorship(sponsorID, sponseeID));
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#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>
|
||||
#include <xrpl/protocol/Concepts.h>
|
||||
@@ -194,7 +193,7 @@ Clawback::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
// Note the order of checks - when SAV is active, this check here will make
|
||||
// the one which follows `sleHolder->isFieldPresent(sfAMMID)` redundant.
|
||||
if (ctx.view.rules().enabled(featureSingleAssetVault) && isPseudoAccount(sleHolder))
|
||||
if (ctx.view.rules().enabled(featureSingleAssetVault) && sleHolder.isPseudoAccount())
|
||||
{
|
||||
return tecPSEUDO_ACCOUNT;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#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>
|
||||
#include <xrpl/protocol/AMMCore.h>
|
||||
@@ -197,7 +196,7 @@ TrustSet::preclaim(PreclaimContext const& ctx)
|
||||
// enabled in the code section below, for specific cases. This block is not
|
||||
// amendment-gated because sleDst will not have a pseudo-account designator
|
||||
// field populated, unless the appropriate amendment was already enabled.
|
||||
if (sleDst && isPseudoAccount(sleDst))
|
||||
if (sleDst && sleDst.isPseudoAccount())
|
||||
{
|
||||
// If destination is AMM and the trustline doesn't exist then only allow
|
||||
// TrustSet if the asset is AMM LP token and AMM is not in empty state.
|
||||
|
||||
@@ -196,7 +196,7 @@ VaultCreate::doApply()
|
||||
if (preFeeBalance_ < owner.reserve())
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
auto maybePseudo = createPseudoAccount(view(), vault->key(), sfVaultID);
|
||||
auto maybePseudo = AccountRootEntryW::createPseudoAccount(view(), vault->key(), sfVaultID);
|
||||
if (!maybePseudo)
|
||||
return maybePseudo.error(); // LCOV_EXCL_LINE
|
||||
auto const& pseudo = *maybePseudo;
|
||||
|
||||
Reference in New Issue
Block a user