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