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