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  // Payment with at least one intermediate step and uses transitive balances.
274  if ((paths || sendMax || !saDstAmount.native()) && ctx.view.open())
275  {
276  STPathSet const& paths = ctx.tx.getFieldPathSet(sfPaths);
277 
278  if (paths.size() > MaxPathSize ||
279  std::any_of(paths.begin(), paths.end(), [](STPath const& path) {
280  return path.size() > MaxPathLength;
281  }))
282  {
283  return telBAD_PATH_COUNT;
284  }
285  }
286 
287  return tesSUCCESS;
288 }
289 
290 TER
292 {
293  auto const deliverMin = ctx_.tx[~sfDeliverMin];
294 
295  // Ripple if source or destination is non-native or if there are paths.
296  std::uint32_t const uTxFlags = ctx_.tx.getFlags();
297  bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
298  bool const limitQuality = uTxFlags & tfLimitQuality;
299  bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
300  auto const paths = ctx_.tx.isFieldPresent(sfPaths);
301  auto const sendMax = ctx_.tx[~sfSendMax];
302 
303  AccountID const uDstAccountID(ctx_.tx.getAccountID(sfDestination));
304  STAmount const saDstAmount(ctx_.tx.getFieldAmount(sfAmount));
305  STAmount maxSourceAmount;
306  if (sendMax)
307  maxSourceAmount = *sendMax;
308  else if (saDstAmount.native())
309  maxSourceAmount = saDstAmount;
310  else
311  maxSourceAmount = STAmount(
312  {saDstAmount.getCurrency(), account_},
313  saDstAmount.mantissa(),
314  saDstAmount.exponent(),
315  saDstAmount < beast::zero);
316 
317  JLOG(j_.trace()) << "maxSourceAmount=" << maxSourceAmount.getFullText()
318  << " saDstAmount=" << saDstAmount.getFullText();
319 
320  // Open a ledger for editing.
321  auto const k = keylet::account(uDstAccountID);
322  SLE::pointer sleDst = view().peek(k);
323 
324  if (!sleDst)
325  {
326  std::uint32_t const seqno{
328  : 1};
329 
330  // Create the account.
331  sleDst = std::make_shared<SLE>(k);
332  sleDst->setAccountID(sfAccount, uDstAccountID);
333  sleDst->setFieldU32(sfSequence, seqno);
334 
335  view().insert(sleDst);
336  }
337  else
338  {
339  // Tell the engine that we are intending to change the destination
340  // account. The source account gets always charged a fee so it's always
341  // marked as modified.
342  view().update(sleDst);
343  }
344 
345  // Determine whether the destination requires deposit authorization.
346  bool const reqDepositAuth = sleDst->getFlags() & lsfDepositAuth &&
348 
349  bool const depositPreauth = view().rules().enabled(featureDepositPreauth);
350 
351  bool const bRipple = paths || sendMax || !saDstAmount.native();
352 
353  // If the destination has lsfDepositAuth set, then only direct XRP
354  // payments (no intermediate steps) are allowed to the destination.
355  if (!depositPreauth && bRipple && reqDepositAuth)
356  return tecNO_PERMISSION;
357 
358  if (bRipple)
359  {
360  // Ripple payment with at least one intermediate step and uses
361  // transitive balances.
362 
363  if (depositPreauth && reqDepositAuth)
364  {
365  // If depositPreauth is enabled, then an account that requires
366  // authorization has two ways to get an IOU Payment in:
367  // 1. If Account == Destination, or
368  // 2. If Account is deposit preauthorized by destination.
369  if (uDstAccountID != account_)
370  {
371  if (!view().exists(
372  keylet::depositPreauth(uDstAccountID, account_)))
373  return tecNO_PERMISSION;
374  }
375  }
376 
377  path::RippleCalc::Input rcInput;
378  rcInput.partialPaymentAllowed = partialPaymentAllowed;
379  rcInput.defaultPathsAllowed = defaultPathsAllowed;
380  rcInput.limitQuality = limitQuality;
381  rcInput.isLedgerOpen = view().open();
382 
384  {
385  PaymentSandbox pv(&view());
386  JLOG(j_.debug()) << "Entering RippleCalc in payment: "
387  << ctx_.tx.getTransactionID();
389  pv,
390  maxSourceAmount,
391  saDstAmount,
392  uDstAccountID,
393  account_,
395  ctx_.app.logs(),
396  &rcInput);
397  // VFALCO NOTE We might not need to apply, depending
398  // on the TER. But always applying *should*
399  // be safe.
400  pv.apply(ctx_.rawView());
401  }
402 
403  // TODO: is this right? If the amount is the correct amount, was
404  // the delivered amount previously set?
405  if (rc.result() == tesSUCCESS && rc.actualAmountOut != saDstAmount)
406  {
407  if (deliverMin && rc.actualAmountOut < *deliverMin)
409  else
411  }
412 
413  auto terResult = rc.result();
414 
415  // Because of its overhead, if RippleCalc
416  // fails with a retry code, claim a fee
417  // instead. Maybe the user will be more
418  // careful with their path spec next time.
419  if (isTerRetry(terResult))
420  terResult = tecPATH_DRY;
421  return terResult;
422  }
423 
424  assert(saDstAmount.native());
425 
426  // Direct XRP payment.
427 
428  auto const sleSrc = view().peek(keylet::account(account_));
429  if (!sleSrc)
430  return tefINTERNAL;
431 
432  // uOwnerCount is the number of entries in this ledger for this
433  // account that require a reserve.
434  auto const uOwnerCount = sleSrc->getFieldU32(sfOwnerCount);
435 
436  // This is the total reserve in drops.
437  auto const reserve = view().fees().accountReserve(uOwnerCount);
438 
439  // mPriorBalance is the balance on the sending account BEFORE the
440  // fees were charged. We want to make sure we have enough reserve
441  // to send. Allow final spend to use reserve for fee.
442  auto const mmm = std::max(reserve, ctx_.tx.getFieldAmount(sfFee).xrp());
443 
444  if (mPriorBalance < saDstAmount.xrp() + mmm)
445  {
446  // Vote no. However the transaction might succeed, if applied in
447  // a different order.
448  JLOG(j_.trace()) << "Delay transaction: Insufficient funds: "
449  << " " << to_string(mPriorBalance) << " / "
450  << to_string(saDstAmount.xrp() + mmm) << " ("
451  << to_string(reserve) << ")";
452 
453  return tecUNFUNDED_PAYMENT;
454  }
455 
456  // AMMs can never receive an XRP payment.
457  // Must use AMMDeposit transaction instead.
458  if (sleDst->isFieldPresent(sfAMMID))
459  return tecNO_PERMISSION;
460 
461  // The source account does have enough money. Make sure the
462  // source account has authority to deposit to the destination.
463  if (reqDepositAuth)
464  {
465  // If depositPreauth is enabled, then an account that requires
466  // authorization has three ways to get an XRP Payment in:
467  // 1. If Account == Destination, or
468  // 2. If Account is deposit preauthorized by destination, or
469  // 3. If the destination's XRP balance is
470  // a. less than or equal to the base reserve and
471  // b. the deposit amount is less than or equal to the base reserve,
472  // then we allow the deposit.
473  //
474  // Rule 3 is designed to keep an account from getting wedged
475  // in an unusable state if it sets the lsfDepositAuth flag and
476  // then consumes all of its XRP. Without the rule if an
477  // account with lsfDepositAuth set spent all of its XRP, it
478  // would be unable to acquire more XRP required to pay fees.
479  //
480  // We choose the base reserve as our bound because it is
481  // a small number that seldom changes but is always sufficient
482  // to get the account un-wedged.
483  if (uDstAccountID != account_)
484  {
485  if (!view().exists(keylet::depositPreauth(uDstAccountID, account_)))
486  {
487  // Get the base reserve.
488  XRPAmount const dstReserve{view().fees().accountReserve(0)};
489 
490  if (saDstAmount > dstReserve ||
491  sleDst->getFieldAmount(sfBalance) > dstReserve)
492  return tecNO_PERMISSION;
493  }
494  }
495  }
496 
497  // Do the arithmetic for the transfer and make the ledger change.
498  sleSrc->setFieldAmount(sfBalance, mSourceBalance - saDstAmount);
499  sleDst->setFieldAmount(
500  sfBalance, sleDst->getFieldAmount(sfBalance) + saDstAmount);
501 
502  // Re-arm the password change fee if we can and need to.
503  if ((sleDst->getFlags() & lsfPasswordSpent))
504  sleDst->clearFlag(lsfPasswordSpent);
505 
506  return tesSUCCESS;
507 }
508 
509 } // 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:129
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:133
ripple::lsfPasswordSpent
@ lsfPasswordSpent
Definition: LedgerFormats.h:254
ripple::temBAD_SEND_XRP_MAX
@ temBAD_SEND_XRP_MAX
Definition: TER.h:99
ripple::tefINTERNAL
@ tefINTERNAL
Definition: TER.h:167
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:89
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:60
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:308
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:350
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:636
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:344
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:289
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:449
ripple::ApplyContext::rawView
RawView & rawView()
Definition: ApplyContext.h:67
std::any_of
T any_of(T... args)
ripple::Payment::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: Payment.cpp:47
ripple::STPathSet::end
std::vector< STPath >::const_iterator end() const
Definition: STPathSet.h:491
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:345
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:81
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:265
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
ripple::tfLimitQuality
constexpr std::uint32_t tfLimitQuality
Definition: TxFlags.h:104
ripple::isTerRetry
bool isTerRetry(TER x)
Definition: TER.h:630
ripple::tecNO_DST_INSUF_XRP
@ tecNO_DST_INSUF_XRP
Definition: TER.h:271
ripple::base_uint< 160, detail::AccountIDTag >
ripple::sfDeliverMin
const SF_AMOUNT sfDeliverMin
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:110
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:559
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:326
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::maxAmount
constexpr T maxAmount()
Definition: AMMLiquidity.cpp:98
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:103
ripple::temBAD_SEND_XRP_PARTIAL
@ temBAD_SEND_XRP_PARTIAL
Definition: TER.h:101
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:142
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:604
ripple::temBAD_SEND_XRP_PATHS
@ temBAD_SEND_XRP_PATHS
Definition: TER.h:102
ripple::TERSubset
Definition: TER.h:379
ripple::temDST_NEEDED
@ temDST_NEEDED
Definition: TER.h:108
ripple::STAmount
Definition: STAmount.h:46
ripple::tecUNFUNDED_PAYMENT
@ tecUNFUNDED_PAYMENT
Definition: TER.h:265
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:496
ripple::Application::logs
virtual Logs & logs()=0
ripple::STTx
Definition: STTx.h:46
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:88
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:100
ripple::telBAD_PATH_COUNT
@ telBAD_PATH_COUNT
Definition: TER.h:54
std::uint32_t
ripple::path::RippleCalc::Output
Definition: RippleCalc.h:55
ripple::tecPATH_PARTIAL
@ tecPATH_PARTIAL
Definition: TER.h:262
ripple::temREDUNDANT
@ temREDUNDANT
Definition: TER.h:111
ripple::sfAMMID
const SF_UINT256 sfAMMID
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:255
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:193
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:332
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::STPathSet::begin
std::vector< STPath >::const_iterator begin() const
Definition: STPathSet.h:485
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: protocol/Fees.h:49
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:122
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:443
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:285
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:274
ripple::Payment::doApply
TER doApply() override
Definition: Payment.cpp:291
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:88
beast::Journal::debug
Stream debug() const
Definition: Journal.h:314
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:105
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:35
ripple::telNO_DST_PARTIAL
@ telNO_DST_PARTIAL
Definition: TER.h:58
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:98
ripple::STObject::getFieldPathSet
STPathSet const & getFieldPathSet(SField const &field) const
Definition: STObject.cpp:625
ripple::STPath
Definition: STPathSet.h:118
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:296
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:356
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:235
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:91
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:618
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:270
ripple::tfNoRippleDirect
constexpr std::uint32_t tfNoRippleDirect
Definition: TxFlags.h:102
ripple::XRPAmount
Definition: XRPAmount.h:46