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>
42 return maxAmount.
native() ? maxAmount.
xrp() : beast::zero;
62 JLOG(j.trace()) <<
"Malformed transaction: "
63 <<
"Invalid flags set.";
70 bool const bPaths = tx.isFieldPresent(
sfPaths);
71 bool const bMax = tx.isFieldPresent(
sfSendMax);
76 auto const account = tx.getAccountID(
sfAccount);
79 maxSourceAmount = tx.getFieldAmount(
sfSendMax);
80 else if (saDstAmount.
native())
81 maxSourceAmount = saDstAmount;
87 saDstAmount < beast::zero);
89 auto const& uSrcCurrency = maxSourceAmount.
getCurrency();
90 auto const& uDstCurrency = saDstAmount.
getCurrency();
93 bool const bXRPDirect = uSrcCurrency.
isZero() && uDstCurrency.isZero();
102 JLOG(j.trace()) <<
"Malformed transaction: "
103 <<
"Payment destination account not specified.";
106 if (bMax && maxSourceAmount <= beast::zero)
108 JLOG(j.trace()) <<
"Malformed transaction: "
109 <<
"bad max amount: " << maxSourceAmount.
getFullText();
112 if (saDstAmount <= beast::zero)
114 JLOG(j.trace()) <<
"Malformed transaction: "
115 <<
"bad dst amount: " << saDstAmount.
getFullText();
120 JLOG(j.trace()) <<
"Malformed transaction: "
124 if (account == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
128 JLOG(j.trace()) <<
"Malformed transaction: "
129 <<
"Redundant payment from " <<
to_string(account)
130 <<
" to self without path for "
134 if (bXRPDirect && bMax)
137 JLOG(j.trace()) <<
"Malformed transaction: "
138 <<
"SendMax specified for XRP to XRP.";
141 if (bXRPDirect && bPaths)
144 JLOG(j.trace()) <<
"Malformed transaction: "
145 <<
"Paths specified for XRP to XRP.";
148 if (bXRPDirect && partialPaymentAllowed)
151 JLOG(j.trace()) <<
"Malformed transaction: "
152 <<
"Partial payment specified for XRP to XRP.";
155 if (bXRPDirect && limitQuality)
158 JLOG(j.trace()) <<
"Malformed transaction: "
159 <<
"Limit quality specified for XRP to XRP.";
162 if (bXRPDirect && !defaultPathsAllowed)
165 JLOG(j.trace()) <<
"Malformed transaction: "
166 <<
"No ripple direct specified for XRP to XRP.";
173 if (!partialPaymentAllowed)
175 JLOG(j.trace()) <<
"Malformed transaction: Partial payment not "
177 << jss::DeliverMin.c_str() <<
".";
181 auto const dMin = *deliverMin;
185 <<
"Malformed transaction: Invalid " << jss::DeliverMin.c_str()
186 <<
" amount. " << dMin.getFullText();
189 if (dMin.issue() != saDstAmount.
issue())
192 <<
"Malformed transaction: Dst issue differs "
194 << jss::DeliverMin.c_str() <<
". " << dMin.getFullText();
197 if (dMin > saDstAmount)
200 <<
"Malformed transaction: Dst amount less than "
201 << jss::DeliverMin.c_str() <<
". " << dMin.getFullText();
222 auto const sleDst = ctx.
view.
read(k);
227 if (!saDstAmount.
native())
230 <<
"Delay transaction: Destination account does not exist.";
236 else if (ctx.
view.
open() && partialPaymentAllowed)
240 JLOG(ctx.
j.
trace()) <<
"Delay transaction: Partial payment not "
241 "allowed to create account.";
252 <<
"Delay transaction: Destination account does not exist. "
253 <<
"Insufficent payment to create account.";
271 <<
"Malformed transaction: DestinationTag required.";
276 if (paths || sendMax || !saDstAmount.
native())
287 for (
auto const& path : spsPaths)
320 maxSourceAmount = *sendMax;
321 else if (saDstAmount.
native())
322 maxSourceAmount = saDstAmount;
328 saDstAmount < beast::zero);
344 sleDst = std::make_shared<SLE>(k);
345 sleDst->setAccountID(
sfAccount, uDstAccountID);
359 bool const reqDepositAuth = sleDst->getFlags() &
lsfDepositAuth &&
364 bool const bRipple = paths || sendMax || !saDstAmount.
native();
368 if (!depositPreauth && bRipple && reqDepositAuth)
376 if (depositPreauth && reqDepositAuth)
402 JLOG(
j_.
debug()) <<
"Entering RippleCalc in payment: "
429 auto terResult = rc.
result();
440 assert(saDstAmount.
native());
450 auto const uOwnerCount = sleSrc->getFieldU32(
sfOwnerCount);
464 JLOG(
j_.
trace()) <<
"Delay transaction: Insufficient funds: "
501 if (saDstAmount > dstReserve ||
502 sleDst->getFieldAmount(
sfBalance) > dstReserve)
510 sleDst->setFieldAmount(
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
const SF_UINT32 sfOwnerCount
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
const std::uint32_t tfNoRippleDirect
const SF_AMOUNT sfSendMax
const std::uint32_t tfPartialPayment
Stream trace() const
Severity stream access functions.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
const SF_ACCOUNT sfDestination
A wrapper which makes credits unavailable to balances.
std::uint64_t mantissa() const noexcept
const uint256 featureDepositPreauth
const SF_UINT32 sfSequence
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
const std::uint32_t tfPaymentMask
const uint256 featureDepositAuth
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
bool isLegalNet(STAmount const &value)
std::string to_string(ListDisposition disposition)
static NotTEC preflight(PreflightContext const &ctx)
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
const uint256 featureDeletableAccounts
const SF_AMOUNT sfDeliverMin
std::string getFullText() const override
int exponent() const noexcept
static TxConsequences makeTxConsequences(PreflightContext const &ctx)
@ temBAD_SEND_XRP_PARTIAL
Keylet account(AccountID const &id) noexcept
AccountID root.
AccountID getAccountID(SField const &field) const
static const std::size_t MaxPathLength
std::uint32_t getFlags() const
void deliver(STAmount const &amount)
Sets the DeliveredAmount field in the metadata.
@ temBAD_SEND_XRP_NO_DIRECT
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
Currency const & getCurrency() const
uint256 getTransactionID() const
State information when determining if a tx is likely to claim a fee.
bool native() const noexcept
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static const std::size_t MaxPathSize
void apply(RawView &to)
Apply changes to base view.
XRPAmount accountReserve(std::size_t ownerCount) const
Returns the account reserve given the owner count, in drops.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
virtual Rules const & rules() const =0
Returns the tx processing rules.
Issue const & issue() const
bool isFieldPresent(SField const &field) const
const std::uint32_t tfLimitQuality
const SF_UINT32 sfDestinationTag
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)
const SF_AMOUNT sfBalance
std::vector< STPath >::size_type size() const
void setResult(TER const value)
const SF_ACCOUNT sfAccount
State information when preflighting a tx.
STPathSet const & getFieldPathSet(SField const &field) const
static TER preclaim(PreclaimContext const &ctx)
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Class describing the consequences to the account of applying a transaction if the transaction consume...
virtual bool open() const =0
Returns true if this reflects an open ledger.
STAmount const & getFieldAmount(SField const &field) const