3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/protocol/Concepts.h>
6#include <xrpl/protocol/Quality.h>
7#include <xrpl/protocol/QualityFunction.h>
8#include <xrpl/protocol/TER.h>
9#include <xrpl/tx/paths/detail/EitherAmount.h>
11#include <boost/container/flat_set.hpp>
85 boost::container::flat_set<uint256>& ofrsToRm,
103 boost::container::flat_set<uint256>& ofrsToRm,
209 [[nodiscard]]
virtual bool
217 [[nodiscard]]
virtual bool
226 [[nodiscard]]
virtual bool
232 [[nodiscard]]
virtual bool
257 return lhs.
equal(rhs);
269 return !(lhs == rhs);
284 [[nodiscard]]
virtual bool
294 return {std::nullopt, res.second};
301offersUsed(Strand
const& strand)
304 for (
auto const& step : strand)
307 r += step->offersUsed();
315operator==(Strand
const& lhs, Strand
const& rhs)
317 if (lhs.size() != rhs.size())
319 for (
size_t i = 0, e = lhs.size(); i != e; ++i)
321 if (*lhs[i] != *rhs[i])
341std::pair<TER, STPath>
345 Asset const& deliver,
378 Asset const& deliver,
382 bool ownerPaysTransferFee,
419 Asset const& deliver,
424 bool ownerPaysTransferFee,
431template <StepAmount TIn, StepAmount TOut,
class TDerived>
432struct StepImp :
public Step
435 explicit StepImp() =
default;
441 boost::container::flat_set<uint256>& ofrsToRm,
444 auto const r =
static_cast<TDerived*
>(
this)->revImp(sb, afView, ofrsToRm,
get<TOut>(out));
450 std::pair<EitherAmount, EitherAmount>
451 fwd(PaymentSandbox& sb,
453 boost::container::flat_set<uint256>& ofrsToRm,
454 EitherAmount
const& in)
override
456 auto const r =
static_cast<TDerived*
>(
this)->fwdImp(sb, afView, ofrsToRm, get<TIn>(in));
457 return {EitherAmount(r.first), EitherAmount(r.second)};
461 isZero(EitherAmount
const& out)
const override
463 return get<TOut>(out) == beast::kZero;
467 equalOut(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
469 return get<TOut>(lhs) == get<TOut>(rhs);
473 equalIn(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
475 return get<TIn>(lhs) == get<TIn>(rhs);
483class FlowException :
public std::runtime_error
488 FlowException(TER t, std::string
const& msg) : std::runtime_error(msg), ter(t)
492 explicit FlowException(TER t) : std::runtime_error(
transHuman(t)), ter(t)
505 return expected == actual;
510 return expected == actual;
562 std::array<boost::container::flat_set<Asset>, 2>&
596 StrandContext
const& ctx,
603 StrandContext
const& ctx,
609makeBookStepIi(StrandContext
const& ctx, Issue
const& in, Issue
const& out);
621makeBookStepMm(StrandContext
const& ctx, MPTIssue
const& in, MPTIssue
const& out);
630makeBookStepMi(StrandContext
const& ctx, MPTIssue
const& in, Issue
const& out);
633makeBookStepIm(StrandContext
const& ctx, Issue
const& in, MPTIssue
const& out);
635template <StepAmount InAmt, StepAmount OutAmt>
637isDirectXrpToXrp(Strand
const& strand)
641 return strand.size() == 2;
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.
Floating point representation of amounts with high dynamic range.
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 mptEndpointStepEqual(Step const &step, AccountID const &src, AccountID const &dst, MPTID const &mptid)
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.
std::pair< TER, std::unique_ptr< Step > > makeXrpEndpointStep(StrandContext const &ctx, AccountID const &acc)
std::pair< TER, std::vector< Strand > > toStrands(ReadView const &sb, AccountID const &src, AccountID const &dst, Asset const &deliver, std::optional< Quality > const &limitQuality, std::optional< Asset > 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).
constexpr bool operator==(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
std::pair< TER, std::unique_ptr< Step > > makeDirectStepI(StrandContext const &ctx, AccountID const &src, AccountID const &dst, Currency const &c)
std::pair< TER, std::unique_ptr< Step > > makeBookStepIi(StrandContext const &ctx, Issue const &in, Issue const &out)
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
std::pair< TER, Strand > toStrand(ReadView const &sb, AccountID const &src, AccountID const &dst, Asset const &deliver, std::optional< Quality > const &limitQuality, std::optional< Asset > const &sendMaxAsset, 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 > > makeBookStepMx(StrandContext const &ctx, MPTIssue const &in)
bool issues(DebtDirection dir)
std::pair< TER, std::unique_ptr< Step > > makeMptEndpointStep(StrandContext const &ctx, AccountID const &src, AccountID const &dst, MPTID const &mpt)
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
std::string transHuman(TER code)
std::pair< TER, std::unique_ptr< Step > > makeBookStepMi(StrandContext const &ctx, MPTIssue const &in, Issue const &out)
std::pair< TER, STPath > normalizePath(AccountID const &src, AccountID const &dst, Asset const &deliver, std::optional< Asset > const &sendMaxAsset, STPath const &path)
std::pair< TER, std::unique_ptr< Step > > makeBookStepIx(StrandContext const &ctx, Issue const &in)
std::pair< TER, std::unique_ptr< Step > > makeBookStepXm(StrandContext const &ctx, MPTIssue const &out)
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
std::pair< TER, std::unique_ptr< Step > > makeBookStepXi(StrandContext const &ctx, Issue const &out)
bool checkNear(IOUAmount const &expected, IOUAmount const &actual)
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
std::pair< TER, std::unique_ptr< Step > > makeBookStepIm(StrandContext const &ctx, Issue const &in, MPTIssue const &out)
TERSubset< CanCvtToTER > TER
bool redeems(DebtDirection dir)
std::pair< TER, std::unique_ptr< Step > > makeBookStepMm(StrandContext const &ctx, MPTIssue const &in, MPTIssue const &out)
StrandContext(ReadView const &view, std::vector< std::unique_ptr< Step > > const &strand, AccountID const &strandSrc, AccountID const &strandDst, Asset const &strandDeliver, std::optional< Quality > const &limitQuality, bool isLast, bool ownerPaysTransferFee, OfferCrossing offerCrossing, bool isDefaultPath, std::array< boost::container::flat_set< Asset >, 2 > &seenDirectAssets, boost::container::flat_set< Asset > &seenBookOuts, AMMContext &ammContext, std::optional< uint256 > const &domainID, beast::Journal j)
StrandContext constructor.
Asset const strandDeliver
Asset strand delivers.
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
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.
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
boost::container::flat_set< Asset > & seenBookOuts
A strand may not include an offer that output the same issue more than once.
AccountID const strandDst
Strand destination account.
Step const *const prevStep
The previous step in the strand.
OfferCrossing const offerCrossing
Yes/Sell if offer crossing, not payment.