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