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