20#include <xrpld/app/misc/AMMUtils.h> 
   21#include <xrpld/app/paths/AMMLiquidity.h> 
   22#include <xrpld/app/paths/AMMOffer.h> 
   23#include <xrpld/app/paths/detail/FlatSets.h> 
   24#include <xrpld/app/paths/detail/Steps.h> 
   25#include <xrpld/app/tx/detail/OfferStream.h> 
   27#include <xrpl/basics/Log.h> 
   28#include <xrpl/basics/contract.h> 
   29#include <xrpl/beast/utility/instrumentation.h> 
   30#include <xrpl/ledger/PaymentSandbox.h> 
   31#include <xrpl/protocol/Book.h> 
   32#include <xrpl/protocol/Feature.h> 
   33#include <xrpl/protocol/IOUAmount.h> 
   34#include <xrpl/protocol/Quality.h> 
   35#include <xrpl/protocol/XRPAmount.h> 
   37#include <boost/container/flat_set.hpp> 
   44template <
class TIn, 
class TOut, 
class TDerived>
 
   45class BookStep : 
public StepImp<TIn, TOut, BookStep<TIn, TOut, TDerived>>
 
   78        Cache(TIn 
const& in_, TOut 
const& out_) : 
in(in_), 
out(out_)
 
 
 
   95            ammSle && ammSle->getFieldAmount(sfLPTokenBalance) != beast::zero)
 
 
  155        boost::container::flat_set<uint256>& ofrsToRm,
 
  162        boost::container::flat_set<uint256>& ofrsToRm,
 
  202        return !(lhs == rhs);
 
 
  213    template <
class Callback>
 
  219        Callback& callback) 
const;
 
  222    template <
template <
typename, 
typename> 
typename Offer>
 
  227        TAmounts<TIn, TOut> 
const& ofrAmt,
 
  228        TAmounts<TIn, TOut> 
const& stepAmt,
 
  229        TOut 
const& ownerGives) 
const;
 
  262template <
class TIn, 
class TOut>
 
  273    template <
template <
typename, 
typename> 
typename Offer>
 
 
  360template <
class TIn, 
class TOut>
 
  362    : 
public BookStep<TIn, TOut, BookOfferCrossingStep<TIn, TOut>>
 
  378            "ripple::BookOfferCrossingStep::getQuality : nonzero quality");
 
  380            Throw<FlowException>(
tefINTERNAL, 
"Offer requires quality.");
 
  381        return *limitQuality;
 
 
  395    template <
template <
typename, 
typename> 
typename Offer>
 
  403        bool const offerAttempted)
 const 
  435            strandSrc == offer.owner() && strandDst == offer.owner())
 
  438            if (
auto const key = offer.
key())
 
  439                offers.permRmOffer(*key);
 
 
  483        Step const* prevStep,
 
  490        return owner == srcAcct  
 
 
  498        Step const* prevStep,
 
 
  517        Rules const& rules)
 const 
  529        if (!rules.
enabled(fixAMMv1_1))
 
  532            offerType == OfferType::CLOB ||
 
 
 
  564template <
class TIn, 
class TOut, 
class TDerived>
 
  569        return book_ == bs->book_;
 
 
  573template <
class TIn, 
class TOut, 
class TDerived>
 
  589    Quality 
