rippled
Payment.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/paths/RippleCalc.h>
21 #include <ripple/app/tx/impl/Payment.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/core/Config.h>
24 #include <ripple/protocol/Feature.h>
25 #include <ripple/protocol/TxFlags.h>
26 #include <ripple/protocol/jss.h>
27 #include <ripple/protocol/st.h>
28 
29 namespace ripple {
30 
31 // See https://ripple.com/wiki/Transaction_Format#Payment_.280.29
32 
33 TxConsequences
35 {
36  auto calculateMaxXRPSpend = [](STTx const& tx) -> XRPAmount {
37  STAmount const maxAmount =
38  tx.isFieldPresent(sfSendMax) ? tx[sfSendMax] : tx[sfAmount];
39 
40  // If there's no sfSendMax in XRP, and the sfAmount isn't
41  // in XRP, then the transaction does not spend XRP.
42  return maxAmount.native() ? maxAmount.xrp() : beast::zero;
43  };
44 
45  return TxConsequences{ctx.tx, calculateMaxXRPSpend(ctx.tx)};
46 }
47 
48 NotTEC
50 {
51  auto const ret = preflight1(ctx);
52  if (!isTesSuccess(ret))
53  return ret;
54 
55  auto& tx = ctx.tx;
56  auto& j = ctx.j;
57 
58  std::uint32_t const uTxFlags = tx.getFlags();
59 
60  if (uTxFlags & tfPaymentMask)
61  {
62  JLOG(j.trace()) << "Malformed transaction: "
63  << "Invalid flags set.";
64  return temINVALID_FLAG;
65  }
66 
67  bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
68  bool const limitQuality = uTxFlags & tfLimitQuality;
69  bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
70  bool const bPaths = tx.isFieldPresent(sfPaths);
71  bool const bMax = tx.isFieldPresent(sfSendMax);
72 
73  STAmount const saDstAmount(tx.getFieldAmount(sfAmount));
74 
75  STAmount maxSourceAmount;
76  auto const account = tx.getAccountID(sfAccount);
77 
78  if (bMax)
79  maxSourceAmount = tx.getFieldAmount(sfSendMax);
80  else if (saDstAmount.native())
81  maxSourceAmount = saDstAmount;
82  else
83  maxSourceAmount = STAmount(
84  {saDstAmount.getCurrency(), account},
85  saDstAmount.mantissa(),
86  saDstAmount.exponent(),
87  saDstAmount < beast::zero);
88 
89  auto const& uSrcCurrency = maxSourceAmount.getCurrency();
90  auto const& uDstCurrency = saDstAmount.getCurrency();
91 
92  // isZero() is XRP. FIX!
93  bool const bXRPDirect = uSrcCurrency.isZero() && uDstCurrency.isZero();
94 
95  if (!isLegalNet(saDstAmount) || !isLegalNet(maxSourceAmount))
96  return temBAD_AMOUNT;
97 
98  auto const uDstAccountID = tx.getAccountID(sfDestination);
99 
100  if (!uDstAccountID)
101  {
102  JLOG(j.trace()) << "Malformed transaction: "
103  << "Payment destination account not specified.";
104  return temDST_NEEDED;
105  }
106  if (bMax && maxSourceAmount <= beast::zero)
107  {
108  JLOG(j.trace()) << "Malformed transaction: "
109  << "bad max amount: " << maxSourceAmount.getFullText();
110  return temBAD_AMOUNT;
111  }
112  if (saDstAmount <= beast::zero)
113  {
114  JLOG(j.trace()) << "Malformed transaction: "
115  << "bad dst amount: " << saDstAmount.getFullText();
116  return temBAD_AMOUNT;
117  }
118  if (badCurrency() == uSrcCurrency || badCurrency() == uDstCurrency)
119  {
120  JLOG(j.trace()) << "Malformed transaction: "
121  << "Bad currency.";
122  return temBAD_CURRENCY;
123  }
124  if (account == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
125  {
126  // You're signing yourself a payment.
127  // If bPaths is true, you might be trying some arbitrage.
128  JLOG(j.trace()) << "Malformed transaction: "
129  << "Redundant payment from " << to_string(account)
130  << " to self without path for "
131  << to_string(uDstCurrency);
132  return temREDUNDANT;
133  }
134  if (bXRPDirect && bMax)
135  {
136  // Consistent but redundant transaction.
137  JLOG(j.trace()) << "Malformed transaction: "
138  << "SendMax specified for XRP to XRP.";
139  return temBAD_SEND_XRP_MAX;
140  }
141  if (bXRPDirect && bPaths)
142  {
143  // XRP is sent without paths.
144  JLOG(j.trace()) << "Malformed transaction: "
145  << "Paths specified for XRP to XRP.";
146  return temBAD_SEND_XRP_PATHS;
147  }
148  if (bXRPDirect && partialPaymentAllowed)
149  {
150  // Consistent but redundant transaction.
151  JLOG(j.trace()) << "Malformed transaction: "
152  << "Partial payment specified for XRP to XRP.";
154  }
155  if (bXRPDirect && limitQuality)
156  {
157  // Consistent but redundant transaction.
158  JLOG(j.trace()) << "Malformed transaction: "
159  << "Limit quality specified for XRP to XRP.";
160  return temBAD_SEND_XRP_LIMIT;
161  }
162  if (bXRPDirect && !defaultPathsAllowed)
163  {
164  // Consistent but redundant transaction.
165  JLOG(j.trace()) << "Malformed transaction: "
166  << "No ripple direct specified for XRP to XRP.";
168  }
169 
170  auto const deliverMin = tx[~sfDeliverMin];
171  if (deliverMin)
172  {
173  if (!partialPaymentAllowed)
174  {
175  JLOG(j.trace()) << "Malformed transaction: Partial payment not "
176  "specified for "
177  << jss::DeliverMin.c_str() << ".";
178  return temBAD_AMOUNT;
179  }
180 
181  auto const dMin = *deliverMin;
182  if (!isLegalNet(dMin) || dMin <= beast::zero)
183  {
184  JLOG(j.trace())
185  << "Malformed transaction: Invalid " << jss::DeliverMin.c_str()
186  << " amount. " << dMin.getFullText();
187  return temBAD_AMOUNT;
188  }
189  if (dMin.issue() != saDstAmount.issue())
190  {
191  JLOG(j.trace())
192  << "Malformed transaction: Dst issue differs "
193  "from "
194  << jss::DeliverMin.c_str() << ". " << dMin.getFullText();
195  return temBAD_AMOUNT;
196  }
197  if (dMin > saDstAmount)
198  {
199  JLOG(j.trace())
200  << "Malformed transaction: Dst amount less than "
201  << jss::DeliverMin.c_str() << ". " << dMin.getFullText();
202  return temBAD_AMOUNT;
203  }
204  }
205 
206  return preflight2(ctx);
207 }
208 
209 TER
211 {
212  // Ripple if source or destination is non-native or if there are paths.
213  std::uint32_t const uTxFlags = ctx.tx.getFlags();
214  bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
215  auto const paths = ctx.tx.isFieldPresent(sfPaths);
216  auto const sendMax = ctx.tx[~sfSendMax];
217 
218  AccountID const uDstAccountID(ctx.tx[sfDestination]);
219  STAmount const saDstAmount(ctx.tx[sfAmount]);
220 
221  auto const k = keylet::account(uDstAccountID);
222  auto const sleDst = ctx.view.read(k);
223 
224  if (!sleDst)
225  {
226  // Destination account does not exist.
227  if (!saDstAmount.native())
228  {
229  JLOG(ctx.j.trace())
230  << "Delay transaction: Destination account does not exist.";
231 
232  // Another transaction could create the account and then this
233  // transaction would succeed.
234  return tecNO_DST;
235  }
236  else if (ctx.view.open() && partialPaymentAllowed)
237  {
238  // You cannot fund an account with a partial payment.
239  // Make retry work smaller, by rejecting this.
240  JLOG(ctx.j.trace()) << "Delay transaction: Partial payment not "
241  "allowed to create account.";
242 
243  // Another transaction could create the account and then this
244  // transaction would succeed.
245  return telNO_DST_PARTIAL;
246  }
247  else if (saDstAmount < STAmount(ctx.view.fees().accountReserve(0)))
248  {
249  // accountReserve is the minimum amount that an account can have.
250  // Reserve is not scaled by load.
251  JLOG(ctx.j.trace())
252  << "Delay transaction: Destination account does not exist. "
253  << "Insufficent payment to create account.";
254 
255  // TODO: dedupe
256  // Another transaction could create the account and then this
257  // transaction would succeed.
258  return tecNO_DST_INSUF_XRP;
259  }
260  }
261  else if (
262  (sleDst->getFlags() & lsfRequireDestTag) &&
264  {
265  // The tag is basically account-specific information we don't
266  // understand, but we can require someone to fill it in.
267 
268  // We didn't make this test for a newly-formed account because there's
269  // no way for this field to be set.
270  JLOG(ctx.j.trace())
271  << "Malformed transaction: DestinationTag required.";
272 
273  return tecDST_TAG_NEEDED;
274  }
275 
276  if (paths || sendMax || !saDstAmount.native())
277  {
278  // Ripple payment with at least one intermediate step and uses
279  // transitive balances.
280 
281  // Copy paths into an editable class.
282  STPathSet const spsPaths = ctx.tx.getFieldPathSet(sfPaths);
283 
284  auto pathTooBig = spsPaths.size() > MaxPathSize;
285 
286  if (!pathTooBig)
287  for (auto const& path : spsPaths)
288  if (path.size() > MaxPathLength)
289  {
290  pathTooBig = true;
291  break;
292  }
293 
294  if (ctx.view.open() && pathTooBig)
295  {
296  return telBAD_PATH_COUNT; // Too many paths for proposed ledger.
297  }
298  }
299 
300  return tesSUCCESS;
301 }
302 
303 TER
305 {
306  auto const deliverMin = ctx_.tx[~sfDeliverMin];
307 
308  // Ripple if source or destination is non-native or if there are paths.
309  std::uint32_t const uTxFlags = ctx_.tx.getFlags();
310  bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
311  bool const limitQuality = uTxFlags & tfLimitQuality;
312  bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
313  auto const paths = ctx_.tx.isFieldPresent(sfPaths);
314  auto const sendMax = ctx_.tx[~sfSendMax];
315 
316  AccountID const uDstAccountID(ctx_.tx.getAccountID(sfDestination));
317  STAmount const saDstAmount(ctx_.tx.getFieldAmount(sfAmount));
318  STAmount maxSourceAmount;
319  if (sendMax)
320  maxSourceAmount = *sendMax;
321  else if (saDstAmount.native())
322  maxSourceAmount = saDstAmount;
323  else
324  maxSourceAmount = STAmount(
325  {saDstAmount.getCurrency(), account_},
326  saDstAmount.mantissa(),
327  saDstAmount.exponent(),
328  saDstAmount < beast::zero);
329 
330  JLOG(j_.trace()) << "maxSourceAmount=" << maxSourceAmount.getFullText()
331  << " saDstAmount=" << saDstAmount.getFullText();
332 
333  // Open a ledger for editing.
334  auto const k = keylet::account(uDstAccountID);
335  SLE::pointer sleDst = view().peek(k);
336 
337  if (!sleDst)
338  {
339  std::uint32_t const seqno{
341  : 1};
342 
343  // Create the account.
344  sleDst = std::make_shared<SLE>(k);
345  sleDst->setAccountID(sfAccount, uDstAccountID);
346  sleDst->setFieldU32(sfSequence, seqno);
347 
348  view().insert(sleDst);
349  }
350  else
351  {
352  // Tell the engine that we are intending to change the destination
353  // account. The source account gets always charged a fee so it's always
354  // marked as modified.
355  view().update(sleDst);
356  }
357 
358  // Determine whether the destination requires deposit authorization.
359  bool const reqDepositAuth = sleDst->getFlags() & lsfDepositAuth &&
361 
362  bool const depositPreauth = view().rules().enabled(featureDepositPreauth);
363 
364  bool const bRipple = paths || sendMax || !saDstAmount.native();
365 
366  // If the destination has lsfDepositAuth set, then only direct XRP
367  // payments (no intermediate steps) are allowed to the destination.
368  if (!depositPreauth && bRipple && reqDepositAuth)
369  return tecNO_PERMISSION;
370 
371  if (bRipple)
372  {
373  // Ripple payment with at least one intermediate step and uses
374  // transitive balances.
375 
376  if (depositPreauth && reqDepositAuth)
377  {
378  // If depositPreauth is enabled, then an account that requires
379  // authorization has two ways to get an IOU Payment in:
380  // 1. If Account == Destination, or
381  // 2. If Account is deposit preauthorized by destination.
382  if (uDstAccountID != account_)
383  {
384  if (!view().exists(
385  keylet::depositPreauth(uDstAccountID, account_)))
386  return tecNO_PERMISSION;
387  }
388  }
389 
390  // Copy paths into an editable class.
392 
393  path::RippleCalc::Input rcInput;
394  rcInput.partialPaymentAllowed = partialPaymentAllowed;
395  rcInput.defaultPathsAllowed = defaultPathsAllowed;
396  rcInput.limitQuality = limitQuality;
397  rcInput.isLedgerOpen = view().open();
398 
400  {
401  PaymentSandbox pv(&view());
402  JLOG(j_.debug()) << "Entering RippleCalc in payment: "
403  << ctx_.tx.getTransactionID();
405  pv,
406  maxSourceAmount,
407  saDstAmount,
408  uDstAccountID,
409  account_,
410  spsPaths,
411  ctx_.app.logs(),
412  &rcInput);
413  // VFALCO NOTE We might not need to apply, depending
414  // on the TER. But always applying *should*
415  // be safe.
416  pv.apply(ctx_.rawView());
417  }
418 
419  // TODO: is this right? If the amount is the correct amount, was
420  // the delivered amount previously set?
421  if (rc.result() == tesSUCCESS && rc.actualAmountOut != saDstAmount)
422  {
423  if (deliverMin && rc.actualAmountOut < *deliverMin)
425  else
427  }
428 
429  auto terResult = rc.result();
430 
431  // Because of its overhead, if RippleCalc
432  // fails with a retry code, claim a fee
433  // instead. Maybe the user will be more
434  // careful with their path spec next time.
435  if (isTerRetry(terResult))
436  terResult = tecPATH_DRY;
437  return terResult;
438  }
439 
440  assert(saDstAmount.native());
441 
442  // Direct XRP payment.
443 
444  auto const sleSrc = view().peek(keylet::account(account_));
445  if (!sleSrc)
446  return tefINTERNAL;
447 
448  // uOwnerCount is the number of entries in this ledger for this
449  // account that require a reserve.
450  auto const uOwnerCount = sleSrc->getFieldU32(sfOwnerCount);
451 
452  // This is the total reserve in drops.
453  auto const reserve = view().fees().accountReserve(uOwnerCount);
454 
455  // mPriorBalance is the balance on the sending account BEFORE the
456  // fees were charged. We want to make sure we have enough reserve
457  // to send. Allow final spend to use reserve for fee.
458  auto const mmm = std::max(reserve, ctx_.tx.getFieldAmount(sfFee).xrp());
459 
460  if (mPriorBalance < saDstAmount.xrp() + mmm)
461  {
462  // Vote no. However the transaction might succeed, if applied in
463  // a different order.
464  JLOG(j_.trace()) << "Delay transaction: Insufficient funds: "
465  << " " << to_string(mPriorBalance) << " / "
466  << to_string(saDstAmount.xrp() + mmm) << " ("
467  << to_string(reserve) << ")";
468 
469  return tecUNFUNDED_PAYMENT;
470  }
471 
472  // The source account does have enough money. Make sure the
473  // source account has authority to deposit to the destination.
474  if (reqDepositAuth)
475  {
476  // If depositPreauth is enabled, then an account that requires
477  // authorization has three ways to get an XRP Payment in:
478  // 1. If Account == Destination, or
479  // 2. If Account is deposit preauthorized by destination, or
480  // 3. If the destination's XRP balance is
481  // a. less than or equal to the base reserve and
482  // b. the deposit amount is less than or equal to the base reserve,
483  // then we allow the deposit.
484  //
485  // Rule 3 is designed to keep an account from getting wedged
486  // in an unusable state if it sets the lsfDepositAuth flag and
487  // then consumes all of its XRP. Without the rule if an
488  // account with lsfDepositAuth set spent all of its XRP, it
489  // would be unable to acquire more XRP required to pay fees.
490  //
491  // We choose the base reserve as our bound because it is
492  // a small number that seldom changes but is always sufficient
493  // to get the account un-wedged.
494  if (uDstAccountID != account_)
495  {
496  if (!view().exists(keylet::depositPreauth(uDstAccountID, account_)))
497  {
498  // Get the base reserve.
499  XRPAmount const dstReserve{view().fees().accountReserve(0)};
500 
501  if (saDstAmount > dstReserve ||
502  sleDst->getFieldAmount(sfBalance) > dstReserve)
503  return tecNO_PERMISSION;
504  }
505  }
506  }
507 
508  // Do the arithmetic for the transfer and make the ledger change.
509  sleSrc->setFieldAmount(sfBalance, mSourceBalance - saDstAmount);
510  sleDst->setFieldAmount(
511  sfBalance, sleDst->getFieldAmount(sfBalance) + saDstAmount);
512 
513  // Re-arm the password change fee if we can and need to.
514  if ((sleDst->getFlags() & lsfPasswordSpent))
515  sleDst->clearFlag(lsfPasswordSpent);
516 
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:138
ripple::sfOwnerCount
const SF_UINT32 sfOwnerCount
ripple::sfPaths
const SField sfPaths
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:108
ripple::tfNoRippleDirect
const std::uint32_t tfNoRippleDirect
Definition: TxFlags.h:84
ripple::lsfPasswordSpent
@ lsfPasswordSpent
Definition: LedgerFormats.h:103
ripple::temBAD_SEND_XRP_MAX
@ temBAD_SEND_XRP_MAX
Definition: TER.h:95
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:150
ripple::sfSendMax
const SF_AMOUNT sfSendMax
std::shared_ptr< STLedgerEntry >
ripple::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:57
ripple::tfPartialPayment
const std::uint32_t tfPartialPayment
Definition: TxFlags.h:85
ripple::temBAD_CURRENCY
@ temBAD_CURRENCY
Definition: TER.h:85
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:61
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::ApplyView::peek
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
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:90
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:580
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:192
ripple::featureDepositPreauth
const uint256 featureDepositPreauth
Definition: Feature.cpp:174
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::tfPaymentMask
const std::uint32_t tfPaymentMask
Definition: TxFlags.h:87
ripple::path::RippleCalc::Input
Definition: RippleCalc.h:46
ripple::featureDepositAuth
const uint256 featureDepositAuth
Definition: Feature.cpp:169
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:270
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
ripple::isLegalNet
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:385
ripple::ApplyContext::rawView
RawView & rawView()
Definition: ApplyContext.h:67
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::Payment::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Payment.cpp:49
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:39
ripple::STPathSet
Definition: STPathSet.h:309
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:299
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:56
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:114
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
Definition: Feature.cpp:182
ripple::isTerRetry
bool isTerRetry(TER x)
Definition: TER.h:574
ripple::tecNO_DST_INSUF_XRP
@ tecNO_DST_INSUF_XRP
Definition: TER.h:252
ripple::base_uint< 160, detail::AccountIDTag >
ripple::sfDeliverMin
const SF_AMOUNT sfDeliverMin
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:106
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:487
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:177
ripple::Payment::makeTxConsequences
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
Definition: Payment.cpp:34
ripple::path::RippleCalc::Input::isLedgerOpen
bool isLedgerOpen
Definition: RippleCalc.h:53
ripple::path::RippleCalc::Input::defaultPathsAllowed
bool defaultPathsAllowed
Definition: RippleCalc.h:51
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:439
ripple::temBAD_SEND_XRP_PARTIAL
@ temBAD_SEND_XRP_PARTIAL
Definition: TER.h:97
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:134
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:562
ripple::temBAD_SEND_XRP_PATHS
@ temBAD_SEND_XRP_PATHS
Definition: TER.h:98
ripple::TERSubset
Definition: TER.h:326
ripple::Payment::MaxPathLength
static const std::size_t MaxPathLength
Definition: Payment.h:38
ripple::temDST_NEEDED
@ temDST_NEEDED
Definition: TER.h:104
ripple::STAmount
Definition: STAmount.h:42
ripple::tecUNFUNDED_PAYMENT
@ tecUNFUNDED_PAYMENT
Definition: TER.h:246
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:454
ripple::Application::logs
virtual Logs & logs()=0
ripple::STTx
Definition: STTx.h:42
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:84
ripple::ApplyContext::deliver
void deliver(STAmount const &amount)
Sets the DeliveredAmount field in the metadata.
Definition: ApplyContext.h:74
ripple::path::RippleCalc::Output::actualAmountOut
STAmount actualAmountOut
Definition: RippleCalc.h:63
ripple::temBAD_SEND_XRP_NO_DIRECT
@ temBAD_SEND_XRP_NO_DIRECT
Definition: TER.h:96
ripple::telBAD_PATH_COUNT
@ telBAD_PATH_COUNT
Definition: TER.h:53
std::uint32_t
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:103
ripple::path::RippleCalc::Output
Definition: RippleCalc.h:55
ripple::tecPATH_PARTIAL
@ tecPATH_PARTIAL
Definition: TER.h:243
ripple::temREDUNDANT
@ temREDUNDANT
Definition: TER.h:107
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:59
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:204
ripple::path::RippleCalc::Output::result
TER result() const
Definition: RippleCalc.h:77
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:104
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:117
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:53
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:182
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::Payment::MaxPathSize
static const std::size_t MaxPathSize
Definition: Payment.h:35
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:108
ripple::PaymentSandbox::apply
void apply(RawView &to)
Apply changes to base view.
Definition: PaymentSandbox.cpp:255
ripple::Fees::accountReserve
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: ReadView.h:66
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:260
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:197
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:401
ripple::tfLimitQuality
const std::uint32_t tfLimitQuality
Definition: TxFlags.h:86
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:93
ripple::path::RippleCalc::rippleCalculate
static Output rippleCalculate(PaymentSandbox &view, STAmount const &saMaxAmountReq, STAmount const &saDstAmountReq, AccountID const &uDstAccountID, AccountID const &uSrcAccountID, STPathSet const &spsPaths, Logs &l, Input const *const pInputs=nullptr)
Definition: RippleCalc.cpp:32
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:266
ripple::Transactor::mSourceBalance
XRPAmount mSourceBalance
Definition: Transactor.h:94
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::path::RippleCalc::Input::partialPaymentAllowed
bool partialPaymentAllowed
Definition: RippleCalc.h:50
ripple::STPathSet::size
std::vector< STPath >::size_type size() const
Definition: STPathSet.h:381
ripple::tecPATH_DRY
@ tecPATH_DRY
Definition: TER.h:255
ripple::Payment::doApply
TER doApply() override
Definition: Payment.cpp:304
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:89
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::path::RippleCalc::Output::setResult
void setResult(TER const value)
Definition: RippleCalc.h:82
ripple::sfFee
const SF_AMOUNT sfFee
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:36
ripple::telNO_DST_PARTIAL
@ telNO_DST_PARTIAL
Definition: TER.h:57
std::max
T max(T... args)
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:32
ripple::path::RippleCalc::Input::limitQuality
bool limitQuality
Definition: RippleCalc.h:52
ripple::temBAD_SEND_XRP_LIMIT
@ temBAD_SEND_XRP_LIMIT
Definition: TER.h:94
ripple::STObject::getFieldPathSet
STPathSet const & getFieldPathSet(SField const &field) const
Definition: STObject.cpp:583
ripple::Payment::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: Payment.cpp:210
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::ReadView::open
virtual bool open() const =0
Returns true if this reflects an open ledger.
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:216
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:92
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:576
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:251
ripple::XRPAmount
Definition: XRPAmount.h:46