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 FeeUnit64
343 {
344  FeeUnit64 extraFee{0};
345 
346  if (auto const fb = tx[~sfFulfillment])
347  {
348  extraFee +=
349  safe_cast<FeeUnit64>(view.fees().units) * (32 + (fb->size() / 16));
350  }
351 
352  return Transactor::calculateBaseFee(view, tx) + extraFee;
353 }
354 
355 TER
357 {
358  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
359  auto const slep = ctx_.view().peek(k);
360  if (!slep)
361  return tecNO_TARGET;
362 
363  // If a cancel time is present, a finish operation should only succeed prior
364  // to that time. fix1571 corrects a logic error in the check that would make
365  // a finish only succeed strictly after the cancel time.
366  if (ctx_.view().rules().enabled(fix1571))
367  {
368  auto const now = ctx_.view().info().parentCloseTime;
369 
370  // Too soon: can't execute before the finish time
371  if ((*slep)[~sfFinishAfter] && !after(now, (*slep)[sfFinishAfter]))
372  return tecNO_PERMISSION;
373 
374  // Too late: can't execute after the cancel time
375  if ((*slep)[~sfCancelAfter] && after(now, (*slep)[sfCancelAfter]))
376  return tecNO_PERMISSION;
377  }
378  else
379  {
380  // Too soon?
381  if ((*slep)[~sfFinishAfter] &&
383  (*slep)[sfFinishAfter])
384  return tecNO_PERMISSION;
385 
386  // Too late?
387  if ((*slep)[~sfCancelAfter] &&
389  (*slep)[sfCancelAfter])
390  return tecNO_PERMISSION;
391  }
392 
393  // Check cryptocondition fulfillment
394  {
395  auto const id = ctx_.tx.getTransactionID();
396  auto flags = ctx_.app.getHashRouter().getFlags(id);
397 
398  auto const cb = ctx_.tx[~sfCondition];
399 
400  // It's unlikely that the results of the check will
401  // expire from the hash router, but if it happens,
402  // simply re-run the check.
403  if (cb && !(flags & (SF_CF_INVALID | SF_CF_VALID)))
404  {
405  auto const fb = ctx_.tx[~sfFulfillment];
406 
407  if (!fb)
408  return tecINTERNAL;
409 
410  if (checkCondition(*fb, *cb))
411  flags = SF_CF_VALID;
412  else
413  flags = SF_CF_INVALID;
414 
415  ctx_.app.getHashRouter().setFlags(id, flags);
416  }
417 
418  // If the check failed, then simply return an error
419  // and don't look at anything else.
420  if (flags & SF_CF_INVALID)
422 
423  // Check against condition in the ledger entry:
424  auto const cond = (*slep)[~sfCondition];
425 
426  // If a condition wasn't specified during creation,
427  // one shouldn't be included now.
428  if (!cond && cb)
430 
431  // If a condition was specified during creation of
432  // the suspended payment, the identical condition
433  // must be presented again. We don't check if the
434  // fulfillment matches the condition since we did
435  // that in preflight.
436  if (cond && (cond != cb))
438  }
439 
440  // NOTE: Escrow payments cannot be used to fund accounts.
441  AccountID const destID = (*slep)[sfDestination];
442  auto const sled = ctx_.view().peek(keylet::account(destID));
443  if (!sled)
444  return tecNO_DST;
445 
447  {
448  // Is EscrowFinished authorized?
449  if (sled->getFlags() & lsfDepositAuth)
450  {
451  // A destination account that requires authorization has two
452  // ways to get an EscrowFinished into the account:
453  // 1. If Account == Destination, or
454  // 2. If Account is deposit preauthorized by destination.
455  if (account_ != destID)
456  {
457  if (!view().exists(keylet::depositPreauth(destID, account_)))
458  return tecNO_PERMISSION;
459  }
460  }
461  }
462 
463  AccountID const account = (*slep)[sfAccount];
464 
465  // Remove escrow from owner directory
466  {
467  auto const page = (*slep)[sfOwnerNode];
468  if (!ctx_.view().dirRemove(
469  keylet::ownerDir(account), page, k.key, true))
470  {
471  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
472  return tefBAD_LEDGER;
473  }
474  }
475 
476  // Remove escrow from recipient's owner directory, if present.
477  if (auto const optPage = (*slep)[~sfDestinationNode])
478  {
479  if (!ctx_.view().dirRemove(
480  keylet::ownerDir(destID), *optPage, k.key, true))
481  {
482  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
483  return tefBAD_LEDGER;
484  }
485  }
486 
487  // Transfer amount to destination
488  (*sled)[sfBalance] = (*sled)[sfBalance] + (*slep)[sfAmount];
489  ctx_.view().update(sled);
490 
491  // Adjust source owner count
492  auto const sle = ctx_.view().peek(keylet::account(account));
493  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
494  ctx_.view().update(sle);
495 
496  // Remove escrow from ledger
497  ctx_.view().erase(slep);
498 
499  return tesSUCCESS;
500 }
501 
502 //------------------------------------------------------------------------------
503 
504 NotTEC
506 {
507  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
508  return temINVALID_FLAG;
509 
510  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
511  return ret;
512 
513  return preflight2(ctx);
514 }
515 
516 TER
518 {
519  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
520  auto const slep = ctx_.view().peek(k);
521  if (!slep)
522  return tecNO_TARGET;
523 
524  if (ctx_.view().rules().enabled(fix1571))
525  {
526  auto const now = ctx_.view().info().parentCloseTime;
527 
528  // No cancel time specified: can't execute at all.
529  if (!(*slep)[~sfCancelAfter])
530  return tecNO_PERMISSION;
531 
532  // Too soon: can't execute before the cancel time.
533  if (!after(now, (*slep)[sfCancelAfter]))
534  return tecNO_PERMISSION;
535  }
536  else
537  {
538  // Too soon?
539  if (!(*slep)[~sfCancelAfter] ||
541  (*slep)[sfCancelAfter])
542  return tecNO_PERMISSION;
543  }
544 
545  AccountID const account = (*slep)[sfAccount];
546 
547  // Remove escrow from owner directory
548  {
549  auto const page = (*slep)[sfOwnerNode];
550  if (!ctx_.view().dirRemove(
551  keylet::ownerDir(account), page, k.key, true))
552  {
553  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
554  return tefBAD_LEDGER;
555  }
556  }
557 
558  // Remove escrow from recipient's owner directory, if present.
559  if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
560  {
561  if (!ctx_.view().dirRemove(
563  *optPage,
564  k.key,
565  true))
566  {
567  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
568  return tefBAD_LEDGER;
569  }
570  }
571 
572  // Transfer amount back to owner, decrement owner count
573  auto const sle = ctx_.view().peek(keylet::account(account));
574  (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount];
575  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
576  ctx_.view().update(sle);
577 
578  // Remove escrow from ledger
579  ctx_.view().erase(slep);
580 
581  return tesSUCCESS;
582 }
583 
584 } // 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:109
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:268
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:152
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:81
ripple::sfOwnerNode
const SF_UINT64 sfOwnerNode
ripple::EscrowFinish::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Escrow.cpp:342
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:517
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:594
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:273
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:313
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:57
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:106
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:149
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::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:133
ripple::TERSubset
Definition: TER.h:337
ripple::tecUNFUNDED
@ tecUNFUNDED
Definition: TER.h:259
ripple::STAmount
Definition: STAmount.h:44
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:274
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::STTx
Definition: STTx.h:45
ripple::Transactor::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Transactor.cpp:141
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:84
std::uint32_t
ripple::feeunit::TaggedFee
Definition: FeeUnits.h:70
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:251
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:135
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:356
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:109
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:67
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::Fees::units
FeeUnit32 units
Definition: ReadView.h:52
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:269
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:271
ripple::sfCancelAfter
const SF_UINT32 sfCancelAfter
ripple::EscrowCancel::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:505
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::temMALFORMED
@ temMALFORMED
Definition: TER.h:82
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:86
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:58
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:219
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:254
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:525
ripple::tecCRYPTOCONDITION_ERROR
@ tecCRYPTOCONDITION_ERROR
Definition: TER.h:276
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:94