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  using duration = NetClock::duration;
130  using timepoint = NetClock::time_point;
131  auto const optExpiry = sleCheck->at(~sfExpiration);
132 
133  // Expiration is defined in terms of the close time of the parent
134  // ledger, because we definitively know the time that it closed but
135  // we do not know the closing time of the ledger that is under
136  // construction.
137  if (optExpiry &&
138  (ctx.view.parentCloseTime() >= timepoint{duration{*optExpiry}}))
139  {
140  JLOG(ctx.j.warn()) << "Cashing a check that has already expired.";
141  return tecEXPIRED;
142  }
143  }
144  {
145  // Preflight verified exactly one of Amount or DeliverMin is present.
146  // Make sure the requested amount is reasonable.
147  STAmount const value{[](STTx const& tx) {
148  auto const optAmount = tx[~sfAmount];
149  return optAmount ? *optAmount : tx[sfDeliverMin];
150  }(ctx.tx)};
151 
152  STAmount const sendMax = sleCheck->at(sfSendMax);
153  Currency const currency{value.getCurrency()};
154  if (currency != sendMax.getCurrency())
155  {
156  JLOG(ctx.j.warn()) << "Check cash does not match check currency.";
157  return temMALFORMED;
158  }
159  AccountID const issuerId{value.getIssuer()};
160  if (issuerId != sendMax.getIssuer())
161  {
162  JLOG(ctx.j.warn()) << "Check cash does not match check issuer.";
163  return temMALFORMED;
164  }
165  if (value > sendMax)
166  {
167  JLOG(ctx.j.warn()) << "Check cashed for more than check sendMax.";
168  return tecPATH_PARTIAL;
169  }
170 
171  // Make sure the check owner holds at least value. If they have
172  // less than value the check cannot be cashed.
173  {
174  STAmount availableFunds{accountFunds(
175  ctx.view,
176  sleCheck->at(sfAccount),
177  value,
179  ctx.j)};
180 
181  // Note that src will have one reserve's worth of additional XRP
182  // once the check is cashed, since the check's reserve will no
183  // longer be required. So, if we're dealing in XRP, we add one
184  // reserve's worth to the available funds.
185  if (value.native())
186  availableFunds += XRPAmount{ctx.view.fees().increment};
187 
188  if (value > availableFunds)
189  {
190  JLOG(ctx.j.warn())
191  << "Check cashed for more than owner's balance.";
192  return tecPATH_PARTIAL;
193  }
194  }
195 
196  // An issuer can always accept their own currency.
197  if (!value.native() && (value.getIssuer() != dstId))
198  {
199  auto const sleTrustLine =
200  ctx.view.read(keylet::line(dstId, issuerId, currency));
201 
202  if (!sleTrustLine &&
203  !ctx.view.rules().enabled(featureCheckCashMakesTrustLine))
204  {
205  JLOG(ctx.j.warn())
206  << "Cannot cash check for IOU without trustline.";
207  return tecNO_LINE;
208  }
209 
210  auto const sleIssuer = ctx.view.read(keylet::account(issuerId));
211  if (!sleIssuer)
212  {
213  JLOG(ctx.j.warn())
214  << "Can't receive IOUs from non-existent issuer: "
215  << to_string(issuerId);
216  return tecNO_ISSUER;
217  }
218 
219  if (sleIssuer->at(sfFlags) & lsfRequireAuth)
220  {
221  if (!sleTrustLine)
222  {
223  // We can only create a trust line if the issuer does not
224  // have requireAuth set.
225  return tecNO_AUTH;
226  }
227 
228  // Entries have a canonical representation, determined by a
229  // lexicographical "greater than" comparison employing strict
230  // weak ordering. Determine which entry we need to access.
231  bool const canonical_gt(dstId > issuerId);
232 
233  bool const is_authorized(
234  sleTrustLine->at(sfFlags) &
235  (canonical_gt ? lsfLowAuth : lsfHighAuth));
236 
237  if (!is_authorized)
238  {
239  JLOG(ctx.j.warn())
240  << "Can't receive IOUs from issuer without auth.";
241  return tecNO_AUTH;
242  }
243  }
244 
245  // The trustline from source to issuer does not need to
246  // be checked for freezing, since we already verified that the
247  // source has sufficient non-frozen funds available.
248 
249  // However, the trustline from destination to issuer may not
250  // be frozen.
251  if (isFrozen(ctx.view, dstId, currency, issuerId))
252  {
253  JLOG(ctx.j.warn()) << "Cashing a check to a frozen trustline.";
254  return tecFROZEN;
255  }
256  }
257  }
258  return tesSUCCESS;
259 }
260 
261 TER
262 CashCheck::doApply()
263 {
264  // Flow requires that we operate on a PaymentSandbox, rather than
265  // directly on a View.
266  PaymentSandbox psb(&ctx_.view());
267 
268  auto sleCheck = psb.peek(keylet::check(ctx_.tx[sfCheckID]));
269  if (!sleCheck)
270  {
271  JLOG(j_.fatal()) << "Precheck did not verify check's existence.";
272  return tecFAILED_PROCESSING;
273  }
274 
275  AccountID const srcId{sleCheck->getAccountID(sfAccount)};
276  if (!psb.exists(keylet::account(srcId)) ||
277  !psb.exists(keylet::account(account_)))
278  {
279  JLOG(ctx_.journal.fatal())
280  << "Precheck did not verify source or destination's existence.";
281  return tecFAILED_PROCESSING;
282  }
283 
284  // Preclaim already checked that source has at least the requested
285  // funds.
286  //
287  // Therefore, if this is a check written to self, (and it shouldn't be)
288  // we know they have sufficient funds to pay the check. Since they are
289  // taking the funds from their own pocket and putting it back in their
290  // pocket no balance will change.
291  //
292  // If it is not a check to self (as should be the case), then there's
293  // work to do...
294  auto viewJ = ctx_.app.journal("View");
295  auto const optDeliverMin = ctx_.tx[~sfDeliverMin];
296  bool const doFix1623{psb.rules().enabled(fix1623)};
297 
298  if (srcId != account_)
299  {
300  STAmount const sendMax = sleCheck->at(sfSendMax);
301 
302  // Flow() doesn't do XRP to XRP transfers.
303  if (sendMax.native())
304  {
305  // Here we need to calculate the amount of XRP src can send.
306  // The amount they have available is their balance minus their
307  // reserve.
308  //
309  // Since (if we're successful) we're about to remove an entry
310  // from src's directory, we allow them to send that additional
311  // incremental reserve amount in the transfer. Hence the -1
312  // argument.
313  STAmount const srcLiquid{xrpLiquid(psb, srcId, -1, viewJ)};
314 
315  // Now, how much do they need in order to be successful?
316  STAmount const xrpDeliver{
317  optDeliverMin
318  ? std::max(*optDeliverMin, std::min(sendMax, srcLiquid))
319  : ctx_.tx.getFieldAmount(sfAmount)};
320 
321  if (srcLiquid < xrpDeliver)
322  {
323  // Vote no. However the transaction might succeed if applied
324  // in a different order.
325  JLOG(j_.trace()) << "Cash Check: Insufficient XRP: "
326  << srcLiquid.getFullText() << " < "
327  << xrpDeliver.getFullText();
328  return tecUNFUNDED_PAYMENT;
329  }
330 
331  if (optDeliverMin && doFix1623)
332  // Set the DeliveredAmount metadata.
333  ctx_.deliver(xrpDeliver);
334 
335  // The source account has enough XRP so make the ledger change.
336  if (TER const ter{
337  transferXRP(psb, srcId, account_, xrpDeliver, viewJ)};
338  ter != tesSUCCESS)
339  {
340  // The transfer failed. Return the error code.
341  return ter;
342  }
343  }
344  else
345  {
346  // Note that for DeliverMin we don't know exactly how much
347  // currency we want flow to deliver. We can't ask for the
348  // maximum possible currency because there might be a gateway
349  // transfer rate to account for. Since the transfer rate cannot
350  // exceed 200%, we use 1/2 maxValue as our limit.
351  STAmount const flowDeliver{
352  optDeliverMin ? STAmount(
353  optDeliverMin->issue(),
354  STAmount::cMaxValue / 2,
355  STAmount::cMaxOffset)
356  : ctx_.tx.getFieldAmount(sfAmount)};
357 
358  // If a trust line does not exist yet create one.
359  Issue const& trustLineIssue = flowDeliver.issue();
360  AccountID const issuer = flowDeliver.getIssuer();
361  AccountID const truster = issuer == account_ ? srcId : account_;
362  Keylet const trustLineKey = keylet::line(truster, trustLineIssue);
363  bool const destLow = issuer > account_;
364 
365  bool const checkCashMakesTrustLine =
367 
368  if (checkCashMakesTrustLine && !psb.exists(trustLineKey))
369  {
370  // 1. Can the check casher meet the reserve for the trust line?
371  // 2. Create trust line between destination (this) account
372  // and the issuer.
373  // 3. Apply correct noRipple settings on trust line. Use...
374  // a. this (destination) account and
375  // b. issuing account (not sending account).
376 
377  auto const sleDst = psb.peek(keylet::account(account_));
378 
379  // Can the account cover the trust line's reserve?
380  if (std::uint32_t const ownerCount = {sleDst->at(sfOwnerCount)};
381  mPriorBalance < psb.fees().accountReserve(ownerCount + 1))
382  {
383  JLOG(j_.trace()) << "Trust line does not exist. "
384  "Insufficent reserve to create line.";
385 
387  }
388 
389  Currency const currency = flowDeliver.getCurrency();
390  STAmount initialBalance(flowDeliver.issue());
391  initialBalance.setIssuer(noAccount());
392 
393  // clang-format off
394  if (TER const ter = trustCreate(
395  psb, // payment sandbox
396  destLow, // is dest low?
397  issuer, // source
398  account_, // destination
399  trustLineKey.key, // ledger index
400  sleDst, // Account to add to
401  false, // authorize account
402  (sleDst->getFlags() & lsfDefaultRipple) == 0,
403  false, // freeze trust line
404  initialBalance, // zero initial balance
405  Issue(currency, account_), // limit of zero
406  0, // quality in
407  0, // quality out
408  viewJ); // journal
409  !isTesSuccess(ter))
410  {
411  return ter;
412  }
413  // clang-format on
414 
415  psb.update(sleDst);
416 
417  // Note that we _don't_ need to be careful about destroying
418  // the trust line if the check cashing fails. The transaction
419  // machinery will automatically clean it up.
420  }
421 
422  // Since the destination is signing the check, they clearly want
423  // the funds even if their new total funds would exceed the limit
424  // on their trust line. So we tweak the trust line limits before
425  // calling flow and then restore the trust line limits afterwards.
426  auto const sleTrustLine = psb.peek(trustLineKey);
427  if (!sleTrustLine)
428  return tecNO_LINE;
429 
430  SF_AMOUNT const& tweakedLimit = destLow ? sfLowLimit : sfHighLimit;
431  STAmount const savedLimit = sleTrustLine->at(tweakedLimit);
432 
433  // Make sure the tweaked limits are restored when we leave scope.
434  scope_exit fixup(
435  [&psb, &trustLineKey, &tweakedLimit, &savedLimit]() {
436  if (auto const sleTrustLine = psb.peek(trustLineKey))
437  sleTrustLine->at(tweakedLimit) = savedLimit;
438  });
439 
440  if (checkCashMakesTrustLine)
441  {
442  // Set the trust line limit to the highest possible value
443  // while flow runs.
444  STAmount const bigAmount(
445  trustLineIssue, STAmount::cMaxValue, STAmount::cMaxOffset);
446  sleTrustLine->at(tweakedLimit) = bigAmount;
447  }
448 
449  // Let flow() do the heavy lifting on a check for an IOU.
450  auto const result = flow(
451  psb,
452  flowDeliver,
453  srcId,
454  account_,
455  STPathSet{},
456  true, // default path
457  static_cast<bool>(optDeliverMin), // partial payment
458  true, // owner pays transfer fee
459  false, // offer crossing
460  std::nullopt,
461  sleCheck->getFieldAmount(sfSendMax),
462  viewJ);
463 
464  if (result.result() != tesSUCCESS)
465  {
466  JLOG(ctx_.journal.warn()) << "flow failed when cashing check.";
467  return result.result();
468  }
469 
470  // Make sure that deliverMin was satisfied.
471  if (optDeliverMin)
472  {
473  if (result.actualAmountOut < *optDeliverMin)
474  {
475  JLOG(ctx_.journal.warn())
476  << "flow did not produce DeliverMin.";
477  return tecPATH_PARTIAL;
478  }
479  if (doFix1623 && !checkCashMakesTrustLine)
480  // Set the delivered_amount metadata.
481  ctx_.deliver(result.actualAmountOut);
482  }
483 
484  // Set the delivered amount metadata in all cases, not just
485  // for DeliverMin.
486  if (checkCashMakesTrustLine)
487  ctx_.deliver(result.actualAmountOut);
488 
489  sleCheck = psb.peek(keylet::check(ctx_.tx[sfCheckID]));
490  }
491  }
492 
493  // Check was cashed. If not a self send (and it shouldn't be), remove
494  // check link from destination directory.
495  if (srcId != account_ &&
496  !psb.dirRemove(
497  keylet::ownerDir(account_),
498  sleCheck->at(sfDestinationNode),
499  sleCheck->key(),
500  true))
501  {
502  JLOG(j_.fatal()) << "Unable to delete check from destination.";
503  return tefBAD_LEDGER;
504  }
505 
506  // Remove check from check owner's directory.
507  if (!psb.dirRemove(
508  keylet::ownerDir(srcId),
509  sleCheck->at(sfOwnerNode),
510  sleCheck->key(),
511  true))
512  {
513  JLOG(j_.fatal()) << "Unable to delete check from owner.";
514  return tefBAD_LEDGER;
515  }
516 
517  // If we succeeded, update the check owner's reserve.
518  adjustOwnerCount(psb, psb.peek(keylet::account(srcId)), -1, viewJ);
519 
520  // Remove check from ledger.
521  psb.erase(sleCheck);
522 
523  psb.apply(ctx_.rawView());
524  return tesSUCCESS;
525 }
526 
527 } // 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::sfOwnerCount
const SF_UINT32 sfOwnerCount
ripple::tecFROZEN
@ tecFROZEN
Definition: TER.h:265
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:108
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::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:56
ripple::fhZERO_IF_FROZEN
@ fhZERO_IF_FROZEN
Definition: View.h:52
ripple::sfOwnerNode
const SF_UINT64 sfOwnerNode
ripple::TypedField
A field with a type known at compile time.
Definition: SField.h:281
ripple::temBAD_CURRENCY
@ temBAD_CURRENCY
Definition: TER.h:85
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::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:584
ripple::CashCheck::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: CashCheck.cpp:36
ripple::lsfLowAuth
@ lsfLowAuth
Definition: LedgerFormats.h:231
ripple::detail::ApplyViewBase::exists
bool exists(Keylet const &k) const override
Determine if a state item exists.
Definition: ApplyViewBase.cpp:58
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:271
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::isLegalNet
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:386
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:304
ripple::detail::ApplyViewBase::fees
Fees const & fees() const override
Returns the fees for the base ledger.
Definition: ApplyViewBase.cpp:46
ripple::ReadView::parentCloseTime
NetClock::time_point parentCloseTime() const
Returns the close time of the previous ledger.
Definition: ReadView.h:253
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:38
ripple::STPathSet
Definition: STPathSet.h:309
algorithm
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:56
ripple::lsfHighAuth
@ lsfHighAuth
Definition: LedgerFormats.h:232
ripple::sfExpiration
const SF_UINT32 sfExpiration
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:106
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
ripple::lsfRequireAuth
@ lsfRequireAuth
Definition: LedgerFormats.h:214
ripple::tefBAD_LEDGER
@ tefBAD_LEDGER
Definition: TER.h:148
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:220
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:130
ripple::CashCheck::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: CashCheck.cpp:83
ripple::TERSubset
Definition: TER.h:327
ripple::scope_exit
Definition: scope.h:42
ripple::tecFAILED_PROCESSING
@ tecFAILED_PROCESSING
Definition: TER.h:248
ripple::TER
TERSubset< CanCvtToTER > TER
Definition: TER.h:555
ripple::fix1623
const uint256 fix1623
Definition: Feature.cpp:176
ripple::STAmount
Definition: STAmount.h:43
ripple::tecUNFUNDED_PAYMENT
@ tecUNFUNDED_PAYMENT
Definition: TER.h:247
ripple::sfDestinationNode
const SF_UINT64 sfDestinationNode
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::tecINTERNAL
@ tecINTERNAL
Definition: TER.h:272
ripple::xrpLiquid
XRPAmount xrpLiquid(ReadView const &view, AccountID const &id, std::int32_t ownerCountAdj, beast::Journal j)
Definition: View.cpp:339
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:454
ripple::STTx
Definition: STTx.h:43
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:84
std::uint32_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:102
ripple::tecPATH_PARTIAL
@ tecPATH_PARTIAL
Definition: TER.h:244
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:190
ripple::featureChecks
const uint256 featureChecks
Definition: Feature.cpp:173
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
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:260
ripple::sfCheckID
const SF_HASH256 sfCheckID
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:212
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:183
ripple::Currency
base_uint< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition: UintTypes.h:56
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
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:254
ripple::tecNO_LINE
@ tecNO_LINE
Definition: TER.h:263
ripple::tecEXPIRED
@ tecEXPIRED
Definition: TER.h:276
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:109
ripple::PaymentSandbox::apply
void apply(RawView &to)
Apply changes to base view.
Definition: PaymentSandbox.cpp:254
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::tecNO_ISSUER
@ tecNO_ISSUER
Definition: TER.h:261
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:267
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:38
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:268
ripple::detail::ApplyViewBase::rules
Rules const & rules() const override
Returns the tx processing rules.
Definition: ApplyViewBase.cpp:52
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:82
ripple::NetClock::duration
std::chrono::duration< rep, period > duration
Definition: chrono.h:55
ripple::tfUniversalMask
const std::uint32_t tfUniversalMask
Definition: TxFlags.h:50
ripple::featureCheckCashMakesTrustLine
const uint256 featureCheckCashMakesTrustLine
Definition: Feature.cpp:196
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::tecNO_AUTH
@ tecNO_AUTH
Definition: TER.h:262
ripple::keylet::check
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition: Indexes.cpp:278
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:56
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:217
ripple::isFrozen
bool isFrozen(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer)
Definition: View.cpp:193
ripple::noAccount
AccountID const & noAccount()
A placeholder for empty accounts.
Definition: AccountID.cpp:97
ripple::AccountID
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition: AccountID.h:47
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:515