xrpld
Loading...
Searching...
No Matches
EscrowCreate.cpp
1#include <xrpl/tx/transactors/escrow/EscrowCreate.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/chrono.h>
5#include <xrpl/beast/utility/Zero.h>
6#include <xrpl/conditions/Condition.h>
7#include <xrpl/core/ServiceRegistry.h>
8#include <xrpl/ledger/ApplyView.h>
9#include <xrpl/ledger/View.h>
10#include <xrpl/ledger/helpers/AccountRootHelpers.h>
11#include <xrpl/ledger/helpers/DirectoryHelpers.h>
12#include <xrpl/ledger/helpers/MPTokenHelpers.h>
13#include <xrpl/ledger/helpers/RippleStateHelpers.h>
14#include <xrpl/ledger/helpers/TokenHelpers.h>
15#include <xrpl/protocol/AccountID.h>
16#include <xrpl/protocol/Concepts.h>
17#include <xrpl/protocol/Feature.h>
18#include <xrpl/protocol/Indexes.h>
19#include <xrpl/protocol/Issue.h>
20#include <xrpl/protocol/LedgerFormats.h>
21#include <xrpl/protocol/MPTAmount.h>
22#include <xrpl/protocol/MPTIssue.h>
23#include <xrpl/protocol/Protocol.h>
24#include <xrpl/protocol/Rate.h>
25#include <xrpl/protocol/SField.h>
26#include <xrpl/protocol/STAmount.h>
27#include <xrpl/protocol/STLedgerEntry.h>
28#include <xrpl/protocol/STTx.h>
29#include <xrpl/protocol/TER.h>
30#include <xrpl/protocol/UintTypes.h>
31#include <xrpl/protocol/XRPAmount.h>
32#include <xrpl/tx/Transactor.h>
33#include <xrpl/tx/applySteps.h>
34
35#include <memory>
36#include <system_error>
37#include <variant>
38
39namespace xrpl {
40
41/*
42 Escrow
43 ======
44
45 Escrow is a feature of the XRP Ledger that allows you to send conditional
46 XRP payments. These conditional payments, called escrows, set aside XRP and
47 deliver it later when certain conditions are met. Conditions to successfully
48 finish an escrow include time-based unlocks and crypto-conditions. Escrows
49 can also be set to expire if not finished in time.
50
51 The XRP set aside in an escrow is locked up. No one can use or destroy the
52 XRP until the escrow has been successfully finished or canceled. Before the
53 expiration time, only the intended receiver can get the XRP. After the
54 expiration time, the XRP can only be returned to the sender.
55
56 For more details on escrow, including examples, diagrams and more please
57 visit https://xrpl.org/escrow.html
58
59 For details on specific transactions, including fields and validation rules
60 please see:
61
62 `EscrowCreate`
63 --------------
64 See: https://xrpl.org/escrowcreate.html
65
66 `EscrowFinish`
67 --------------
68 See: https://xrpl.org/escrowfinish.html
69
70 `EscrowCancel`
71 --------------
72 See: https://xrpl.org/escrowcancel.html
73*/
74
75//------------------------------------------------------------------------------
76
79{
80 auto const amount = ctx.tx[sfAmount];
81 return TxConsequences{ctx.tx, isXRP(amount) ? amount.xrp() : beast::kZero};
82}
83
84bool
86{
87 // Only require featureMPTokensV1 when the escrow amount is an MPT and
88 // fixCleanup3_2_0 is active; XRP/IOU escrows are unaffected by this gate.
89 if (ctx.rules.enabled(fixCleanup3_2_0) && ctx.tx[sfAmount].holds<MPTIssue>())
90 return ctx.rules.enabled(featureMPTokensV1);
91 return true;
92}
93
94template <ValidIssueType T>
95static NotTEC
97
98template <>
101{
102 STAmount const amount = ctx.tx[sfAmount];
103 if (amount.native() || amount <= beast::kZero)
104 return temBAD_AMOUNT;
105
106 if (badCurrency() == amount.get<Issue>().currency)
107 return temBAD_CURRENCY;
108
109 return tesSUCCESS;
110}
111
112template <>
115{
116 if (!ctx.rules.enabled(fixCleanup3_2_0) && !ctx.rules.enabled(featureMPTokensV1))
117 return temDISABLED;
118
119 auto const amount = ctx.tx[sfAmount];
120 if (amount.native() || amount.mpt() > MPTAmount{kMaxMpTokenAmount} || amount <= beast::kZero)
121 return temBAD_AMOUNT;
122
123 return tesSUCCESS;
124}
125
126NotTEC
128{
129 STAmount const amount{ctx.tx[sfAmount]};
130 if (!isXRP(amount))
131 {
132 if (!ctx.rules.enabled(featureTokenEscrow))
133 return temBAD_AMOUNT;
134
135 if (auto const ret = std::visit(
136 [&]<typename T>(T const&) { return escrowCreatePreflightHelper<T>(ctx); },
137 amount.asset().value());
138 !isTesSuccess(ret))
139 return ret;
140 }
141 else
142 {
143 if (amount <= beast::kZero)
144 return temBAD_AMOUNT;
145 }
146
147 // We must specify at least one timeout value
148 if (!ctx.tx[~sfCancelAfter] && !ctx.tx[~sfFinishAfter])
149 return temBAD_EXPIRATION;
150
151 // If both finish and cancel times are specified then the cancel time must
152 // be strictly after the finish time.
153 if (ctx.tx[~sfCancelAfter] && ctx.tx[~sfFinishAfter] &&
154 ctx.tx[sfCancelAfter] <= ctx.tx[sfFinishAfter])
155 return temBAD_EXPIRATION;
156
157 // In the absence of a FinishAfter, the escrow can be finished
158 // immediately, which can be confusing. When creating an escrow,
159 // we want to ensure that either a FinishAfter time is explicitly
160 // specified or a completion condition is attached.
161 if (!ctx.tx[~sfFinishAfter] && !ctx.tx[~sfCondition])
162 return temMALFORMED;
163
164 if (auto const cb = ctx.tx[~sfCondition])
165 {
166 using namespace xrpl::cryptoconditions;
167
169
170 auto condition = Condition::deserialize(*cb, ec);
171 if (!condition)
172 {
173 JLOG(ctx.j.debug()) << "Malformed condition during escrow creation: " << ec.message();
174 return temMALFORMED;
175 }
176 }
177
178 return tesSUCCESS;
179}
180
181template <ValidIssueType T>
182static TER
184 PreclaimContext const& ctx,
185 AccountID const& account,
186 AccountID const& dest,
187 STAmount const& amount);
188
189template <>
192 PreclaimContext const& ctx,
193 AccountID const& account,
194 AccountID const& dest,
195 STAmount const& amount)
196{
197 Issue const& issue = amount.get<Issue>();
198 AccountID const& issuer = amount.getIssuer();
199 // If the issuer is the same as the account, return tecNO_PERMISSION
200 if (issuer == account)
201 return tecNO_PERMISSION;
202
203 // If the lsfAllowTrustLineLocking is not enabled, return tecNO_PERMISSION
204 auto const sleIssuer = ctx.view.read(keylet::account(issuer));
205 if (!sleIssuer)
206 return tecNO_ISSUER;
207 if (!sleIssuer->isFlag(lsfAllowTrustLineLocking))
208 return tecNO_PERMISSION;
209
210 // If the account does not have a trustline to the issuer, return tecNO_LINE
211 auto const sleRippleState = ctx.view.read(keylet::trustLine(account, issuer, issue.currency));
212 if (!sleRippleState)
213 return tecNO_LINE;
214
215 STAmount const balance = (*sleRippleState)[sfBalance];
216
217 // If balance is positive, issuer must have higher address than account
218 if (balance > beast::kZero && issuer < account)
219 return tecNO_PERMISSION; // LCOV_EXCL_LINE
220
221 // If balance is negative, issuer must have lower address than account
222 if (balance < beast::kZero && issuer > account)
223 return tecNO_PERMISSION; // LCOV_EXCL_LINE
224
225 // If the issuer has requireAuth set, check if the account is authorized
226 if (auto const ter = requireAuth(ctx.view, issue, account); !isTesSuccess(ter))
227 return ter;
228
229 // If the issuer has requireAuth set, check if the destination is authorized
230 if (auto const ter = requireAuth(ctx.view, issue, dest); !isTesSuccess(ter))
231 return ter;
232
233 // If the issuer has frozen the account, return tecFROZEN
234 if (isFrozen(ctx.view, account, issue))
235 return tecFROZEN;
236
237 // If the issuer has frozen the destination, return tecFROZEN
238 if (isFrozen(ctx.view, dest, issue))
239 return tecFROZEN;
240
241 STAmount const spendableAmount = accountHolds(
242 ctx.view, account, issue.currency, issuer, FreezeHandling::IgnoreFreeze, ctx.j);
243
244 // If the balance is less than or equal to 0, return tecINSUFFICIENT_FUNDS
245 if (spendableAmount <= beast::kZero)
247
248 // If the spendable amount is less than the amount, return
249 // tecINSUFFICIENT_FUNDS
250 if (spendableAmount < amount)
252
253 // If the amount is not addable to the balance, return tecPRECISION_LOSS
254 if (!canAdd(spendableAmount, amount))
255 return tecPRECISION_LOSS;
256
257 return tesSUCCESS;
258}
259
260template <>
263 PreclaimContext const& ctx,
264 AccountID const& account,
265 AccountID const& dest,
266 STAmount const& amount)
267{
268 AccountID const issuer = amount.getIssuer();
269 // If the issuer is the same as the account, return tecNO_PERMISSION
270 if (issuer == account)
271 return tecNO_PERMISSION;
272
273 // If the mpt does not exist, return tecOBJECT_NOT_FOUND
274 auto const issuanceKey = keylet::mptokenIssuance(amount.get<MPTIssue>().getMptID());
275 auto const sleIssuance = ctx.view.read(issuanceKey);
276 if (!sleIssuance)
277 return tecOBJECT_NOT_FOUND;
278
279 // If the lsfMPTCanEscrow is not enabled, return tecNO_PERMISSION
280 if (!sleIssuance->isFlag(lsfMPTCanEscrow))
281 return tecNO_PERMISSION;
282
283 // If the issuer is not the same as the issuer of the mpt, return
284 // tecNO_PERMISSION
285 if (sleIssuance->getAccountID(sfIssuer) != issuer)
286 return tecNO_PERMISSION; // LCOV_EXCL_LINE
287
288 // If the account does not have the mpt, return tecOBJECT_NOT_FOUND
289 if (!ctx.view.exists(keylet::mptoken(issuanceKey.key, account)))
290 return tecOBJECT_NOT_FOUND;
291
292 // If the issuer has requireAuth set, check if the account is
293 // authorized
294 auto const& mptIssue = amount.get<MPTIssue>();
295 if (auto const ter = requireAuth(ctx.view, mptIssue, account, AuthType::WeakAuth);
296 !isTesSuccess(ter))
297 return ter;
298
299 // If the issuer has requireAuth set, check if the destination is
300 // authorized
301 if (auto const ter = requireAuth(ctx.view, mptIssue, dest, AuthType::WeakAuth);
302 !isTesSuccess(ter))
303 return ter;
304
305 // If the issuer has frozen the account, return tecLOCKED
306 if (isFrozen(ctx.view, account, mptIssue))
307 return tecLOCKED;
308
309 // If the issuer has frozen the destination, return tecLOCKED
310 if (isFrozen(ctx.view, dest, mptIssue))
311 return tecLOCKED;
312
313 // If the mpt cannot be transferred, return tecNO_AUTH
314 if (auto const ter = canTransfer(ctx.view, mptIssue, account, dest); !isTesSuccess(ter))
315 return ter;
316
317 STAmount const spendableAmount = accountHolds(
318 ctx.view,
319 account,
320 amount.get<MPTIssue>(),
323 ctx.j);
324
325 // If the balance is less than or equal to 0, return tecINSUFFICIENT_FUNDS
326 if (spendableAmount <= beast::kZero)
328
329 // If the spendable amount is less than the amount, return
330 // tecINSUFFICIENT_FUNDS
331 if (spendableAmount < amount)
333
334 return tesSUCCESS;
335}
336
337TER
339{
340 STAmount const amount{ctx.tx[sfAmount]};
341 AccountID const account{ctx.tx[sfAccount]};
342 AccountID const dest{ctx.tx[sfDestination]};
343
344 auto const sled = ctx.view.read(keylet::account(dest));
345 if (!sled)
346 return tecNO_DST;
347
348 // Pseudo-accounts cannot receive escrow. Note, this is not amendment-gated
349 // because all writes to pseudo-account discriminator fields **are**
350 // amendment gated, hence the behaviour of this check will always match the
351 // currently active amendments.
352 if (isPseudoAccount(sled))
353 return tecNO_PERMISSION;
354
355 if (!isXRP(amount))
356 {
357 if (!ctx.view.rules().enabled(featureTokenEscrow))
358 return temDISABLED; // LCOV_EXCL_LINE
359
360 if (auto const ret = std::visit(
361 [&]<typename T>(T const&) {
362 return escrowCreatePreclaimHelper<T>(ctx, account, dest, amount);
363 },
364 amount.asset().value());
365 !isTesSuccess(ret))
366 return ret;
367 }
368 return tesSUCCESS;
369}
370
371template <ValidIssueType T>
372static TER
374 ApplyView& view,
375 AccountID const& issuer,
376 AccountID const& sender,
377 STAmount const& amount,
378 beast::Journal journal);
379
380template <>
383 ApplyView& view,
384 AccountID const& issuer,
385 AccountID const& sender,
386 STAmount const& amount,
387 beast::Journal journal)
388{
389 // Defensive: Issuer cannot create an escrow
390 if (issuer == sender)
391 return tecINTERNAL; // LCOV_EXCL_LINE
392
393 auto const ter =
394 directSendNoFee(view, sender, issuer, amount, !amount.holds<MPTIssue>(), journal);
395 if (!isTesSuccess(ter))
396 return ter; // LCOV_EXCL_LINE
397 return tesSUCCESS;
398}
399
400template <>
403 ApplyView& view,
404 AccountID const& issuer,
405 AccountID const& sender,
406 STAmount const& amount,
407 beast::Journal journal)
408{
409 // Defensive: Issuer cannot create an escrow
410 if (issuer == sender)
411 return tecINTERNAL; // LCOV_EXCL_LINE
412
413 auto const ter = lockEscrowMPT(view, sender, amount, journal);
414 if (!isTesSuccess(ter))
415 return ter; // LCOV_EXCL_LINE
416 return tesSUCCESS;
417}
418
419TER
421{
422 auto const closeTime = ctx_.view().header().parentCloseTime;
423
424 if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
425 return tecNO_PERMISSION;
426
427 if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter]))
428 return tecNO_PERMISSION;
429
430 auto const sle = ctx_.view().peek(keylet::account(accountID_));
431 if (!sle)
432 return tefINTERNAL; // LCOV_EXCL_LINE
433
434 // Check reserve and funds availability
435 STAmount const amount{ctx_.tx[sfAmount]};
436
437 auto const reserve = ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + 1);
438
439 auto const balance = sle->getFieldAmount(sfBalance).xrp();
440 if (balance < reserve)
442
443 // Check reserve and funds availability
444 if (isXRP(amount))
445 {
446 if (balance < reserve + STAmount(amount).xrp())
447 return tecUNFUNDED;
448 }
449
450 // Check destination account
451 {
452 auto const sled = ctx_.view().read(keylet::account(ctx_.tx[sfDestination]));
453 if (!sled)
454 return tecNO_DST; // LCOV_EXCL_LINE
455 if (sled->isFlag(lsfRequireDestTag) && !ctx_.tx[~sfDestinationTag])
456 return tecDST_TAG_NEEDED;
457 }
458
459 // Create escrow in ledger. Note that we use the value from the
460 // sequence or ticket. For more explanation see comments in SeqProxy.h.
461 Keylet const escrowKeylet = keylet::escrow(accountID_, ctx_.tx.getSeqValue());
462 auto const slep = std::make_shared<SLE>(escrowKeylet);
463 (*slep)[sfAmount] = amount;
464 (*slep)[sfAccount] = accountID_;
465 (*slep)[~sfCondition] = ctx_.tx[~sfCondition];
466 (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
467 (*slep)[sfDestination] = ctx_.tx[sfDestination];
468 (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
469 (*slep)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
470 (*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
471
472 if (ctx_.view().rules().enabled(fixIncludeKeyletFields))
473 {
474 (*slep)[sfSequence] = ctx_.tx.getSeqValue();
475 }
476
477 if (ctx_.view().rules().enabled(featureTokenEscrow) && !isXRP(amount))
478 {
479 auto const xferRate = transferRate(ctx_.view(), amount);
480 if (xferRate != kParityRate)
481 (*slep)[sfTransferRate] = xferRate.value;
482 }
483
484 ctx_.view().insert(slep);
485
486 // Add escrow to sender's owner directory
487 {
488 auto page = ctx_.view().dirInsert(
490 if (!page)
491 return tecDIR_FULL; // LCOV_EXCL_LINE
492 (*slep)[sfOwnerNode] = *page;
493 }
494
495 // If it's not a self-send, add escrow to recipient's owner directory.
496 AccountID const dest = ctx_.tx[sfDestination];
497 if (dest != accountID_)
498 {
499 auto page =
500 ctx_.view().dirInsert(keylet::ownerDir(dest), escrowKeylet, describeOwnerDir(dest));
501 if (!page)
502 return tecDIR_FULL; // LCOV_EXCL_LINE
503 (*slep)[sfDestinationNode] = *page;
504 }
505
506 // IOU escrow objects are added to the issuer's owner directory to help
507 // track the total locked balance. For MPT, this isn't necessary because the
508 // locked balance is already stored directly in the MPTokenIssuance object.
509 AccountID const issuer = amount.getIssuer();
510 if (!isXRP(amount) && issuer != accountID_ && issuer != dest && !amount.holds<MPTIssue>())
511 {
512 auto page =
513 ctx_.view().dirInsert(keylet::ownerDir(issuer), escrowKeylet, describeOwnerDir(issuer));
514 if (!page)
515 return tecDIR_FULL; // LCOV_EXCL_LINE
516 (*slep)[sfIssuerNode] = *page;
517 }
518
519 // Deduct owner's balance
520 if (isXRP(amount))
521 {
522 (*sle)[sfBalance] = (*sle)[sfBalance] - amount;
523 }
524 else
525 {
526 if (auto const ret = std::visit(
527 [&]<typename T>(T const&) {
528 return escrowLockApplyHelper<T>(ctx_.view(), issuer, accountID_, amount, j_);
529 },
530 amount.asset().value());
531 !isTesSuccess(ret))
532 {
533 return ret; // LCOV_EXCL_LINE
534 }
535 }
536
537 // increment owner count
538 adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal);
539 ctx_.view().update(sle);
540 return tesSUCCESS;
541}
542
543void
545{
546 // No transaction-specific invariants yet (future work).
547}
548
549bool
551 STTx const&,
552 TER,
553 XRPAmount,
554 ReadView const&,
555 beast::Journal const&)
556{
557 // No transaction-specific invariants yet (future work).
558 return true;
559}
560} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:38
Stream debug() const
Definition Journal.h:297
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:118
static bool checkExtraFeatures(PreflightContext const &ctx)
static NotTEC preflight(PreflightContext const &ctx)
void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override
Inspect a single ledger entry modified by this transaction.
TER doApply() override
static TER preclaim(PreclaimContext const &ctx)
bool finalizeInvariants(STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j) override
Check transaction-specific post-conditions after all entries have been visited.
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
A currency issued by an account.
Definition Issue.h:13
Currency currency
Definition Issue.h:15
constexpr MPTID const & getMptID() const
Definition MPTIssue.h:33
A view into a ledger.
Definition ReadView.h:31
virtual Rules const & rules() const =0
Returns the tx processing rules.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
virtual SLE::const_pointer 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.
Definition Rules.cpp:171
constexpr bool holds() const noexcept
Definition STAmount.h:460
constexpr TIss const & get() const
bool native() const noexcept
Definition STAmount.h:453
Asset const & asset() const
Definition STAmount.h:478
AccountID const & getIssuer() const
Definition STAmount.h:498
std::shared_ptr< STLedgerEntry const > const & const_ref
beast::Journal const j_
Definition Transactor.h:118
AccountID const accountID_
Definition Transactor.h:120
ApplyContext & ctx_
Definition Transactor.h:116
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition applySteps.h:38
static std::unique_ptr< Condition > deserialize(Slice s, std::error_code &ec)
Load a condition from its binary form.
T make_shared(T... args)
T message(T... args)
Keylet mptokenIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Definition Indexes.cpp:521
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Definition Indexes.cpp:372
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:357
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:533
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:186
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition Indexes.cpp:241
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool isXRP(AccountID const &c)
Definition AccountID.h:70
NotTEC escrowCreatePreflightHelper< Issue >(PreflightContext const &ctx)
@ tefINTERNAL
Definition TER.h:163
TER lockEscrowMPT(ApplyView &view, AccountID const &uGrantorID, STAmount const &saAmount, beast::Journal j)
TER canTransfer(ReadView const &view, MPTIssue const &mptIssue, AccountID const &from, AccountID const &to, WaiveMPTCanTransfer waive=WaiveMPTCanTransfer::No, std::uint8_t depth=0)
Check whether to may receive the given MPT from from.
TER escrowCreatePreclaimHelper< MPTIssue >(PreclaimContext const &ctx, AccountID const &account, AccountID const &dest, STAmount const &amount)
bool canAdd(STAmount const &amt1, STAmount const &amt2)
Safely checks if two STAmount values can be added without overflow, underflow, or precision loss.
Definition STAmount.cpp:464
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:594
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?
Definition View.cpp:554
Rate const kParityRate
A transfer rate signifying a 1:1 exchange.
TER directSendNoFee(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, bool bCheckIssuer, beast::Journal j)
Calls static directSendNoFeeIOU if saAmount represents Issue.
static TER escrowLockApplyHelper(ApplyView &view, AccountID const &issuer, AccountID const &sender, STAmount const &amount, beast::Journal journal)
void adjustOwnerCount(ApplyView &view, SLE::ref sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Returns a function that sets the owner on a directory SLE.
bool isFrozen(ReadView const &view, AccountID const &account, MPTIssue const &mptIssue, std::uint8_t depth=0)
TER escrowCreatePreclaimHelper< Issue >(PreclaimContext const &ctx, AccountID const &account, AccountID const &dest, STAmount const &amount)
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
static NotTEC escrowCreatePreflightHelper(PreflightContext const &ctx)
@ temBAD_CURRENCY
Definition TER.h:76
@ temBAD_EXPIRATION
Definition TER.h:77
@ temMALFORMED
Definition TER.h:73
@ temDISABLED
Definition TER.h:100
@ temBAD_AMOUNT
Definition TER.h:75
bool isTesSuccess(TER x) noexcept
Definition TER.h:663
TERSubset< CanCvtToTER > TER
Definition TER.h:634
TER requireAuth(ReadView const &view, MPTIssue const &mptIssue, AccountID const &account, AuthType authType=AuthType::Legacy, std::uint8_t depth=0)
Check if the account lacks required authorization for MPT.
static TER escrowCreatePreclaimHelper(PreclaimContext const &ctx, AccountID const &account, AccountID const &dest, STAmount const &amount)
@ tecDIR_FULL
Definition TER.h:285
@ tecLOCKED
Definition TER.h:356
@ tecOBJECT_NOT_FOUND
Definition TER.h:324
@ tecINTERNAL
Definition TER.h:308
@ tecFROZEN
Definition TER.h:301
@ tecINSUFFICIENT_FUNDS
Definition TER.h:323
@ tecNO_LINE
Definition TER.h:299
@ tecPRECISION_LOSS
Definition TER.h:361
@ tecINSUFFICIENT_RESERVE
Definition TER.h:305
@ tecNO_PERMISSION
Definition TER.h:303
@ tecDST_TAG_NEEDED
Definition TER.h:307
@ tecNO_ISSUER
Definition TER.h:297
@ tecNO_DST
Definition TER.h:288
@ tecUNFUNDED
Definition TER.h:293
TER escrowLockApplyHelper< Issue >(ApplyView &view, AccountID const &issuer, AccountID const &sender, STAmount const &amount, beast::Journal journal)
NotTEC escrowCreatePreflightHelper< MPTIssue >(PreflightContext const &ctx)
bool isPseudoAccount(SLE::const_pointer sleAcct, std::set< SField const * > const &pseudoFieldFilter={})
Returns true if and only if sleAcct is a pseudo-account or specific pseudo-accounts in pseudoFieldFil...
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j, SpendableHandling includeFullBalance=SpendableHandling::SimpleBalance)
@ tesSUCCESS
Definition TER.h:240
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:19
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:61
ReadView const & view
Definition Transactor.h:64
beast::Journal const j
Definition Transactor.h:69
State information when preflighting a tx.
Definition Transactor.h:18
beast::Journal const j
Definition Transactor.h:25
T visit(T... args)