1#ifndef XRPL_APP_PATHS_IMPL_PAYSTEPS_H_INCLUDED
2#define XRPL_APP_PATHS_IMPL_PAYSTEPS_H_INCLUDED
4#include <xrpld/app/paths/detail/AmountSpec.h>
6#include <xrpl/basics/Log.h>
7#include <xrpl/basics/base_uint.h>
8#include <xrpl/protocol/Quality.h>
9#include <xrpl/protocol/QualityFunction.h>
10#include <xrpl/protocol/STLedgerEntry.h>
11#include <xrpl/protocol/TER.h>
13#include <boost/container/flat_set.hpp>
86 boost::container::flat_set<uint256>& ofrsToRm,
104 boost::container::flat_set<uint256>& ofrsToRm,
261 return lhs.
equal(rhs);
273 return !(lhs == rhs);
307offersUsed(Strand
const& strand)
310 for (
auto const& step : strand)
313 r += step->offersUsed();
321operator==(Strand
const& lhs, Strand
const& rhs)
323 if (lhs.size() != rhs.size())
325 for (
size_t i = 0, e = lhs.size(); i != e; ++i)
326 if (*lhs[i] != *rhs[i])
349 Issue const& deliver,
382 Issue const& deliver,
386 bool ownerPaysTransferFee,
423 Issue const& deliver,
428 bool ownerPaysTransferFee,
435template <
class TIn,
class TOut,
class TDerived>
436struct StepImp :
public Step
438 explicit StepImp() =
default;
443 boost::container::flat_set<uint256>& ofrsToRm,
446 auto const r =
static_cast<TDerived*
>(
this)->revImp(
447 sb, afView, ofrsToRm, get<TOut>(out));
454 fwd(PaymentSandbox& sb,
456 boost::container::flat_set<uint256>& ofrsToRm,
457 EitherAmount
const& in)
override
459 auto const r =
static_cast<TDerived*
>(
this)->fwdImp(
460 sb, afView, ofrsToRm, get<TIn>(in));
461 return {EitherAmount(r.first), EitherAmount(r.second)};
465 isZero(EitherAmount
const& out)
const override
467 return get<TOut>(out) == beast::zero;
471 equalOut(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
473 return get<TOut>(lhs) == get<TOut>(rhs);
477 equalIn(EitherAmount
const& lhs, EitherAmount
const& rhs)
const override
479 return get<TIn>(lhs) == get<TIn>(rhs);
492 :
std::runtime_error(msg), ter(t)
496 explicit FlowException(TER t) :
std::runtime_error(
transHuman(t)), ter(t)
505checkNear(IOUAmount
const& expected, IOUAmount
const& actual);
507checkNear(XRPAmount
const& expected, XRPAmount
const& actual);
553 Issue const& strandDeliver_,
556 bool ownerPaysTransferFee_,
559 std::array<boost::container::flat_set<Issue>, 2>&
561 boost::container::flat_set<Issue>&
587 StrandContext
const& ctx,
604template <
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.