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