20#include <xrpld/app/paths/Credit.h>
21#include <xrpld/app/paths/detail/AmountSpec.h>
22#include <xrpld/app/paths/detail/StepChecks.h>
23#include <xrpld/app/paths/detail/Steps.h>
25#include <xrpl/basics/Log.h>
26#include <xrpl/ledger/PaymentSandbox.h>
27#include <xrpl/protocol/Feature.h>
28#include <xrpl/protocol/IOUAmount.h>
29#include <xrpl/protocol/Quality.h>
30#include <xrpl/protocol/XRPAmount.h>
32#include <boost/container/flat_set.hpp>
38template <
class TDerived>
40 :
public StepImp<XRPAmount, XRPAmount, XRPEndpointStep<TDerived>>
106 boost::container::flat_set<uint256>& ofrsToRm,
113 boost::container::flat_set<uint256>& ofrsToRm,
136 <<
"\nAcc: " <<
acc_;
148 return !(lhs == rhs);
235template <
class TDerived>
244template <
class TDerived>
255template <
class TDerived>
260 boost::container::flat_set<uint256>& ofrsToRm,
263 auto const balance =
static_cast<TDerived const*
>(
this)->
xrpLiquid(sb);
268 auto& receiver = isLast_ ? acc_ :
xrpAccount();
273 cache_.emplace(result);
274 return {result, result};
277template <
class TDerived>
282 boost::container::flat_set<uint256>& ofrsToRm,
285 XRPL_ASSERT(cache_,
"ripple::XRPEndpointStep::fwdImp : cache is set");
286 auto const balance =
static_cast<TDerived const*
>(
this)->
xrpLiquid(sb);
288 auto const result = isLast_ ?
in :
std::min(balance,
in);
291 auto& receiver = isLast_ ? acc_ :
xrpAccount();
296 cache_.emplace(result);
297 return {result, result};
300template <
class TDerived>
309 JLOG(j_.
error()) <<
"Expected valid cache in validFwd";
313 XRPL_ASSERT(
in.native,
"ripple::XRPEndpointStep::validFwd : input is XRP");
315 auto const& xrpIn =
in.xrp;
316 auto const balance =
static_cast<TDerived const*
>(
this)->
xrpLiquid(sb);
318 if (!isLast_ && balance < xrpIn)
320 JLOG(j_.
warn()) <<
"XRPEndpointStep: Strand re-execute check failed."
321 <<
" Insufficient balance: " <<
to_string(balance)
326 if (xrpIn != *cache_)
328 JLOG(j_.
warn()) <<
"XRPEndpointStep: Strand re-execute check failed."
335template <
class TDerived>
341 JLOG(j_.
debug()) <<
"XRPEndpointStep: specified bad account.";
348 JLOG(j_.
warn()) <<
"XRPEndpointStep: can't send or receive XRP from "
349 "non-existent account: "
367 auto const issuesIndex = isLast_ ? 0 : 1;
371 <<
"XRPEndpointStep: loop detected: Index: " << ctx.
strandSize
390 return xs->acc() == acc;
405 auto offerCrossingStep =
407 ter = offerCrossingStep->check(ctx);
408 r = std::move(offerCrossingStep);
413 ter = paymentStep->check(ctx);
414 r = std::move(paymentStep);
417 return {ter,
nullptr};
A generic endpoint for log messages.
Writeable view to a ledger, for applying a transaction.
A wrapper which makes credits unavailable to balances.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
static std::uint64_t const uRateOne
A step in a payment path.
std::int32_t const reserveReduction_
std::string logString() const override
XRPAmount xrpLiquid(ReadView &sb) const
static std::int32_t computeReserveReduction(StrandContext const &ctx, AccountID const &acc)
XRPEndpointOfferCrossingStep(StrandContext const &ctx, AccountID const &acc)
XRPAmount xrpLiquid(ReadView &sb) const
std::string logString() const override
std::optional< EitherAmount > cachedIn() const override
std::string logStringImpl(char const *name) const
TER check(StrandContext const &ctx) const
std::optional< XRPAmount > cache_
friend bool operator==(XRPEndpointStep< P > const &lhs, XRPEndpointStep< P > const &rhs)
std::pair< XRPAmount, XRPAmount > revImp(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, XRPAmount const &out)
std::pair< XRPAmount, XRPAmount > fwdImp(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, XRPAmount const &in)
friend bool operator!=(XRPEndpointStep const &lhs, XRPEndpointStep const &rhs)
std::pair< bool, EitherAmount > validFwd(PaymentSandbox &sb, ApplyView &afView, EitherAmount const &in) override
std::optional< std::pair< AccountID, AccountID > > directStepAccts() const override
std::optional< EitherAmount > cached() const
XRPAmount xrpLiquidImpl(ReadView &sb, std::int32_t reserveReduction) const
std::optional< EitherAmount > cachedOut() const override
XRPEndpointStep(StrandContext const &ctx, AccountID const &acc)
DebtDirection debtDirection(ReadView const &sb, StrandDirection dir) const override
AccountID const & acc() const
bool equal(Step const &rhs) const override
std::pair< std::optional< Quality >, DebtDirection > qualityUpperBound(ReadView const &v, DebtDirection prevStepDir) const override
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
Keylet account(AccountID const &id) noexcept
AccountID root.
bool xrpEndpointStepEqual(Step const &step, AccountID const &acc)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
AccountID const & xrpAccount()
Compute AccountID from public key.
std::pair< TER, std::unique_ptr< Step > > make_XRPEndpointStep(StrandContext const &ctx, AccountID const &acc)
TER checkFreeze(ReadView const &view, AccountID const &src, AccountID const &dst, Currency const ¤cy)
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
TER accountSend(ApplyView &view, AccountID const &from, AccountID const &to, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee=WaiveTransferFee::No)
Calls static accountSendIOU if saAmount represents Issue.
Currency const & xrpCurrency()
XRP currency.
std::string to_string(base_uint< Bits, Tag > const &a)
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
XRPAmount xrpLiquid(ReadView const &view, AccountID const &id, std::int32_t ownerCountAdj, beast::Journal j)
Context needed to build Strand Steps and for error checking.
size_t const strandSize
Length of Strand.
ReadView const & view
Current ReadView.
std::array< boost::container::flat_set< Issue >, 2 > & seenDirectIssues
A strand may not include the same account node more than once in the same currency.
OfferCrossing const offerCrossing
Yes/Sell if offer crossing, not payment.
bool const isFirst
true if Step is first in Strand
bool const isLast
true if Step is last in Strand
Issue const strandDeliver
Issue strand delivers.