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;
59 JLOG(j.trace()) <<
"Malformed transaction: "
60 <<
"Invalid flags set.";
67 bool const bPaths = tx.isFieldPresent(
sfPaths);
68 bool const bMax = tx.isFieldPresent(
sfSendMax);
73 auto const account = tx.getAccountID(
sfAccount);
76 maxSourceAmount = tx.getFieldAmount(
sfSendMax);
77 else if (saDstAmount.
native())
78 maxSourceAmount = saDstAmount;
84 saDstAmount < beast::zero);
86 auto const& uSrcCurrency = maxSourceAmount.
getCurrency();
87 auto const& uDstCurrency = saDstAmount.
getCurrency();
90 bool const bXRPDirect = uSrcCurrency.
isZero() && uDstCurrency.isZero();
99 JLOG(j.trace()) <<
"Malformed transaction: "
100 <<
"Payment destination account not specified.";
103 if (bMax && maxSourceAmount <= beast::zero)
105 JLOG(j.trace()) <<
"Malformed transaction: "
106 <<
"bad max amount: " << maxSourceAmount.
getFullText();
109 if (saDstAmount <= beast::zero)
111 JLOG(j.trace()) <<
"Malformed transaction: "
112 <<
"bad dst amount: " << saDstAmount.
getFullText();
117 JLOG(j.trace()) <<
"Malformed transaction: "
121 if (account == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
125 JLOG(j.trace()) <<
"Malformed transaction: "
126 <<
"Redundant payment from " <<
to_string(account)
127 <<
" to self without path for "
131 if (bXRPDirect && bMax)
134 JLOG(j.trace()) <<
"Malformed transaction: "
135 <<
"SendMax specified for XRP to XRP.";
138 if (bXRPDirect && bPaths)
141 JLOG(j.trace()) <<
"Malformed transaction: "
142 <<
"Paths specified for XRP to XRP.";
145 if (bXRPDirect && partialPaymentAllowed)
148 JLOG(j.trace()) <<
"Malformed transaction: "
149 <<
"Partial payment specified for XRP to XRP.";
152 if (bXRPDirect && limitQuality)
155 JLOG(j.trace()) <<
"Malformed transaction: "
156 <<
"Limit quality specified for XRP to XRP.";
159 if (bXRPDirect && !defaultPathsAllowed)
162 JLOG(j.trace()) <<
"Malformed transaction: "
163 <<
"No ripple direct specified for XRP to XRP.";
170 if (!partialPaymentAllowed)
172 JLOG(j.trace()) <<
"Malformed transaction: Partial payment not "
174 << jss::DeliverMin.c_str() <<
".";
178 auto const dMin = *deliverMin;
182 <<
"Malformed transaction: Invalid " << jss::DeliverMin.c_str()
183 <<
" amount. " << dMin.getFullText();
186 if (dMin.issue() != saDstAmount.
issue())
189 <<
"Malformed transaction: Dst issue differs "
191 << jss::DeliverMin.c_str() <<
". " << dMin.getFullText();
194 if (dMin > saDstAmount)
197 <<
"Malformed transaction: Dst amount less than "
198 << jss::DeliverMin.c_str() <<
". " << dMin.getFullText();
219 auto const sleDst = ctx.
view.
read(k);
224 if (!saDstAmount.
native())
227 <<
"Delay transaction: Destination account does not exist.";
233 else if (ctx.
view.
open() && partialPaymentAllowed)
237 JLOG(ctx.
j.
trace()) <<
"Delay transaction: Partial payment not "
238 "allowed to create account.";
249 <<
"Delay transaction: Destination account does not exist. "
250 <<
"Insufficent payment to create account.";
268 <<
"Malformed transaction: DestinationTag required.";
273 if (paths || sendMax || !saDstAmount.
native())
284 for (
auto const& path : spsPaths)
317 maxSourceAmount = *sendMax;
318 else if (saDstAmount.
native())
319 maxSourceAmount = saDstAmount;
325 saDstAmount < beast::zero);
341 sleDst = std::make_shared<SLE>(k);
342 sleDst->setAccountID(
sfAccount, uDstAccountID);
356 bool const reqDepositAuth = sleDst->getFlags() &
lsfDepositAuth &&
361 bool const bRipple = paths || sendMax || !saDstAmount.
native();
365 if (!depositPreauth && bRipple && reqDepositAuth)
373 if (depositPreauth && reqDepositAuth)
399 JLOG(
j_.
debug()) <<
"Entering RippleCalc in payment: "
426 auto terResult = rc.
result();
437 assert(saDstAmount.
native());
447 auto const uOwnerCount = sleSrc->getFieldU32(
sfOwnerCount);
461 JLOG(
j_.
trace()) <<
"Delay transaction: Insufficient funds: "
498 if (saDstAmount > dstReserve ||
499 sleDst->getFieldAmount(
sfBalance) > dstReserve)
507 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 SF_AMOUNT sfSendMax
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
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 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
constexpr std::uint32_t tfLimitQuality
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
constexpr std::uint32_t tfPartialPayment
@ 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
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 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
constexpr std::uint32_t tfPaymentMask
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
constexpr std::uint32_t tfNoRippleDirect