const q = 
static_cast<TDerived const*
>(
this)->adjustQualityWithFees(
 
 
  599template <
class TIn, 
class TOut, 
class TDerived>
 
  616            static_cast<TDerived const*
>(
this)->adjustQualityWithFees(
 
  631    Quality 
const q = 
static_cast<TDerived const*
>(
this)->adjustQualityWithFees(
 
 
  641template <
class TIn, 
class TOut, 
class TDerived>
 
  649template <
class TIn, 
class TOut, 
class Offer>
 
  653    TAmounts<TIn, TOut>& ofrAmt,
 
  654    TAmounts<TIn, TOut>& stpAmt,
 
  660    if (limit < stpAmt.in)
 
  664            mulRatio(stpAmt.in, QUALITY_ONE, transferRateIn,  
false);
 
  672        ofrAmt = offer.limitIn(ofrAmt, inLmt,  
false);
 
  673        stpAmt.out = ofrAmt.out;
 
  675            ofrAmt.out, transferRateOut, QUALITY_ONE,  
false);
 
 
  680template <
class TIn, 
class TOut, 
class Offer>
 
  684    TAmounts<TIn, TOut>& ofrAmt,
 
  685    TAmounts<TIn, TOut>& stpAmt,
 
  691    if (limit < stpAmt.out)
 
  695            stpAmt.out, transferRateOut, QUALITY_ONE,  
false);
 
  696        ofrAmt = offer.limitOut(
 
  701            mulRatio(ofrAmt.in, transferRateIn, QUALITY_ONE,  
true);
 
 
  705template <
class TIn, 
class TOut, 
class TDerived>
 
  706template <
class Callback>
 
  712    Callback& callback)
 const 
  720        if (
isXRP(
id) || 
id == this->strandDst_)
 
  726        redeems(prevStepDir) ? rate(book_.in.account) : QUALITY_ONE;
 
  729        ownerPaysTransferFee_ ? rate(book_.out.account) : QUALITY_ONE;
 
  732        MaxOffersToConsume, j_);
 
  737    bool offerAttempted = 
