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  auto const ret = preflight1(ctx);
106  if (!isTesSuccess(ret))
107  return ret;
108 
109  if (!isXRP(ctx.tx[sfAmount]))
110  return temBAD_AMOUNT;
111 
112  if (ctx.tx[sfAmount] <= beast::zero)
113  return temBAD_AMOUNT;
114 
115  // We must specify at least one timeout value
116  if (!ctx.tx[~sfCancelAfter] && !ctx.tx[~sfFinishAfter])
117  return temBAD_EXPIRATION;
118 
119  // If both finish and cancel times are specified then the cancel time must
120  // be strictly after the finish time.
121  if (ctx.tx[~sfCancelAfter] && ctx.tx[~sfFinishAfter] &&
122  ctx.tx[sfCancelAfter] <= ctx.tx[sfFinishAfter])
123  return temBAD_EXPIRATION;
124 
125  if (ctx.rules.enabled(fix1571))
126  {
127  // In the absence of a FinishAfter, the escrow can be finished
128  // immediately, which can be confusing. When creating an escrow,
129  // we want to ensure that either a FinishAfter time is explicitly
130  // specified or a completion condition is attached.
131  if (!ctx.tx[~sfFinishAfter] && !ctx.tx[~sfCondition])
132  return temMALFORMED;
133  }
134 
135  if (auto const cb = ctx.tx[~sfCondition])
136  {
137  using namespace ripple::cryptoconditions;
138 
139  std::error_code ec;
140 
141  auto condition = Condition::deserialize(*cb, ec);
142  if (!condition)
143  {
144  JLOG(ctx.j.debug())
145  << "Malformed condition during escrow creation: "
146  << ec.message();
147  return temMALFORMED;
148  }
149 
150  // Conditions other than PrefixSha256 require the
151  // "CryptoConditionsSuite" amendment:
152  if (condition->type != Type::preimageSha256 &&
154  return temDISABLED;
155  }
156 
157  return preflight2(ctx);
158 }
159 
160 TER
162 {
163  auto const closeTime = ctx_.view().info().parentCloseTime;
164 
165  // Prior to fix1571, the cancel and finish times could be greater
166  // than or equal to the parent ledgers' close time.
167  //
168  // With fix1571, we require that they both be strictly greater
169  // than the parent ledgers' close time.
170  if (ctx_.view().rules().enabled(fix1571))
171  {
172  if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
173  return tecNO_PERMISSION;
174 
175  if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter]))
176  return tecNO_PERMISSION;
177  }
178  else
179  {
180  if (ctx_.tx[~sfCancelAfter])
181  {
182  auto const cancelAfter = ctx_.tx[sfCancelAfter];
183 
184  if (closeTime.time_since_epoch().count() >= cancelAfter)
185  return tecNO_PERMISSION;
186  }
187 
188  if (ctx_.tx[~sfFinishAfter])
189  {
190  auto const finishAfter = ctx_.tx[sfFinishAfter];
191 
192  if (closeTime.time_since_epoch().count() >= finishAfter)
193  return tecNO_PERMISSION;
194  }
195  }
196 
197  auto const account = ctx_.tx[sfAccount];
198  auto const sle = ctx_.view().peek(keylet::account(account));
199  if (!sle)
200  return tefINTERNAL;
201 
202  // Check reserve and funds availability
203  {
204  auto const balance = STAmount((*sle)[sfBalance]).xrp();
205  auto const reserve =
206  ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + 1);
207 
208  if (balance < reserve)
210 
211  if (balance < reserve + STAmount(ctx_.tx[sfAmount]).xrp())
212  return tecUNFUNDED;
213  }
214 
215  // Check destination account
216  {
217  auto const sled =
219  if (!sled)
220  return tecNO_DST;
221  if (((*sled)[sfFlags] & lsfRequireDestTag) &&
223  return tecDST_TAG_NEEDED;
224 
225  // Obeying the lsfDissalowXRP flag was a bug. Piggyback on
226  // featureDepositAuth to remove the bug.
228  ((*sled)[sfFlags] & lsfDisallowXRP))
229  return tecNO_TARGET;
230  }
231 
232  // Create escrow in ledger. Note that we we use the value from the
233  // sequence or ticket. For more explanation see comments in SeqProxy.h.
234  Keylet const escrowKeylet =
235  keylet::escrow(account, ctx_.tx.getSeqProxy().value());
236  auto const slep = std::make_shared<SLE>(escrowKeylet);
237  (*slep)[sfAmount] = ctx_.tx[sfAmount];
238  (*slep)[sfAccount] = account;
239  (*slep)[~sfCondition] = ctx_.tx[~sfCondition];
240  (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
241  (*slep)[sfDestination] = ctx_.tx[sfDestination];
242  (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
243  (*slep)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
245 
246  ctx_.view().insert(slep);
247 
248  // Add escrow to sender's owner directory
249  {
250  auto page = ctx_.view().dirInsert(
251  keylet::ownerDir(account), escrowKeylet, describeOwnerDir(account));
252  if (!page)
253  return tecDIR_FULL;
254  (*slep)[sfOwnerNode] = *page;
255  }
256 
257  // If it's not a self-send, add escrow to recipient's owner directory.
258  if (auto const dest = ctx_.tx[sfDestination]; dest != ctx_.tx[sfAccount])
259  {
260  auto page = ctx_.view().dirInsert(
261  keylet::ownerDir(dest), escrowKeylet, describeOwnerDir(dest));
262  if (!page)
263  return tecDIR_FULL;
264  (*slep)[sfDestinationNode] = *page;
265  }
266 
267  // Deduct owner's balance, increment owner count
268  (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
269  adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal);
270  ctx_.view().update(sle);
271 
272  return tesSUCCESS;
273 }
274 
275 //------------------------------------------------------------------------------
276 
277 static bool
279 {
280  using namespace ripple::cryptoconditions;
281 
282  std::error_code ec;
283 
284  auto condition = Condition::deserialize(c, ec);
285  if (!condition)
286  return false;
287 
288  auto fulfillment = Fulfillment::deserialize(f, ec);
289  if (!fulfillment)
290  return false;
291 
292  return validate(*fulfillment, *condition);
293 }
294 
295 NotTEC
297 {
298  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
299  return temINVALID_FLAG;
300 
301  {
302  auto const ret = preflight1(ctx);
303  if (!isTesSuccess(ret))
304  return ret;
305  }
306 
307  auto const cb = ctx.tx[~sfCondition];
308  auto const fb = ctx.tx[~sfFulfillment];
309 
310  // If you specify a condition, then you must also specify
311  // a fulfillment.
312  if (static_cast<bool>(cb) != static_cast<bool>(fb))
313  return temMALFORMED;
314 
315  // Verify the transaction signature. If it doesn't work
316  // then don't do any more work.
317  {
318  auto const ret = preflight2(ctx);
319  if (!isTesSuccess(ret))
320  return ret;
321  }
322 
323  if (cb && fb)
324  {
325  auto& router = ctx.app.getHashRouter();
326 
327  auto const id = ctx.tx.getTransactionID();
328  auto const flags = router.getFlags(id);
329 
330  // If we haven't checked the condition, check it
331  // now. Whether it passes or not isn't important
332  // in preflight.
333  if (!(flags & (SF_CF_INVALID | SF_CF_VALID)))
334  {
335  if (checkCondition(*fb, *cb))
336  router.setFlags(id, SF_CF_VALID);
337  else
338  router.setFlags(id, SF_CF_INVALID);
339  }
340  }
341 
342  return tesSUCCESS;
343 }
344 
345 FeeUnit64
347 {
348  FeeUnit64 extraFee{0};
349 
350  if (auto const fb = tx[~sfFulfillment])
351  {
352  extraFee +=
353  safe_cast<FeeUnit64>(view.fees().units) * (32 + (fb->size() / 16));
354  }
355 
356  return Transactor::calculateBaseFee(view, tx) + extraFee;
357 }
358 
359 TER
361 {
362  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
363  auto const slep = ctx_.view().peek(k);
364  if (!slep)
365  return tecNO_TARGET;
366 
367  // If a cancel time is present, a finish operation should only succeed prior
368  // to that time. fix1571 corrects a logic error in the check that would make
369  // a finish only succeed strictly after the cancel time.
370  if (ctx_.view().rules().enabled(fix1571))
371  {
372  auto const now = ctx_.view().info().parentCloseTime;
373 
374  // Too soon: can't execute before the finish time
375  if ((*slep)[~sfFinishAfter] && !after(now, (*slep)[sfFinishAfter]))
376  return tecNO_PERMISSION;
377 
378  // Too late: can't execute after the cancel time
379  if ((*slep)[~sfCancelAfter] && after(now, (*slep)[sfCancelAfter]))
380  return tecNO_PERMISSION;
381  }
382  else
383  {
384  // Too soon?
385  if ((*slep)[~sfFinishAfter] &&
387  (*slep)[sfFinishAfter])
388  return tecNO_PERMISSION;
389 
390  // Too late?
391  if ((*slep)[~sfCancelAfter] &&
393  (*slep)[sfCancelAfter])
394  return tecNO_PERMISSION;
395  }
396 
397  // Check cryptocondition fulfillment
398  {
399  auto const id = ctx_.tx.getTransactionID();
400  auto flags = ctx_.app.getHashRouter().getFlags(id);
401 
402  auto const cb = ctx_.tx[~sfCondition];
403 
404  // It's unlikely that the results of the check will
405  // expire from the hash router, but if it happens,
406  // simply re-run the check.
407  if (cb && !(flags & (SF_CF_INVALID | SF_CF_VALID)))
408  {
409  auto const fb = ctx_.tx[~sfFulfillment];
410 
411  if (!fb)
412  return tecINTERNAL;
413 
414  if (checkCondition(*fb, *cb))
415  flags = SF_CF_VALID;
416  else
417  flags = SF_CF_INVALID;
418 
419  ctx_.app.getHashRouter().setFlags(id, flags);
420  }
421 
422  // If the check failed, then simply return an error
423  // and don't look at anything else.
424  if (flags & SF_CF_INVALID)
426 
427  // Check against condition in the ledger entry:
428  auto const cond = (*slep)[~sfCondition];
429 
430  // If a condition wasn't specified during creation,
431  // one shouldn't be included now.
432  if (!cond && cb)
434 
435  // If a condition was specified during creation of
436  // the suspended payment, the identical condition
437  // must be presented again. We don't check if the
438  // fulfillment matches the condition since we did
439  // that in preflight.
440  if (cond && (cond != cb))
442  }
443 
444  // NOTE: Escrow payments cannot be used to fund accounts.
445  AccountID const destID = (*slep)[sfDestination];
446  auto const sled = ctx_.view().peek(keylet::account(destID));
447  if (!sled)
448  return tecNO_DST;
449 
451  {
452  // Is EscrowFinished authorized?
453  if (sled->getFlags() & lsfDepositAuth)
454  {
455  // A destination account that requires authorization has two
456  // ways to get an EscrowFinished into the account:
457  // 1. If Account == Destination, or
458  // 2. If Account is deposit preauthorized by destination.
459  if (account_ != destID)
460  {
461  if (!view().exists(keylet::depositPreauth(destID, account_)))
462  return tecNO_PERMISSION;
463  }
464  }
465  }
466 
467  AccountID const account = (*slep)[sfAccount];
468 
469  // Remove escrow from owner directory
470  {
471  auto const page = (*slep)[sfOwnerNode];
472  if (!ctx_.view().dirRemove(
473  keylet::ownerDir(account), page, k.key, true))
474  {
475  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
476  return tefBAD_LEDGER;
477  }
478  }
479 
480  // Remove escrow from recipient's owner directory, if present.
481  if (auto const optPage = (*slep)[~sfDestinationNode])
482  {
483  if (!ctx_.view().dirRemove(
484  keylet::ownerDir(destID), *optPage, k.key, true))
485  {
486  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
487  return tefBAD_LEDGER;
488  }
489  }
490 
491  // Transfer amount to destination
492  (*sled)[sfBalance] = (*sled)[sfBalance] + (*slep)[sfAmount];
493  ctx_.view().update(sled);
494 
495  // Adjust source owner count
496  auto const sle = ctx_.view().peek(keylet::account(account));
497  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
498  ctx_.view().update(sle);
499 
500  // Remove escrow from ledger
501  ctx_.view().erase(slep);
502 
503  return tesSUCCESS;
504 }
505 
506 //------------------------------------------------------------------------------
507 
508 NotTEC
510 {
511  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
512  return temINVALID_FLAG;
513 
514  auto const ret = preflight1(ctx);
515  if (!isTesSuccess(ret))
516  return ret;
517 
518  return preflight2(ctx);
519 }
520 
521 TER
523 {
524  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
525  auto const slep = ctx_.view().peek(k);
526  if (!slep)
527  return tecNO_TARGET;
528 
529  if (ctx_.view().rules().enabled(fix1571))
530  {
531  auto const now = ctx_.view().info().parentCloseTime;
532 
533  // No cancel time specified: can't execute at all.
534  if (!(*slep)[~sfCancelAfter])
535  return tecNO_PERMISSION;
536 
537  // Too soon: can't execute before the cancel time.
538  if (!after(now, (*slep)[sfCancelAfter]))
539  return tecNO_PERMISSION;
540  }
541  else
542  {
543  // Too soon?
544  if (!(*slep)[~sfCancelAfter] ||
546  (*slep)[sfCancelAfter])
547  return tecNO_PERMISSION;
548  }
549 
550  AccountID const account = (*slep)[sfAccount];
551 
552  // Remove escrow from owner directory
553  {
554  auto const page = (*slep)[sfOwnerNode];
555  if (!ctx_.view().dirRemove(
556  keylet::ownerDir(account), page, k.key, true))
557  {
558  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
559  return tefBAD_LEDGER;
560  }
561  }
562 
563  // Remove escrow from recipient's owner directory, if present.
564  if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
565  {
566  if (!ctx_.view().dirRemove(
568  *optPage,
569  k.key,
570  true))
571  {
572  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
573  return tefBAD_LEDGER;
574  }
575  }
576 
577  // Transfer amount back to owner, decrement owner count
578  auto const sle = ctx_.view().peek(keylet::account(account));
579  (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount];
580  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
581  ctx_.view().update(sle);
582 
583  // Remove escrow from ledger
584  ctx_.view().erase(slep);
585 
586  return tesSUCCESS;
587 }
588 
589 } // 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:300
ripple::sfOwnerCount
const SF_UINT32 sfOwnerCount
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:108
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:266
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:151
ripple::sfOwnerNode
const SF_UINT64 sfOwnerNode
ripple::EscrowFinish::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Escrow.cpp:346
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:522
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:584
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:271
ripple::EscrowFinish::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:296
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:56
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:222
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:315
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:148
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:130
ripple::TERSubset
Definition: TER.h:327
ripple::tecUNFUNDED
@ tecUNFUNDED
Definition: TER.h:257
ripple::STAmount
Definition: STAmount.h:43
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:272
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::STTx
Definition: STTx.h:43
ripple::Transactor::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Transactor.cpp:140
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:84
std::uint32_t
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:102
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:278
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:212
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:177
ripple::fix1543
const uint256 fix1543
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:249
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:192
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:360
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:66
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:51
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:267
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:269
ripple::sfCancelAfter
const SF_UINT32 sfCancelAfter
ripple::EscrowCancel::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:509
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:161
ripple::lsfDisallowXRP
@ lsfDisallowXRP
Definition: LedgerFormats.h:216
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:82
ripple::tfUniversalMask
const std::uint32_t tfUniversalMask
Definition: TxFlags.h:50
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::keylet::depositPreauth
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition: Indexes.cpp:284
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:217
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:252
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:515
ripple::tecCRYPTOCONDITION_ERROR
@ tecCRYPTOCONDITION_ERROR
Definition: TER.h:274
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:93