mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-24 07:30:30 +00:00
This change enables the following clang-tidy checks: - readability-avoid-nested-conditional-operator, - readability-avoid-return-with-void-value, - readability-braces-around-statements, - readability-const-return-type, - readability-container-contains, - readability-container-size-empty, - readability-else-after-return, - readability-make-member-function-const, - readability-redundant-casting, - readability-redundant-inline-specifier, - readability-redundant-member-init, - readability-redundant-string-init, - readability-reference-to-constructed-temporary, - readability-static-definition
193 lines
4.9 KiB
C++
193 lines
4.9 KiB
C++
#include <xrpl/basics/Log.h>
|
|
#include <xrpl/ledger/Credit.h>
|
|
#include <xrpl/protocol/IOUAmount.h>
|
|
#include <xrpl/protocol/XRPAmount.h>
|
|
#include <xrpl/tx/paths/Flow.h>
|
|
#include <xrpl/tx/paths/detail/AmountSpec.h>
|
|
#include <xrpl/tx/paths/detail/Steps.h>
|
|
#include <xrpl/tx/paths/detail/StrandFlow.h>
|
|
#include <xrpl/tx/transactors/dex/AMMContext.h>
|
|
|
|
namespace xrpl {
|
|
|
|
template <class FlowResult>
|
|
static auto
|
|
finishFlow(PaymentSandbox& sb, Issue const& srcIssue, Issue const& dstIssue, FlowResult&& f)
|
|
{
|
|
path::RippleCalc::Output result;
|
|
if (isTesSuccess(f.ter))
|
|
{
|
|
f.sandbox->apply(sb);
|
|
}
|
|
else
|
|
{
|
|
result.removableOffers = std::move(f.removableOffers);
|
|
}
|
|
|
|
result.setResult(f.ter);
|
|
result.actualAmountIn = toSTAmount(f.in, srcIssue);
|
|
result.actualAmountOut = toSTAmount(f.out, dstIssue);
|
|
|
|
return result;
|
|
};
|
|
|
|
path::RippleCalc::Output
|
|
flow(
|
|
PaymentSandbox& sb,
|
|
STAmount const& deliver,
|
|
AccountID const& src,
|
|
AccountID const& dst,
|
|
STPathSet const& paths,
|
|
bool defaultPaths,
|
|
bool partialPayment,
|
|
bool ownerPaysTransferFee,
|
|
OfferCrossing offerCrossing,
|
|
std::optional<Quality> const& limitQuality,
|
|
std::optional<STAmount> const& sendMax,
|
|
std::optional<uint256> const& domainID,
|
|
beast::Journal j,
|
|
path::detail::FlowDebugInfo* flowDebugInfo)
|
|
{
|
|
Issue const srcIssue = [&] {
|
|
if (sendMax)
|
|
return sendMax->issue();
|
|
if (!isXRP(deliver.issue().currency))
|
|
return Issue(deliver.issue().currency, src);
|
|
return xrpIssue();
|
|
}();
|
|
|
|
Issue const dstIssue = deliver.issue();
|
|
|
|
std::optional<Issue> sendMaxIssue;
|
|
if (sendMax)
|
|
sendMaxIssue = sendMax->issue();
|
|
|
|
AMMContext ammContext(src, false);
|
|
|
|
// convert the paths to a collection of strands. Each strand is the
|
|
// collection of account->account steps and book steps that may be used in
|
|
// this payment.
|
|
auto [toStrandsTer, strands] = toStrands(
|
|
sb,
|
|
src,
|
|
dst,
|
|
dstIssue,
|
|
limitQuality,
|
|
sendMaxIssue,
|
|
paths,
|
|
defaultPaths,
|
|
ownerPaysTransferFee,
|
|
offerCrossing,
|
|
ammContext,
|
|
domainID,
|
|
j);
|
|
|
|
if (!isTesSuccess(toStrandsTer))
|
|
{
|
|
path::RippleCalc::Output result;
|
|
result.setResult(toStrandsTer);
|
|
return result;
|
|
}
|
|
|
|
ammContext.setMultiPath(strands.size() > 1);
|
|
|
|
if (j.trace())
|
|
{
|
|
j.trace() << "\nsrc: " << src << "\ndst: " << dst << "\nsrcIssue: " << srcIssue
|
|
<< "\ndstIssue: " << dstIssue;
|
|
j.trace() << "\nNumStrands: " << strands.size();
|
|
for (auto const& curStrand : strands)
|
|
{
|
|
j.trace() << "NumSteps: " << curStrand.size();
|
|
for (auto const& step : curStrand)
|
|
{
|
|
j.trace() << '\n' << *step << '\n';
|
|
}
|
|
}
|
|
}
|
|
|
|
bool const srcIsXRP = isXRP(srcIssue.currency);
|
|
bool const dstIsXRP = isXRP(dstIssue.currency);
|
|
|
|
auto const asDeliver = toAmountSpec(deliver);
|
|
|
|
// The src account may send either xrp or iou. The dst account may receive
|
|
// either xrp or iou. Since XRP and IOU amounts are represented by different
|
|
// types, use templates to tell `flow` about the amount types.
|
|
if (srcIsXRP && dstIsXRP)
|
|
{
|
|
return finishFlow(
|
|
sb,
|
|
srcIssue,
|
|
dstIssue,
|
|
flow<XRPAmount, XRPAmount>(
|
|
sb,
|
|
strands,
|
|
asDeliver.xrp,
|
|
partialPayment,
|
|
offerCrossing,
|
|
limitQuality,
|
|
sendMax,
|
|
j,
|
|
ammContext,
|
|
flowDebugInfo));
|
|
}
|
|
|
|
if (srcIsXRP && !dstIsXRP)
|
|
{
|
|
return finishFlow(
|
|
sb,
|
|
srcIssue,
|
|
dstIssue,
|
|
flow<XRPAmount, IOUAmount>(
|
|
sb,
|
|
strands,
|
|
asDeliver.iou,
|
|
partialPayment,
|
|
offerCrossing,
|
|
limitQuality,
|
|
sendMax,
|
|
j,
|
|
ammContext,
|
|
flowDebugInfo));
|
|
}
|
|
|
|
if (!srcIsXRP && dstIsXRP)
|
|
{
|
|
return finishFlow(
|
|
sb,
|
|
srcIssue,
|
|
dstIssue,
|
|
flow<IOUAmount, XRPAmount>(
|
|
sb,
|
|
strands,
|
|
asDeliver.xrp,
|
|
partialPayment,
|
|
offerCrossing,
|
|
limitQuality,
|
|
sendMax,
|
|
j,
|
|
ammContext,
|
|
flowDebugInfo));
|
|
}
|
|
|
|
XRPL_ASSERT(!srcIsXRP && !dstIsXRP, "xrpl::flow : neither is XRP");
|
|
return finishFlow(
|
|
sb,
|
|
srcIssue,
|
|
dstIssue,
|
|
flow<IOUAmount, IOUAmount>(
|
|
sb,
|
|
strands,
|
|
asDeliver.iou,
|
|
partialPayment,
|
|
offerCrossing,
|
|
limitQuality,
|
|
sendMax,
|
|
j,
|
|
ammContext,
|
|
flowDebugInfo));
|
|
}
|
|
|
|
} // namespace xrpl
|