3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/protocol/Quality.h>
6#include <xrpl/protocol/QualityFunction.h>
7#include <xrpl/protocol/STLedgerEntry.h>
8#include <xrpl/protocol/TER.h>
9#include <xrpl/tx/paths/detail/AmountSpec.h>
11#include <boost/container/flat_set.hpp>
84 boost::container::flat_set<uint256>& ofrsToRm,
102 boost::container::flat_set<uint256>& ofrsToRm,
256 return lhs.
equal(rhs);
268 return !(lhs == rhs);
300offersUsed(Strand
const& strand)
303 for (
auto const& step : strand)
306 r += step->offersUsed();
314operator==(Strand
const& lhs, Strand
const& rhs)
316 if (lhs.size() != rhs.size())
318 for (
size_t i = 0, e = lhs.size(); i != e; ++i)
319 if (*lhs[i] != *rhs[i])
342 Issue const& deliver,
375 Issue const& deliver,
379 bool ownerPaysTransferFee,
416 Issue const& deliver,
421 bool ownerPaysTransferFee,
428template <
class TIn,
class TOut,
class TDerived>
429struct StepImp :
public Step
431 explicit StepImp() =
default;
436 boost::container::flat_set<uint256>& ofrsToRm,
439 auto const r =
static_cast<TDerived*
>(
this)->revImp(sb, afView, ofrsToRm, get<TOut>(out));
446 fwd(PaymentSandbox& sb,
448 boost::container::flat_set<uint256>& ofrsToRm,
449 EitherAmount
const& in)
override
451 auto const r =
static_cast<TDerived*
>(
this)->fwdImp(sb, afView, ofrsToRm, get<TIn>(in));
452 return {EitherAmount(r.first), EitherAmount(r.second)};
456 isZero(EitherAmount
const& out)
const override
458 return get<TOut>(out) == beast::zero;
462 equalOut(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
464 return get<TOut>(lhs) == get<TOut>(rhs);
468 equalIn(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
470 return get<TIn>(lhs) == get<TIn>(rhs);
482 FlowException(TER t,
std::string const& msg) :
std::runtime_error(msg), ter(t)
486 explicit FlowException(TER t) :
std::runtime_error(
transHuman(t)), ter(t)
495checkNear(IOUAmount
const& expected, IOUAmount
const& actual);
497checkNear(XRPAmount
const& expected, XRPAmount
const& actual);
542 Issue const& strandDeliver_,
545 bool ownerPaysTransferFee_,
548 std::array<boost::container::flat_set<Issue>, 2>&
550 boost::container::flat_set<Issue>& seenBookOuts_,
575 StrandContext
const& ctx,
592template <
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 &sb, 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, Strand > toStrand(ReadView const &sb, 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.
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)
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.