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 const 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  auto const sleSrc = psb.peek(keylet::account(srcId));
277  auto const sleDst = psb.peek(keylet::account(account_));
278 
279  if (!sleSrc || !sleDst)
280  {
281  JLOG(ctx_.journal.fatal())
282  << "Precheck did not verify source or destination's existence.";
283  return tecFAILED_PROCESSING;
284  }
285 
286  // Preclaim already checked that source has at least the requested
287  // funds.
288  //
289  // Therefore, if this is a check written to self, (and it shouldn't be)
290  // we know they have sufficient funds to pay the check. Since they are
291  // taking the funds from their own pocket and putting it back in their
292  // pocket no balance will change.
293  //
294  // If it is not a check to self (as should be the case), then there's
295  // work to do...
296  auto viewJ = ctx_.app.journal("View");
297  auto const optDeliverMin = ctx_.tx[~sfDeliverMin];
298  bool const doFix1623{ctx_.view().rules().enabled(fix1623)};
299 
300  if (srcId != account_)
301  {
302  STAmount const sendMax = sleCheck->at(sfSendMax);
303 
304  // Flow() doesn't do XRP to XRP transfers.
305  if (sendMax.native())
306  {
307  // Here we need to calculate the amount of XRP sleSrc can send.
308  // The amount they have available is their balance minus their
309  // reserve.
310  //
311  // Since (if we're successful) we're about to remove an entry
312  // from src's directory, we allow them to send that additional
313  // incremental reserve amount in the transfer. Hence the -1
314  // argument.
315  STAmount const srcLiquid{xrpLiquid(psb, srcId, -1, viewJ)};
316 
317  // Now, how much do they need in order to be successful?
318  STAmount const xrpDeliver{
319  optDeliverMin
320  ? std::max(*optDeliverMin, std::min(sendMax, srcLiquid))
321  : ctx_.tx.getFieldAmount(sfAmount)};
322 
323  if (srcLiquid < xrpDeliver)
324  {
325  // Vote no. However the transaction might succeed if applied
326  // in a different order.
327  JLOG(j_.trace()) << "Cash Check: Insufficient XRP: "
328  << srcLiquid.getFullText() << " < "
329  << xrpDeliver.getFullText();
330  return tecUNFUNDED_PAYMENT;
331  }
332 
333  if (optDeliverMin && doFix1623)
334  // Set the DeliveredAmount metadata.
335  ctx_.deliver(xrpDeliver);
336 
337  // The source account has enough XRP so make the ledger change.
338  if (TER const ter{
339  transferXRP(psb, srcId, account_, xrpDeliver, viewJ)};
340  ter != tesSUCCESS)
341  {
342  // The transfer failed. Return the error code.
343  return ter;
344  }
345  }
346  else
347  {
348  // Note that for DeliverMin we don't know exactly how much
349  // currency we want flow to deliver. We can't ask for the
350  // maximum possible currency because there might be a gateway
351  // transfer rate to account for. Since the transfer rate cannot
352  // exceed 200%, we use 1/2 maxValue as our limit.
353  STAmount const flowDeliver{
354  optDeliverMin ? STAmount(
355  optDeliverMin->issue(),
356  STAmount::cMaxValue / 2,
357  STAmount::cMaxOffset)
358  : ctx_.tx.getFieldAmount(sfAmount)};
359 
360  // If a trust line does not exist yet create one.
361  Issue const& trustLineIssue = flowDeliver.issue();
362  AccountID const issuer = flowDeliver.getIssuer();
363  AccountID const truster = issuer == account_ ? srcId : account_;
364  Keylet const trustLineKey = keylet::line(truster, trustLineIssue);
365  bool const destLow = issuer > account_;
366 
367  bool const checkCashMakesTrustLine =
369 
370  if (checkCashMakesTrustLine && !psb.exists(trustLineKey))
371  {
372  // 1. Can the check casher meet the reserve for the trust line?
373  // 2. Create trust line between destination (this) account
374  // and the issuer.
375  // 3. Apply correct noRipple settings on trust line. Use...
376  // a. this (destination) account and
377  // b. issuing account (not sending 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  // Note that we _don't_ need to be careful about destroying
416  // the trust line if the check cashing fails. The transaction
417  // machinery will automatically clean it up.
418  }
419 
420  // Since the destination is signing the check, they clearly want
421  // the funds even if their new total funds would exceed the limit
422  // on their trust line. So we tweak the trust line limits before
423  // calling flow and then restore the trust line limits afterwards.
424  auto const sleTrustLine = psb.peek(trustLineKey);
425  if (!sleTrustLine)
426  return tecNO_LINE;
427 
428  SF_AMOUNT const& tweakedLimit = destLow ? sfLowLimit : sfHighLimit;
429  STAmount const savedLimit = sleTrustLine->at(tweakedLimit);
430 
431  // Make sure the tweaked limits are restored when we leave scope.
432  scope_exit fixup(
433  [&psb, &trustLineKey, &tweakedLimit, &savedLimit]() {
434  if (auto const sleTrustLine = psb.peek(trustLineKey))
435  sleTrustLine->at(tweakedLimit) = savedLimit;
436  });
437 
438  if (checkCashMakesTrustLine)
439  {
440  // Set the trust line limit to the highest possible value
441  // while flow runs.
442  STAmount const bigAmount(
443  trustLineIssue, STAmount::cMaxValue, STAmount::cMaxOffset);
444  sleTrustLine->at(tweakedLimit) = bigAmount;
445  }
446 
447  // Let flow() do the heavy lifting on a check for an IOU.
448  auto const result = flow(
449  psb,
450  flowDeliver,
451  srcId,
452  account_,
453  STPathSet{},
454  true, // default path
455  static_cast<bool>(optDeliverMin), // partial payment
456  true, // owner pays transfer fee
457  false, // offer crossing
458  std::nullopt,
459  sleCheck->getFieldAmount(sfSendMax),
460  viewJ);
461 
462  if (result.result() != tesSUCCESS)
463  {
464  JLOG(ctx_.journal.warn()) << "flow failed when cashing check.";
465  return result.result();
466  }
467 
468  // Make sure that deliverMin was satisfied.
469  if (optDeliverMin)
470  {
471  if (result.actualAmountOut < *optDeliverMin)
472  {
473  JLOG(ctx_.journal.warn())
474  << "flow did not produce DeliverMin.";
475  return tecPATH_PARTIAL;
476  }
477  if (doFix1623 && !checkCashMakesTrustLine)
478  // Set the delivered_amount metadata.
479  ctx_.deliver(result.actualAmountOut);
480  }
481  // Set the delivered amount metadata in all cases, not just
482  // for DeliverMin.
483  if (checkCashMakesTrustLine)
484  ctx_.deliver(result.actualAmountOut);
485  }
486  }
487 
488  // Check was cashed. If not a self send (and it shouldn't be), remove
489  // check link from destination directory.
490  if (srcId != account_)
491  {
492  std::uint64_t const page = {sleCheck->at(sfDestinationNode)};
493  if (!ctx_.view().dirRemove(
494  keylet::ownerDir(account_), page, sleCheck->key(), true))
495  {
496  JLOG(j_.fatal()) << "Unable to delete check from destination.";
497  return tefBAD_LEDGER;
498  }
499  }
500  // Remove check from check owner's directory.
501  {
502  std::uint64_t const page = {sleCheck->at(sfOwnerNode)};
503  if (!ctx_.view().dirRemove(
504  keylet::ownerDir(srcId), page, sleCheck->key(), true))
505  {
506  JLOG(j_.fatal()) << "Unable to delete check from owner.";
507  return tefBAD_LEDGER;
508  }
509  }
510  // If we succeeded, update the check owner's reserve.
511  adjustOwnerCount(psb, sleSrc, -1, viewJ);
512 
513  // Remove check from ledger.
514  psb.erase(sleCheck);
515 
516  psb.apply(ctx_.rawView());
517  return tesSUCCESS;
518 }
519 
520 } // 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:581
ripple::CashCheck::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: CashCheck.cpp:36
ripple::lsfLowAuth
@ lsfLowAuth
Definition: LedgerFormats.h:123
ripple::detail::ApplyViewBase::exists
bool exists(Keylet const &k) const override
Determine if a state item exists.
Definition: ApplyViewBase.cpp:59
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:271
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:47
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:124
ripple::sfExpiration
const SF_UINT32 sfExpiration
ripple::Keylet::key
uint256 key
Definition: Keylet.h:41
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:106
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:646
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:112
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:552
ripple::fix1623
const uint256 fix1623
Definition: Feature.cpp:177
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:219
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:454
ripple::STTx
Definition: STTx.h:42
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:174
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:140
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:1433
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:104
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:135
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:725
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:39
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:129
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:53
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:197
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:73
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:512