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/tx/impl/Payment.h>
21 #include <ripple/app/paths/RippleCalc.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/core/Config.h>
24 #include <ripple/protocol/Feature.h>
25 #include <ripple/protocol/jss.h>
26 #include <ripple/protocol/st.h>
27 #include <ripple/protocol/TxFlags.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(), 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 " << 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 " << jss::DeliverMin.c_str() << ".";
174  return temBAD_AMOUNT;
175  }
176 
177  auto const dMin = *deliverMin;
178  if (!isLegalNet(dMin) || dMin <= beast::zero)
179  {
180  JLOG(j.trace()) << "Malformed transaction: Invalid " <<
181  jss::DeliverMin.c_str() << " amount. " <<
182  dMin.getFullText();
183  return temBAD_AMOUNT;
184  }
185  if (dMin.issue() != saDstAmount.issue())
186  {
187  JLOG(j.trace()) << "Malformed transaction: Dst issue differs "
188  "from " << jss::DeliverMin.c_str() << ". " <<
189  dMin.getFullText();
190  return temBAD_AMOUNT;
191  }
192  if (dMin > saDstAmount)
193  {
194  JLOG(j.trace()) << "Malformed transaction: Dst amount less than " <<
195  jss::DeliverMin.c_str() << ". " <<
196  dMin.getFullText();
197  return temBAD_AMOUNT;
198  }
199  }
200 
201  return preflight2 (ctx);
202 }
203 
204 TER
206 {
207  // Ripple if source or destination is non-native or if there are paths.
208  std::uint32_t const uTxFlags = ctx.tx.getFlags();
209  bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
210  auto const paths = ctx.tx.isFieldPresent(sfPaths);
211  auto const sendMax = ctx.tx[~sfSendMax];
212 
213  AccountID const uDstAccountID(ctx.tx[sfDestination]);
214  STAmount const saDstAmount(ctx.tx[sfAmount]);
215 
216  auto const k = keylet::account(uDstAccountID);
217  auto const sleDst = ctx.view.read(k);
218 
219  if (!sleDst)
220  {
221  // Destination account does not exist.
222  if (!saDstAmount.native())
223  {
224  JLOG(ctx.j.trace()) <<
225  "Delay transaction: Destination account does not exist.";
226 
227  // Another transaction could create the account and then this
228  // transaction would succeed.
229  return tecNO_DST;
230  }
231  else if (ctx.view.open()
232  && partialPaymentAllowed)
233  {
234  // You cannot fund an account with a partial payment.
235  // Make retry work smaller, by rejecting this.
236  JLOG(ctx.j.trace()) <<
237  "Delay transaction: Partial payment not allowed to create account.";
238 
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 ((sleDst->getFlags() & lsfRequireDestTag) &&
260  {
261  // The tag is basically account-specific information we don't
262  // understand, but we can require someone to fill it in.
263 
264  // We didn't make this test for a newly-formed account because there's
265  // no way for this field to be set.
266  JLOG(ctx.j.trace()) << "Malformed transaction: DestinationTag required.";
267 
268  return tecDST_TAG_NEEDED;
269  }
270 
271  if (paths || sendMax || !saDstAmount.native())
272  {
273  // Ripple payment with at least one intermediate step and uses
274  // transitive balances.
275 
276  // Copy paths into an editable class.
277  STPathSet const spsPaths = ctx.tx.getFieldPathSet(sfPaths);
278 
279  auto pathTooBig = spsPaths.size() > MaxPathSize;
280 
281  if(!pathTooBig)
282  for (auto const& path : spsPaths)
283  if (path.size() > MaxPathLength)
284  {
285  pathTooBig = true;
286  break;
287  }
288 
289  if (ctx.view.open() && pathTooBig)
290  {
291  return telBAD_PATH_COUNT; // Too many paths for proposed ledger.
292  }
293  }
294 
295  return tesSUCCESS;
296 }
297 
298 
299 TER
301 {
302  auto const deliverMin = ctx_.tx[~sfDeliverMin];
303 
304  // Ripple if source or destination is non-native or if there are paths.
305  std::uint32_t const uTxFlags = ctx_.tx.getFlags ();
306  bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
307  bool const limitQuality = uTxFlags & tfLimitQuality;
308  bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
309  auto const paths = ctx_.tx.isFieldPresent(sfPaths);
310  auto const sendMax = ctx_.tx[~sfSendMax];
311 
312  AccountID const uDstAccountID (ctx_.tx.getAccountID (sfDestination));
313  STAmount const saDstAmount (ctx_.tx.getFieldAmount (sfAmount));
314  STAmount maxSourceAmount;
315  if (sendMax)
316  maxSourceAmount = *sendMax;
317  else if (saDstAmount.native ())
318  maxSourceAmount = saDstAmount;
319  else
320  maxSourceAmount = STAmount (
321  {saDstAmount.getCurrency (), account_},
322  saDstAmount.mantissa(), saDstAmount.exponent (),
323  saDstAmount < beast::zero);
324 
325  JLOG(j_.trace()) <<
326  "maxSourceAmount=" << maxSourceAmount.getFullText () <<
327  " saDstAmount=" << saDstAmount.getFullText ();
328 
329  // Open a ledger for editing.
330  auto const k = keylet::account(uDstAccountID);
331  SLE::pointer sleDst = view().peek (k);
332 
333  if (!sleDst)
334  {
335  std::uint32_t const seqno {
337  view().seq() : 1};
338 
339  // Create the account.
340  sleDst = std::make_shared<SLE>(k);
341  sleDst->setAccountID(sfAccount, uDstAccountID);
342  sleDst->setFieldU32(sfSequence, seqno);
343 
344  view().insert(sleDst);
345  }
346  else
347  {
348  // Tell the engine that we are intending to change the destination
349  // account. The source account gets always charged a fee so it's always
350  // marked as modified.
351  view().update (sleDst);
352  }
353 
354  // Determine whether the destination requires deposit authorization.
355  bool const reqDepositAuth = sleDst->getFlags() & lsfDepositAuth &&
357 
358  bool const depositPreauth = view().rules().enabled(featureDepositPreauth);
359 
360  bool const bRipple = paths || sendMax || !saDstAmount.native ();
361 
362  // If the destination has lsfDepositAuth set, then only direct XRP
363  // payments (no intermediate steps) are allowed to the destination.
364  if (!depositPreauth && bRipple && reqDepositAuth)
365  return tecNO_PERMISSION;
366 
367  if (bRipple)
368  {
369  // Ripple payment with at least one intermediate step and uses
370  // transitive balances.
371 
372  if (depositPreauth && reqDepositAuth)
373  {
374  // If depositPreauth is enabled, then an account that requires
375  // authorization has two ways to get an IOU Payment in:
376  // 1. If Account == Destination, or
377  // 2. If Account is deposit preauthorized by destination.
378  if (uDstAccountID != account_)
379  {
380  if (! view().exists (
381  keylet::depositPreauth (uDstAccountID, account_)))
382  return tecNO_PERMISSION;
383  }
384  }
385 
386  // Copy paths into an editable class.
387  STPathSet spsPaths = ctx_.tx.getFieldPathSet (sfPaths);
388 
389  path::RippleCalc::Input rcInput;
390  rcInput.partialPaymentAllowed = partialPaymentAllowed;
391  rcInput.defaultPathsAllowed = defaultPathsAllowed;
392  rcInput.limitQuality = limitQuality;
393  rcInput.isLedgerOpen = view().open();
394 
396  {
397  PaymentSandbox pv(&view());
398  JLOG(j_.debug())
399  << "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 &&
419  rc.actualAmountOut != saDstAmount)
420  {
421  if (deliverMin && rc.actualAmountOut <
422  *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,
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 (
497  keylet::depositPreauth (uDstAccountID, account_)))
498  {
499  // Get the base reserve.
500  XRPAmount const dstReserve {view().fees().accountReserve (0)};
501 
502  if (saDstAmount > dstReserve ||
503  sleDst->getFieldAmount (sfBalance) > dstReserve)
504  return tecNO_PERMISSION;
505  }
506  }
507  }
508 
509  // Do the arithmetic for the transfer and make the ledger change.
510  sleSrc->setFieldAmount(sfBalance, mSourceBalance - saDstAmount);
511  sleDst->setFieldAmount(
512  sfBalance, sleDst->getFieldAmount(sfBalance) + saDstAmount);
513 
514  // Re-arm the password change fee if we can and need to.
515  if ((sleDst->getFlags() & lsfPasswordSpent))
516  sleDst->clearFlag(lsfPasswordSpent);
517 
518  return tesSUCCESS;
519 }
520 
521 } // 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:123
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:83
ripple::lsfPasswordSpent
@ lsfPasswordSpent
Definition: LedgerFormats.h:132
ripple::temBAD_SEND_XRP_MAX
@ temBAD_SEND_XRP_MAX
Definition: TER.h:98
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:153
std::shared_ptr< STLedgerEntry >
ripple::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:53
ripple::tfPartialPayment
const std::uint32_t tfPartialPayment
Definition: TxFlags.h:84
ripple::temBAD_CURRENCY
@ temBAD_CURRENCY
Definition: TER.h:88
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:57
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:287
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:110
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:82
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:501
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:155
ripple::featureDepositPreauth
const uint256 featureDepositPreauth
Definition: Feature.cpp:169
ripple::sfSequence
const SF_U32 sfSequence(access, STI_UINT32, 4, "Sequence")
Definition: SField.h:340
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:86
ripple::path::RippleCalc::Input
Definition: RippleCalc.h:46
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:460
ripple::featureDepositAuth
const uint256 featureDepositAuth
Definition: Feature.cpp:164
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:274
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:325
ripple::ApplyContext::rawView
RawView & rawView()
Definition: ApplyContext.h:64
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::sfAmount
const SF_Amount sfAmount(access, STI_AMOUNT, 1, "Amount")
Definition: SField.h:423
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:349
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:39
ripple::STPathSet
Definition: STPathSet.h:297
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:294
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:140
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:44
ripple::keylet::depositPreauth
static const depositPreauth_t depositPreauth
Definition: Indexes.h:269
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
Definition: Feature.cpp:177
ripple::sfDestinationTag
const SF_U32 sfDestinationTag(access, STI_UINT32, 14, "DestinationTag")
Definition: SField.h:350
ripple::isTerRetry
bool isTerRetry(TER x)
Definition: TER.h:496
ripple::tecNO_DST_INSUF_XRP
@ tecNO_DST_INSUF_XRP
Definition: TER.h:256
ripple::base_uint< 160, detail::AccountIDTag >
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:469
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:152
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:429
ripple::temBAD_SEND_XRP_PARTIAL
@ temBAD_SEND_XRP_PARTIAL
Definition: TER.h:100
ripple::keylet::account
static const account_t account
Definition: Indexes.h:116
ripple::sfSendMax
const SF_Amount sfSendMax(access, STI_AMOUNT, 9, "SendMax")
Definition: SField.h:431
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:537
ripple::temBAD_SEND_XRP_PATHS
@ temBAD_SEND_XRP_PATHS
Definition: TER.h:101
ripple::TERSubset
Definition: TER.h:311
ripple::Payment::MaxPathLength
static const std::size_t MaxPathLength
Definition: Payment.h:39
ripple::temDST_NEEDED
@ temDST_NEEDED
Definition: TER.h:107
ripple::STAmount
Definition: STAmount.h:42
ripple::tecUNFUNDED_PAYMENT
@ tecUNFUNDED_PAYMENT
Definition: TER.h:250
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:439
ripple::Application::logs
virtual Logs & logs()=0
ripple::STTx
Definition: STTx.h:43
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:71
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:55
std::uint32_t
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:107
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:247
ripple::temREDUNDANT
@ temREDUNDANT
Definition: TER.h:110
ripple::sfFee
const SF_Amount sfFee(access, STI_AMOUNT, 8, "Fee")
Definition: SField.h:430
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:55
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:159
ripple::path::RippleCalc::Output::result
TER result() const
Definition: RippleCalc.h:77
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:133
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:120
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:49
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:153
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:36
ripple::sfBalance
const SF_Amount sfBalance(access, STI_AMOUNT, 2, "Balance")
Definition: SField.h:424
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:98
ripple::sfDeliverMin
const SF_Amount sfDeliverMin(access, STI_AMOUNT, 10, "DeliverMin")
Definition: SField.h:432
ripple::PaymentSandbox::apply
void apply(RawView &to)
Apply changes to base view.
Definition: PaymentSandbox.cpp:245
ripple::Fees::accountReserve
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
Definition: ReadView.h:64
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:258
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:156
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:392
ripple::tfLimitQuality
const std::uint32_t tfLimitQuality
Definition: TxFlags.h:85
ripple::Transactor::mPriorBalance
XRPAmount mPriorBalance
Definition: Transactor.h:85
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:270
ripple::Transactor::mSourceBalance
XRPAmount mSourceBalance
Definition: Transactor.h:86
ripple::sfPaths
const SField sfPaths(access, STI_PATHSET, 1, "Paths")
Definition: SField.h:470
ripple::path::RippleCalc::Input::partialPaymentAllowed
bool partialPaymentAllowed
Definition: RippleCalc.h:50
ripple::STPathSet::size
std::vector< STPath >::size_type size() const
Definition: STPathSet.h:371
ripple::tecPATH_DRY
@ tecPATH_DRY
Definition: TER.h:259
ripple::Payment::doApply
TER doApply() override
Definition: Payment.cpp:300
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:81
ripple::Transactor::account_
AccountID account_
Definition: Transactor.h:84
ripple::sfDestination
const SF_Account sfDestination(access, STI_ACCOUNT, 3, "Destination")
Definition: SField.h:462
beast::Journal::debug
Stream debug() const
Definition: Journal.h:292
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:59
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:97
ripple::STObject::getFieldPathSet
STPathSet const & getFieldPathSet(SField const &field) const
Definition: STObject.cpp:555
ripple::Payment::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: Payment.cpp:205
ripple::ReadView::open
virtual bool open() const =0
Returns true if this reflects an open ledger.
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:219
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:549
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:45
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:255
ripple::XRPAmount
Definition: XRPAmount.h:46