rippled
Escrow.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/tx/impl/Escrow.h>
21 
22 #include <ripple/app/misc/HashRouter.h>
23 #include <ripple/basics/Log.h>
24 #include <ripple/basics/XRPAmount.h>
25 #include <ripple/basics/chrono.h>
26 #include <ripple/basics/safe_cast.h>
27 #include <ripple/conditions/Condition.h>
28 #include <ripple/conditions/Fulfillment.h>
29 #include <ripple/ledger/ApplyView.h>
30 #include <ripple/ledger/View.h>
31 #include <ripple/protocol/Feature.h>
32 #include <ripple/protocol/Indexes.h>
33 #include <ripple/protocol/TxFlags.h>
34 #include <ripple/protocol/digest.h>
35 #include <ripple/protocol/st.h>
36 
37 // During an EscrowFinish, the transaction must specify both
38 // a condition and a fulfillment. We track whether that
39 // fulfillment matches and validates the condition.
40 #define SF_CF_INVALID SF_PRIVATE5
41 #define SF_CF_VALID SF_PRIVATE6
42 
43 namespace ripple {
44 
45 /*
46  Escrow
47  ======
48 
49  Escrow is a feature of the XRP Ledger that allows you to send conditional
50  XRP payments. These conditional payments, called escrows, set aside XRP and
51  deliver it later when certain conditions are met. Conditions to successfully
52  finish an escrow include time-based unlocks and crypto-conditions. Escrows
53  can also be set to expire if not finished in time.
54 
55  The XRP set aside in an escrow is locked up. No one can use or destroy the
56  XRP until the escrow has been successfully finished or canceled. Before the
57  expiration time, only the intended receiver can get the XRP. After the
58  expiration time, the XRP can only be returned to the sender.
59 
60  For more details on escrow, including examples, diagrams and more please
61  visit https://xrpl.org/escrow.html
62 
63  For details on specific transactions, including fields and validation rules
64  please see:
65 
66  `EscrowCreate`
67  --------------
68  See: https://xrpl.org/escrowcreate.html
69 
70  `EscrowFinish`
71  --------------
72  See: https://xrpl.org/escrowfinish.html
73 
74  `EscrowCancel`
75  --------------
76  See: https://xrpl.org/escrowcancel.html
77 */
78 
79 //------------------------------------------------------------------------------
80 
87 static inline bool
89 {
90  return now.time_since_epoch().count() > mark;
91 }
92 
93 TxConsequences
95 {
96  return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()};
97 }
98 
99 NotTEC
101 {
102  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
103  return temINVALID_FLAG;
104 
105  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
106  return ret;
107 
108  if (!isXRP(ctx.tx[sfAmount]))
109  return temBAD_AMOUNT;
110 
111  if (ctx.tx[sfAmount] <= beast::zero)
112  return temBAD_AMOUNT;
113 
114  // We must specify at least one timeout value
115  if (!ctx.tx[~sfCancelAfter] && !ctx.tx[~sfFinishAfter])
116  return temBAD_EXPIRATION;
117 
118  // If both finish and cancel times are specified then the cancel time must
119  // be strictly after the finish time.
120  if (ctx.tx[~sfCancelAfter] && ctx.tx[~sfFinishAfter] &&
121  ctx.tx[sfCancelAfter] <= ctx.tx[sfFinishAfter])
122  return temBAD_EXPIRATION;
123 
124  if (ctx.rules.enabled(fix1571))
125  {
126  // In the absence of a FinishAfter, the escrow can be finished
127  // immediately, which can be confusing. When creating an escrow,
128  // we want to ensure that either a FinishAfter time is explicitly
129  // specified or a completion condition is attached.
130  if (!ctx.tx[~sfFinishAfter] && !ctx.tx[~sfCondition])
131  return temMALFORMED;
132  }
133 
134  if (auto const cb = ctx.tx[~sfCondition])
135  {
136  using namespace ripple::cryptoconditions;
137 
138  std::error_code ec;
139 
140  auto condition = Condition::deserialize(*cb, ec);
141  if (!condition)
142  {
143  JLOG(ctx.j.debug())
144  << "Malformed condition during escrow creation: "
145  << ec.message();
146  return temMALFORMED;
147  }
148 
149  // Conditions other than PrefixSha256 require the
150  // "CryptoConditionsSuite" amendment:
151  if (condition->type != Type::preimageSha256 &&
153  return temDISABLED;
154  }
155 
156  return preflight2(ctx);
157 }
158 
159 TER
161 {
162  auto const sled = ctx.view.read(keylet::account(ctx.tx[sfDestination]));
163  if (!sled)
164  return tecNO_DST;
165  if (sled->isFieldPresent(sfAMMID))
166  return tecNO_PERMISSION;
167 
168  return tesSUCCESS;
169 }
170 
171 TER
173 {
174  auto const closeTime = ctx_.view().info().parentCloseTime;
175 
176  // Prior to fix1571, the cancel and finish times could be greater
177  // than or equal to the parent ledgers' close time.
178  //
179  // With fix1571, we require that they both be strictly greater
180  // than the parent ledgers' close time.
181  if (ctx_.view().rules().enabled(fix1571))
182  {
183  if (ctx_.tx[~sfCancelAfter] && after(closeTime, ctx_.tx[sfCancelAfter]))
184  return tecNO_PERMISSION;
185 
186  if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter]))
187  return tecNO_PERMISSION;
188  }
189  else
190  {
191  if (ctx_.tx[~sfCancelAfter])
192  {
193  auto const cancelAfter = ctx_.tx[sfCancelAfter];
194 
195  if (closeTime.time_since_epoch().count() >= cancelAfter)
196  return tecNO_PERMISSION;
197  }
198 
199  if (ctx_.tx[~sfFinishAfter])
200  {
201  auto const finishAfter = ctx_.tx[sfFinishAfter];
202 
203  if (closeTime.time_since_epoch().count() >= finishAfter)
204  return tecNO_PERMISSION;
205  }
206  }
207 
208  auto const account = ctx_.tx[sfAccount];
209  auto const sle = ctx_.view().peek(keylet::account(account));
210  if (!sle)
211  return tefINTERNAL;
212 
213  // Check reserve and funds availability
214  {
215  auto const balance = STAmount((*sle)[sfBalance]).xrp();
216  auto const reserve =
217  ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + 1);
218 
219  if (balance < reserve)
221 
222  if (balance < reserve + STAmount(ctx_.tx[sfAmount]).xrp())
223  return tecUNFUNDED;
224  }
225 
226  // Check destination account
227  {
228  auto const sled =
230  if (!sled)
231  return tecNO_DST;
232  if (((*sled)[sfFlags] & lsfRequireDestTag) &&
234  return tecDST_TAG_NEEDED;
235 
236  // Obeying the lsfDissalowXRP flag was a bug. Piggyback on
237  // featureDepositAuth to remove the bug.
239  ((*sled)[sfFlags] & lsfDisallowXRP))
240  return tecNO_TARGET;
241  }
242 
243  // Create escrow in ledger. Note that we we use the value from the
244  // sequence or ticket. For more explanation see comments in SeqProxy.h.
245  Keylet const escrowKeylet =
246  keylet::escrow(account, ctx_.tx.getSeqProxy().value());
247  auto const slep = std::make_shared<SLE>(escrowKeylet);
248  (*slep)[sfAmount] = ctx_.tx[sfAmount];
249  (*slep)[sfAccount] = account;
250  (*slep)[~sfCondition] = ctx_.tx[~sfCondition];
251  (*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
252  (*slep)[sfDestination] = ctx_.tx[sfDestination];
253  (*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
254  (*slep)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
256 
257  ctx_.view().insert(slep);
258 
259  // Add escrow to sender's owner directory
260  {
261  auto page = ctx_.view().dirInsert(
262  keylet::ownerDir(account), escrowKeylet, describeOwnerDir(account));
263  if (!page)
264  return tecDIR_FULL;
265  (*slep)[sfOwnerNode] = *page;
266  }
267 
268  // If it's not a self-send, add escrow to recipient's owner directory.
269  if (auto const dest = ctx_.tx[sfDestination]; dest != ctx_.tx[sfAccount])
270  {
271  auto page = ctx_.view().dirInsert(
272  keylet::ownerDir(dest), escrowKeylet, describeOwnerDir(dest));
273  if (!page)
274  return tecDIR_FULL;
275  (*slep)[sfDestinationNode] = *page;
276  }
277 
278  // Deduct owner's balance, increment owner count
279  (*sle)[sfBalance] = (*sle)[sfBalance] - ctx_.tx[sfAmount];
280  adjustOwnerCount(ctx_.view(), sle, 1, ctx_.journal);
281  ctx_.view().update(sle);
282 
283  return tesSUCCESS;
284 }
285 
286 //------------------------------------------------------------------------------
287 
288 static bool
290 {
291  using namespace ripple::cryptoconditions;
292 
293  std::error_code ec;
294 
295  auto condition = Condition::deserialize(c, ec);
296  if (!condition)
297  return false;
298 
299  auto fulfillment = Fulfillment::deserialize(f, ec);
300  if (!fulfillment)
301  return false;
302 
303  return validate(*fulfillment, *condition);
304 }
305 
306 NotTEC
308 {
309  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
310  return temINVALID_FLAG;
311 
312  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
313  return ret;
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 XRPAmount
355 {
356  XRPAmount extraFee{0};
357 
358  if (auto const fb = tx[~sfFulfillment])
359  {
360  extraFee += view.fees().base * (32 + (fb->size() / 16));
361  }
362 
363  return Transactor::calculateBaseFee(view, tx) + extraFee;
364 }
365 
366 TER
368 {
369  auto const k = keylet::escrow(ctx_.tx[sfOwner], ctx_.tx[sfOfferSequence]);
370  auto const slep = ctx_.view().peek(k);
371  if (!slep)
372  return tecNO_TARGET;
373 
374  // If a cancel time is present, a finish operation should only succeed prior
375  // to that time. fix1571 corrects a logic error in the check that would make
376  // a finish only succeed strictly after the cancel time.
377  if (ctx_.view().rules().enabled(fix1571))
378  {
379  auto const now = ctx_.view().info().parentCloseTime;
380 
381  // Too soon: can't execute before the finish time
382  if ((*slep)[~sfFinishAfter] && !after(now, (*slep)[sfFinishAfter]))
383  return tecNO_PERMISSION;
384 
385  // Too late: can't execute after the cancel time
386  if ((*slep)[~sfCancelAfter] && after(now, (*slep)[sfCancelAfter]))
387  return tecNO_PERMISSION;
388  }
389  else
390  {
391  // Too soon?
392  if ((*slep)[~sfFinishAfter] &&
394  (*slep)[sfFinishAfter])
395  return tecNO_PERMISSION;
396 
397  // Too late?
398  if ((*slep)[~sfCancelAfter] &&
400  (*slep)[sfCancelAfter])
401  return tecNO_PERMISSION;
402  }
403 
404  // Check cryptocondition fulfillment
405  {
406  auto const id = ctx_.tx.getTransactionID();
407  auto flags = ctx_.app.getHashRouter().getFlags(id);
408 
409  auto const cb = ctx_.tx[~sfCondition];
410 
411  // It's unlikely that the results of the check will
412  // expire from the hash router, but if it happens,
413  // simply re-run the check.
414  if (cb && !(flags & (SF_CF_INVALID | SF_CF_VALID)))
415  {
416  auto const fb = ctx_.tx[~sfFulfillment];
417 
418  if (!fb)
419  return tecINTERNAL;
420 
421  if (checkCondition(*fb, *cb))
422  flags = SF_CF_VALID;
423  else
424  flags = SF_CF_INVALID;
425 
426  ctx_.app.getHashRouter().setFlags(id, flags);
427  }
428 
429  // If the check failed, then simply return an error
430  // and don't look at anything else.
431  if (flags & SF_CF_INVALID)
433 
434  // Check against condition in the ledger entry:
435  auto const cond = (*slep)[~sfCondition];
436 
437  // If a condition wasn't specified during creation,
438  // one shouldn't be included now.
439  if (!cond && cb)
441 
442  // If a condition was specified during creation of
443  // the suspended payment, the identical condition
444  // must be presented again. We don't check if the
445  // fulfillment matches the condition since we did
446  // that in preflight.
447  if (cond && (cond != cb))
449  }
450 
451  // NOTE: Escrow payments cannot be used to fund accounts.
452  AccountID const destID = (*slep)[sfDestination];
453  auto const sled = ctx_.view().peek(keylet::account(destID));
454  if (!sled)
455  return tecNO_DST;
456 
458  {
459  // Is EscrowFinished authorized?
460  if (sled->getFlags() & lsfDepositAuth)
461  {
462  // A destination account that requires authorization has two
463  // ways to get an EscrowFinished into the account:
464  // 1. If Account == Destination, or
465  // 2. If Account is deposit preauthorized by destination.
466  if (account_ != destID)
467  {
468  if (!view().exists(keylet::depositPreauth(destID, account_)))
469  return tecNO_PERMISSION;
470  }
471  }
472  }
473 
474  AccountID const account = (*slep)[sfAccount];
475 
476  // Remove escrow from owner directory
477  {
478  auto const page = (*slep)[sfOwnerNode];
479  if (!ctx_.view().dirRemove(
480  keylet::ownerDir(account), page, k.key, true))
481  {
482  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
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  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
494  return tefBAD_LEDGER;
495  }
496  }
497 
498  // Transfer amount to destination
499  (*sled)[sfBalance] = (*sled)[sfBalance] + (*slep)[sfAmount];
500  ctx_.view().update(sled);
501 
502  // Adjust source owner count
503  auto const sle = ctx_.view().peek(keylet::account(account));
504  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
505  ctx_.view().update(sle);
506 
507  // Remove escrow from ledger
508  ctx_.view().erase(slep);
509 
510  return tesSUCCESS;
511 }
512 
513 //------------------------------------------------------------------------------
514 
515 NotTEC
517 {
518  if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
519  return temINVALID_FLAG;
520 
521  if (auto const ret = preflight1(ctx); !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  JLOG(j_.fatal()) << "Unable to delete Escrow from owner.";
565  return tefBAD_LEDGER;
566  }
567  }
568 
569  // Remove escrow from recipient's owner directory, if present.
570  if (auto const optPage = (*slep)[~sfDestinationNode]; optPage)
571  {
572  if (!ctx_.view().dirRemove(
574  *optPage,
575  k.key,
576  true))
577  {
578  JLOG(j_.fatal()) << "Unable to delete Escrow from recipient.";
579  return tefBAD_LEDGER;
580  }
581  }
582 
583  // Transfer amount back to owner, decrement owner count
584  auto const sle = ctx_.view().peek(keylet::account(account));
585  (*sle)[sfBalance] = (*sle)[sfBalance] + (*slep)[sfAmount];
586  adjustOwnerCount(ctx_.view(), sle, -1, ctx_.journal);
587  ctx_.view().update(sle);
588 
589  // Remove escrow from ledger
590  ctx_.view().erase(slep);
591 
592  return tesSUCCESS;
593 }
594 
595 } // 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:130
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:274
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:157
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:94
ripple::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:56
ripple::sfOwnerNode
const SF_UINT64 sfOwnerNode
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::sfDestination
const SF_ACCOUNT sfDestination
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:748
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:608
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:279
ripple::EscrowFinish::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:307
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::EscrowCreate::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: Escrow.cpp:160
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:334
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:78
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:240
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:109
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::LedgerHeader::parentCloseTime
NetClock::time_point parentCloseTime
Definition: LedgerHeader.h:42
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:154
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:730
ripple::Transactor::calculateBaseFee
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Transactor.cpp:162
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:134
ripple::TERSubset
Definition: TER.h:351
ripple::tecUNFUNDED
@ tecUNFUNDED
Definition: TER.h:265
ripple::STAmount
Definition: STAmount.h:45
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:280
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::STTx
Definition: STTx.h:45
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:87
std::uint32_t
ripple::sfAMMID
const SF_UINT256 sfAMMID
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:289
ripple::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:58
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:230
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:191
ripple::fix1543
const uint256 fix1543
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:257
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:52
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:54
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:367
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
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: protocol/Fees.h:49
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:275
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:277
ripple::sfCancelAfter
const SF_UINT32 sfCancelAfter
ripple::EscrowCancel::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Escrow.cpp:516
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:172
ripple::lsfDisallowXRP
@ lsfDisallowXRP
Definition: LedgerFormats.h:234
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::EscrowFinish::calculateBaseFee
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: Escrow.cpp:354
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:85
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:89
ripple::ApplyView::dirInsert
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition: ApplyView.h:306
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::tfUniversalMask
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:60
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:225
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:260
ripple::Fees::base
XRPAmount base
Definition: protocol/Fees.h:34
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:539
ripple::tecCRYPTOCONDITION_ERROR
@ tecCRYPTOCONDITION_ERROR
Definition: TER.h:282