1#include <xrpld/app/paths/Credit.h>
2#include <xrpld/app/paths/detail/AmountSpec.h>
3#include <xrpld/app/paths/detail/StepChecks.h>
4#include <xrpld/app/paths/detail/Steps.h>
6#include <xrpl/basics/Log.h>
7#include <xrpl/ledger/PaymentSandbox.h>
8#include <xrpl/protocol/Feature.h>
9#include <xrpl/protocol/IOUAmount.h>
10#include <xrpl/protocol/Quality.h>
11#include <xrpl/protocol/XRPAmount.h>
13#include <boost/container/flat_set.hpp>
19template <
class TDerived>
21 :
public StepImp<XRPAmount, XRPAmount, XRPEndpointStep<TDerived>>
87 boost::container::flat_set<uint256>& ofrsToRm,
94 boost::container::flat_set<uint256>& ofrsToRm,
117 <<
"\nAcc: " <<
acc_;
129 return !(lhs == rhs);
216template <
class TDerived>
225template <
class TDerived>
236template <
class TDerived>
241 boost::container::flat_set<uint256>& ofrsToRm,
244 auto const balance =
static_cast<TDerived const*
>(
this)->
xrpLiquid(sb);
249 auto& receiver = isLast_ ? acc_ :
xrpAccount();
254 cache_.emplace(result);
255 return {result, result};
258template <
class TDerived>
263 boost::container::flat_set<uint256>& ofrsToRm,
266 XRPL_ASSERT(cache_,
"ripple::XRPEndpointStep::fwdImp : cache is set");
267 auto const balance =
static_cast<TDerived const*
>(
this)->
xrpLiquid(sb);
269 auto const result = isLast_ ?
in :
std::min(balance,
in);
272 auto& receiver = isLast_ ? acc_ :
xrpAccount();
277 cache_.emplace(result);
278 return {result, result};
281template <
class TDerived>
290 JLOG(j_.
error()) <<
"Expected valid cache in validFwd";
294 XRPL_ASSERT(
in.native,
"ripple::XRPEndpointStep::validFwd : input is XRP");
296 auto const& xrpIn =
in.xrp;
297 auto const balance =
static_cast<TDerived const*
>(
this)->
xrpLiquid(sb);
299 if (!isLast_ && balance < xrpIn)
301 JLOG(j_.
warn()) <<
"XRPEndpointStep: Strand re-execute check failed."
302 <<
" Insufficient balance: " <<
to_string(balance)
307 if (xrpIn != *cache_)
309 JLOG(j_.
warn()) <<
"XRPEndpointStep: Strand re-execute check failed."
316template <
class TDerived>
322 JLOG(j_.
debug()) <<
"XRPEndpointStep: specified bad account.";
329 JLOG(j_.
warn()) <<
"XRPEndpointStep: can't send or receive XRP from "
330 "non-existent account: "
346 auto const issuesIndex = isLast_ ? 0 : 1;
349 JLOG(j_.
debug()) <<
"XRPEndpointStep: loop detected: Index: "
367 return xs->acc() == acc;
382 auto offerCrossingStep =
384 ter = offerCrossingStep->check(ctx);
385 r = std::move(offerCrossingStep);
390 ter = paymentStep->check(ctx);
391 r = std::move(paymentStep);
394 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.
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.