rippled
Loading...
Searching...
No Matches
Escrow.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/misc/CredentialHelpers.h>
21#include <xrpld/app/misc/HashRouter.h>
22#include <xrpld/app/tx/detail/Escrow.h>
23#include <xrpld/conditions/Condition.h>
24#include <xrpld/conditions/Fulfillment.h>
25#include <xrpld/ledger/ApplyView.h>
26#include <xrpld/ledger/View.h>
27
28#include <xrpl/basics/Log.h>
29#include <xrpl/basics/chrono.h>
30#include <xrpl/protocol/Feature.h>
31#include <xrpl/protocol/Indexes.h>
32#include <xrpl/protocol/TxFlags.h>
33#include <xrpl/protocol/XRPAmount.h>
34
35// During an EscrowFinish, the transaction must specify both
36// a condition and a fulfillment. We track whether that
37// fulfillment matches and validates the condition.
38#define SF_CF_INVALID SF_PRIVATE5
39#define SF_CF_VALID SF_PRIVATE6
40
41namespace ripple {
42
43/*
44 Escrow
45 ======
46
47 Escrow is a feature of the XRP Ledger that allows you to send conditional
48 XRP payments. These conditional payments, called escrows, set aside XRP and
49 deliver it later when certain conditions are met. Conditions to successfully
50 finish an escrow include time-based unlocks and crypto-conditions. Escrows
51 can also be set to expire if not finished in time.
52
53 The XRP set aside in an escrow is locked up. No one can use or destroy the
54 XRP until the escrow has been successfully finished or canceled. Before the
55 expiration time, only the intended receiver can get the XRP. After the
56 expiration time, the XRP can only be returned to the sender.
57
58 For more details on escrow, including examples, diagrams and more please
59 visit https://xrpl.org/escrow.html
60
61 For details on specific transactions, including fields and validation rules
62 please see:
63
64 `EscrowCreate`
65 --------------
66 See: https://xrpl.org/escrowcreate.html
67
68 `EscrowFinish`
69 --------------
70 See: https://xrpl.org/escrowfinish.html
71
72 `EscrowCancel`
73 --------------
74 See: https://xrpl.org/escrowcancel.html
75*/
76
77//------------------------------------------------------------------------------
78
79TxConsequences
81{
82 return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
83}
84
87{
88 if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
89 return temINVALID_FLAG;
90
91 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
92 return ret;
93
94 if (!isXRP(ctx.tx[sfAmount]))
95 return temBAD_AMOUNT;
96
97 if (ctx.tx[sfAmount] <= beast::zero)
98 return temBAD_AMOUNT;
99
100 // We must specify at least one timeout value
101 if (!ctx.tx[~sfCancelAfter] && !ctx.tx[~sfFinishAfter])
102 return temBAD_EXPIRATION;
103
104 // If both finish and cancel times are specified then the cancel time must
105 // be strictly after the finish time.
106 if (ctx.tx[~sfCancelAfter] && ctx.tx[~sfFinishAfter] &&
107 ctx.tx[sfCancelAfter] <= ctx.tx[sfFinishAfter])
108 return temBAD_EXPIRATION;
109
110 if (ctx.rules.enabled(fix1571))
111 {
112 // In the absence of a FinishAfter, the escrow can be finished
113 // immediately, which can be confusing. When creating an escrow,
114 // we want to ensure that either a FinishAfter time is explicitly
115 // specified or a completion condition is attached.
116 if (!ctx.tx[~sfFinishAfter] && !ctx.tx[~sfCondition])
117 return temMALFORMED;
118 }
119
120 if (auto const cb = ctx.tx[~sfCondition])
121 {
122 using namespace ripple::cryptoconditions;
123
125
126 auto condition = Condition::deserialize(*cb, ec);
127 if (!condition)
128 {
129 JLOG(ctx.j.debug())
130 << "Malformed condition during escrow creation: "
131 << ec.message();
132 return temMALFORMED;
133 }
134
135 // Conditions other than PrefixSha256 require the
136 // "CryptoConditionsSuite" amendment:
137 if (condition->type != Type::preimageSha256 &&
138 !ctx.rules.enabled(featureCryptoConditionsSuite))
139 return temDISABLED;
140 }
141
142 return preflight2(ctx);
143}
144
145TER
147{
148 auto const sled = ctx.view.read(keylet::account(ctx.tx[sfDestination]));
149 if (!sled)
150 return tecNO_DST;
151
152 // Pseudo-accounts cannot receive escrow. Note, this is not amendment-gated
153 // because all writes to pseudo-account discriminator fields **are**
154 // amendment gated, hence the behaviour of this check will always match the
155 // currently active amendments.
156 if (isPseudoAccount(sled))
157 return tecNO_PERMISSION;
158
159 return tesSUCCESS;
160}
161
162TER
164{
165 auto const closeTime = ctx_.view().info().parentCloseTime;
166
167 // Prior to fix1571, the cancel and finish times could be greater
168 // than or equal to the parent ledgers' close time.
169 //
170 // With fix1571, we require that they both be strictly greater
171 // than the parent ledgers' close time.
172 if (ctx_.view().rules().enabled(fix1571))
173 {
174 if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
175 return tecNO_PERMISSION;
176
177 if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter]))
178 return tecNO_PERMISSION;
179 }
180 else
181 {
182 if (ctx_.tx[~sfCancelAfter])
183 {
184 auto const cancelAfter = ctx_.tx[sfCancelAfter];
185
186 if (closeTime.time_since_epoch().count() >= cancelAfter)
187 return tecNO_PERMISSION;
188 }
189
190 if (ctx_.tx[~sfFinishAfter])
191 {
192 auto const finishAfter = ctx_.tx[sfFinishAfter];
193
194 if (closeTime.time_since_epoch().count() >= finishAfter)
195 return tecNO_PERMISSION;
196 }
197 }
198
199 auto const account = ctx_.tx[sfAccount];
200 auto const sle = ctx_.view().peek(keylet::account(account));
201 if (!sle)
202 return tefINTERNAL;
203
204 // Check reserve and funds availability
205 {
206 auto const balance = STAmount((*sle)[sfBalance]).xrp();
207 auto const reserve =
208 ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + 1);
209
210 if (balance < reserve)
212
213 if (balance < reserve + STAmount(ctx_.tx[sfAmount]).xrp())
214 return tecUNFUNDED;
215 }
216
217 // Check destination account
218 {
219 auto const sled =
220 ctx_.view().read(keylet::account(ctx_.tx[sfDestination]));
221 if (!sled)
222 return tecNO_DST;
223 if (((*sled)[sfFlags] & lsfRequireDestTag) &&
224 !ctx_.tx[~sfDestinationTag])
225 return tecDST_TAG_NEEDED;
226
227 // Obeying the lsfDissalowXRP flag was a bug. Piggyback on
228 // featureDepositAuth to remove the bug.
229 if (!ctx_.view().rules().enabled(featureDepositAuth) &&
230 ((*sled)[sfFlags] & lsfDisallowXRP))
231 return tecNO_TARGET;
232 }
233
234 // Create escrow in ledger. Note that we we use the value from the
235 // sequence or ticket. For more explanation see comments in SeqProxy.h.
236 Keylet const escrowKeylet = keylet::escrow(account, ctx_.tx.getSeqValue());
237 auto const slep = std::make_shared<SLE>(escrowKeylet);
238 (*slep)[sfAmount] = ctx_.tx[sfAmount];
239 (*slep)[sfAccount] = account;
240 (*slep)[~sfCondition] = ctx_.tx[~sfCondition];
241 (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
242 (*slep)[sfDestination] = ctx_.tx[sfDestination];
243 (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
244 (*slep)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
245 (*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
246
247 ctx_.view().insert(slep);
248
249 // Add escrow to sender's owner directory
250 {
251 auto page = ctx_.view().dirInsert(
252 keylet::ownerDir(account), escrowKeylet, describeOwnerDir(account));
253 if (!page)
254 return tecDIR_FULL;
255 (*slep)[sfOwnerNode] = *page;
256 }
257
258 // If it's not a self-send, add escrow to recipient's owner directory.
259 if (auto const dest = ctx_.tx[sfDestination]; dest != ctx_.tx[sfAccount])
260 {
261 auto page = ctx_.view().dirInsert(
262 keylet::ownerDir(dest), escrowKeylet, describeOwnerDir(dest));
263 if (!page)
264 return tecDIR_FULL;
265 (*slep)[sfDestinationNode] = *page;
266 }
267
268 // Deduct owner's balance, increment owner count
269 (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
271 ctx_.view().update(sle);
272
273 return tesSUCCESS;
274}
275
276//------------------------------------------------------------------------------
277
278static bool
280{
281 using namespace ripple::cryptoconditions;
282
284
285 auto condition = Condition::deserialize(c, ec);
286 if (!condition)
287 return false;
288
289 auto fulfillment = Fulfillment::deserialize(f, ec);
290 if (!fulfillment)
291 return false;
292
293 return validate(*fulfillment, *condition);
294}
295
296NotTEC
298{
299 if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
300 return temINVALID_FLAG;
301
302 if (ctx.tx.isFieldPresent(sfCredentialIDs) &&
303 !ctx.rules.enabled(featureCredentials))
304 return temDISABLED;
305
306 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
307 return ret;
308
309 auto const cb = ctx.tx[~sfCondition];
310 auto const fb = ctx.tx[~sfFulfillment];
311
312 // If you specify a condition, then you must also specify
313 // a fulfillment.
314 if (static_cast<bool>(cb) != static_cast<bool>(fb))
315 return temMALFORMED;
316
317 // Verify the transaction signature. If it doesn't work
318 // then don't do any more work.
319 {
320 auto const ret = preflight2(ctx);
321 if (!isTesSuccess(ret))
322 return ret;
323 }
324
325 if (cb && fb)
326 {
327 auto& router = ctx.app.getHashRouter();
328
329 auto const id = ctx.tx.getTransactionID();
330 auto const flags = router.getFlags(id);
331
332 // If we haven't checked the condition, check it
333 // now. Whether it passes or not isn't important
334 // in preflight.
335 if (!(flags & (SF_CF_INVALID | SF_CF_VALID)))
336 {
337 if (checkCondition(*fb, *cb))
338 router.setFlags(id, SF_CF_VALID);
339 else
340 router.setFlags(id, SF_CF_INVALID);
341 }
342 }
343
344 if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
345 return err;
346
347 return tesSUCCESS;
348}
349
352{
353 XRPAmount extraFee{0};
354
355 if (auto const fb = tx[~sfFulfillment])
356 {
357 extraFee += view.fees().base * (32 + (fb->size() / 16));
358 }
359
360 return Transactor::calculateBaseFee(view, tx) + extraFee;
361}
362
363TER
365{
366 if (!ctx.view.rules().enabled(featureCredentials))
367 return Transactor::preclaim(ctx);
368
369 if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
370 !isTesSuccess(err))
371 return err;
372
373 return tesSUCCESS;
374}
375
376TER
378{
379 auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
380 auto const slep = ctx_.view().peek(k);
381 if (!slep)
382 return tecNO_TARGET;
383
384 // If a cancel time is present, a finish operation should only succeed prior
385 // to that time. fix1571 corrects a logic error in the check that would make
386 // a finish only succeed strictly after the cancel time.
387 if (ctx_.view().rules().enabled(fix1571))
388 {
389 auto const now = ctx_.view().info().parentCloseTime;
390
391 // Too soon: can't execute before the finish time
392 if ((*slep)[~sfFinishAfter] && !after(now, (*slep)[sfFinishAfter]))
393 return tecNO_PERMISSION;
394
395 // Too late: can't execute after the cancel time
396 if ((*slep)[~sfCancelAfter] && after(now, (*slep)[sfCancelAfter]))
397 return tecNO_PERMISSION;
398 }
399 else
400 {
401 // Too soon?
402 if ((*slep)[~sfFinishAfter] &&
404 (*slep)[sfFinishAfter])
405 return tecNO_PERMISSION;
406
407 // Too late?
408 if ((*slep)[~sfCancelAfter] &&
410 (*slep)[sfCancelAfter])
411 return tecNO_PERMISSION;
412 }
413
414 // Check cryptocondition fulfillment
415 {
416 auto const id = ctx_.tx.getTransactionID();
417 auto flags = ctx_.app.getHashRouter().getFlags(id);
418
419 auto const cb = ctx_.tx[~sfCondition];
420
421 // It's unlikely that the results of the check will
422 // expire from the hash router, but if it happens,
423 // simply re-run the check.
424 if (cb && !(flags & (SF_CF_INVALID | SF_CF_VALID)))
425 {
426 auto const fb = ctx_.tx[~sfFulfillment];
427
428 if (!fb)
429 return tecINTERNAL;
430
431 if (checkCondition(*fb, *cb))
432 flags = SF_CF_VALID;
433 else
434 flags = SF_CF_INVALID;
435
436 ctx_.app.getHashRouter().setFlags(id, flags);
437 }
438
439 // If the check failed, then simply return an error
440 // and don't look at anything else.
441 if (flags & SF_CF_INVALID)
443
444 // Check against condition in the ledger entry:
445 auto const cond = (*slep)[~sfCondition];
446
447 // If a condition wasn't specified during creation,
448 // one shouldn't be included now.
449 if (!cond && cb)
451
452 // If a condition was specified during creation of
453 // the suspended payment, the identical condition
454 // must be presented again. We don't check if the
455 // fulfillment matches the condition since we did
456 // that in preflight.
457 if (cond && (cond != cb))
459 }
460
461 // NOTE: Escrow payments cannot be used to fund accounts.
462 AccountID const destID = (*slep)[sfDestination];
463 auto const sled = ctx_.view().peek(keylet::account(destID));
464 if (!sled)
465 return tecNO_DST;
466
467 if (ctx_.view().rules().enabled(featureDepositAuth))
468 {
469 if (auto err = verifyDepositPreauth(ctx_, account_, destID, sled);
470 !isTesSuccess(err))
471 return err;
472 }
473
474 AccountID const account = (*slep)[sfAccount];
475
476 // Remove escrow from owner directory
477 {
478 auto const page = (*slep)[sfOwnerNode];
479 if (!ctx_.view().dirRemove(
480 keylet::ownerDir(account), page, k.key, true))
481 {
482 JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
483 return tefBAD_LEDGER;
484 }
485 }
486
487 // Remove escrow from recipient's owner directory, if present.
488 if (auto const optPage = (*slep)[~sfDestinationNode])
489 {
490 if (!ctx_.view().dirRemove(
491 keylet::ownerDir(destID), *optPage, k.key, true))
492 {
493 JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
494 return tefBAD_LEDGER;
495 }
496 }
497
498 // Transfer amount to destination
499 (*sled)[sfBalance] = (*sled)[sfBalance] + (*slep)[sfAmount];
500 ctx_.view().update(sled);
501
502 // Adjust source owner count
503 auto const sle = ctx_.view().peek(keylet::account(account));
505 ctx_.view().update(sle);
506
507 // Remove escrow from ledger
508 ctx_.view().erase(slep);
509
510 return tesSUCCESS;
511}
512
513//------------------------------------------------------------------------------
514
515NotTEC
517{
518 if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
519 return temINVALID_FLAG;
520
521 if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
522 return ret;
523
524 return preflight2(ctx);
525}
526
527TER
529{
530 auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
531 auto const slep = ctx_.view().peek(k);
532 if (!slep)
533 return tecNO_TARGET;
534
535 if (ctx_.view().rules().enabled(fix1571))
536 {
537 auto const now = ctx_.view().info().parentCloseTime;
538
539 // No cancel time specified: can't execute at all.
540 if (!(*slep)[~sfCancelAfter])
541 return tecNO_PERMISSION;
542
543 // Too soon: can't execute before the cancel time.
544 if (!after(now, (*slep)[sfCancelAfter]))
545 return tecNO_PERMISSION;
546 }
547 else
548 {
549 // Too soon?
550 if (!(*slep)[~sfCancelAfter] ||
552 (*slep)[sfCancelAfter])
553 return tecNO_PERMISSION;
554 }
555
556 AccountID const account = (*slep)[sfAccount];
557
558 // Remove escrow from owner directory
559 {
560 auto const page = (*slep)[sfOwnerNode];
561 if (!ctx_.view().dirRemove(
562 keylet::ownerDir(account), page, k.key, true))
563 {
564 JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
565 return tefBAD_LEDGER;
566 }
567 }
568
569 // Remove escrow from recipient's owner directory, if present.
570 if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
571 {
572 if (!ctx_.view().dirRemove(
573 keylet::ownerDir((*slep)[sfDestination]),
574 *optPage,
575 k.key,
576 true))
577 {
578 JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
579 return tefBAD_LEDGER;
580 }
581 }
582
583 // Transfer amount back to owner, decrement owner count
584 auto const sle = ctx_.view().peek(keylet::account(account));
585 (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount];
587 ctx_.view().update(sle);
588
589 // Remove escrow from ledger
590 ctx_.view().erase(slep);
591
592 return tesSUCCESS;
593}
594
595} // namespace ripple
Stream fatal() const
Definition: Journal.h:352
Stream debug() const
Definition: Journal.h:328
virtual HashRouter & getHashRouter()=0
ApplyView & view()
Definition: ApplyContext.h:78
Application & app
Definition: ApplyContext.h:71
beast::Journal const journal
Definition: ApplyContext.h:75
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
Definition: ApplyView.cpp:190
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.
Definition: ApplyView.h:318
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
TER doApply() override
Definition: Escrow.cpp:528
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:516
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:86
TER doApply() override
Definition: Escrow.cpp:163
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition: Escrow.cpp:80
static TER preclaim(PreclaimContext const &ctx)
Definition: Escrow.cpp:146
static TER preclaim(PreclaimContext const &ctx)
Definition: Escrow.cpp:364
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:297
TER doApply() override
Definition: Escrow.cpp:377
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Escrow.cpp:351
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:95
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:103
A view into a ledger.
Definition: ReadView.h:52
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:130
XRPAmount xrp() const
Definition: STAmount.cpp:306
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:484
std::uint32_t getFlags() const
Definition: STObject.cpp:537
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Definition: STTx.cpp:231
uint256 getTransactionID() const
Definition: STTx.h:219
An immutable linear range of bytes.
Definition: Slice.h:46
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Transactor.cpp:224
AccountID const account_
Definition: Transactor.h:143
ApplyView & view()
Definition: Transactor.h:159
static TER preclaim(PreclaimContext const &ctx)
Definition: Transactor.h:200
beast::Journal const j_
Definition: Transactor.h:141
ApplyContext & ctx_
Definition: Transactor.h:140
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition: applySteps.h:59
T message(T... args)
NotTEC checkFields(PreflightContext const &ctx)
TER valid(PreclaimContext const &ctx, AccountID const &src)
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:184
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Definition: Indexes.cpp:389
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:374
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
@ lsfRequireDestTag
@ lsfDisallowXRP
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:1036
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:91
@ tefBAD_LEDGER
Definition: TER.h:170
@ tefINTERNAL
Definition: TER.h:173
static bool adjustOwnerCount(ApplyContext &ctx, int count)
Definition: SetOracle.cpp:186
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:160
static bool checkCondition(Slice f, Slice c)
Definition: Escrow.cpp:279
@ tecCRYPTOCONDITION_ERROR
Definition: TER.h:312
@ tecNO_DST
Definition: TER.h:290
@ tecUNFUNDED
Definition: TER.h:295
@ tecNO_TARGET
Definition: TER.h:304
@ tecDIR_FULL
Definition: TER.h:287
@ tecINTERNAL
Definition: TER.h:310
@ tecNO_PERMISSION
Definition: TER.h:305
@ tecDST_TAG_NEEDED
Definition: TER.h:309
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:307
@ tesSUCCESS
Definition: TER.h:244
TER verifyDepositPreauth(ApplyContext &ctx, AccountID const &src, AccountID const &dst, std::shared_ptr< SLE > const &sleDst)
bool isTesSuccess(TER x) noexcept
Definition: TER.h:672
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: View.cpp:2727
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:63
bool isPseudoAccount(std::shared_ptr< SLE const > sleAcct)
Definition: View.cpp:1127
@ temBAD_AMOUNT
Definition: TER.h:89
@ temMALFORMED
Definition: TER.h:87
@ temBAD_EXPIRATION
Definition: TER.h:91
@ temINVALID_FLAG
Definition: TER.h:111
@ temDISABLED
Definition: TER.h:114
XRPAmount base
Definition: protocol/Fees.h:34
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: protocol/Fees.h:49
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:39
uint256 key
Definition: Keylet.h:40
NetClock::time_point parentCloseTime
Definition: LedgerHeader.h:42
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:79
ReadView const & view
Definition: Transactor.h:82
State information when preflighting a tx.
Definition: Transactor.h:34
beast::Journal const j
Definition: Transactor.h:41
T time_since_epoch(T... args)