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>
40 return maxAmount.
native() ? maxAmount.
xrp() : beast::zero;
60 JLOG(j.trace()) <<
"Malformed transaction: "
61 <<
"Invalid flags set.";
68 bool const bPaths = tx.isFieldPresent(
sfPaths);
69 bool const bMax = tx.isFieldPresent(
sfSendMax);
74 auto const account = tx.getAccountID(
sfAccount);
77 maxSourceAmount = tx.getFieldAmount(
sfSendMax);
78 else if (saDstAmount.
native())
79 maxSourceAmount = saDstAmount;
85 saDstAmount < beast::zero);
87 auto const& uSrcCurrency = maxSourceAmount.
getCurrency();
88 auto const& uDstCurrency = saDstAmount.
getCurrency();
91 bool const bXRPDirect = uSrcCurrency.
isZero() && uDstCurrency.isZero();
100 JLOG(j.trace()) <<
"Malformed transaction: "
101 <<
"Payment destination account not specified.";
104 if (bMax && maxSourceAmount <= beast::zero)
106 JLOG(j.trace()) <<
"Malformed transaction: "
107 <<
"bad max amount: " << maxSourceAmount.
getFullText();
110 if (saDstAmount <= beast::zero)
112 JLOG(j.trace()) <<
"Malformed transaction: "
113 <<
"bad dst amount: " << saDstAmount.
getFullText();
118 JLOG(j.trace()) <<
"Malformed transaction: "
122 if (account == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
126 JLOG(j.trace()) <<
"Malformed transaction: "
127 <<
"Redundant payment from " <<
to_string(account)
128 <<
" to self without path for "
132 if (bXRPDirect && bMax)
135 JLOG(j.trace()) <<
"Malformed transaction: "
136 <<
"SendMax specified for XRP to XRP.";
139 if (bXRPDirect && bPaths)
142 JLOG(j.trace()) <<
"Malformed transaction: "
143 <<
"Paths specified for XRP to XRP.";
146 if (bXRPDirect && partialPaymentAllowed)
149 JLOG(j.trace()) <<
"Malformed transaction: "
150 <<
"Partial payment specified for XRP to XRP.";
153 if (bXRPDirect && limitQuality)
156 JLOG(j.trace()) <<
"Malformed transaction: "
157 <<
"Limit quality specified for XRP to XRP.";
160 if (bXRPDirect && !defaultPathsAllowed)
163 JLOG(j.trace()) <<
"Malformed transaction: "
164 <<
"No ripple direct specified for XRP to XRP.";
171 if (!partialPaymentAllowed)
173 JLOG(j.trace()) <<
"Malformed transaction: Partial payment not "
175 << jss::DeliverMin.c_str() <<
".";
179 auto const dMin = *deliverMin;
183 <<
"Malformed transaction: Invalid " << jss::DeliverMin.c_str()
184 <<
" amount. " << dMin.getFullText();
187 if (dMin.issue() != saDstAmount.
issue())
190 <<
"Malformed transaction: Dst issue differs "
192 << jss::DeliverMin.c_str() <<
". " << dMin.getFullText();
195 if (dMin > saDstAmount)
198 <<
"Malformed transaction: Dst amount less than "
199 << jss::DeliverMin.c_str() <<
". " << dMin.getFullText();
220 auto const sleDst = ctx.
view.
read(k);
225 if (!saDstAmount.
native())
228 <<
"Delay transaction: Destination account does not exist.";
234 else if (ctx.
view.
open() && partialPaymentAllowed)
238 JLOG(ctx.
j.
trace()) <<
"Delay transaction: Partial payment not "
239 "allowed to create account.";
250 <<
"Delay transaction: Destination account does not exist. "
251 <<
"Insufficent payment to create account.";
269 <<
"Malformed transaction: DestinationTag required.";
274 if (paths || sendMax || !saDstAmount.
native())
285 for (
auto const& path : spsPaths)
318 maxSourceAmount = *sendMax;
319 else if (saDstAmount.
native())
320 maxSourceAmount = saDstAmount;
326 saDstAmount < beast::zero);
342 sleDst = std::make_shared<SLE>(k);
343 sleDst->setAccountID(
sfAccount, uDstAccountID);
357 bool const reqDepositAuth = sleDst->getFlags() &
lsfDepositAuth &&
362 bool const bRipple = paths || sendMax || !saDstAmount.
native();
366 if (!depositPreauth && bRipple && reqDepositAuth)
374 if (depositPreauth && reqDepositAuth)
400 JLOG(
j_.
debug()) <<
"Entering RippleCalc in payment: "
427 auto terResult = rc.
result();
438 assert(saDstAmount.
native());
448 auto const uOwnerCount = sleSrc->getFieldU32(
sfOwnerCount);
462 JLOG(
j_.
trace()) <<
"Delay transaction: Insufficient funds: "
499 if (saDstAmount > dstReserve ||
500 sleDst->getFieldAmount(
sfBalance) > dstReserve)
508 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.
Issue const & issue() const
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)
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)
std::vector< STPath >::size_type size() const
@ 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.
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.
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
void setResult(TER const value)
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
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.
Currency const & getCurrency() const
STAmount const & getFieldAmount(SField const &field) const