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 XRPAmount
95 {
96  return 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
233  auto const slep =
234  std::make_shared<SLE>(keylet::escrow(account, (*sle)[sfSequence] - 1));
235  (*slep)[sfAmount] = ctx_.tx[sfAmount];
236  (*slep)[sfAccount] = account;
237  (*slep)[~sfCondition] = ctx_.tx[~sfCondition];
238  (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
239  (*slep)[sfDestination] = ctx_.tx[sfDestination];
240  (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
241  (*slep)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
243 
244  ctx_.view().insert(slep);
245 
246  // Add escrow to sender's owner directory
247  {
248  auto page = dirAdd(
249  ctx_.view(),
250  keylet::ownerDir(account),
251  slep->key(),
252  false,
253  describeOwnerDir(account),
254  ctx_.app.journal("View"));
255  if (!page)
256  return tecDIR_FULL;
257  (*slep)[sfOwnerNode] = *page;
258  }
259 
260  // If it's not a self-send, add escrow to recipient's owner directory.
261  if (auto const dest = ctx_.tx[sfDestination]; dest != ctx_.tx[sfAccount])
262  {
263  auto page = dirAdd(
264  ctx_.view(),
265  keylet::ownerDir(dest),
266  slep->key(),
267  false,
268  describeOwnerDir(dest),
269  ctx_.app.journal("View"));
270  if (!page)
271  return tecDIR_FULL;
272  (*slep)[sfDestinationNode] = *page;
273  }
274 
275  // Deduct owner's balance, increment owner count
276  (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
277  adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal);
278  ctx_.view().update(sle);
279 
280  return tesSUCCESS;
281 }
282 
283 //------------------------------------------------------------------------------
284 
285 static bool
287 {
288  using namespace ripple::cryptoconditions;
289 
290  std::error_code ec;
291 
292  auto condition = Condition::deserialize(c, ec);
293  if (!condition)
294  return false;
295 
296  auto fulfillment = Fulfillment::deserialize(f, ec);
297  if (!fulfillment)
298  return false;
299 
300  return validate(*fulfillment, *condition);
301 }
302 
303 NotTEC
305 {
306  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
307  return temINVALID_FLAG;
308 
309  {
310  auto const ret = preflight1(ctx);
311  if (!isTesSuccess(ret))
312  return ret;
313  }
314 
315  auto const cb = ctx.tx[~sfCondition];
316  auto const fb = ctx.tx[~sfFulfillment];
317 
318  // If you specify a condition, then you must also specify
319  // a fulfillment.
320  if (static_cast<bool>(cb) != static_cast<bool>(fb))
321  return temMALFORMED;
322 
323  // Verify the transaction signature. If it doesn't work
324  // then don't do any more work.
325  {
326  auto const ret = preflight2(ctx);
327  if (!isTesSuccess(ret))
328  return ret;
329  }
330 
331  if (cb && fb)
332  {
333  auto& router = ctx.app.getHashRouter();
334 
335  auto const id = ctx.tx.getTransactionID();
336  auto const flags = router.getFlags(id);
337 
338  // If we haven't checked the condition, check it
339  // now. Whether it passes or not isn't important
340  // in preflight.
341  if (!(flags & (SF_CF_INVALID | SF_CF_VALID)))
342  {
343  if (checkCondition(*fb, *cb))
344  router.setFlags(id, SF_CF_VALID);
345  else
346  router.setFlags(id, SF_CF_INVALID);
347  }
348  }
349 
350  return tesSUCCESS;
351 }
352 
353 FeeUnit64
355 {
356  FeeUnit64 extraFee{0};
357 
358  if (auto const fb = tx[~sfFulfillment])
359  {
360  extraFee +=
361  safe_cast<FeeUnit64>(view.fees().units) * (32 + (fb->size() / 16));
362  }
363 
364  return Transactor::calculateBaseFee(view, tx) + extraFee;
365 }
366 
367 TER
369 {
370  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
371  auto const slep = ctx_.view().peek(k);
372  if (!slep)
373  return tecNO_TARGET;
374 
375  // If a cancel time is present, a finish operation should only succeed prior
376  // to that time. fix1571 corrects a logic error in the check that would make
377  // a finish only succeed strictly after the cancel time.
378  if (ctx_.view().rules().enabled(fix1571))
379  {
380  auto const now = ctx_.view().info().parentCloseTime;
381 
382  // Too soon: can't execute before the finish time
383  if ((*slep)[~sfFinishAfter] && !after(now, (*slep)[sfFinishAfter]))
384  return tecNO_PERMISSION;
385 
386  // Too late: can't execute after the cancel time
387  if ((*slep)[~sfCancelAfter] && after(now, (*slep)[sfCancelAfter]))
388  return tecNO_PERMISSION;
389  }
390  else
391  {
392  // Too soon?
393  if ((*slep)[~sfFinishAfter] &&
395  (*slep)[sfFinishAfter])
396  return tecNO_PERMISSION;
397 
398  // Too late?
399  if ((*slep)[~sfCancelAfter] &&
401  (*slep)[sfCancelAfter])
402  return tecNO_PERMISSION;
403  }
404 
405  // Check cryptocondition fulfillment
406  {
407  auto const id = ctx_.tx.getTransactionID();
408  auto flags = ctx_.app.getHashRouter().getFlags(id);
409 
410  auto const cb = ctx_.tx[~sfCondition];
411 
412  // It's unlikely that the results of the check will
413  // expire from the hash router, but if it happens,
414  // simply re-run the check.
415  if (cb && !(flags & (SF_CF_INVALID | SF_CF_VALID)))
416  {
417  auto const fb = ctx_.tx[~sfFulfillment];
418 
419  if (!fb)
420  return tecINTERNAL;
421 
422  if (checkCondition(*fb, *cb))
423  flags = SF_CF_VALID;
424  else
425  flags = SF_CF_INVALID;
426 
427  ctx_.app.getHashRouter().setFlags(id, flags);
428  }
429 
430  // If the check failed, then simply return an error
431  // and don't look at anything else.
432  if (flags & SF_CF_INVALID)
434 
435  // Check against condition in the ledger entry:
436  auto const cond = (*slep)[~sfCondition];
437 
438  // If a condition wasn't specified during creation,
439  // one shouldn't be included now.
440  if (!cond && cb)
442 
443  // If a condition was specified during creation of
444  // the suspended payment, the identical condition
445  // must be presented again. We don't check if the
446  // fulfillment matches the condition since we did
447  // that in preflight.
448  if (cond && (cond != cb))
450  }
451 
452  // NOTE: Escrow payments cannot be used to fund accounts.
453  AccountID const destID = (*slep)[sfDestination];
454  auto const sled = ctx_.view().peek(keylet::account(destID));
455  if (!sled)
456  return tecNO_DST;
457 
459  {
460  // Is EscrowFinished authorized?
461  if (sled->getFlags() & lsfDepositAuth)
462  {
463  // A destination account that requires authorization has two
464  // ways to get an EscrowFinished into the account:
465  // 1. If Account == Destination, or
466  // 2. If Account is deposit preauthorized by destination.
467  if (account_ != destID)
468  {
469  if (!view().exists(keylet::depositPreauth(destID, account_)))
470  return tecNO_PERMISSION;
471  }
472  }
473  }
474 
475  AccountID const account = (*slep)[sfAccount];
476 
477  // Remove escrow from owner directory
478  {
479  auto const page = (*slep)[sfOwnerNode];
480  if (!ctx_.view().dirRemove(
481  keylet::ownerDir(account), page, k.key, true))
482  {
483  return tefBAD_LEDGER;
484  }
485  }
486 
487  // Remove escrow from recipient's owner directory, if present.
488  if (auto const optPage = (*slep)[~sfDestinationNode])
489  {
490  if (!ctx_.view().dirRemove(
491  keylet::ownerDir(destID), *optPage, k.key, true))
492  {
493  return tefBAD_LEDGER;
494  }
495  }
496 
497  // Transfer amount to destination
498  (*sled)[sfBalance] = (*sled)[sfBalance] + (*slep)[sfAmount];
499  ctx_.view().update(sled);
500 
501  // Adjust source owner count
502  auto const sle = ctx_.view().peek(keylet::account(account));
503  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
504  ctx_.view().update(sle);
505 
506  // Remove escrow from ledger
507  ctx_.view().erase(slep);
508 
509  return tesSUCCESS;
510 }
511 
512 //------------------------------------------------------------------------------
513 
514 NotTEC
516 {
517  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
518  return temINVALID_FLAG;
519 
520  auto const ret = preflight1(ctx);
521  if (!isTesSuccess(ret))
522  return ret;
523 
524  return preflight2(ctx);
525 }
526 
527 TER
529 {
530  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
531  auto const slep = ctx_.view().peek(k);
532  if (!slep)
533  return tecNO_TARGET;
534 
535  if (ctx_.view().rules().enabled(fix1571))
536  {
537  auto const now = ctx_.view().info().parentCloseTime;
538 
539  // No cancel time specified: can't execute at all.
540  if (!(*slep)[~sfCancelAfter])
541  return tecNO_PERMISSION;
542 
543  // Too soon: can't execute before the cancel time.
544  if (!after(now, (*slep)[sfCancelAfter]))
545  return tecNO_PERMISSION;
546  }
547  else
548  {
549  // Too soon?
550  if (!(*slep)[~sfCancelAfter] ||
552  (*slep)[sfCancelAfter])
553  return tecNO_PERMISSION;
554  }
555 
556  AccountID const account = (*slep)[sfAccount];
557 
558  // Remove escrow from owner directory
559  {
560  auto const page = (*slep)[sfOwnerNode];
561  if (!ctx_.view().dirRemove(
562  keylet::ownerDir(account), page, k.key, true))
563  {
564  return tefBAD_LEDGER;
565  }
566  }
567 
568  // Remove escrow from recipient's owner directory, if present.
569  if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
570  {
571  if (!ctx_.view().dirRemove(
573  *optPage,
574  k.key,
575  true))
576  {
577  return tefBAD_LEDGER;
578  }
579  }
580 
581  // Transfer amount back to owner, decrement owner count
582  auto const sle = ctx_.view().peek(keylet::account(account));
583  (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount];
584  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
585  ctx_.view().update(sle);
586 
587  // Remove escrow from ledger
588  ctx_.view().erase(slep);
589 
590  return tesSUCCESS;
591 }
592 
593 } // namespace ripple
ripple::ReadView::info
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:285
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:90
ripple::tecNO_TARGET
@ tecNO_TARGET
Definition: TER.h:262
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:149
ripple::EscrowFinish::calculateBaseFee
static FeeUnit64 calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Escrow.cpp:354
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:528
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:88
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:576
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
ripple::ApplyView::erase
virtual void erase(std::shared_ptr< SLE > const &sle)=0
Remove a peeked SLE.
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:356
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:480
ripple::sfFlags
const SF_U32 sfFlags(access, STI_UINT32, 2, "Flags")
Definition: SField.h:354
ripple::featureDepositAuth
const uint256 featureDepositAuth
Definition: Feature.cpp:170
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:267
ripple::EscrowFinish::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:304
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::sfOwnerNode
const SF_U64 sfOwnerNode(access, STI_UINT64, 4, "OwnerNode")
Definition: SField.h:398
ripple::cryptoconditions
Definition: Condition.h:34
ripple::sfAmount
const SF_Amount sfAmount(access, STI_AMOUNT, 1, "Amount")
Definition: SField.h:440
ripple::sfOwnerCount
const SF_U32 sfOwnerCount(access, STI_UINT32, 13, "OwnerCount")
Definition: SField.h:365
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:39
ripple::sfFinishAfter
const SF_U32 sfFinishAfter(access, STI_UINT32, 37, "FinishAfter")
Definition: SField.h:390
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
ripple::sfDestinationTag
const SF_U32 sfDestinationTag(access, STI_UINT32, 14, "DestinationTag")
Definition: SField.h:366
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::sfFulfillment
const SF_Blob sfFulfillment(access, STI_VL, 16, "Fulfillment")
Definition: SField.h:472
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:300
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:146
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::sfOwner
const SF_Account sfOwner(access, STI_ACCOUNT, 2, "Owner")
Definition: SField.h:481
ripple::EscrowCreate::calculateMaxSpend
static XRPAmount calculateMaxSpend(STTx const &tx)
Definition: Escrow.cpp:94
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:121
ripple::TERSubset
Definition: TER.h:322
ripple::sfDestinationNode
const SF_U64 sfDestinationNode(access, STI_UINT64, 9, "DestinationNode")
Definition: SField.h:403
ripple::tecUNFUNDED
@ tecUNFUNDED
Definition: TER.h:253
ripple::STAmount
Definition: STAmount.h:42
ripple::PreflightContext::app
Application & app
Definition: Transactor.h:35
std::chrono::time_point
ripple::tecINTERNAL
@ tecINTERNAL
Definition: TER.h:268
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:121
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:118
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::sfSourceTag
const SF_U32 sfSourceTag(access, STI_UINT32, 3, "SourceTag")
Definition: SField.h:355
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:286
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:131
ripple::fix1543
const uint256 fix1543
Definition: Feature.cpp:173
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:245
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::ReadView
A view into a ledger.
Definition: ReadView.h:188
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:168
ripple::EscrowCreate::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:100
ripple::EscrowFinish::doApply
TER doApply() override
Definition: Escrow.cpp:368
ripple::sfBalance
const SF_Amount sfBalance(access, STI_AMOUNT, 2, "Balance")
Definition: SField.h:441
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::sfOfferSequence
const SF_U32 sfOfferSequence(access, STI_UINT32, 25, "OfferSequence")
Definition: SField.h:378
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:109
ripple::Fees::accountReserve
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: ReadView.h:65
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::Fees::units
FeeUnit32 units
Definition: ReadView.h:50
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:263
ripple::sfCondition
const SF_Blob sfCondition(access, STI_VL, 17, "Condition")
Definition: SField.h:473
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:265
ripple::EscrowCancel::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:515
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:89
ripple::Transactor::account_
AccountID account_
Definition: Transactor.h:92
ripple::sfDestination
const SF_Account sfDestination(access, STI_ACCOUNT, 3, "Destination")
Definition: SField.h:482
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::EscrowCreate::doApply
TER doApply() override
Definition: Escrow.cpp:161
ripple::lsfDisallowXRP
@ lsfDisallowXRP
Definition: LedgerFormats.h:108
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:172
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:269
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:213
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:96
ripple::sfCancelAfter
const SF_U32 sfCancelAfter(access, STI_UINT32, 36, "CancelAfter")
Definition: SField.h:389
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:248
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:507
ripple::tecCRYPTOCONDITION_ERROR
@ tecCRYPTOCONDITION_ERROR
Definition: TER.h:270
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:89