false;
 
  739    auto execOffer = [&](
auto& offer) {
 
  743            ofrQ = offer.quality();
 
  744        else if (*ofrQ != offer.quality())
 
  747        if (
static_cast<TDerived const*
>(
this)->limitSelfCrossQuality(
 
  748                strandSrc_, strandDst_, offer, ofrQ, offers, offerAttempted))
 
  753        if (!
isXRP(offer.issueIn().currency) &&
 
  754            offer.owner() != offer.issueIn().account)
 
  756            auto const& issuerID = offer.issueIn().account;
 
  761                auto const& ownerID = offer.owner();
 
  762                auto const authFlag =
 
  765                auto const line = afView.
read(
 
  766                    keylet::line(ownerID, issuerID, offer.issueIn().currency));
 
  768                if (!line || (((*line)[sfFlags] & authFlag) == 0))
 
  772                    if (
auto const key = offer.
key())
 
  773                        offers.permRmOffer(*key);
 
  783        if (!
static_cast<TDerived const*
>(
this)->checkQualityThreshold(
 
  787        auto const [ofrInRate, ofrOutRate] = offer.adjustRates(
 
  788            static_cast<TDerived const*
>(
this)->getOfrInRate(
 
  789                prevStep_, offer.owner(), trIn),
 
  790            static_cast<TDerived const*
>(
this)->getOfrOutRate(
 
  791                prevStep_, offer.owner(), strandDst_, trOut));
 
  793        auto ofrAmt = offer.amount();
 
  795            mulRatio(ofrAmt.in, ofrInRate, QUALITY_ONE,  
true),
 
  800            mulRatio(ofrAmt.out, ofrOutRate, QUALITY_ONE,  
false);
 
  802        auto const funds = offer.isFunded()
 
  804            : offers.ownerFunds();
 
  807        if (funds < ownerGives)
 
  812                ownerGives, QUALITY_ONE, ofrOutRate,  
false);
 
  817            ofrAmt = offer.limitOut(ofrAmt, stpAmt.out,  
false);
 
  820                mulRatio(ofrAmt.in, ofrInRate, QUALITY_ONE,  
true);
 
  823        offerAttempted = 
true;
 
  825            offer, ofrAmt, stpAmt, ownerGives, ofrInRate, ofrOutRate);
 
  838                return static_cast<TDerived const*
>(
this)->qualityThreshold(
 
  842        auto ammOffer = getAMMOffer(sb, qualityThreshold);
 
  843        return !ammOffer || execOffer(*ammOffer);
 
  848        if (tryAMM(offers.tip().quality()))
 
  852                if (!execOffer(offers.tip()))
 
  854            } 
while (offers.step());
 
  863    return {offers.permToRemove(), counter.
count()};
 
 
  866template <
class TIn, 
class TOut, 
class TDerived>
 
  867template <
template <
typename, 
typename> 
typename Offer>
 
  872    TAmounts<TIn, TOut> 
const& ofrAmt,
 
  873    TAmounts<TIn, TOut> 
const& stepAmt,
 
  874    TOut 
const& ownerGives)
 const 
  876    if (!offer.checkInvariant(ofrAmt, j_))
 
  882            Throw<FlowException>(
 
  890        auto const dr = offer.send(
 
  897            Throw<FlowException>(dr);
 
  903        auto const cr = offer.send(
 
  910            Throw<FlowException>(cr);
 
  913    offer.consume(sb, ofrAmt);
 
 
  916template <
class TIn, 
class TOut, 
class TDerived>
 
  923        return ammLiquidity_->getOffer(view, clobQuality);
 
 
  927template <
class TIn, 
class TOut, 
class TDerived>
 
  934    auto const lobQuality =
 
  955            return static_cast<TDerived const*
>(
this)->qualityThreshold(
 
  960    if (
auto const ammOffer = getAMMOffer(view, qualityThreshold); ammOffer &&
 
  961        ((lobQuality && ammOffer->quality() > lobQuality) || !lobQuality))
 
 
  967template <
class TIn, 
class TOut, 
class TDerived>
 
  972    if (
auto const res = tip(view); !res)
 
 
  981template <
class TIn, 
class TOut, 
class TDerived>
 
  985    if (
auto const res = tip(view); !res)
 
 
 
  993template <
class TCollection>
 
  995sum(TCollection 
const& col)
 
  999        return TResult{beast::zero};
 
 
 1003template <
class TIn, 
class TOut, 
class TDerived>
 
 1008    boost::container::flat_set<uint256>& ofrsToRm,
 
 1013    TAmounts<TIn, TOut> result(beast::zero, beast::zero);
 
 1015    auto remainingOut = 
out;
 
 1017    boost::container::flat_multiset<TIn> savedIns;
 
 1018    savedIns.reserve(64);
 
 1019    boost::container::flat_multiset<TOut> savedOuts;
 
 1020    savedOuts.reserve(64);
 
 1026    auto eachOffer = [&](
auto& offer,
 
 1027                         TAmounts<TIn, TOut> 
const& ofrAmt,
 
 1028                         TAmounts<TIn, TOut> 
const& stpAmt,
 
 1029                         TOut 
const& ownerGives,
 
 1032        if (remainingOut <= beast::zero)
 
 1035        if (stpAmt.out <= remainingOut)
 
 1037            savedIns.insert(stpAmt.in);
 
 1038            savedOuts.insert(stpAmt.out);
 
 1039            result = TAmounts<TIn, TOut>(
sum(savedIns), 
sum(savedOuts));
 
 1040            remainingOut = 
out - result.out;
 
 1041            this->consumeOffer(sb, offer, ofrAmt, stpAmt, ownerGives);
 
 1048            auto ofrAdjAmt = ofrAmt;
 
 1049            auto stpAdjAmt = stpAmt;
 
 1050            auto ownerGivesAdj = ownerGives;
 
 1059            remainingOut = beast::zero;
 
 1060            savedIns.insert(stpAdjAmt.in);
 
 1061            savedOuts.insert(remainingOut);
 
 1062            result.in = 
sum(savedIns);
 
 1064            this->consumeOffer(sb, offer, ofrAdjAmt, stpAdjAmt, ownerGivesAdj);
 
 1071            return offer.fully_consumed();
 
 1076        auto const prevStepDebtDir = [&] {
 
 1081        auto const r = forEachOffer(sb, afView, prevStepDebtDir, eachOffer);
 
 1082        boost::container::flat_set<uint256> toRm = std::move(
std::get<0>(r));
 
 1084        offersUsed_ = offersConsumed;
 
 1088        if (offersConsumed >= MaxOffersToConsume)
 
 1094    switch (remainingOut.signum())
 
 1100                << 
"BookStep remainingOut < 0 " << 
to_string(remainingOut);
 
 1101            UNREACHABLE(
"ripple::BookStep::revImp : remaining less than zero");
 
 1102            cache_.emplace(beast::zero, beast::zero);
 
 1103            return {beast::zero, beast::zero};
 
 1113    cache_.emplace(result.in, result.out);
 
 1114    return {result.in, result.out};
 
 
 1117template <
class TIn, 
class TOut, 
class TDerived>
 
 1122    boost::container::flat_set<uint256>& ofrsToRm,
 
 1125    XRPL_ASSERT(cache_, 
"ripple::BookStep::fwdImp : cache is set");
 
 1127    TAmounts<TIn, TOut> result(beast::zero, beast::zero);
 
 1129    auto remainingIn = 
in;
 
 1131    boost::container::flat_multiset<TIn> savedIns;
 
 1132    savedIns.reserve(64);
 
 1133    boost::container::flat_multiset<TOut> savedOuts;
 
 1134    savedOuts.reserve(64);
 
 1138    auto eachOffer = [&](
auto& offer,
 
 1139                         TAmounts<TIn, TOut> 
const& ofrAmt,
 
 1140                         TAmounts<TIn, TOut> 
const& stpAmt,
 
 1141                         TOut 
const& ownerGives,
 
 1145            cache_, 
"ripple::BookStep::fwdImp::eachOffer : cache is set");
 
 1147        if (remainingIn <= beast::zero)
 
 1150        bool processMore = 
true;
 
 1151        auto ofrAdjAmt = ofrAmt;
 
 1152        auto stpAdjAmt = stpAmt;
 
 1153        auto ownerGivesAdj = ownerGives;
 
 1155        typename boost::container::flat_multiset<TOut>::const_iterator lastOut;
 
 1156        if (stpAmt.in <= remainingIn)
 
 1158            savedIns.insert(stpAmt.in);
 
 1159            lastOut = savedOuts.insert(stpAmt.out);
 
 1160            result = TAmounts<TIn, TOut>(
sum(savedIns), 
sum(savedOuts));
 
 1174            savedIns.insert(remainingIn);
 
 1175            lastOut = savedOuts.insert(stpAdjAmt.out);
 
 1176            result.out = 
sum(savedOuts);
 
 1179            processMore = 
false;
 
 1182        if (result.out > cache_->out && result.in <= cache_->in)
 
 1191            auto const lastOutAmt = *lastOut;
 
 1192            savedOuts.erase(lastOut);
 
 1193            auto const remainingOut = cache_->out - 
sum(savedOuts);
 
 1194            auto ofrAdjAmtRev = ofrAmt;
 
 1195            auto stpAdjAmtRev = stpAmt;
 
 1196            auto ownerGivesAdjRev = ownerGives;
 
 1206            if (stpAdjAmtRev.in == remainingIn)
 
 1209                result.out = cache_->out;
 
 1212                savedIns.insert(result.in);
 
 1214                savedOuts.insert(result.out);
 
 1216                ofrAdjAmt = ofrAdjAmtRev;
 
 1217                stpAdjAmt.in = remainingIn;
 
 1218                stpAdjAmt.out = remainingOut;
 
 1219                ownerGivesAdj = ownerGivesAdjRev;
 
 1225                savedOuts.insert(lastOutAmt);
 
 1229        remainingIn = 
in - result.in;
 
 1230        this->consumeOffer(sb, offer, ofrAdjAmt, stpAdjAmt, ownerGivesAdj);
 
 1236        return processMore || offer.fully_consumed();
 
 1240        auto const prevStepDebtDir = [&] {
 
 1245        auto const r = forEachOffer(sb, afView, prevStepDebtDir, eachOffer);
 
 1246        boost::container::flat_set<uint256> toRm = std::move(
std::get<0>(r));
 
 1248        offersUsed_ = offersConsumed;
 
 1252        if (offersConsumed >= MaxOffersToConsume)
 
 1258    switch (remainingIn.signum())
 
 1264                << 
"BookStep remainingIn < 0 " << 
to_string(remainingIn);
 
 1265            UNREACHABLE(
"ripple::BookStep::fwdImp : remaining less than zero");
 
 1266            cache_.emplace(beast::zero, beast::zero);
 
 1267            return {beast::zero, beast::zero};
 
 1277    cache_.emplace(result.in, result.out);
 
 1278    return {result.in, result.out};
 
 
 1281template <
class TIn, 
class TOut, 
class TDerived>
 
 1290        JLOG(j_.
trace()) << 
"Expected valid cache in validFwd";
 
 1294    auto const savCache = *cache_;
 
 1298        boost::container::flat_set<uint256> dummy;
 
 1299        fwdImp(sb, afView, dummy, get<TIn>(
in));  
 
 1301    catch (FlowException 
const&)
 
 1306    if (!(
checkNear(savCache.in, cache_->in) &&
 
 1309        JLOG(j_.
warn()) << 
"Strand re-execute check failed." 
 1310                        << 
" ExpectedIn: " << 
to_string(savCache.in)
 
 1311                        << 
" CachedIn: " << 
to_string(cache_->in)
 
 1312                        << 
" ExpectedOut: " << 
to_string(savCache.out)
 
 1313                        << 
" CachedOut: " << 
to_string(cache_->out);
 
 
 1319template <
class TIn, 
class TOut, 
class TDerived>
 
 1323    if (book_.in == book_.out)
 
 1325        JLOG(j_.
debug()) << 
"BookStep: Book with same in and out issuer " 
 1331        JLOG(j_.
debug()) << 
"Book: currency is inconsistent with issuer." 
 1341        JLOG(j_.
debug()) << 
"BookStep: loop detected: " << *
this;
 
 1347        JLOG(j_.
debug()) << 
"BookStep: loop detected: " << *
this;
 
 1351    auto issuerExists = [](
ReadView const& view, 
Issue const& iss) -> 
bool {
 
 1355    if (!issuerExists(ctx.
view, book_.in) || !issuerExists(ctx.
view, book_.out))
 
 1357        JLOG(j_.
debug()) << 
"BookStep: deleted issuer detected: " << *
this;
 
 1365            auto const& view = ctx.
view;
 
 1366            auto const& cur = book_.in.account;
 
 1371            if ((*sle)[sfFlags] &
 
 
 1385template <
class TIn, 
class TOut, 
class TDerived>
 
 1390        return book == bs->book();
 
 
 1399    if (inXRP && outXRP)
 
 1402        UNREACHABLE(
"ripple::test::bookStepEqual : no XRP to XRP book step");
 
 1406    if (inXRP && !outXRP)
 
 1411    if (!inXRP && outXRP)
 
 1416    if (!inXRP && !outXRP)
 
 
 1427template <
class TIn, 
class TOut>
 
 1435        auto offerCrossingStep =
 
 1437        ter = offerCrossingStep->check(ctx);
 
 1438        r = std::move(offerCrossingStep);
 
 1444        ter = paymentStep->check(ctx);
 
 1445        r = std::move(paymentStep);
 
 1448        return {ter, 
nullptr};
 
 
 1456    return make_BookStepHelper<IOUAmount, IOUAmount>(ctx, 
in, 
out);
 
 
 1462    return make_BookStepHelper<IOUAmount, XRPAmount>(ctx, 
in, 
xrpIssue());
 
 
 1468    return make_BookStepHelper<XRPAmount, IOUAmount>(ctx, 
xrpIssue(), 
out);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
AccountID account() const
 
Represents synthetic AMM offer in BookStep.
 
Quality quality() const noexcept
 
Writeable view to a ledger, for applying a transaction.
 
std::uint32_t getOfrInRate(Step const *prevStep, AccountID const &owner, std::uint32_t trIn) const
 
static Quality getQuality(std::optional< Quality > const &limitQuality)
 
BookOfferCrossingStep(StrandContext const &ctx, Issue const &in, Issue const &out)
 
bool checkQualityThreshold(Quality const &quality) const
 
std::string logString() const override
 
std::uint32_t getOfrOutRate(Step const *prevStep, AccountID const &owner, AccountID const &strandDst, std::uint32_t trOut) const
 
bool limitSelfCrossQuality(AccountID const &strandSrc, AccountID const &strandDst, Offer< TIn, TOut > const &offer, std::optional< Quality > &ofrQ, FlowOfferStream< TIn, TOut > &offers, bool const offerAttempted) const
 
Quality const qualityThreshold_
 
std::optional< Quality > qualityThreshold(Quality const &lobQuality) const
 
Quality adjustQualityWithFees(ReadView const &v, Quality const &ofrQ, DebtDirection prevStepDir, WaiveTransferFee waiveFee, OfferType offerType, Rules const &rules) const
 
bool limitSelfCrossQuality(AccountID const &, AccountID const &, Offer< TIn, TOut > const &offer, std::optional< Quality > &, FlowOfferStream< TIn, TOut > &, bool) const
 
Quality adjustQualityWithFees(ReadView const &v, Quality const &ofrQ, DebtDirection prevStepDir, WaiveTransferFee waiveFee, OfferType, Rules const &) const
 
std::uint32_t getOfrOutRate(Step const *, AccountID const &, AccountID const &, std::uint32_t trOut) const
 
BookPaymentStep()=default
 
std::uint32_t getOfrInRate(Step const *, AccountID const &, std::uint32_t trIn) const
 
bool checkQualityThreshold(Quality const &quality) const
 
std::optional< Quality > qualityThreshold(Quality const &lobQuality) const
 
std::string logString() const override
 
std::optional< AMMOffer< TIn, TOut > > getAMMOffer(ReadView const &view, std::optional< Quality > const &clobQuality) const
 
std::optional< AMMLiquidity< TIn, TOut > > ammLiquidity_
 
friend bool operator==(BookStep const &lhs, BookStep const &rhs)
 
std::uint32_t offersUsed() const override
 
std::optional< Book > bookStepBook() const override
 
std::uint32_t offersUsed_
Number of offers consumed or partially consumed the last time the step ran, including expired and unf...
 
std::optional< EitherAmount > cachedOut() const override
 
std::optional< std::pair< Quality, OfferType > > tipOfferQuality(ReadView const &view) const
 
void consumeOffer(PaymentSandbox &sb, Offer< TIn, TOut > &offer, TAmounts< TIn, TOut > const &ofrAmt, TAmounts< TIn, TOut > const &stepAmt, TOut const &ownerGives) const
 
std::pair< std::optional< QualityFunction >, DebtDirection > getQualityFunc(ReadView const &v, DebtDirection prevStepDir) const override
 
TER check(StrandContext const &ctx) const
 
std::pair< boost::container::flat_set< uint256 >, std::uint32_t > forEachOffer(PaymentSandbox &sb, ApplyView &afView, DebtDirection prevStepDebtDir, Callback &callback) const
 
std::pair< bool, EitherAmount > validFwd(PaymentSandbox &sb, ApplyView &afView, EitherAmount const &in) override
 
Book const & book() const
 
std::optional< EitherAmount > cachedIn() const override
 
bool equal(Step const &rhs) const override
 
DebtDirection debtDirection(ReadView const &sb, StrandDirection dir) const override
 
std::pair< TIn, TOut > revImp(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, TOut const &out)
 
static constexpr uint32_t MaxOffersToConsume
 
Step const  *const prevStep_
 
friend bool operator!=(BookStep const &lhs, BookStep const &rhs)
 
std::string logStringImpl(char const *name) const
 
BookStep(StrandContext const &ctx, Issue const &in, Issue const &out)
 
std::pair< TIn, TOut > fwdImp(PaymentSandbox &sb, ApplyView &afView, boost::container::flat_set< uint256 > &ofrsToRm, TIn const &in)
 
std::optional< QualityFunction > tipOfferQualityF(ReadView const &view) const
 
bool inactive() const override
 
std::optional< std::variant< Quality, AMMOffer< TIn, TOut > > > tip(ReadView const &view) const
 
std::pair< std::optional< Quality >, DebtDirection > qualityUpperBound(ReadView const &v, DebtDirection prevStepDir) const override
 
bool const ownerPaysTransferFee_
 
std::optional< Cache > cache_
 
Iterates and consumes raw offers in an order book.
 
bool step(beast::Journal j)
Erases the current offer and advance to the next offer.
 
Quality const & quality() const noexcept
 
Presents and consumes the offers in an order book.
 
Floating point representation of amounts with high dynamic range.
 
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,...
 
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
 
NetClock::time_point parentCloseTime() const
Returns the close time of the previous ledger.
 
virtual Rules const & rules() const =0
Returns the tx processing rules.
 
Rules controlling protocol behavior.
 
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
 
static std::uint64_t const uRateOne
 
Discardable, editable view to a ledger.
 
A step in a payment path.
 
virtual std::optional< Book > bookStepBook() const
If this step is a BookStep, return the book.
 
virtual std::optional< AccountID > directStepSrcAcct() const
If this step is DirectStepI (IOU->IOU direct step), return the src account.
 
std::uint32_t count() const
 
Rules const & rules() const override
Returns the tx processing rules.
 
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
 
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
static bool equalHelper(Step const &step, ripple::Book const &book)
 
bool bookStepEqual(Step const &step, ripple::Book const &book)
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
 
static auto sum(TCollection const &col)
 
bool isConsistent(Book const &book)
 
bool isXRP(AccountID const &c)
 
static void limitStepIn(Offer const &offer, TAmounts< TIn, TOut > &ofrAmt, TAmounts< TIn, TOut > &stpAmt, TOut &ownerGives, std::uint32_t transferRateIn, std::uint32_t transferRateOut, TIn const &limit)
 
std::uint16_t getTradingFee(ReadView const &view, SLE const &ammSle, AccountID const &account)
Get AMM trading fee for the given account.
 
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
 
static bool isDefaultPath(STPath const &path)
 
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
 
Quality composed_quality(Quality const &lhs, Quality const &rhs)
 
void SetUnion(boost::container::flat_set< T > &dst, boost::container::flat_set< T > const &src)
Given two flat sets dst and src, compute dst = dst union src.
 
std::pair< TER, std::unique_ptr< Step > > make_BookStepXI(StrandContext const &ctx, Issue const &out)
 
std::pair< TER, std::unique_ptr< Step > > make_BookStepIX(StrandContext const &ctx, Issue const &in)
 
bool checkNear(IOUAmount const &expected, IOUAmount const &actual)
 
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
 
static void limitStepOut(Offer const &offer, TAmounts< TIn, TOut > &ofrAmt, TAmounts< TIn, TOut > &stpAmt, TOut &ownerGives, std::uint32_t transferRateIn, std::uint32_t transferRateOut, TOut const &limit)
 
static std::pair< TER, std::unique_ptr< Step > > make_BookStepHelper(StrandContext const &ctx, Issue const &in, Issue const &out)
 
std::pair< TER, std::unique_ptr< Step > > make_BookStepII(StrandContext const &ctx, Issue const &in, Issue const &out)
 
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
Rate const parityRate
A transfer rate signifying a 1:1 exchange.
 
Cache(TIn const &in_, TOut 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.
 
ReadView const  & view
Current ReadView.
 
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.
 
OfferCrossing const offerCrossing
Yes/Sell if offer crossing, not payment.