1#include <xrpl/basics/Log.h>
2#include <xrpl/basics/chrono.h>
3#include <xrpl/conditions/Condition.h>
4#include <xrpl/ledger/ApplyView.h>
5#include <xrpl/ledger/View.h>
6#include <xrpl/ledger/helpers/AccountRootHelpers.h>
7#include <xrpl/ledger/helpers/DirectoryHelpers.h>
8#include <xrpl/ledger/helpers/MPTokenHelpers.h>
9#include <xrpl/ledger/helpers/RippleStateHelpers.h>
10#include <xrpl/protocol/Feature.h>
11#include <xrpl/protocol/Indexes.h>
12#include <xrpl/protocol/MPTAmount.h>
13#include <xrpl/protocol/Rate.h>
14#include <xrpl/protocol/TxFlags.h>
15#include <xrpl/protocol/XRPAmount.h>
16#include <xrpl/tx/transactors/escrow/EscrowCreate.h>
59 auto const amount = ctx.
tx[sfAmount];
63template <Val
idIssueType T>
72 if (amount.native() || amount <= beast::zero)
88 auto const amount = ctx.
tx[sfAmount];
89 if (amount.native() || amount.mpt() >
MPTAmount{maxMPTokenAmount} || amount <= beast::zero)
105 [&]<
typename T>(T
const&) {
return escrowCreatePreflightHelper<T>(ctx); },
106 amount.asset().value());
112 if (amount <= beast::zero)
117 if (!ctx.
tx[~sfCancelAfter] && !ctx.
tx[~sfFinishAfter])
122 if (ctx.
tx[~sfCancelAfter] && ctx.
tx[~sfFinishAfter] &&
123 ctx.
tx[sfCancelAfter] <= ctx.
tx[sfFinishAfter])
130 if (!ctx.
tx[~sfFinishAfter] && !ctx.
tx[~sfCondition])
133 if (
auto const cb = ctx.
tx[~sfCondition])
139 auto condition = Condition::deserialize(*cb, ec);
142 JLOG(ctx.
j.
debug()) <<
"Malformed condition during escrow creation: " << ec.
message();
150template <Val
idIssueType T>
166 AccountID const issuer = amount.getIssuer();
168 if (issuer == account)
175 if (!sleIssuer->isFlag(lsfAllowTrustLineLocking))
183 STAmount const balance = (*sleRippleState)[sfBalance];
186 if (balance > beast::zero && issuer < account)
190 if (balance < beast::zero && issuer > account)
213 if (spendableAmount <= beast::zero)
218 if (spendableAmount < amount)
222 if (!
canAdd(spendableAmount, amount))
236 AccountID const issuer = amount.getIssuer();
238 if (issuer == account)
243 auto const sleIssuance = ctx.
view.
read(issuanceKey);
248 if (!sleIssuance->isFlag(lsfMPTCanEscrow))
253 if (sleIssuance->getAccountID(sfIssuer) != issuer)
262 auto const& mptIssue = amount.get<
MPTIssue>();
289 if (spendableAmount <= beast::zero)
294 if (spendableAmount < amount)
324 [&]<
typename T>(T
const&) {
325 return escrowCreatePreclaimHelper<T>(ctx, account, dest, amount);
327 amount.asset().value());
334template <Val
idIssueType T>
353 if (issuer == sender)
356 auto const ter =
rippleCredit(view, sender, issuer, amount, !amount.holds<
MPTIssue>(), journal);
372 if (issuer == sender)
401 auto const balance = sle->getFieldAmount(sfBalance).xrp();
402 if (balance < reserve)
408 if (balance < reserve +
STAmount(amount).xrp())
417 if ((((*sled)[sfFlags] & lsfRequireDestTag) != 0u) && !
ctx_.
tx[~sfDestinationTag])
425 (*slep)[sfAmount] = amount;
427 (*slep)[~sfCondition] =
ctx_.
tx[~sfCondition];
428 (*slep)[~sfSourceTag] =
ctx_.
tx[~sfSourceTag];
429 (*slep)[sfDestination] =
ctx_.
tx[sfDestination];
430 (*slep)[~sfCancelAfter] =
ctx_.
tx[~sfCancelAfter];
431 (*slep)[~sfFinishAfter] =
ctx_.
tx[~sfFinishAfter];
432 (*slep)[~sfDestinationTag] =
ctx_.
tx[~sfDestinationTag];
443 (*slep)[sfTransferRate] = xferRate.value;
454 (*slep)[sfOwnerNode] = *page;
465 (*slep)[sfDestinationNode] = *page;
471 AccountID const issuer = amount.getIssuer();
478 (*slep)[sfIssuerNode] = *page;
484 (*sle)[sfBalance] = (*sle)[sfBalance] - amount;
489 [&]<
typename T>(T
const&) {
492 amount.asset().value());
A generic endpoint for log messages.
beast::Journal const journal
Writeable view to a ledger, for applying a transaction.
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
static NotTEC preflight(PreflightContext const &ctx)
static TER preclaim(PreclaimContext const &ctx)
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
constexpr MPTID const & getMptID() const
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
virtual LedgerHeader const & header() const =0
Returns information about the ledger.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Class describing the consequences to the account of applying a transaction if the transaction consume...
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Keylet account(AccountID const &id) noexcept
AccountID root.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool isXRP(AccountID const &c)
NotTEC escrowCreatePreflightHelper< Issue >(PreflightContext const &ctx)
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j, SpendableHandling includeFullBalance=shSIMPLE_BALANCE)
bool isPseudoAccount(std::shared_ptr< SLE const > sleAcct, std::set< SField const * > const &pseudoFieldFilter={})
Returns true if and only if sleAcct is a pseudo-account or specific pseudo-accounts in pseudoFieldFil...
TER escrowCreatePreclaimHelper< MPTIssue >(PreclaimContext const &ctx, AccountID const &account, AccountID const &dest, STAmount const &amount)
bool isFrozen(ReadView const &view, AccountID const &account, MPTIssue const &mptIssue, int depth=0)
bool canAdd(STAmount const &amt1, STAmount const &amt2)
Safely checks if two STAmount values can be added without overflow, underflow, or precision loss.
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
TER escrowLockApplyHelper< MPTIssue >(ApplyView &view, AccountID const &issuer, AccountID const &sender, STAmount const &amount, beast::Journal journal)
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
static TER escrowLockApplyHelper(ApplyView &view, AccountID const &issuer, AccountID const &sender, STAmount const &amount, beast::Journal journal)
TER canTransfer(ReadView const &view, MPTIssue const &mptIssue, AccountID const &from, AccountID const &to)
Check if the destination account is allowed to receive MPT.
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Returns a function that sets the owner on a directory SLE.
TER escrowCreatePreclaimHelper< Issue >(PreclaimContext const &ctx, AccountID const &account, AccountID const &dest, STAmount const &amount)
static NotTEC escrowCreatePreflightHelper(PreflightContext const &ctx)
bool isTesSuccess(TER x) noexcept
static TER escrowCreatePreclaimHelper(PreclaimContext const &ctx, AccountID const &account, AccountID const &dest, STAmount const &amount)
TER rippleLockEscrowMPT(ApplyView &view, AccountID const &uGrantorID, STAmount const &saAmount, beast::Journal j)
@ tecINSUFFICIENT_RESERVE
TER escrowLockApplyHelper< Issue >(ApplyView &view, AccountID const &issuer, AccountID const &sender, STAmount const &amount, beast::Journal journal)
NotTEC escrowCreatePreflightHelper< MPTIssue >(PreflightContext const &ctx)
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
TERSubset< CanCvtToNotTEC > NotTEC
Rate const parityRate
A transfer rate signifying a 1:1 exchange.
TER requireAuth(ReadView const &view, MPTIssue const &mptIssue, AccountID const &account, AuthType authType=AuthType::Legacy, int depth=0)
Check if the account lacks required authorization for MPT.
TER rippleCredit(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, bool bCheckIssuer, beast::Journal j)
Calls static rippleCreditIOU if saAmount represents Issue.
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
A pair of SHAMap key and LedgerEntryType.
State information when determining if a tx is likely to claim a fee.
State information when preflighting a tx.