20 #include <ripple/app/paths/Credit.h>
21 #include <ripple/app/paths/Flow.h>
22 #include <ripple/app/paths/impl/AmountSpec.h>
23 #include <ripple/app/paths/impl/StrandFlow.h>
24 #include <ripple/app/paths/impl/Steps.h>
25 #include <ripple/basics/Log.h>
26 #include <ripple/basics/IOUAmount.h>
27 #include <ripple/basics/XRPAmount.h>
29 #include <boost/container/flat_set.hpp>
36 template<
class FlowResult>
38 auto finishFlow (PaymentSandbox& sb,
39 Issue
const& srcIssue, Issue
const& dstIssue,
42 path::RippleCalc::Output result;
44 f.sandbox->apply (sb);
46 result.removableOffers = std::move (f.removableOffers);
48 result.setResult (f.ter);
49 result.actualAmountIn =
toSTAmount (f.in, srcIssue);
50 result.actualAmountOut =
toSTAmount (f.out, dstIssue);
55 path::RippleCalc::Output
58 STAmount
const& deliver,
61 STPathSet
const& paths,
64 bool ownerPaysTransferFee,
66 boost::optional<Quality>
const& limitQuality,
67 boost::optional<STAmount>
const& sendMax,
69 path::detail::FlowDebugInfo* flowDebugInfo)
71 Issue
const srcIssue = [&] {
73 return sendMax->issue ();
74 if (!
isXRP (deliver.issue ().currency))
75 return Issue (deliver.issue ().currency, src);
79 Issue
const dstIssue = deliver.issue ();
81 boost::optional<Issue> sendMaxIssue;
83 sendMaxIssue = sendMax->issue ();
87 auto [toStrandsTer, strands] =
88 toStrands(sb, src, dst, dstIssue, limitQuality, sendMaxIssue, paths,
89 defaultPaths, ownerPaysTransferFee, offerCrossing, j);
93 path::RippleCalc::Output result;
94 result.setResult (toStrandsTer);
100 j.
trace() <<
"\nsrc: " << src <<
"\ndst: " << dst
101 <<
"\nsrcIssue: " << srcIssue <<
"\ndstIssue: " << dstIssue;
102 j.
trace() <<
"\nNumStrands: " << strands.size ();
103 for (
auto const& curStrand : strands)
105 j.
trace() <<
"NumSteps: " << curStrand.size ();
106 for (
auto const& step : curStrand)
108 j.
trace() <<
'\n' << *step <<
'\n';
113 const bool srcIsXRP =
isXRP (srcIssue.currency);
114 const bool dstIsXRP =
isXRP (dstIssue.currency);
121 if (srcIsXRP && dstIsXRP)
123 return finishFlow (sb, srcIssue, dstIssue,
124 flow<XRPAmount, XRPAmount> (
125 sb, strands, asDeliver.xrp, partialPayment, offerCrossing,
126 limitQuality, sendMax, j, flowDebugInfo));
129 if (srcIsXRP && !dstIsXRP)
131 return finishFlow (sb, srcIssue, dstIssue,
132 flow<XRPAmount, IOUAmount> (
133 sb, strands, asDeliver.iou, partialPayment, offerCrossing,
134 limitQuality, sendMax, j, flowDebugInfo));
137 if (!srcIsXRP && dstIsXRP)
139 return finishFlow (sb, srcIssue, dstIssue,
140 flow<IOUAmount, XRPAmount> (
141 sb, strands, asDeliver.xrp, partialPayment, offerCrossing,
142 limitQuality, sendMax, j, flowDebugInfo));
145 assert (!srcIsXRP && !dstIsXRP);
146 return finishFlow (sb, srcIssue, dstIssue,
147 flow<IOUAmount, IOUAmount> (
148 sb, strands, asDeliver.iou, partialPayment, offerCrossing,
149 limitQuality, sendMax, j, flowDebugInfo));