3#include <xrpld/app/paths/detail/AmountSpec.h>
5#include <xrpl/basics/Log.h>
6#include <xrpl/basics/base_uint.h>
7#include <xrpl/protocol/Quality.h>
8#include <xrpl/protocol/QualityFunction.h>
9#include <xrpl/protocol/STLedgerEntry.h>
10#include <xrpl/protocol/TER.h>
12#include <boost/container/flat_set.hpp>
85 boost::container::flat_set<uint256>& ofrsToRm,
103 boost::container::flat_set<uint256>& ofrsToRm,
260 return lhs.
equal(rhs);
272 return !(lhs == rhs);
304offersUsed(Strand
const& strand)
307 for (
auto const& step : strand)
310 r += step->offersUsed();
318operator==(Strand
const& lhs, Strand
const& rhs)
320 if (lhs.size() != rhs.size())
322 for (
size_t i = 0, e = lhs.size(); i != e; ++i)
323 if (*lhs[i] != *rhs[i])
346 Issue const& deliver,
379 Issue const& deliver,
383 bool ownerPaysTransferFee,
420 Issue const& deliver,
425 bool ownerPaysTransferFee,
432template <
class TIn,
class TOut,
class TDerived>
433struct StepImp :
public Step
435 explicit StepImp() =
default;
440 boost::container::flat_set<uint256>& ofrsToRm,
443 auto const r =
static_cast<TDerived*
>(
this)->revImp(sb, afView, ofrsToRm, get<TOut>(out));
450 fwd(PaymentSandbox& sb,
452 boost::container::flat_set<uint256>& ofrsToRm,
453 EitherAmount
const& in)
override
455 auto const r =
static_cast<TDerived*
>(
this)->fwdImp(sb, afView, ofrsToRm, get<TIn>(in));
456 return {EitherAmount(r.first), EitherAmount(r.second)};
460 isZero(EitherAmount
const& out)
const override
462 return get<TOut>(out) == beast::zero;
466 equalOut(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
468 return get<TOut>(lhs) == get<TOut>(rhs);
472 equalIn(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
474 return get<TIn>(lhs) == get<TIn>(rhs);
486 FlowException(TER t,
std::string const& msg) :
std::runtime_error(msg), ter(t)
490 explicit FlowException(TER t) :
std::runtime_error(
transHuman(t)), ter(t)
499checkNear(IOUAmount
const& expected, IOUAmount
const& actual);
501checkNear(XRPAmount
const& expected, XRPAmount
const& actual);
546 Issue const& strandDeliver_,
549 bool ownerPaysTransferFee_,
552 std::array<boost::container::flat_set<Issue>, 2>& seenDirectIssues_,
553 boost::container::flat_set<Issue>& seenBookOuts_,
587template <
class InAmt,
class OutAmt>
A generic endpoint for log messages.
Maintains AMM info per overall payment engine execution and individual iteration.
Writeable view to a ledger, for applying a transaction.
A currency issued by an account.
A wrapper which makes credits unavailable to balances.
Average quality of a path as a function of out: q(out) = m * out + b, where m = -1 / poolGets,...
A step in a payment path.
virtual std::optional< EitherAmount > cachedIn() const =0
Amount of currency computed coming into the Step the last time the step ran in reverse.
virtual std::pair< std::optional< Quality >, DebtDirection > qualityUpperBound(ReadView const &v, DebtDirection prevStepDir) const =0
Find an upper bound of quality for the step.
virtual std::optional< AccountID > directStepSrcAcct() const
If this step is DirectStepI (IOU->IOU direct step), return the src account.
virtual std::string logString() const =0
virtual std::optional< std::pair< AccountID, AccountID > > directStepAccts() const
virtual std::pair< EitherAmount, EitherAmount > rev(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, EitherAmount const &out)=0
Find the amount we need to put into the step to get the requested out subject to liquidity limits.
virtual std::uint32_t offersUsed() const
Return the number of offers consumed or partially consumed the last time the step ran,...
friend bool operator!=(Step const &lhs, Step const &rhs)
Return true if lhs != rhs.
virtual std::pair< std::optional< QualityFunction >, DebtDirection > getQualityFunc(ReadView const &v, DebtDirection prevStepDir) const
Get QualityFunction.
virtual bool inactive() const
Return true if the step should be considered inactive.
friend bool operator==(Step const &lhs, Step const &rhs)
Return true if lhs == rhs.
virtual std::pair< bool, EitherAmount > validFwd(PaymentSandbox &sb, ApplyView &afView, EitherAmount const &in)=0
Check that the step can correctly execute in the forward direction.
virtual bool equalOut(EitherAmount const &lhs, EitherAmount const &rhs) const =0
Return true if Out of lhs == Out of rhs.
virtual std::optional< Book > bookStepBook() const
If this step is a BookStep, return the book.
virtual DebtDirection debtDirection(ReadView const &sb, StrandDirection dir) const =0
If this step is a DirectStepI and the src redeems to the dst, return true, otherwise return false.
friend std::ostream & operator<<(std::ostream &stream, Step const &step)
Streaming operator for a Step.
virtual std::uint32_t lineQualityIn(ReadView const &) const
If this step is a DirectStepI, return the quality in of the dst account.
virtual std::pair< EitherAmount, EitherAmount > fwd(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, EitherAmount const &in)=0
Find the amount we get out of the step given the input subject to liquidity limits.
virtual bool equalIn(EitherAmount const &lhs, EitherAmount const &rhs) const =0
Return true if In of lhs == In of rhs.
virtual bool equal(Step const &rhs) const =0
virtual std::optional< EitherAmount > cachedOut() const =0
Amount of currency computed coming out of the Step the last time the step ran in reverse.
virtual bool isZero(EitherAmount const &out) const =0
Check if amount is zero.
bool bookStepEqual(Step const &step, xrpl::Book const &book)
bool xrpEndpointStepEqual(Step const &step, AccountID const &acc)
bool directStepEqual(Step const &step, AccountID const &src, AccountID const &dst, Currency const ¤cy)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
base_uint< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
bool isDirectXrpToXrp(Strand const &strand)
std::pair< TER, std::vector< Strand > > toStrands(ReadView const &view, AccountID const &src, AccountID const &dst, Issue const &deliver, std::optional< Quality > const &limitQuality, std::optional< Issue > const &sendMax, STPathSet const &paths, bool addDefaultPath, bool ownerPaysTransferFee, OfferCrossing offerCrossing, AMMContext &ammContext, std::optional< uint256 > const &domainID, beast::Journal j)
Create a Strand for each specified path (including the default path, if indicated)
std::pair< TER, std::unique_ptr< Step > > make_XRPEndpointStep(StrandContext const &ctx, AccountID const &acc)
std::pair< TER, std::unique_ptr< Step > > make_BookStepXI(StrandContext const &ctx, Issue const &out)
std::string transHuman(TER code)
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
TERSubset< CanCvtToTER > TER
std::pair< TER, std::unique_ptr< Step > > make_DirectStepI(StrandContext const &ctx, AccountID const &src, AccountID const &dst, Currency const &c)
std::pair< TER, STPath > normalizePath(AccountID const &src, AccountID const &dst, Issue const &deliver, std::optional< Issue > const &sendMaxIssue, STPath const &path)
std::pair< TER, std::unique_ptr< Step > > make_BookStepIX(StrandContext const &ctx, Issue const &in)
bool checkNear(IOUAmount const &expected, IOUAmount const &actual)
std::pair< TER, std::unique_ptr< Step > > make_BookStepII(StrandContext const &ctx, Issue const &in, Issue const &out)
std::pair< TER, Strand > toStrand(ReadView const &view, AccountID const &src, AccountID const &dst, Issue const &deliver, std::optional< Quality > const &limitQuality, std::optional< Issue > const &sendMaxIssue, STPath const &path, bool ownerPaysTransferFee, OfferCrossing offerCrossing, AMMContext &ammContext, std::optional< uint256 > const &domainID, beast::Journal j)
Create a Strand for the specified path.
Context needed to build Strand Steps and for error checking.
boost::container::flat_set< Issue > & seenBookOuts
A strand may not include an offer that output the same issue more than once.
std::optional< uint256 > domainID
std::optional< Quality > const limitQuality
Worst accepted quality.
size_t const strandSize
Length of Strand.
ReadView const & view
Current ReadView.
bool const isFirst
true if Step is first in Strand
AccountID const strandSrc
Strand source account.
bool const ownerPaysTransferFee
true if owner, not sender, pays fee
bool const isLast
true if Step is last in Strand
bool const isDefaultPath
true if Strand is default path
AccountID const strandDst
Strand destination account.
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.
Step const *const prevStep
The previous step in the strand.
Issue const strandDeliver
Issue strand delivers.
OfferCrossing const offerCrossing
Yes/Sell if offer crossing, not payment.