mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 01:07:57 +00:00
Use enums for some parameters in payments:
* Use enums for StrandDirection, DebtDirection, and QualityDirection
This commit is contained in:
@@ -110,10 +110,11 @@ public:
|
|||||||
return EitherAmount (cache_->out);
|
return EitherAmount (cache_->out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
DebtDirection
|
||||||
redeems (ReadView const& sb, bool fwd) const override
|
debtDirection(ReadView const& sb, StrandDirection dir) const override
|
||||||
{
|
{
|
||||||
return !ownerPaysTransferFee_;
|
return ownerPaysTransferFee_ ? DebtDirection::issues
|
||||||
|
: DebtDirection::redeems;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<Book>
|
boost::optional<Book>
|
||||||
@@ -123,7 +124,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<Quality>
|
boost::optional<Quality>
|
||||||
qualityUpperBound(ReadView const& v, bool& redeems) const override;
|
qualityUpperBound(ReadView const& v, DebtDirection& dir) const override;
|
||||||
|
|
||||||
std::pair<TIn, TOut>
|
std::pair<TIn, TOut>
|
||||||
revImp (
|
revImp (
|
||||||
@@ -188,7 +189,7 @@ private:
|
|||||||
forEachOffer (
|
forEachOffer (
|
||||||
PaymentSandbox& sb,
|
PaymentSandbox& sb,
|
||||||
ApplyView& afView,
|
ApplyView& afView,
|
||||||
bool prevStepRedeems,
|
DebtDirection prevStepDebtDir,
|
||||||
Callback& callback) const;
|
Callback& callback) const;
|
||||||
|
|
||||||
void consumeOffer (PaymentSandbox& sb,
|
void consumeOffer (PaymentSandbox& sb,
|
||||||
@@ -248,7 +249,7 @@ public:
|
|||||||
Quality
|
Quality
|
||||||
qualityUpperBound(ReadView const& v,
|
qualityUpperBound(ReadView const& v,
|
||||||
Quality const& ofrQ,
|
Quality const& ofrQ,
|
||||||
bool prevStepRedeems) const
|
DebtDirection prevStepDir) const
|
||||||
{
|
{
|
||||||
// Charge the offer owner, not the sender
|
// Charge the offer owner, not the sender
|
||||||
// Charge a fee even if the owner is the same as the issuer
|
// Charge a fee even if the owner is the same as the issuer
|
||||||
@@ -262,7 +263,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto const trIn =
|
auto const trIn =
|
||||||
prevStepRedeems ? rate(this->book_.in.account) : parityRate;
|
redeems(prevStepDir) ? rate(this->book_.in.account) : parityRate;
|
||||||
// Always charge the transfer fee, even if the owner is the issuer
|
// Always charge the transfer fee, even if the owner is the issuer
|
||||||
auto const trOut =
|
auto const trOut =
|
||||||
this->ownerPaysTransferFee_
|
this->ownerPaysTransferFee_
|
||||||
@@ -393,7 +394,7 @@ public:
|
|||||||
Quality
|
Quality
|
||||||
qualityUpperBound(ReadView const& v,
|
qualityUpperBound(ReadView const& v,
|
||||||
Quality const& ofrQ,
|
Quality const& ofrQ,
|
||||||
bool prevStepRedeems) const
|
DebtDirection prevStepDir) const
|
||||||
{
|
{
|
||||||
// Offer x-ing does not charge a transfer fee when the offer's owner
|
// Offer x-ing does not charge a transfer fee when the offer's owner
|
||||||
// is the same as the strand dst. It is important that `qualityUpperBound`
|
// is the same as the strand dst. It is important that `qualityUpperBound`
|
||||||
@@ -427,10 +428,10 @@ bool BookStep<TIn, TOut, TDerived>::equal (Step const& rhs) const
|
|||||||
template <class TIn, class TOut, class TDerived>
|
template <class TIn, class TOut, class TDerived>
|
||||||
boost::optional<Quality>
|
boost::optional<Quality>
|
||||||
BookStep<TIn, TOut, TDerived>::qualityUpperBound(
|
BookStep<TIn, TOut, TDerived>::qualityUpperBound(
|
||||||
ReadView const& v, bool& redeems) const
|
ReadView const& v, DebtDirection& dir) const
|
||||||
{
|
{
|
||||||
auto const prevStepRedeems = redeems;
|
auto const prevStepDir = dir;
|
||||||
redeems = this->redeems(v, true);
|
dir = this->debtDirection(v, StrandDirection::forward);
|
||||||
|
|
||||||
// This can be simplified (and sped up) if directories are never empty.
|
// This can be simplified (and sped up) if directories are never empty.
|
||||||
Sandbox sb(&v, tapNONE);
|
Sandbox sb(&v, tapNONE);
|
||||||
@@ -439,7 +440,7 @@ BookStep<TIn, TOut, TDerived>::qualityUpperBound(
|
|||||||
return boost::none;
|
return boost::none;
|
||||||
|
|
||||||
return static_cast<TDerived const*>(this)->qualityUpperBound(
|
return static_cast<TDerived const*>(this)->qualityUpperBound(
|
||||||
v, bt.quality(), prevStepRedeems);
|
v, bt.quality(), prevStepDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the offer amount and step amount subject to the given input limit
|
// Adjust the offer amount and step amount subject to the given input limit
|
||||||
@@ -493,7 +494,7 @@ std::pair<boost::container::flat_set<uint256>, std::uint32_t>
|
|||||||
BookStep<TIn, TOut, TDerived>::forEachOffer (
|
BookStep<TIn, TOut, TDerived>::forEachOffer (
|
||||||
PaymentSandbox& sb,
|
PaymentSandbox& sb,
|
||||||
ApplyView& afView,
|
ApplyView& afView,
|
||||||
bool prevStepRedeems,
|
DebtDirection prevStepDir,
|
||||||
Callback& callback) const
|
Callback& callback) const
|
||||||
{
|
{
|
||||||
// Charge the offer owner, not the sender
|
// Charge the offer owner, not the sender
|
||||||
@@ -507,9 +508,8 @@ BookStep<TIn, TOut, TDerived>::forEachOffer (
|
|||||||
return transferRate (sb, id).value;
|
return transferRate (sb, id).value;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::uint32_t const trIn = prevStepRedeems
|
std::uint32_t const trIn =
|
||||||
? rate (book_.in.account)
|
redeems(prevStepDir) ? rate(book_.in.account) : QUALITY_ONE;
|
||||||
: QUALITY_ONE;
|
|
||||||
// Always charge the transfer fee, even if the owner is the issuer
|
// Always charge the transfer fee, even if the owner is the issuer
|
||||||
std::uint32_t const trOut = ownerPaysTransferFee_
|
std::uint32_t const trOut = ownerPaysTransferFee_
|
||||||
? rate (book_.out.account)
|
? rate (book_.out.account)
|
||||||
@@ -726,8 +726,12 @@ BookStep<TIn, TOut, TDerived>::revImp (
|
|||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
auto const prevStepRedeems = prevStep_ && prevStep_->redeems (sb, false);
|
auto const prevStepDebtDir = [&]{
|
||||||
auto const r = forEachOffer (sb, afView, prevStepRedeems, eachOffer);
|
if (prevStep_)
|
||||||
|
return prevStep_->debtDirection (sb, StrandDirection::reverse);
|
||||||
|
return DebtDirection::issues;
|
||||||
|
}();
|
||||||
|
auto const r = forEachOffer (sb, afView, prevStepDebtDir, eachOffer);
|
||||||
boost::container::flat_set<uint256> toRm = std::move(std::get<0>(r));
|
boost::container::flat_set<uint256> toRm = std::move(std::get<0>(r));
|
||||||
std::uint32_t const offersConsumed = std::get<1>(r);
|
std::uint32_t const offersConsumed = std::get<1>(r);
|
||||||
SetUnion(ofrsToRm, toRm);
|
SetUnion(ofrsToRm, toRm);
|
||||||
@@ -887,8 +891,12 @@ BookStep<TIn, TOut, TDerived>::fwdImp (
|
|||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
auto const prevStepRedeems = prevStep_ && prevStep_->redeems (sb, true);
|
auto const prevStepDebtDir = [&] {
|
||||||
auto const r = forEachOffer (sb, afView, prevStepRedeems, eachOffer);
|
if (prevStep_)
|
||||||
|
return prevStep_->debtDirection(sb, StrandDirection::forward);
|
||||||
|
return DebtDirection::issues;
|
||||||
|
}();
|
||||||
|
auto const r = forEachOffer(sb, afView, prevStepDebtDir, eachOffer);
|
||||||
boost::container::flat_set<uint256> toRm = std::move(std::get<0>(r));
|
boost::container::flat_set<uint256> toRm = std::move(std::get<0>(r));
|
||||||
std::uint32_t const offersConsumed = std::get<1>(r);
|
std::uint32_t const offersConsumed = std::get<1>(r);
|
||||||
SetUnion(ofrsToRm, toRm);
|
SetUnion(ofrsToRm, toRm);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <ripple/protocol/Quality.h>
|
#include <ripple/protocol/Quality.h>
|
||||||
|
|
||||||
#include <boost/container/flat_set.hpp>
|
#include <boost/container/flat_set.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -50,17 +51,17 @@ protected:
|
|||||||
IOUAmount in;
|
IOUAmount in;
|
||||||
IOUAmount srcToDst;
|
IOUAmount srcToDst;
|
||||||
IOUAmount out;
|
IOUAmount out;
|
||||||
bool srcRedeems;
|
DebtDirection srcDebtDir;
|
||||||
|
|
||||||
Cache (
|
Cache (
|
||||||
IOUAmount const& in_,
|
IOUAmount const& in_,
|
||||||
IOUAmount const& srcToDst_,
|
IOUAmount const& srcToDst_,
|
||||||
IOUAmount const& out_,
|
IOUAmount const& out_,
|
||||||
bool srcRedeems_)
|
DebtDirection srcDebtDir_)
|
||||||
: in(in_)
|
: in(in_)
|
||||||
, srcToDst(srcToDst_)
|
, srcToDst(srcToDst_)
|
||||||
, out(out_)
|
, out(out_)
|
||||||
, srcRedeems(srcRedeems_)
|
, srcDebtDir(srcDebtDir_)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,17 +70,28 @@ protected:
|
|||||||
// Compute the maximum value that can flow from src->dst at
|
// Compute the maximum value that can flow from src->dst at
|
||||||
// the best available quality.
|
// the best available quality.
|
||||||
// return: first element is max amount that can flow,
|
// return: first element is max amount that can flow,
|
||||||
// second is true if dst holds an iou from src.
|
// second is the debt direction of the source w.r.t. the dst
|
||||||
std::pair<IOUAmount, bool>
|
std::pair<IOUAmount, DebtDirection>
|
||||||
maxPaymentFlow (
|
maxPaymentFlow (
|
||||||
ReadView const& sb) const;
|
ReadView const& sb) const;
|
||||||
|
|
||||||
|
// Compute srcQOut and dstQIn when the source redeems.
|
||||||
|
std::pair<std::uint32_t, std::uint32_t>
|
||||||
|
qualitiesSrcRedeems(
|
||||||
|
ReadView const& sb) const;
|
||||||
|
|
||||||
|
// Compute srcQOut and dstQIn when the source issues.
|
||||||
|
std::pair<std::uint32_t, std::uint32_t>
|
||||||
|
qualitiesSrcIssues(
|
||||||
|
ReadView const& sb,
|
||||||
|
DebtDirection prevStepDebtDirection) const;
|
||||||
|
|
||||||
// Returns srcQOut, dstQIn
|
// Returns srcQOut, dstQIn
|
||||||
std::pair <std::uint32_t, std::uint32_t>
|
std::pair <std::uint32_t, std::uint32_t>
|
||||||
qualities (
|
qualities (
|
||||||
ReadView const& sb,
|
ReadView const& sb,
|
||||||
bool srcRedeems,
|
DebtDirection srcDebtDir,
|
||||||
bool fwd) const;
|
StrandDirection strandDir) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirectStepI (
|
DirectStepI (
|
||||||
@@ -135,14 +147,14 @@ public:
|
|||||||
return std::make_pair(src_, dst_);
|
return std::make_pair(src_, dst_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
DebtDirection
|
||||||
redeems (ReadView const& sb, bool fwd) const override;
|
debtDirection (ReadView const& sb, StrandDirection dir) const override;
|
||||||
|
|
||||||
std::uint32_t
|
std::uint32_t
|
||||||
lineQualityIn (ReadView const& v) const override;
|
lineQualityIn (ReadView const& v) const override;
|
||||||
|
|
||||||
boost::optional<Quality>
|
boost::optional<Quality>
|
||||||
qualityUpperBound(ReadView const& v, bool& redeems) const override;
|
qualityUpperBound(ReadView const& v, DebtDirection& dir) const override;
|
||||||
|
|
||||||
std::pair<IOUAmount, IOUAmount>
|
std::pair<IOUAmount, IOUAmount>
|
||||||
revImp (
|
revImp (
|
||||||
@@ -172,7 +184,7 @@ public:
|
|||||||
IOUAmount const& fwdIn,
|
IOUAmount const& fwdIn,
|
||||||
IOUAmount const& fwdSrcToDst,
|
IOUAmount const& fwdSrcToDst,
|
||||||
IOUAmount const& fwdOut,
|
IOUAmount const& fwdOut,
|
||||||
bool srcRedeems);
|
DebtDirection srcDebtDir);
|
||||||
|
|
||||||
friend bool operator==(DirectStepI const& lhs, DirectStepI const& rhs)
|
friend bool operator==(DirectStepI const& lhs, DirectStepI const& rhs)
|
||||||
{
|
{
|
||||||
@@ -223,7 +235,7 @@ public:
|
|||||||
using DirectStepI<DirectIPaymentStep>::DirectStepI;
|
using DirectStepI<DirectIPaymentStep>::DirectStepI;
|
||||||
using DirectStepI<DirectIPaymentStep>::check;
|
using DirectStepI<DirectIPaymentStep>::check;
|
||||||
|
|
||||||
bool verifyPrevStepRedeems (bool) const
|
bool verifyPrevStepDebtDirection (DebtDirection) const
|
||||||
{
|
{
|
||||||
// A payment doesn't care whether or not prevStepRedeems.
|
// A payment doesn't care whether or not prevStepRedeems.
|
||||||
return true;
|
return true;
|
||||||
@@ -237,14 +249,13 @@ public:
|
|||||||
|
|
||||||
std::uint32_t
|
std::uint32_t
|
||||||
quality (ReadView const& sb,
|
quality (ReadView const& sb,
|
||||||
// set true for quality in, false for quality out
|
QualityDirection qDir) const;
|
||||||
bool qin) const;
|
|
||||||
|
|
||||||
// Compute the maximum value that can flow from src->dst at
|
// Compute the maximum value that can flow from src->dst at
|
||||||
// the best available quality.
|
// the best available quality.
|
||||||
// return: first element is max amount that can flow,
|
// return: first element is max amount that can flow,
|
||||||
// second is true if dst holds an iou from src.
|
// second is the debt direction w.r.t. the source account
|
||||||
std::pair<IOUAmount, bool>
|
std::pair<IOUAmount, DebtDirection>
|
||||||
maxFlow (ReadView const& sb, IOUAmount const& desired) const;
|
maxFlow (ReadView const& sb, IOUAmount const& desired) const;
|
||||||
|
|
||||||
// Verify the consistency of the step. These checks are specific to
|
// Verify the consistency of the step. These checks are specific to
|
||||||
@@ -266,15 +277,15 @@ public:
|
|||||||
using DirectStepI<DirectIOfferCrossingStep>::DirectStepI;
|
using DirectStepI<DirectIOfferCrossingStep>::DirectStepI;
|
||||||
using DirectStepI<DirectIOfferCrossingStep>::check;
|
using DirectStepI<DirectIOfferCrossingStep>::check;
|
||||||
|
|
||||||
bool verifyPrevStepRedeems (bool prevStepRedeems) const
|
bool verifyPrevStepDebtDirection (DebtDirection prevStepDir) const
|
||||||
{
|
{
|
||||||
// During offer crossing we rely on the fact that prevStepRedeems
|
// During offer crossing we rely on the fact that prevStepRedeems
|
||||||
// will *always* be false. That's because:
|
// will *always* issue. That's because:
|
||||||
// o If there's a prevStep_, it will always be a BookStep.
|
// o If there's a prevStep_, it will always be a BookStep.
|
||||||
// o BookStep::redeems() aways returns false when offer crossing.
|
// o BookStep::debtDirection() aways returns `issues` when offer crossing.
|
||||||
// An assert based on this return value will tell us if that
|
// An assert based on this return value will tell us if that
|
||||||
// behavior changes.
|
// behavior changes.
|
||||||
return !prevStepRedeems;
|
return issues(prevStepDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool verifyDstQualityIn (std::uint32_t dstQIn) const
|
bool verifyDstQualityIn (std::uint32_t dstQIn) const
|
||||||
@@ -286,14 +297,13 @@ public:
|
|||||||
|
|
||||||
std::uint32_t
|
std::uint32_t
|
||||||
quality (ReadView const& sb,
|
quality (ReadView const& sb,
|
||||||
// set true for quality in, false for quality out
|
QualityDirection qDir) const;
|
||||||
bool qin) const;
|
|
||||||
|
|
||||||
// Compute the maximum value that can flow from src->dst at
|
// Compute the maximum value that can flow from src->dst at
|
||||||
// the best available quality.
|
// the best available quality.
|
||||||
// return: first element is max amount that can flow,
|
// return: first element is max amount that can flow,
|
||||||
// second is true if dst holds an iou from src.
|
// second is the debt direction w.r.t the source
|
||||||
std::pair<IOUAmount, bool>
|
std::pair<IOUAmount, DebtDirection>
|
||||||
maxFlow (ReadView const& sb, IOUAmount const& desired) const;
|
maxFlow (ReadView const& sb, IOUAmount const& desired) const;
|
||||||
|
|
||||||
// Verify the consistency of the step. These checks are specific to
|
// Verify the consistency of the step. These checks are specific to
|
||||||
@@ -313,8 +323,7 @@ public:
|
|||||||
|
|
||||||
std::uint32_t
|
std::uint32_t
|
||||||
DirectIPaymentStep::quality (ReadView const& sb,
|
DirectIPaymentStep::quality (ReadView const& sb,
|
||||||
// set true for quality in, false for quality out
|
QualityDirection qDir) const
|
||||||
bool qin) const
|
|
||||||
{
|
{
|
||||||
if (src_ == dst_)
|
if (src_ == dst_)
|
||||||
return QUALITY_ONE;
|
return QUALITY_ONE;
|
||||||
@@ -324,9 +333,9 @@ DirectIPaymentStep::quality (ReadView const& sb,
|
|||||||
if (!sle)
|
if (!sle)
|
||||||
return QUALITY_ONE;
|
return QUALITY_ONE;
|
||||||
|
|
||||||
auto const& field = [this, qin]() -> SF_U32 const&
|
auto const& field = [this, qDir]() -> SF_U32 const&
|
||||||
{
|
{
|
||||||
if (qin)
|
if (qDir == QualityDirection::in)
|
||||||
{
|
{
|
||||||
// compute dst quality in
|
// compute dst quality in
|
||||||
if (this->dst_ < this->src_)
|
if (this->dst_ < this->src_)
|
||||||
@@ -355,21 +364,20 @@ DirectIPaymentStep::quality (ReadView const& sb,
|
|||||||
|
|
||||||
std::uint32_t
|
std::uint32_t
|
||||||
DirectIOfferCrossingStep::quality (ReadView const&,
|
DirectIOfferCrossingStep::quality (ReadView const&,
|
||||||
// set true for quality in, false for quality out
|
QualityDirection qDir) const
|
||||||
bool) const
|
|
||||||
{
|
{
|
||||||
// If offer crossing then ignore trust line Quality fields. This
|
// If offer crossing then ignore trust line Quality fields. This
|
||||||
// preserves a long-standing tradition.
|
// preserves a long-standing tradition.
|
||||||
return QUALITY_ONE;
|
return QUALITY_ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<IOUAmount, bool>
|
std::pair<IOUAmount, DebtDirection>
|
||||||
DirectIPaymentStep::maxFlow (ReadView const& sb, IOUAmount const&) const
|
DirectIPaymentStep::maxFlow (ReadView const& sb, IOUAmount const&) const
|
||||||
{
|
{
|
||||||
return maxPaymentFlow (sb);
|
return maxPaymentFlow (sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<IOUAmount, bool>
|
std::pair<IOUAmount, DebtDirection>
|
||||||
DirectIOfferCrossingStep::maxFlow (
|
DirectIOfferCrossingStep::maxFlow (
|
||||||
ReadView const& sb, IOUAmount const& desired) const
|
ReadView const& sb, IOUAmount const& desired) const
|
||||||
{
|
{
|
||||||
@@ -386,7 +394,7 @@ DirectIOfferCrossingStep::maxFlow (
|
|||||||
// "dstQIn" is always QUALITY_ONE for offer crossing.
|
// "dstQIn" is always QUALITY_ONE for offer crossing.
|
||||||
|
|
||||||
if (isLast_)
|
if (isLast_)
|
||||||
return {desired, false};
|
return {desired, DebtDirection::issues};
|
||||||
|
|
||||||
return maxPaymentFlow (sb);
|
return maxPaymentFlow (sb);
|
||||||
}
|
}
|
||||||
@@ -460,29 +468,31 @@ DirectIOfferCrossingStep::check (
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
std::pair<IOUAmount, bool>
|
std::pair<IOUAmount, DebtDirection>
|
||||||
DirectStepI<TDerived>::maxPaymentFlow (ReadView const& sb) const
|
DirectStepI<TDerived>::maxPaymentFlow (ReadView const& sb) const
|
||||||
{
|
{
|
||||||
auto const srcOwed = toAmount<IOUAmount> (
|
auto const srcOwed = toAmount<IOUAmount> (
|
||||||
accountHolds (sb, src_, currency_, dst_, fhIGNORE_FREEZE, j_));
|
accountHolds (sb, src_, currency_, dst_, fhIGNORE_FREEZE, j_));
|
||||||
|
|
||||||
if (srcOwed.signum () > 0)
|
if (srcOwed.signum () > 0)
|
||||||
return {srcOwed, true};
|
return {srcOwed, DebtDirection::redeems};
|
||||||
|
|
||||||
// srcOwed is negative or zero
|
// srcOwed is negative or zero
|
||||||
return {creditLimit2 (sb, dst_, src_, currency_) + srcOwed, false};
|
return {creditLimit2 (sb, dst_, src_, currency_) + srcOwed, DebtDirection::issues};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
bool
|
DebtDirection
|
||||||
DirectStepI<TDerived>::redeems (ReadView const& sb, bool fwd) const
|
DirectStepI<TDerived>::debtDirection(ReadView const& sb, StrandDirection dir)
|
||||||
|
const
|
||||||
{
|
{
|
||||||
if (fwd && cache_)
|
if (dir == StrandDirection::forward && cache_)
|
||||||
return cache_->srcRedeems;
|
return cache_->srcDebtDir;
|
||||||
|
|
||||||
auto const srcOwed = accountHolds (
|
auto const srcOwed =
|
||||||
sb, src_, currency_, dst_, fhIGNORE_FREEZE, j_);
|
accountHolds(sb, src_, currency_, dst_, fhIGNORE_FREEZE, j_);
|
||||||
return srcOwed.signum () > 0;
|
return srcOwed.signum() > 0 ? DebtDirection::redeems
|
||||||
|
: DebtDirection::issues;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
@@ -495,21 +505,22 @@ DirectStepI<TDerived>::revImp (
|
|||||||
{
|
{
|
||||||
cache_.reset ();
|
cache_.reset ();
|
||||||
|
|
||||||
bool srcRedeems;
|
DebtDirection srcDebtDir;
|
||||||
IOUAmount maxSrcToDst;
|
IOUAmount maxSrcToDst;
|
||||||
|
|
||||||
std::tie (maxSrcToDst, srcRedeems) =
|
std::tie (maxSrcToDst, srcDebtDir) =
|
||||||
static_cast<TDerived const*>(this)->maxFlow (sb, out);
|
static_cast<TDerived const*>(this)->maxFlow (sb, out);
|
||||||
|
|
||||||
std::uint32_t srcQOut, dstQIn;
|
std::uint32_t srcQOut, dstQIn;
|
||||||
std::tie (srcQOut, dstQIn) = qualities (sb, srcRedeems, false);
|
std::tie (srcQOut, dstQIn) = qualities (sb, srcDebtDir, StrandDirection::reverse);
|
||||||
assert (static_cast<TDerived const*>(this)->verifyDstQualityIn (dstQIn));
|
assert (static_cast<TDerived const*>(this)->verifyDstQualityIn (dstQIn));
|
||||||
|
|
||||||
Issue const srcToDstIss (currency_, srcRedeems ? dst_ : src_);
|
Issue const srcToDstIss(
|
||||||
|
currency_, redeems(srcDebtDir) ? dst_ : src_);
|
||||||
|
|
||||||
JLOG (j_.trace()) <<
|
JLOG (j_.trace()) <<
|
||||||
"DirectStepI::rev" <<
|
"DirectStepI::rev" <<
|
||||||
" srcRedeems: " << srcRedeems <<
|
" srcRedeems: " << redeems(srcDebtDir) <<
|
||||||
" outReq: " << to_string (out) <<
|
" outReq: " << to_string (out) <<
|
||||||
" maxSrcToDst: " << to_string (maxSrcToDst) <<
|
" maxSrcToDst: " << to_string (maxSrcToDst) <<
|
||||||
" srcQOut: " << srcQOut <<
|
" srcQOut: " << srcQOut <<
|
||||||
@@ -522,7 +533,7 @@ DirectStepI<TDerived>::revImp (
|
|||||||
IOUAmount (beast::zero),
|
IOUAmount (beast::zero),
|
||||||
IOUAmount (beast::zero),
|
IOUAmount (beast::zero),
|
||||||
IOUAmount (beast::zero),
|
IOUAmount (beast::zero),
|
||||||
srcRedeems);
|
srcDebtDir);
|
||||||
return {beast::zero, beast::zero};
|
return {beast::zero, beast::zero};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,13 +544,13 @@ DirectStepI<TDerived>::revImp (
|
|||||||
{
|
{
|
||||||
IOUAmount const in = mulRatio (
|
IOUAmount const in = mulRatio (
|
||||||
srcToDst, srcQOut, QUALITY_ONE, /*roundUp*/ true);
|
srcToDst, srcQOut, QUALITY_ONE, /*roundUp*/ true);
|
||||||
cache_.emplace (in, srcToDst, out, srcRedeems);
|
cache_.emplace (in, srcToDst, out, srcDebtDir);
|
||||||
rippleCredit (sb,
|
rippleCredit (sb,
|
||||||
src_, dst_, toSTAmount (srcToDst, srcToDstIss),
|
src_, dst_, toSTAmount (srcToDst, srcToDstIss),
|
||||||
/*checkIssuer*/ true, j_);
|
/*checkIssuer*/ true, j_);
|
||||||
JLOG (j_.trace()) <<
|
JLOG (j_.trace()) <<
|
||||||
"DirectStepI::rev: Non-limiting" <<
|
"DirectStepI::rev: Non-limiting" <<
|
||||||
" srcRedeems: " << srcRedeems <<
|
" srcRedeems: " << redeems(srcDebtDir) <<
|
||||||
" in: " << to_string (in) <<
|
" in: " << to_string (in) <<
|
||||||
" srcToDst: " << to_string (srcToDst) <<
|
" srcToDst: " << to_string (srcToDst) <<
|
||||||
" out: " << to_string (out);
|
" out: " << to_string (out);
|
||||||
@@ -551,13 +562,13 @@ DirectStepI<TDerived>::revImp (
|
|||||||
maxSrcToDst, srcQOut, QUALITY_ONE, /*roundUp*/ true);
|
maxSrcToDst, srcQOut, QUALITY_ONE, /*roundUp*/ true);
|
||||||
IOUAmount const actualOut = mulRatio (
|
IOUAmount const actualOut = mulRatio (
|
||||||
maxSrcToDst, dstQIn, QUALITY_ONE, /*roundUp*/ false);
|
maxSrcToDst, dstQIn, QUALITY_ONE, /*roundUp*/ false);
|
||||||
cache_.emplace (in, maxSrcToDst, actualOut, srcRedeems);
|
cache_.emplace (in, maxSrcToDst, actualOut, srcDebtDir);
|
||||||
rippleCredit (sb,
|
rippleCredit (sb,
|
||||||
src_, dst_, toSTAmount (maxSrcToDst, srcToDstIss),
|
src_, dst_, toSTAmount (maxSrcToDst, srcToDstIss),
|
||||||
/*checkIssuer*/ true, j_);
|
/*checkIssuer*/ true, j_);
|
||||||
JLOG (j_.trace()) <<
|
JLOG (j_.trace()) <<
|
||||||
"DirectStepI::rev: Limiting" <<
|
"DirectStepI::rev: Limiting" <<
|
||||||
" srcRedeems: " << srcRedeems <<
|
" srcRedeems: " << redeems(srcDebtDir) <<
|
||||||
" in: " << to_string (in) <<
|
" in: " << to_string (in) <<
|
||||||
" srcToDst: " << to_string (maxSrcToDst) <<
|
" srcToDst: " << to_string (maxSrcToDst) <<
|
||||||
" out: " << to_string (out);
|
" out: " << to_string (out);
|
||||||
@@ -574,7 +585,7 @@ DirectStepI<TDerived>::setCacheLimiting (
|
|||||||
IOUAmount const& fwdIn,
|
IOUAmount const& fwdIn,
|
||||||
IOUAmount const& fwdSrcToDst,
|
IOUAmount const& fwdSrcToDst,
|
||||||
IOUAmount const& fwdOut,
|
IOUAmount const& fwdOut,
|
||||||
bool srcRedeems)
|
DebtDirection srcDebtDir)
|
||||||
{
|
{
|
||||||
if (cache_->in < fwdIn)
|
if (cache_->in < fwdIn)
|
||||||
{
|
{
|
||||||
@@ -596,7 +607,7 @@ DirectStepI<TDerived>::setCacheLimiting (
|
|||||||
<< " cacheSrcToDst: " << to_string (cache_->srcToDst)
|
<< " cacheSrcToDst: " << to_string (cache_->srcToDst)
|
||||||
<< " fwdOut: " << to_string (fwdOut)
|
<< " fwdOut: " << to_string (fwdOut)
|
||||||
<< " cacheOut: " << to_string (cache_->out);
|
<< " cacheOut: " << to_string (cache_->out);
|
||||||
cache_.emplace (fwdIn, fwdSrcToDst, fwdOut, srcRedeems);
|
cache_.emplace (fwdIn, fwdSrcToDst, fwdOut, srcDebtDir);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -606,7 +617,7 @@ DirectStepI<TDerived>::setCacheLimiting (
|
|||||||
cache_->srcToDst = fwdSrcToDst;
|
cache_->srcToDst = fwdSrcToDst;
|
||||||
if (fwdOut < cache_->out)
|
if (fwdOut < cache_->out)
|
||||||
cache_->out = fwdOut;
|
cache_->out = fwdOut;
|
||||||
cache_->srcRedeems = srcRedeems;
|
cache_->srcDebtDir = srcDebtDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
@@ -619,19 +630,19 @@ DirectStepI<TDerived>::fwdImp (
|
|||||||
{
|
{
|
||||||
assert (cache_);
|
assert (cache_);
|
||||||
|
|
||||||
bool srcRedeems;
|
DebtDirection srcDebtDir;
|
||||||
IOUAmount maxSrcToDst;
|
IOUAmount maxSrcToDst;
|
||||||
std::tie (maxSrcToDst, srcRedeems) =
|
std::tie (maxSrcToDst, srcDebtDir) =
|
||||||
static_cast<TDerived const*>(this)->maxFlow (sb, cache_->srcToDst);
|
static_cast<TDerived const*>(this)->maxFlow (sb, cache_->srcToDst);
|
||||||
|
|
||||||
std::uint32_t srcQOut, dstQIn;
|
std::uint32_t srcQOut, dstQIn;
|
||||||
std::tie (srcQOut, dstQIn) = qualities (sb, srcRedeems, true);
|
std::tie (srcQOut, dstQIn) = qualities (sb, srcDebtDir, StrandDirection::forward);
|
||||||
|
|
||||||
Issue const srcToDstIss (currency_, srcRedeems ? dst_ : src_);
|
Issue const srcToDstIss (currency_, redeems(srcDebtDir) ? dst_ : src_);
|
||||||
|
|
||||||
JLOG (j_.trace()) <<
|
JLOG (j_.trace()) <<
|
||||||
"DirectStepI::fwd" <<
|
"DirectStepI::fwd" <<
|
||||||
" srcRedeems: " << srcRedeems <<
|
" srcRedeems: " << redeems(srcDebtDir) <<
|
||||||
" inReq: " << to_string (in) <<
|
" inReq: " << to_string (in) <<
|
||||||
" maxSrcToDst: " << to_string (maxSrcToDst) <<
|
" maxSrcToDst: " << to_string (maxSrcToDst) <<
|
||||||
" srcQOut: " << srcQOut <<
|
" srcQOut: " << srcQOut <<
|
||||||
@@ -644,7 +655,7 @@ DirectStepI<TDerived>::fwdImp (
|
|||||||
IOUAmount (beast::zero),
|
IOUAmount (beast::zero),
|
||||||
IOUAmount (beast::zero),
|
IOUAmount (beast::zero),
|
||||||
IOUAmount (beast::zero),
|
IOUAmount (beast::zero),
|
||||||
srcRedeems);
|
srcDebtDir);
|
||||||
return {beast::zero, beast::zero};
|
return {beast::zero, beast::zero};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,13 +666,13 @@ DirectStepI<TDerived>::fwdImp (
|
|||||||
{
|
{
|
||||||
IOUAmount const out = mulRatio (
|
IOUAmount const out = mulRatio (
|
||||||
srcToDst, dstQIn, QUALITY_ONE, /*roundUp*/ false);
|
srcToDst, dstQIn, QUALITY_ONE, /*roundUp*/ false);
|
||||||
setCacheLimiting (in, srcToDst, out, srcRedeems);
|
setCacheLimiting (in, srcToDst, out, srcDebtDir);
|
||||||
rippleCredit (sb,
|
rippleCredit (sb,
|
||||||
src_, dst_, toSTAmount (cache_->srcToDst, srcToDstIss),
|
src_, dst_, toSTAmount (cache_->srcToDst, srcToDstIss),
|
||||||
/*checkIssuer*/ true, j_);
|
/*checkIssuer*/ true, j_);
|
||||||
JLOG (j_.trace()) <<
|
JLOG (j_.trace()) <<
|
||||||
"DirectStepI::fwd: Non-limiting" <<
|
"DirectStepI::fwd: Non-limiting" <<
|
||||||
" srcRedeems: " << srcRedeems <<
|
" srcRedeems: " << redeems(srcDebtDir) <<
|
||||||
" in: " << to_string (in) <<
|
" in: " << to_string (in) <<
|
||||||
" srcToDst: " << to_string (srcToDst) <<
|
" srcToDst: " << to_string (srcToDst) <<
|
||||||
" out: " << to_string (out);
|
" out: " << to_string (out);
|
||||||
@@ -673,13 +684,13 @@ DirectStepI<TDerived>::fwdImp (
|
|||||||
maxSrcToDst, srcQOut, QUALITY_ONE, /*roundUp*/ true);
|
maxSrcToDst, srcQOut, QUALITY_ONE, /*roundUp*/ true);
|
||||||
IOUAmount const out = mulRatio (
|
IOUAmount const out = mulRatio (
|
||||||
maxSrcToDst, dstQIn, QUALITY_ONE, /*roundUp*/ false);
|
maxSrcToDst, dstQIn, QUALITY_ONE, /*roundUp*/ false);
|
||||||
setCacheLimiting (actualIn, maxSrcToDst, out, srcRedeems);
|
setCacheLimiting (actualIn, maxSrcToDst, out, srcDebtDir);
|
||||||
rippleCredit (sb,
|
rippleCredit (sb,
|
||||||
src_, dst_, toSTAmount (cache_->srcToDst, srcToDstIss),
|
src_, dst_, toSTAmount (cache_->srcToDst, srcToDstIss),
|
||||||
/*checkIssuer*/ true, j_);
|
/*checkIssuer*/ true, j_);
|
||||||
JLOG (j_.trace()) <<
|
JLOG (j_.trace()) <<
|
||||||
"DirectStepI::rev: Limiting" <<
|
"DirectStepI::rev: Limiting" <<
|
||||||
" srcRedeems: " << srcRedeems <<
|
" srcRedeems: " << redeems(srcDebtDir) <<
|
||||||
" in: " << to_string (actualIn) <<
|
" in: " << to_string (actualIn) <<
|
||||||
" srcToDst: " << to_string (srcToDst) <<
|
" srcToDst: " << to_string (srcToDst) <<
|
||||||
" out: " << to_string (out);
|
" out: " << to_string (out);
|
||||||
@@ -705,9 +716,9 @@ DirectStepI<TDerived>::validFwd (
|
|||||||
|
|
||||||
assert (!in.native);
|
assert (!in.native);
|
||||||
|
|
||||||
bool srcRedeems;
|
DebtDirection srcDebtDir;
|
||||||
IOUAmount maxSrcToDst;
|
IOUAmount maxSrcToDst;
|
||||||
std::tie (maxSrcToDst, srcRedeems) =
|
std::tie (maxSrcToDst, srcDebtDir) =
|
||||||
static_cast<TDerived const*>(this)->maxFlow (sb, cache_->srcToDst);
|
static_cast<TDerived const*>(this)->maxFlow (sb, cache_->srcToDst);
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -747,40 +758,65 @@ DirectStepI<TDerived>::validFwd (
|
|||||||
// Returns srcQOut, dstQIn
|
// Returns srcQOut, dstQIn
|
||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
std::pair<std::uint32_t, std::uint32_t>
|
std::pair<std::uint32_t, std::uint32_t>
|
||||||
DirectStepI<TDerived>::qualities (
|
DirectStepI<TDerived>::qualitiesSrcRedeems(
|
||||||
ReadView const& sb,
|
ReadView const& sb) const
|
||||||
bool srcRedeems,
|
|
||||||
bool fwd) const
|
|
||||||
{
|
|
||||||
if (srcRedeems)
|
|
||||||
{
|
{
|
||||||
if (!prevStep_)
|
if (!prevStep_)
|
||||||
return {QUALITY_ONE, QUALITY_ONE};
|
return {QUALITY_ONE, QUALITY_ONE};
|
||||||
|
|
||||||
auto const prevStepQIn = prevStep_->lineQualityIn(sb);
|
auto const prevStepQIn = prevStep_->lineQualityIn(sb);
|
||||||
auto srcQOut = static_cast<TDerived const*>(this)->quality (
|
auto srcQOut =
|
||||||
sb, /* src quality out */ false);
|
static_cast<TDerived const*>(this)->quality(sb, QualityDirection::out);
|
||||||
|
|
||||||
if (prevStepQIn > srcQOut)
|
if (prevStepQIn > srcQOut)
|
||||||
srcQOut = prevStepQIn;
|
srcQOut = prevStepQIn;
|
||||||
return {srcQOut, QUALITY_ONE};
|
return {srcQOut, QUALITY_ONE};
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Returns srcQOut, dstQIn
|
||||||
|
template <class TDerived>
|
||||||
|
std::pair<std::uint32_t, std::uint32_t>
|
||||||
|
DirectStepI<TDerived>::qualitiesSrcIssues(
|
||||||
|
ReadView const& sb,
|
||||||
|
DebtDirection prevStepDebtDirection) const
|
||||||
{
|
{
|
||||||
// Charge a transfer rate when issuing and previous step redeems
|
// Charge a transfer rate when issuing and previous step redeems
|
||||||
auto const prevStepRedeems = prevStep_ && prevStep_->redeems (sb, fwd);
|
|
||||||
assert (static_cast<TDerived const*>(this)->verifyPrevStepRedeems (
|
|
||||||
prevStepRedeems));
|
|
||||||
|
|
||||||
std::uint32_t const srcQOut =
|
assert(static_cast<TDerived const*>(this)->verifyPrevStepDebtDirection(
|
||||||
prevStepRedeems ? transferRate (sb, src_).value : QUALITY_ONE;
|
prevStepDebtDirection));
|
||||||
|
|
||||||
|
std::uint32_t const srcQOut = redeems(prevStepDebtDirection)
|
||||||
|
? transferRate(sb, src_).value
|
||||||
|
: QUALITY_ONE;
|
||||||
auto dstQIn = static_cast<TDerived const*>(this)->quality(
|
auto dstQIn = static_cast<TDerived const*>(this)->quality(
|
||||||
sb, /* dst quality in */ true);
|
sb, QualityDirection::in);
|
||||||
|
|
||||||
if (isLast_ && dstQIn > QUALITY_ONE)
|
if (isLast_ && dstQIn > QUALITY_ONE)
|
||||||
dstQIn = QUALITY_ONE;
|
dstQIn = QUALITY_ONE;
|
||||||
return {srcQOut, dstQIn};
|
return {srcQOut, dstQIn};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns srcQOut, dstQIn
|
||||||
|
template <class TDerived>
|
||||||
|
std::pair<std::uint32_t, std::uint32_t>
|
||||||
|
DirectStepI<TDerived>::qualities(
|
||||||
|
ReadView const& sb,
|
||||||
|
DebtDirection srcDebtDir,
|
||||||
|
StrandDirection strandDir) const
|
||||||
|
{
|
||||||
|
if (redeems(srcDebtDir))
|
||||||
|
{
|
||||||
|
return qualitiesSrcRedeems(sb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto const prevStepDebtDirection = [&] {
|
||||||
|
if (prevStep_)
|
||||||
|
return prevStep_->debtDirection(sb, strandDir);
|
||||||
|
return DebtDirection::issues;
|
||||||
|
}();
|
||||||
|
return qualitiesSrcIssues(sb, prevStepDebtDirection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
@@ -789,19 +825,23 @@ DirectStepI<TDerived>::lineQualityIn (ReadView const& v) const
|
|||||||
{
|
{
|
||||||
// dst quality in
|
// dst quality in
|
||||||
return static_cast<TDerived const*>(this)->quality (
|
return static_cast<TDerived const*>(this)->quality (
|
||||||
v, /* dst quality in */ true);
|
v, QualityDirection::in);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
boost::optional<Quality>
|
boost::optional<Quality>
|
||||||
DirectStepI<TDerived>::qualityUpperBound(ReadView const& v, bool& redeems) const
|
DirectStepI<TDerived>::qualityUpperBound(ReadView const& v, DebtDirection& dir)
|
||||||
|
const
|
||||||
{
|
{
|
||||||
auto const prevRedeems = redeems;
|
auto const prevStepDebtDir = dir;
|
||||||
redeems = this->redeems(v, true);
|
dir = this->debtDirection(v, StrandDirection::forward);
|
||||||
std::uint32_t const srcQOut =
|
std::uint32_t const srcQOut = [&]() -> std::uint32_t {
|
||||||
(prevRedeems && !redeems) ? transferRate(v, src_).value : QUALITY_ONE;
|
if (redeems(prevStepDebtDir) && issues(dir))
|
||||||
auto dstQIn = static_cast<TDerived const*>(this)->quality (
|
return transferRate(v, src_).value;
|
||||||
v, /* dst quality in */ true);
|
return QUALITY_ONE;
|
||||||
|
}();
|
||||||
|
auto dstQIn =
|
||||||
|
static_cast<TDerived const*>(this)->quality(v, QualityDirection::in);
|
||||||
|
|
||||||
if (isLast_ && dstQIn > QUALITY_ONE)
|
if (isLast_ && dstQIn > QUALITY_ONE)
|
||||||
dstQIn = QUALITY_ONE;
|
dstQIn = QUALITY_ONE;
|
||||||
|
|||||||
@@ -34,6 +34,24 @@ class PaymentSandbox;
|
|||||||
class ReadView;
|
class ReadView;
|
||||||
class ApplyView;
|
class ApplyView;
|
||||||
|
|
||||||
|
enum class DebtDirection { issues, redeems };
|
||||||
|
enum class QualityDirection { in, out };
|
||||||
|
enum class StrandDirection { forward, reverse };
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
redeems(DebtDirection dir)
|
||||||
|
{
|
||||||
|
return dir == DebtDirection::redeems;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
issues(DebtDirection dir)
|
||||||
|
{
|
||||||
|
return dir == DebtDirection::issues;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A step in a payment path
|
A step in a payment path
|
||||||
|
|
||||||
@@ -63,7 +81,6 @@ class ApplyView;
|
|||||||
class Step
|
class Step
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Step destructor. */
|
|
||||||
virtual ~Step() = default;
|
virtual ~Step() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,13 +162,10 @@ public:
|
|||||||
otherwise return true.
|
otherwise return true.
|
||||||
|
|
||||||
@param sb view with the strand's state of balances and offers
|
@param sb view with the strand's state of balances and offers
|
||||||
@param fwd false -> called from rev(); true -> called from fwd().
|
@param dir reverse -> called from rev(); forward -> called from fwd().
|
||||||
*/
|
*/
|
||||||
virtual bool
|
virtual DebtDirection
|
||||||
redeems (ReadView const& sb, bool fwd) const
|
debtDirection (ReadView const& sb, StrandDirection dir) const = 0;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
If this step is a DirectStepI, return the quality in of the dst account.
|
If this step is a DirectStepI, return the quality in of the dst account.
|
||||||
@@ -166,14 +180,14 @@ public:
|
|||||||
Find an upper bound of quality for the step
|
Find an upper bound of quality for the step
|
||||||
|
|
||||||
@param v view to query the ledger state from
|
@param v view to query the ledger state from
|
||||||
@param redeems in/out param. Set to true if the previous step redeems.
|
@param dir in/out param. Set to DebtDirection::redeems if the previous step redeems.
|
||||||
Will be set to true if this step redeems; Will be set to false if this
|
Will be set to DebtDirection::redeems if this step redeems; Will be set to DebtDirection::issues if this
|
||||||
step does not redeem.
|
step does not redeem
|
||||||
@return The upper bound of quality for the step, or boost::none if the
|
@return The upper bound of quality for the step, or boost::none if the
|
||||||
step is dry.
|
step is dry.
|
||||||
*/
|
*/
|
||||||
virtual boost::optional<Quality>
|
virtual boost::optional<Quality>
|
||||||
qualityUpperBound(ReadView const& v, bool& redeems) const = 0;
|
qualityUpperBound(ReadView const& v, DebtDirection& dir) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
If this step is a BookStep, return the book.
|
If this step is a BookStep, return the book.
|
||||||
|
|||||||
@@ -401,10 +401,10 @@ boost::optional<Quality>
|
|||||||
qualityUpperBound(ReadView const& v, Strand const& strand)
|
qualityUpperBound(ReadView const& v, Strand const& strand)
|
||||||
{
|
{
|
||||||
Quality q{STAmount::uRateOne};
|
Quality q{STAmount::uRateOne};
|
||||||
bool redeems = false;
|
DebtDirection dir = DebtDirection::issues;
|
||||||
for (auto const& step : strand)
|
for (auto const& step : strand)
|
||||||
{
|
{
|
||||||
if (auto const stepQ = step->qualityUpperBound(v, redeems))
|
if (auto const stepQ = step->qualityUpperBound(v, dir))
|
||||||
q = composed_quality(q, *stepQ);
|
q = composed_quality(q, *stepQ);
|
||||||
else
|
else
|
||||||
return boost::none;
|
return boost::none;
|
||||||
|
|||||||
@@ -89,8 +89,14 @@ public:
|
|||||||
return cached ();
|
return cached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DebtDirection
|
||||||
|
debtDirection(ReadView const& sb, StrandDirection dir) const override
|
||||||
|
{
|
||||||
|
return DebtDirection::issues;
|
||||||
|
}
|
||||||
|
|
||||||
boost::optional<Quality>
|
boost::optional<Quality>
|
||||||
qualityUpperBound(ReadView const& v, bool& redeems) const override;
|
qualityUpperBound(ReadView const& v, DebtDirection& dir) const override;
|
||||||
|
|
||||||
std::pair<XRPAmount, XRPAmount>
|
std::pair<XRPAmount, XRPAmount>
|
||||||
revImp (
|
revImp (
|
||||||
@@ -237,9 +243,9 @@ inline bool operator==(XRPEndpointStep<TDerived> const& lhs,
|
|||||||
template <class TDerived>
|
template <class TDerived>
|
||||||
boost::optional<Quality>
|
boost::optional<Quality>
|
||||||
XRPEndpointStep<TDerived>::qualityUpperBound(
|
XRPEndpointStep<TDerived>::qualityUpperBound(
|
||||||
ReadView const& v, bool& redeems) const
|
ReadView const& v, DebtDirection& dir) const
|
||||||
{
|
{
|
||||||
redeems = this->redeems(v, true);
|
dir = this->debtDirection(v, StrandDirection::forward);
|
||||||
return Quality{STAmount::uRateOne};
|
return Quality{STAmount::uRateOne};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user