1#include <xrpl/basics/Log.h>
2#include <xrpl/basics/base_uint.h>
3#include <xrpl/beast/utility/Journal.h>
4#include <xrpl/beast/utility/Zero.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/ledger/PaymentSandbox.h>
7#include <xrpl/ledger/helpers/AccountRootHelpers.h>
8#include <xrpl/ledger/helpers/TokenHelpers.h>
9#include <xrpl/protocol/AccountID.h>
10#include <xrpl/protocol/IOUAmount.h>
11#include <xrpl/protocol/Indexes.h>
12#include <xrpl/protocol/Issue.h>
13#include <xrpl/protocol/MPTIssue.h>
14#include <xrpl/protocol/Quality.h>
15#include <xrpl/protocol/STAmount.h>
16#include <xrpl/protocol/TER.h>
17#include <xrpl/protocol/UintTypes.h>
18#include <xrpl/protocol/XRPAmount.h>
19#include <xrpl/tx/paths/detail/EitherAmount.h>
20#include <xrpl/tx/paths/detail/StepChecks.h>
21#include <xrpl/tx/paths/detail/Steps.h>
23#include <boost/container/flat_set.hpp>
34template <
class TDerived>
35class XRPEndpointStep :
public StepImp<XRPAmount, XRPAmount, XRPEndpointStep<TDerived>>
100 boost::container::flat_set<uint256>& ofrsToRm,
107 boost::container::flat_set<uint256>& ofrsToRm,
129 <<
"\nAcc: " <<
acc_;
141 return !(lhs == rhs);
205 [&](
Issue const& issue) {
244template <
class TDerived>
251template <
class TDerived>
258template <
class TDerived>
263 boost::container::flat_set<uint256>& ofrsToRm,
277 return {result, result};
280template <
class TDerived>
285 boost::container::flat_set<uint256>& ofrsToRm,
288 XRPL_ASSERT(
cache_,
"xrpl::XRPEndpointStep::fwdImp : cache is set");
300 return {result, result};
303template <
class TDerived>
309 JLOG(
j_.error()) <<
"Expected valid cache in validFwd";
313 XRPL_ASSERT(in.
holds<
XRPAmount>(),
"xrpl::XRPEndpointStep::validFwd : input is XRP");
318 if (!
isLast_ && balance < xrpIn)
320 JLOG(
j_.warn()) <<
"XRPEndpointStep: Strand re-execute check failed."
321 <<
" Insufficient balance: " <<
to_string(balance)
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: "
365 auto const issuesIndex =
isLast_ ? 0 : 1;
368 JLOG(
j_.debug()) <<
"XRPEndpointStep: loop detected: Index: " << ctx.
strandSize <<
' '
385 return xs->acc() == acc;
401 ter = offerCrossingStep->check(ctx);
402 r = std::move(offerCrossingStep);
407 ter = paymentStep->check(ctx);
408 r = std::move(paymentStep);
411 return {ter,
nullptr};
A generic endpoint for log messages.
Writeable view to a ledger, for applying a transaction.
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
A currency issued by an account.
A wrapper which makes credits unavailable to balances.
Represents the logical ratio of output currency to input currency.
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
static std::uint64_t const kURateOne
A step in a payment path.
static std::int32_t computeReserveReduction(StrandContext const &ctx, AccountID const &acc)
XRPAmount xrpLiquid(ReadView &sb) const
std::int32_t const reserveReduction_
std::string logString() const override
XRPEndpointOfferCrossingStep(StrandContext const &ctx, AccountID const &acc)
XRPAmount xrpLiquid(ReadView &sb) const
XRPEndpointPaymentStep(StrandContext const &ctx, AccountID const &acc)
std::string logString() const override
std::optional< EitherAmount > cachedIn() const override
std::pair< bool, EitherAmount > validFwd(PaymentSandbox &sb, ApplyView &afView, EitherAmount const &in) override
std::optional< EitherAmount > cached() const
XRPEndpointStep(StrandContext const &ctx, AccountID const &acc)
friend bool operator==(XRPEndpointStep< P > const &lhs, XRPEndpointStep< P > const &rhs)
std::optional< EitherAmount > cachedOut() const override
std::optional< std::pair< AccountID, AccountID > > directStepAccts() const override
DebtDirection debtDirection(ReadView const &sb, StrandDirection dir) const override
friend bool operator!=(XRPEndpointStep const &lhs, XRPEndpointStep const &rhs)
std::optional< XRPAmount > cache_
AccountID const & acc() const
XRPAmount xrpLiquidImpl(ReadView &sb, std::int32_t reserveReduction) const
bool equal(Step const &rhs) const override
TER check(StrandContext const &ctx) const
std::pair< XRPAmount, XRPAmount > revImp(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, XRPAmount const &out)
std::string logStringImpl(char const *name) const
std::pair< std::optional< Quality >, DebtDirection > qualityUpperBound(ReadView const &v, DebtDirection prevStepDir) const override
std::pair< XRPAmount, XRPAmount > fwdImp(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, XRPAmount const &in)
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
bool xrpEndpointStepEqual(Step const &step, AccountID const &acc)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::pair< TER, std::unique_ptr< Step > > makeXrpEndpointStep(StrandContext const &ctx, AccountID const &acc)
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
XRPAmount xrpLiquid(ReadView const &view, AccountID const &id, std::int32_t ownerCountAdj, beast::Journal j)
constexpr bool operator==(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
Currency const & xrpCurrency()
XRP currency.
std::string to_string(BaseUInt< Bits, Tag > const &a)
TER checkFreeze(ReadView const &view, AccountID const &src, AccountID const &dst, Currency const ¤cy)
TER accountSend(ApplyView &view, AccountID const &from, AccountID const &to, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee=WaiveTransferFee::No, AllowMPTOverflow allowOverflow=AllowMPTOverflow::No)
Calls static accountSendIOU if saAmount represents Issue.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
AccountID const & xrpAccount()
Compute AccountID from public key.
STAmount toSTAmount(IOUAmount const &iou, Asset const &asset)
Context needed to build Strand Steps and for error checking.
Asset const strandDeliver
Asset strand delivers.
size_t const strandSize
Length of Strand.
ReadView const & view
Current ReadView.
bool const isFirst
true if Step is first in Strand
std::array< boost::container::flat_set< Asset >, 2 > & seenDirectAssets
A strand may not include the same account node more than once in the same currency.
bool const isLast
true if Step is last in Strand
OfferCrossing const offerCrossing
Yes/Sell if offer crossing, not payment.