rippled
Loading...
Searching...
No Matches
Flow.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/paths/AMMContext.h>
21#include <xrpld/app/paths/Credit.h>
22#include <xrpld/app/paths/Flow.h>
23#include <xrpld/app/paths/detail/AmountSpec.h>
24#include <xrpld/app/paths/detail/Steps.h>
25#include <xrpld/app/paths/detail/StrandFlow.h>
26
27#include <xrpl/basics/Log.h>
28#include <xrpl/protocol/IOUAmount.h>
29#include <xrpl/protocol/XRPAmount.h>
30
31namespace ripple {
32
33template <class FlowResult>
34static auto
37 Issue const& srcIssue,
38 Issue const& dstIssue,
39 FlowResult&& f)
40{
42 if (f.ter == tesSUCCESS)
43 f.sandbox->apply(sb);
44 else
45 result.removableOffers = std::move(f.removableOffers);
46
47 result.setResult(f.ter);
48 result.actualAmountIn = toSTAmount(f.in, srcIssue);
49 result.actualAmountOut = toSTAmount(f.out, dstIssue);
50
51 return result;
52};
53
54path::RippleCalc::Output
57 STAmount const& deliver,
58 AccountID const& src,
59 AccountID const& dst,
60 STPathSet const& paths,
61 bool defaultPaths,
62 bool partialPayment,
63 bool ownerPaysTransferFee,
64 OfferCrossing offerCrossing,
65 std::optional<Quality> const& limitQuality,
66 std::optional<STAmount> const& sendMax,
68 path::detail::FlowDebugInfo* flowDebugInfo)
69{
70 Issue const srcIssue = [&] {
71 if (sendMax)
72 return sendMax->issue();
73 if (!isXRP(deliver.issue().currency))
74 return Issue(deliver.issue().currency, src);
75 return xrpIssue();
76 }();
77
78 Issue const dstIssue = deliver.issue();
79
80 std::optional<Issue> sendMaxIssue;
81 if (sendMax)
82 sendMaxIssue = sendMax->issue();
83
84 AMMContext ammContext(src, false);
85
86 // convert the paths to a collection of strands. Each strand is the
87 // collection of account->account steps and book steps that may be used in
88 // this payment.
89 auto [toStrandsTer, strands] = toStrands(
90 sb,
91 src,
92 dst,
93 dstIssue,
94 limitQuality,
95 sendMaxIssue,
96 paths,
97 defaultPaths,
98 ownerPaysTransferFee,
99 offerCrossing,
100 ammContext,
101 j);
102
103 if (toStrandsTer != tesSUCCESS)
104 {
106 result.setResult(toStrandsTer);
107 return result;
108 }
109
110 ammContext.setMultiPath(strands.size() > 1);
111
112 if (j.trace())
113 {
114 j.trace() << "\nsrc: " << src << "\ndst: " << dst
115 << "\nsrcIssue: " << srcIssue << "\ndstIssue: " << dstIssue;
116 j.trace() << "\nNumStrands: " << strands.size();
117 for (auto const& curStrand : strands)
118 {
119 j.trace() << "NumSteps: " << curStrand.size();
120 for (auto const& step : curStrand)
121 {
122 j.trace() << '\n' << *step << '\n';
123 }
124 }
125 }
126
127 bool const srcIsXRP = isXRP(srcIssue.currency);
128 bool const dstIsXRP = isXRP(dstIssue.currency);
129
130 auto const asDeliver = toAmountSpec(deliver);
131
132 // The src account may send either xrp or iou. The dst account may receive
133 // either xrp or iou. Since XRP and IOU amounts are represented by different
134 // types, use templates to tell `flow` about the amount types.
135 if (srcIsXRP && dstIsXRP)
136 {
137 return finishFlow(
138 sb,
139 srcIssue,
140 dstIssue,
141 flow<XRPAmount, XRPAmount>(
142 sb,
143 strands,
144 asDeliver.xrp,
145 partialPayment,
146 offerCrossing,
147 limitQuality,
148 sendMax,
149 j,
150 ammContext,
151 flowDebugInfo));
152 }
153
154 if (srcIsXRP && !dstIsXRP)
155 {
156 return finishFlow(
157 sb,
158 srcIssue,
159 dstIssue,
160 flow<XRPAmount, IOUAmount>(
161 sb,
162 strands,
163 asDeliver.iou,
164 partialPayment,
165 offerCrossing,
166 limitQuality,
167 sendMax,
168 j,
169 ammContext,
170 flowDebugInfo));
171 }
172
173 if (!srcIsXRP && dstIsXRP)
174 {
175 return finishFlow(
176 sb,
177 srcIssue,
178 dstIssue,
179 flow<IOUAmount, XRPAmount>(
180 sb,
181 strands,
182 asDeliver.xrp,
183 partialPayment,
184 offerCrossing,
185 limitQuality,
186 sendMax,
187 j,
188 ammContext,
189 flowDebugInfo));
190 }
191
192 XRPL_ASSERT(!srcIsXRP && !dstIsXRP, "ripple::flow : neither is XRP");
193 return finishFlow(
194 sb,
195 srcIssue,
196 dstIssue,
197 flow<IOUAmount, IOUAmount>(
198 sb,
199 strands,
200 asDeliver.iou,
201 partialPayment,
202 offerCrossing,
203 limitQuality,
204 sendMax,
205 j,
206 ammContext,
207 flowDebugInfo));
208}
209
210} // namespace ripple
A generic endpoint for log messages.
Definition: Journal.h:60
Stream trace() const
Severity stream access functions.
Definition: Journal.h:322
Maintains AMM info per overall payment engine execution and individual iteration.
Definition: AMMContext.h:36
void setMultiPath(bool fs)
Definition: AMMContext.h:70
A currency issued by an account.
Definition: Issue.h:36
Currency currency
Definition: Issue.h:38
A wrapper which makes credits unavailable to balances.
Issue const & issue() const
Definition: STAmount.h:496
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition: Issue.h:118
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
static auto finishFlow(PaymentSandbox &sb, Issue const &srcIssue, Issue const &dstIssue, FlowResult &&f)
Definition: Flow.cpp:35
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, beast::Journal j)
Create a Strand for each specified path (including the default path, if indicated)
Definition: PaySteps.cpp:467
StrandResult< TInAmt, TOutAmt > flow(PaymentSandbox const &baseView, Strand const &strand, std::optional< TInAmt > const &maxIn, TOutAmt const &out, beast::Journal j)
Request out amount from a strand.
Definition: StrandFlow.h:105
AmountSpec toAmountSpec(STAmount const &amt)
Definition: AmountSpec.h:169
OfferCrossing
Definition: Steps.h:44
@ tesSUCCESS
Definition: TER.h:244
boost::container::flat_set< uint256 > removableOffers
Definition: RippleCalc.h:71
void setResult(TER const value)
Definition: RippleCalc.h:83