rippled
CashCheck.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2017 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/ledger/Ledger.h>
21 #include <ripple/app/paths/Flow.h>
22 #include <ripple/app/tx/impl/CashCheck.h>
23 #include <ripple/basics/Log.h>
24 #include <ripple/basics/scope.h>
25 #include <ripple/protocol/Feature.h>
26 #include <ripple/protocol/Indexes.h>
27 #include <ripple/protocol/STAccount.h>
28 #include <ripple/protocol/TER.h>
29 #include <ripple/protocol/TxFlags.h>
30 
31 #include <algorithm>
32 
33 namespace ripple {
34 
35 NotTEC
37 {
38  if (!ctx.rules.enabled(featureChecks))
39  return temDISABLED;
40 
41  NotTEC const ret{preflight1(ctx)};
42  if (!isTesSuccess(ret))
43  return ret;
44 
45  if (ctx.tx.getFlags() & tfUniversalMask)
46  {
47  // There are no flags (other than universal) for CashCheck yet.
48  JLOG(ctx.j.warn()) << "Malformed transaction: Invalid flags set.";
49  return temINVALID_FLAG;
50  }
51 
52  // Exactly one of Amount or DeliverMin must be present.
53  auto const optAmount = ctx.tx[~sfAmount];
54  auto const optDeliverMin = ctx.tx[~sfDeliverMin];
55 
56  if (static_cast<bool>(optAmount) == static_cast<bool>(optDeliverMin))
57  {
58  JLOG(ctx.j.warn())
59  << "Malformed transaction: "
60  "does not specify exactly one of Amount and DeliverMin.";
61  return temMALFORMED;
62  }
63 
64  // Make sure the amount is valid.
65  STAmount const value{optAmount ? *optAmount : *optDeliverMin};
66  if (!isLegalNet(value) || value.signum() <= 0)
67  {
68  JLOG(ctx.j.warn()) << "Malformed transaction: bad amount: "
69  << value.getFullText();
70  return temBAD_AMOUNT;
71  }
72 
73  if (badCurrency() == value.getCurrency())
74  {
75  JLOG(ctx.j.warn()) << "Malformed transaction: Bad currency.";
76  return temBAD_CURRENCY;
77  }
78 
79  return preflight2(ctx);
80 }
81 
82 TER
84 {
85  auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID]));
86  if (!sleCheck)
87  {
88  JLOG(ctx.j.warn()) << "Check does not exist.";
89  return tecNO_ENTRY;
90  }
91 
92  // Only cash a check with this account as the destination.
93  AccountID const dstId = sleCheck->at(sfDestination);
94  if (ctx.tx[sfAccount] != dstId)
95  {
96  JLOG(ctx.j.warn()) << "Cashing a check with wrong Destination.";
97  return tecNO_PERMISSION;
98  }
99  AccountID const srcId = sleCheck->at(sfAccount);
100  if (srcId == dstId)
101  {
102  // They wrote a check to themselves. This should be caught when
103  // the check is created, but better late than never.
104  JLOG(ctx.j.error()) << "Malformed transaction: Cashing check to self.";
105  return tecINTERNAL;
106  }
107  {
108  auto const sleSrc = ctx.view.read(keylet::account(srcId));
109  auto const sleDst = ctx.view.read(keylet::account(dstId));
110  if (!sleSrc || !sleDst)
111  {
112  // If the check exists this should never occur.
113  JLOG(ctx.j.warn())
114  << "Malformed transaction: source or destination not in ledger";
115  return tecNO_ENTRY;
116  }
117 
118  if ((sleDst->getFlags() & lsfRequireDestTag) &&
119  !sleCheck->isFieldPresent(sfDestinationTag))
120  {
121  // The tag is basically account-specific information we don't
122  // understand, but we can require someone to fill it in.
123  JLOG(ctx.j.warn())
124  << "Malformed transaction: DestinationTag required in check.";
125  return tecDST_TAG_NEEDED;
126  }
127  }
128 
129  if (hasExpired(ctx.view, sleCheck->at(~sfExpiration)))
130  {
131  JLOG(ctx.j.warn()) << "Cashing a check that has already expired.";
132  return tecEXPIRED;
133  }
134 
135  {
136  // Preflight verified exactly one of Amount or DeliverMin is present.
137  // Make sure the requested amount is reasonable.
138  STAmount const value{[](STTx const& tx) {
139  auto const optAmount = tx[~sfAmount];
140  return optAmount ? *optAmount : tx[sfDeliverMin];
141  }(ctx.tx)};
142 
143  STAmount const sendMax = sleCheck->at(sfSendMax);
144  Currency const currency{value.getCurrency()};
145  if (currency != sendMax.getCurrency())
146  {
147  JLOG(ctx.j.warn()) << "Check cash does not match check currency.";
148  return temMALFORMED;
149  }
150  AccountID const issuerId{value.getIssuer()};
151  if (issuerId != sendMax.getIssuer())
152  {
153  JLOG(ctx.j.warn()) << "Check cash does not match check issuer.";
154  return temMALFORMED;
155  }
156  if (value > sendMax)
157  {
158  JLOG(ctx.j.warn()) << "Check cashed for more than check sendMax.";
159  return tecPATH_PARTIAL;
160  }
161 
162  // Make sure the check owner holds at least value. If they have
163  // less than value the check cannot be cashed.
164  {
165  STAmount availableFunds{accountFunds(
166  ctx.view,
167  sleCheck->at(sfAccount),
168  value,
170  ctx.j)};
171 
172  // Note that src will have one reserve's worth of additional XRP
173  // once the check is cashed, since the check's reserve will no
174  // longer be required. So, if we're dealing in XRP, we add one
175  // reserve's worth to the available funds.
176  if (value.native())
177  availableFunds += XRPAmount{ctx.view.fees().increment};
178 
179  if (value > availableFunds)
180  {
181  JLOG(ctx.j.warn())
182  << "Check cashed for more than owner's balance.";
183  return tecPATH_PARTIAL;
184  }
185  }
186 
187  // An issuer can always accept their own currency.
188  if (!value.native() && (value.getIssuer() != dstId))
189  {
190  auto const sleTrustLine =
191  ctx.view.read(keylet::line(dstId, issuerId, currency));
192 
193  if (!sleTrustLine &&
195  {
196  JLOG(ctx.j.warn())
197  << "Cannot cash check for IOU without trustline.";
198  return tecNO_LINE;
199  }
200 
201  auto const sleIssuer = ctx.view.read(keylet::account(issuerId));
202  if (!sleIssuer)
203  {
204  JLOG(ctx.j.warn())
205  << "Can't receive IOUs from non-existent issuer: "
206  << to_string(issuerId);
207  return tecNO_ISSUER;
208  }
209 
210  if (sleIssuer->at(sfFlags) & lsfRequireAuth)
211  {
212  if (!sleTrustLine)
213  {
214  // We can only create a trust line if the issuer does not
215  // have requireAuth set.
216  return tecNO_AUTH;
217  }
218 
219  // Entries have a canonical representation, determined by a
220  // lexicographical "greater than" comparison employing strict
221  // weak ordering. Determine which entry we need to access.
222  bool const canonical_gt(dstId > issuerId);
223 
224  bool const is_authorized(
225  sleTrustLine->at(sfFlags) &
226  (canonical_gt ? lsfLowAuth : lsfHighAuth));
227 
228  if (!is_authorized)
229  {
230  JLOG(ctx.j.warn())
231  << "Can't receive IOUs from issuer without auth.";
232  return tecNO_AUTH;
233  }
234  }
235 
236  // The trustline from source to issuer does not need to
237  // be checked for freezing, since we already verified that the
238  // source has sufficient non-frozen funds available.
239 
240  // However, the trustline from destination to issuer may not
241  // be frozen.
242  if (isFrozen(ctx.view, dstId, currency, issuerId))
243  {
244  JLOG(ctx.j.warn()) << "Cashing a check to a frozen trustline.";
245  return tecFROZEN;
246  }
247  }
248  }
249  return tesSUCCESS;
250 }
251 
252 TER
254 {
255  // Flow requires that we operate on a PaymentSandbox, rather than
256  // directly on a View.
257  PaymentSandbox psb(&ctx_.view());
258 
259  auto sleCheck = psb.peek(keylet::check(ctx_.tx[sfCheckID]));
260  if (!sleCheck)
261  {
262  JLOG(j_.fatal()) << "Precheck did not verify check's existence.";
263  return tecFAILED_PROCESSING;
264  }
265 
266  AccountID const srcId{sleCheck->getAccountID(sfAccount)};
267  if (!psb.exists(keylet::account(srcId)) ||
269  {
270  JLOG(ctx_.journal.fatal())
271  << "Precheck did not verify source or destination's existence.";
272  return tecFAILED_PROCESSING;
273  }
274 
275  // Preclaim already checked that source has at least the requested
276  // funds.
277  //
278  // Therefore, if this is a check written to self, (and it shouldn't be)
279  // we know they have sufficient funds to pay the check. Since they are
280  // taking the funds from their own pocket and putting it back in their
281  // pocket no balance will change.
282  //
283  // If it is not a check to self (as should be the case), then there's
284  // work to do...
285  auto viewJ = ctx_.app.journal("View");
286  auto const optDeliverMin = ctx_.tx[~sfDeliverMin];
287  bool const doFix1623{psb.rules().enabled(fix1623)};
288 
289  if (srcId != account_)
290  {
291  STAmount const sendMax = sleCheck->at(sfSendMax);
292 
293  // Flow() doesn't do XRP to XRP transfers.
294  if (sendMax.native())
295  {
296  // Here we need to calculate the amount of XRP src can send.
297  // The amount they have available is their balance minus their
298  // reserve.
299  //
300  // Since (if we're successful) we're about to remove an entry
301  // from src's directory, we allow them to send that additional
302  // incremental reserve amount in the transfer. Hence the -1
303  // argument.
304  STAmount const srcLiquid{xrpLiquid(psb, srcId, -1, viewJ)};
305 
306  // Now, how much do they need in order to be successful?
307  STAmount const xrpDeliver{
308  optDeliverMin
309  ? std::max(*optDeliverMin, std::min(sendMax, srcLiquid))
311 
312  if (srcLiquid < xrpDeliver)
313  {
314  // Vote no. However the transaction might succeed if applied
315  // in a different order.
316  JLOG(j_.trace()) << "Cash Check: Insufficient XRP: "
317  << srcLiquid.getFullText() << " < "
318  << xrpDeliver.getFullText();
319  return tecUNFUNDED_PAYMENT;
320  }
321 
322  if (optDeliverMin && doFix1623)
323  // Set the DeliveredAmount metadata.
324  ctx_.deliver(xrpDeliver);
325 
326  // The source account has enough XRP so make the ledger change.
327  if (TER const ter{
328  transferXRP(psb, srcId, account_, xrpDeliver, viewJ)};
329  ter != tesSUCCESS)
330  {
331  // The transfer failed. Return the error code.
332  return ter;
333  }
334  }
335  else
336  {
337  // Note that for DeliverMin we don't know exactly how much
338  // currency we want flow to deliver. We can't ask for the
339  // maximum possible currency because there might be a gateway
340  // transfer rate to account for. Since the transfer rate cannot
341  // exceed 200%, we use 1/2 maxValue as our limit.
342  STAmount const flowDeliver{
343  optDeliverMin ? STAmount(
344  optDeliverMin->issue(),
348 
349  // If a trust line does not exist yet create one.
350  Issue const& trustLineIssue = flowDeliver.issue();
351  AccountID const issuer = flowDeliver.getIssuer();
352  AccountID const truster = issuer == account_ ? srcId : account_;
353  Keylet const trustLineKey = keylet::line(truster, trustLineIssue);
354  bool const destLow = issuer > account_;
355 
356  bool const checkCashMakesTrustLine =
358 
359  if (checkCashMakesTrustLine && !psb.exists(trustLineKey))
360  {
361  // 1. Can the check casher meet the reserve for the trust line?
362  // 2. Create trust line between destination (this) account
363  // and the issuer.
364  // 3. Apply correct noRipple settings on trust line. Use...
365  // a. this (destination) account and
366  // b. issuing account (not sending account).
367 
368  auto const sleDst = psb.peek(keylet::account(account_));
369 
370  // Can the account cover the trust line's reserve?
371  if (std::uint32_t const ownerCount = {sleDst->at(sfOwnerCount)};
372  mPriorBalance < psb.fees().accountReserve(ownerCount + 1))
373  {
374  JLOG(j_.trace()) << "Trust line does not exist. "
375  "Insufficent reserve to create line.";
376 
378  }
379 
380  Currency const currency = flowDeliver.getCurrency();
381  STAmount initialBalance(flowDeliver.issue());
382  initialBalance.setIssuer(noAccount());
383 
384  // clang-format off
385  if (TER const ter = trustCreate(
386  psb, // payment sandbox
387  destLow, // is dest low?
388  issuer, // source
389  account_, // destination
390  trustLineKey.key, // ledger index
391  sleDst, // Account to add to
392  false, // authorize account
393  (sleDst->getFlags() & lsfDefaultRipple) == 0,
394  false, // freeze trust line
395  initialBalance, // zero initial balance
396  Issue(currency, account_), // limit of zero
397  0, // quality in
398  0, // quality out
399  viewJ); // journal
400  !isTesSuccess(ter))
401  {
402  return ter;
403  }
404  // clang-format on
405 
406  psb.update(sleDst);
407 
408  // Note that we _don't_ need to be careful about destroying
409  // the trust line if the check cashing fails. The transaction
410  // machinery will automatically clean it up.
411  }
412 
413  // Since the destination is signing the check, they clearly want
414  // the funds even if their new total funds would exceed the limit
415  // on their trust line. So we tweak the trust line limits before
416  // calling flow and then restore the trust line limits afterwards.
417  auto const sleTrustLine = psb.peek(trustLineKey);
418  if (!sleTrustLine)
419  return tecNO_LINE;
420 
421  SF_AMOUNT const& tweakedLimit = destLow ? sfLowLimit : sfHighLimit;
422  STAmount const savedLimit = sleTrustLine->at(tweakedLimit);
423 
424  // Make sure the tweaked limits are restored when we leave scope.
425  scope_exit fixup(
426  [&psb, &trustLineKey, &tweakedLimit, &savedLimit]() {
427  if (auto const sleTrustLine = psb.peek(trustLineKey))
428  sleTrustLine->at(tweakedLimit) = savedLimit;
429  });
430 
431  if (checkCashMakesTrustLine)
432  {
433  // Set the trust line limit to the highest possible value
434  // while flow runs.
435  STAmount const bigAmount(
436  trustLineIssue, STAmount::cMaxValue, STAmount::cMaxOffset);
437  sleTrustLine->at(tweakedLimit) = bigAmount;
438  }
439 
440  // Let flow() do the heavy lifting on a check for an IOU.
441  auto const result = flow(
442  psb,
443  flowDeliver,
444  srcId,
445  account_,
446  STPathSet{},
447  true, // default path
448  static_cast<bool>(optDeliverMin), // partial payment
449  true, // owner pays transfer fee
450  false, // offer crossing
451  std::nullopt,
452  sleCheck->getFieldAmount(sfSendMax),
453  viewJ);
454 
455  if (result.result() != tesSUCCESS)
456  {
457  JLOG(ctx_.journal.warn()) << "flow failed when cashing check.";
458  return result.result();
459  }
460 
461  // Make sure that deliverMin was satisfied.
462  if (optDeliverMin)
463  {
464  if (result.actualAmountOut < *optDeliverMin)
465  {
466  JLOG(ctx_.journal.warn())
467  << "flow did not produce DeliverMin.";
468  return tecPATH_PARTIAL;
469  }
470  if (doFix1623 && !checkCashMakesTrustLine)
471  // Set the delivered_amount metadata.
472  ctx_.deliver(result.actualAmountOut);
473  }
474 
475  // Set the delivered amount metadata in all cases, not just
476  // for DeliverMin.
477  if (checkCashMakesTrustLine)
478  ctx_.deliver(result.actualAmountOut);
479 
480  sleCheck = psb.peek(keylet::check(ctx_.tx[sfCheckID]));
481  }
482  }
483 
484  // Check was cashed. If not a self send (and it shouldn't be), remove
485  // check link from destination directory.
486  if (srcId != account_ &&
487  !psb.dirRemove(
489  sleCheck->at(sfDestinationNode),
490  sleCheck->key(),
491  true))
492  {
493  JLOG(j_.fatal()) << "Unable to delete check from destination.";
494  return tefBAD_LEDGER;
495  }
496 
497  // Remove check from check owner's directory.
498  if (!psb.dirRemove(
499  keylet::ownerDir(srcId),
500  sleCheck->at(sfOwnerNode),
501  sleCheck->key(),
502  true))
503  {
504  JLOG(j_.fatal()) << "Unable to delete check from owner.";
505  return tefBAD_LEDGER;
506  }
507 
508  // If we succeeded, update the check owner's reserve.
509  adjustOwnerCount(psb, psb.peek(keylet::account(srcId)), -1, viewJ);
510 
511  // Remove check from ledger.
512  psb.erase(sleCheck);
513 
514  psb.apply(ctx_.rawView());
515  return tesSUCCESS;
516 }
517 
518 } // namespace ripple
ripple::badCurrency
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
Definition: UintTypes.cpp:135
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:303
ripple::sfOwnerCount
const SF_UINT32 sfOwnerCount
ripple::tecFROZEN
@ tecFROZEN
Definition: TER.h:270
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:130
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
ripple::sfSendMax
const SF_AMOUNT sfSendMax
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::fhZERO_IF_FROZEN
@ fhZERO_IF_FROZEN
Definition: View.h:76
ripple::sfOwnerNode
const SF_UINT64 sfOwnerNode
ripple::TypedField
A field with a type known at compile time.
Definition: SField.h:271
ripple::temBAD_CURRENCY
@ temBAD_CURRENCY
Definition: TER.h:88
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:60
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::sfDestination
const SF_ACCOUNT sfDestination
ripple::sfAmount
const SF_AMOUNT sfAmount
ripple::PaymentSandbox
A wrapper which makes credits unavailable to balances.
Definition: PaymentSandbox.h:112
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:89
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:597
ripple::sfCheckID
const SF_UINT256 sfCheckID
ripple::CashCheck::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: CashCheck.cpp:36
ripple::lsfLowAuth
@ lsfLowAuth
Definition: LedgerFormats.h:254
ripple::detail::ApplyViewBase::exists
bool exists(Keylet const &k) const override
Determine if a state item exists.
Definition: ApplyViewBase.cpp:58
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:276
ripple::detail::ApplyViewBase::update
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
Definition: ApplyViewBase.cpp:146
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::hasExpired
bool hasExpired(ReadView const &view, std::optional< std::uint32_t > const &exp)
Determines whether the given expiration time has passed.
Definition: View.cpp:179
ripple::ApplyContext::journal
const beast::Journal journal
Definition: ApplyContext.h:51
ripple::isLegalNet
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:446
ripple::ApplyContext::rawView
RawView & rawView()
Definition: ApplyContext.h:67
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:433
ripple::detail::ApplyViewBase::fees
Fees const & fees() const override
Returns the fees for the base ledger.
Definition: ApplyViewBase.cpp:46
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:38
ripple::STPathSet
Definition: STPathSet.h:176
algorithm
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:78
ripple::lsfHighAuth
@ lsfHighAuth
Definition: LedgerFormats.h:255
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:359
ripple::sfExpiration
const SF_UINT32 sfExpiration
ripple::Fees::increment
XRPAmount increment
Definition: ReadView.h:53
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::sfDeliverMin
const SF_AMOUNT sfDeliverMin
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
ripple::lsfRequireAuth
@ lsfRequireAuth
Definition: LedgerFormats.h:226
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:152
ripple::adjustOwnerCount
void adjustOwnerCount(ApplyView &view, std::shared_ptr< SLE > const &sle, std::int32_t amount, beast::Journal j)
Adjust the owner count up or down.
Definition: View.cpp:713
ripple::flow
path::RippleCalc::Output flow(PaymentSandbox &view, STAmount const &deliver, AccountID const &src, AccountID const &dst, STPathSet const &paths, bool defaultPaths, bool partialPayment, bool ownerPaysTransferFee, bool offerCrossing, std::optional< Quality > const &limitQuality, std::optional< STAmount > const &sendMax, beast::Journal j, path::detail::FlowDebugInfo *flowDebugInfo=nullptr)
Make a payment from the src account to the dst account.
ripple::lsfDefaultRipple
@ lsfDefaultRipple
Definition: LedgerFormats.h:232
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:133
ripple::CashCheck::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: CashCheck.cpp:83
ripple::TERSubset
Definition: TER.h:340
ripple::scope_exit
Definition: scope.h:42
ripple::tecFAILED_PROCESSING
@ tecFAILED_PROCESSING
Definition: TER.h:253
ripple::fix1623
const uint256 fix1623
ripple::STAmount
Definition: STAmount.h:45
ripple::tecUNFUNDED_PAYMENT
@ tecUNFUNDED_PAYMENT
Definition: TER.h:252
ripple::sfDestinationNode
const SF_UINT64 sfDestinationNode
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::tecINTERNAL
@ tecINTERNAL
Definition: TER.h:277
ripple::xrpLiquid
XRPAmount xrpLiquid(ReadView const &view, AccountID const &id, std::int32_t ownerCountAdj, beast::Journal j)
Definition: View.cpp:331
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::STTx
Definition: STTx.h:45
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:87
ripple::ApplyContext::deliver
void deliver(STAmount const &amount)
Sets the DeliveredAmount field in the metadata.
Definition: ApplyContext.h:74
std::uint32_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
ripple::tecPATH_PARTIAL
@ tecPATH_PARTIAL
Definition: TER.h:249
ripple::keylet::line
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition: Indexes.cpp:193
ripple::featureChecks
const uint256 featureChecks
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::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:58
ripple::accountFunds
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, beast::Journal j)
Definition: View.cpp:267
ripple::transferXRP
TER transferXRP(ApplyView &view, AccountID const &from, AccountID const &to, STAmount const &amount, beast::Journal j)
Definition: View.cpp:1447
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:224
std::min
T min(T... args)
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:52
ripple::detail::ApplyViewBase::erase
void erase(std::shared_ptr< SLE > const &sle) override
Remove a peeked SLE.
Definition: ApplyViewBase.cpp:134
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:329
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::trustCreate
TER trustCreate(ApplyView &view, const bool bSrcHigh, AccountID const &uSrcAccountID, AccountID const &uDstAccountID, uint256 const &uIndex, SLE::ref sleAccount, const bool bAuth, const bool bNoRipple, const bool bFreeze, STAmount const &saBalance, STAmount const &saLimit, std::uint32_t uQualityIn, std::uint32_t uQualityOut, beast::Journal j)
Create a trust line.
Definition: View.cpp:739
ripple::tecNO_LINE_INSUF_RESERVE
@ tecNO_LINE_INSUF_RESERVE
Definition: TER.h:259
ripple::tecNO_LINE
@ tecNO_LINE
Definition: TER.h:268
ripple::tecEXPIRED
@ tecEXPIRED
Definition: TER.h:281
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
ripple::PaymentSandbox::apply
void apply(RawView &to)
Apply changes to base view.
Definition: PaymentSandbox.cpp:254
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::tecNO_ISSUER
@ tecNO_ISSUER
Definition: TER.h:266
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:92
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:272
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:88
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::detail::ApplyViewBase::peek
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
Definition: ApplyViewBase.cpp:128
ripple::tecNO_ENTRY
@ tecNO_ENTRY
Definition: TER.h:273
ripple::detail::ApplyViewBase::rules
Rules const & rules() const override
Returns the tx processing rules.
Definition: ApplyViewBase.cpp:52
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:85
ripple::featureCheckCashMakesTrustLine
const uint256 featureCheckCashMakesTrustLine
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:35
std::max
T max(T... args)
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:31
ripple::STAmount::cMaxOffset
static const int cMaxOffset
Definition: STAmount.h:63
ripple::tecNO_AUTH
@ tecNO_AUTH
Definition: TER.h:267
ripple::keylet::check
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition: Indexes.cpp:281
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::tfUniversalMask
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:60
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:353
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:222
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:91
ripple::CashCheck::doApply
TER doApply() override
Definition: CashCheck.cpp:253
ripple::isFrozen
bool isFrozen(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer)
Definition: View.cpp:200
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:603
ripple::noAccount
AccountID const & noAccount()
A placeholder for empty accounts.
Definition: AccountID.cpp:175
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::STAmount::cMaxValue
static const std::uint64_t cMaxValue
Definition: STAmount.h:67
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:528