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://ripple.com/build/escrow/#escrow
62 
63  For details on specific transactions, including fields and validation rules
64  please see:
65 
66  `EscrowCreate`
67  --------------
68  See: https://ripple.com/build/transactions/#escrowcreate
69 
70  `EscrowFinish`
71  --------------
72  See: https://ripple.com/build/transactions/#escrowfinish
73 
74  `EscrowCancel`
75  --------------
76  See: https://ripple.com/build/transactions/#escrowcancel
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  auto const slep = std::make_shared<SLE>(
235  keylet::escrow(account, ctx_.tx.getSeqProxy().value()));
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 = dirAdd(
250  ctx_.view(),
251  keylet::ownerDir(account),
252  slep->key(),
253  false,
254  describeOwnerDir(account),
255  ctx_.app.journal("View"));
256  if (!page)
257  return tecDIR_FULL;
258  (*slep)[sfOwnerNode] = *page;
259  }
260 
261  // If it's not a self-send, add escrow to recipient's owner directory.
262  if (auto const dest = ctx_.tx[sfDestination]; dest != ctx_.tx[sfAccount])
263  {
264  auto page = dirAdd(
265  ctx_.view(),
266  keylet::ownerDir(dest),
267  slep->key(),
268  false,
269  describeOwnerDir(dest),
270  ctx_.app.journal("View"));
271  if (!page)
272  return tecDIR_FULL;
273  (*slep)[sfDestinationNode] = *page;
274  }
275 
276  // Deduct owner's balance, increment owner count
277  (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
278  adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal);
279  ctx_.view().update(sle);
280 
281  return tesSUCCESS;
282 }
283 
284 //------------------------------------------------------------------------------
285 
286 static bool
288 {
289  using namespace ripple::cryptoconditions;
290 
291  std::error_code ec;
292 
293  auto condition = Condition::deserialize(c, ec);
294  if (!condition)
295  return false;
296 
297  auto fulfillment = Fulfillment::deserialize(f, ec);
298  if (!fulfillment)
299  return false;
300 
301  return validate(*fulfillment, *condition);
302 }
303 
304 NotTEC
306 {
307  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
308  return temINVALID_FLAG;
309 
310  {
311  auto const ret = preflight1(ctx);
312  if (!isTesSuccess(ret))
313  return ret;
314  }
315 
316  auto const cb = ctx.tx[~sfCondition];
317  auto const fb = ctx.tx[~sfFulfillment];
318 
319  // If you specify a condition, then you must also specify
320  // a fulfillment.
321  if (static_cast<bool>(cb) != static_cast<bool>(fb))
322  return temMALFORMED;
323 
324  // Verify the transaction signature. If it doesn't work
325  // then don't do any more work.
326  {
327  auto const ret = preflight2(ctx);
328  if (!isTesSuccess(ret))
329  return ret;
330  }
331 
332  if (cb && fb)
333  {
334  auto& router = ctx.app.getHashRouter();
335 
336  auto const id = ctx.tx.getTransactionID();
337  auto const flags = router.getFlags(id);
338 
339  // If we haven't checked the condition, check it
340  // now. Whether it passes or not isn't important
341  // in preflight.
342  if (!(flags & (SF_CF_INVALID | SF_CF_VALID)))
343  {
344  if (checkCondition(*fb, *cb))
345  router.setFlags(id, SF_CF_VALID);
346  else
347  router.setFlags(id, SF_CF_INVALID);
348  }
349  }
350 
351  return tesSUCCESS;
352 }
353 
354 FeeUnit64
356 {
357  FeeUnit64 extraFee{0};
358 
359  if (auto const fb = tx[~sfFulfillment])
360  {
361  extraFee +=
362  safe_cast<FeeUnit64>(view.fees().units) * (32 + (fb->size() / 16));
363  }
364 
365  return Transactor::calculateBaseFee(view, tx) + extraFee;
366 }
367 
368 TER
370 {
371  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
372  auto const slep = ctx_.view().peek(k);
373  if (!slep)
374  return tecNO_TARGET;
375 
376  // If a cancel time is present, a finish operation should only succeed prior
377  // to that time. fix1571 corrects a logic error in the check that would make
378  // a finish only succeed strictly after the cancel time.
379  if (ctx_.view().rules().enabled(fix1571))
380  {
381  auto const now = ctx_.view().info().parentCloseTime;
382 
383  // Too soon: can't execute before the finish time
384  if ((*slep)[~sfFinishAfter] && !after(now, (*slep)[sfFinishAfter]))
385  return tecNO_PERMISSION;
386 
387  // Too late: can't execute after the cancel time
388  if ((*slep)[~sfCancelAfter] && after(now, (*slep)[sfCancelAfter]))
389  return tecNO_PERMISSION;
390  }
391  else
392  {
393  // Too soon?
394  if ((*slep)[~sfFinishAfter] &&
396  (*slep)[sfFinishAfter])
397  return tecNO_PERMISSION;
398 
399  // Too late?
400  if ((*slep)[~sfCancelAfter] &&
402  (*slep)[sfCancelAfter])
403  return tecNO_PERMISSION;
404  }
405 
406  // Check cryptocondition fulfillment
407  {
408  auto const id = ctx_.tx.getTransactionID();
409  auto flags = ctx_.app.getHashRouter().getFlags(id);
410 
411  auto const cb = ctx_.tx[~sfCondition];
412 
413  // It's unlikely that the results of the check will
414  // expire from the hash router, but if it happens,
415  // simply re-run the check.
416  if (cb && !(flags & (SF_CF_INVALID | SF_CF_VALID)))
417  {
418  auto const fb = ctx_.tx[~sfFulfillment];
419 
420  if (!fb)
421  return tecINTERNAL;
422 
423  if (checkCondition(*fb, *cb))
424  flags = SF_CF_VALID;
425  else
426  flags = SF_CF_INVALID;
427 
428  ctx_.app.getHashRouter().setFlags(id, flags);
429  }
430 
431  // If the check failed, then simply return an error
432  // and don't look at anything else.
433  if (flags & SF_CF_INVALID)
435 
436  // Check against condition in the ledger entry:
437  auto const cond = (*slep)[~sfCondition];
438 
439  // If a condition wasn't specified during creation,
440  // one shouldn't be included now.
441  if (!cond && cb)
443 
444  // If a condition was specified during creation of
445  // the suspended payment, the identical condition
446  // must be presented again. We don't check if the
447  // fulfillment matches the condition since we did
448  // that in preflight.
449  if (cond && (cond != cb))
451  }
452 
453  // NOTE: Escrow payments cannot be used to fund accounts.
454  AccountID const destID = (*slep)[sfDestination];
455  auto const sled = ctx_.view().peek(keylet::account(destID));
456  if (!sled)
457  return tecNO_DST;
458 
460  {
461  // Is EscrowFinished authorized?
462  if (sled->getFlags() & lsfDepositAuth)
463  {
464  // A destination account that requires authorization has two
465  // ways to get an EscrowFinished into the account:
466  // 1. If Account == Destination, or
467  // 2. If Account is deposit preauthorized by destination.
468  if (account_ != destID)
469  {
470  if (!view().exists(keylet::depositPreauth(destID, account_)))
471  return tecNO_PERMISSION;
472  }
473  }
474  }
475 
476  AccountID const account = (*slep)[sfAccount];
477 
478  // Remove escrow from owner directory
479  {
480  auto const page = (*slep)[sfOwnerNode];
481  if (!ctx_.view().dirRemove(
482  keylet::ownerDir(account), page, k.key, true))
483  {
484  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
485  return tefBAD_LEDGER;
486  }
487  }
488 
489  // Remove escrow from recipient's owner directory, if present.
490  if (auto const optPage = (*slep)[~sfDestinationNode])
491  {
492  if (!ctx_.view().dirRemove(
493  keylet::ownerDir(destID), *optPage, k.key, true))
494  {
495  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
496  return tefBAD_LEDGER;
497  }
498  }
499 
500  // Transfer amount to destination
501  (*sled)[sfBalance] = (*sled)[sfBalance] + (*slep)[sfAmount];
502  ctx_.view().update(sled);
503 
504  // Adjust source owner count
505  auto const sle = ctx_.view().peek(keylet::account(account));
506  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
507  ctx_.view().update(sle);
508 
509  // Remove escrow from ledger
510  ctx_.view().erase(slep);
511 
512  return tesSUCCESS;
513 }
514 
515 //------------------------------------------------------------------------------
516 
517 NotTEC
519 {
520  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
521  return temINVALID_FLAG;
522 
523  auto const ret = preflight1(ctx);
524  if (!isTesSuccess(ret))
525  return ret;
526 
527  return preflight2(ctx);
528 }
529 
530 TER
532 {
533  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
534  auto const slep = ctx_.view().peek(k);
535  if (!slep)
536  return tecNO_TARGET;
537 
538  if (ctx_.view().rules().enabled(fix1571))
539  {
540  auto const now = ctx_.view().info().parentCloseTime;
541 
542  // No cancel time specified: can't execute at all.
543  if (!(*slep)[~sfCancelAfter])
544  return tecNO_PERMISSION;
545 
546  // Too soon: can't execute before the cancel time.
547  if (!after(now, (*slep)[sfCancelAfter]))
548  return tecNO_PERMISSION;
549  }
550  else
551  {
552  // Too soon?
553  if (!(*slep)[~sfCancelAfter] ||
555  (*slep)[sfCancelAfter])
556  return tecNO_PERMISSION;
557  }
558 
559  AccountID const account = (*slep)[sfAccount];
560 
561  // Remove escrow from owner directory
562  {
563  auto const page = (*slep)[sfOwnerNode];
564  if (!ctx_.view().dirRemove(
565  keylet::ownerDir(account), page, k.key, true))
566  {
567  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
568  return tefBAD_LEDGER;
569  }
570  }
571 
572  // Remove escrow from recipient's owner directory, if present.
573  if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
574  {
575  if (!ctx_.view().dirRemove(
577  *optPage,
578  k.key,
579  true))
580  {
581  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
582  return tefBAD_LEDGER;
583  }
584  }
585 
586  // Transfer amount back to owner, decrement owner count
587  auto const sle = ctx_.view().peek(keylet::account(account));
588  (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount];
589  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
590  ctx_.view().update(sle);
591 
592  // Remove escrow from ledger
593  ctx_.view().erase(slep);
594 
595  return tesSUCCESS;
596 }
597 
598 } // 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:304
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::tecNO_TARGET
@ tecNO_TARGET
Definition: TER.h:265
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:150
ripple::sfOwnerNode
const SF_UINT64 sfOwnerNode
ripple::EscrowFinish::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Escrow.cpp:355
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:531
ripple::sfDestination
const SF_ACCOUNT sfDestination
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:713
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:90
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:580
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
Definition: Feature.cpp:169
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:270
ripple::EscrowFinish::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:305
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:164
ripple::cryptoconditions
Definition: Condition.h:34
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:39
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:299
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:114
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:41
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:319
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:147
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:642
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:134
ripple::TERSubset
Definition: TER.h:326
ripple::tecUNFUNDED
@ tecUNFUNDED
Definition: TER.h:256
ripple::STAmount
Definition: STAmount.h:42
ripple::PreflightContext::app
Application & app
Definition: Transactor.h:35
ripple::sfDestinationNode
const SF_UINT64 sfDestinationNode
std::chrono::time_point
ripple::tecINTERNAL
@ tecINTERNAL
Definition: TER.h:271
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:454
ripple::STTx
Definition: STTx.h:42
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:103
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:287
ripple::cryptoconditions::validate
bool validate(Fulfillment const &f, Condition const &c, Slice m)
Verify if the given message satisfies the fulfillment.
Definition: Fulfillment.cpp:47
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:104
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:117
ripple::fix1543
const uint256 fix1543
Definition: Feature.cpp:172
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:248
ripple::dirAdd
boost::optional< std::uint64_t > dirAdd(ApplyView &view, Keylet const &dir, uint256 const &uLedgerIndex, bool strictOrder, std::function< void(SLE::ref)> fDescriber, beast::Journal j)
Definition: View.cpp:721
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::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::featureCryptoConditionsSuite
const uint256 featureCryptoConditionsSuite
Definition: Feature.cpp:167
ripple::EscrowCreate::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:100
ripple::EscrowFinish::doApply
TER doApply() override
Definition: Escrow.cpp:369
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:108
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:266
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:268
ripple::sfCancelAfter
const SF_UINT32 sfCancelAfter
ripple::EscrowCancel::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:518
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:89
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:108
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:36
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:32
ripple::fix1571
const uint256 fix1571
Definition: Feature.cpp:171
ripple::temBAD_EXPIRATION
@ temBAD_EXPIRATION
Definition: TER.h:86
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:37
ripple::keylet::depositPreauth
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition: Indexes.cpp:288
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:216
ripple::sfFulfillment
const SF_VL sfFulfillment
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:92
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:251
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:511
ripple::tecCRYPTOCONDITION_ERROR
@ tecCRYPTOCONDITION_ERROR
Definition: TER.h:273
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:93