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#include <xrpl/basics/Log.h>
27#include <xrpl/protocol/IOUAmount.h>
28#include <xrpl/protocol/XRPAmount.h>
29
30#include <boost/container/flat_set.hpp>
31
32#include <numeric>
33#include <sstream>
34
35namespace ripple {
36
37template <class FlowResult>
38static auto
41 Issue const& srcIssue,
42 Issue const& dstIssue,
43 FlowResult&& f)
44{
46 if (f.ter == tesSUCCESS)
47 f.sandbox->apply(sb);
48 else
49 result.removableOffers = std::move(f.removableOffers);
50
51 result.setResult(f.ter);
52 result.actualAmountIn = toSTAmount(f.in, srcIssue);
53 result.actualAmountOut = toSTAmount(f.out, dstIssue);
54
55 return result;
56};
57
58path::RippleCalc::Output
61 STAmount const& deliver,
62 AccountID const& src,
63 AccountID const& dst,
64 STPathSet const& paths,
65 bool defaultPaths,
66 bool partialPayment,
67 bool ownerPaysTransferFee,
68 OfferCrossing offerCrossing,
69 std::optional<Quality> const& limitQuality,
70 std::optional<STAmount> const& sendMax,
72 path::detail::FlowDebugInfo* flowDebugInfo)
73{
74 Issue const srcIssue = [&] {
75 if (sendMax)
76 return sendMax->issue();
77 if (!isXRP(deliver.issue().currency))
78 return Issue(deliver.issue().currency, src);
79 return xrpIssue();
80 }();
81
82 Issue const dstIssue = deliver.issue();
83
84 std::optional<Issue> sendMaxIssue;
85 if (sendMax)
86 sendMaxIssue = sendMax->issue();
87
88 AMMContext ammContext(src, false);
89
90 // convert the paths to a collection of strands. Each strand is the
91 // collection of account->account steps and book steps that may be used in
92 // this payment.
93 auto [toStrandsTer, strands] = toStrands(
94 sb,
95 src,
96 dst,
97 dstIssue,
98 limitQuality,
99 sendMaxIssue,
100 paths,
101 defaultPaths,
102 ownerPaysTransferFee,
103 offerCrossing,
104 ammContext,
105 j);
106
107 if (toStrandsTer != tesSUCCESS)
108 {
110 result.setResult(toStrandsTer);
111 return result;
112 }
113
114 ammContext.setMultiPath(strands.size() > 1);
115
116 if (j.trace())
117 {
118 j.trace() << "\nsrc: " << src << "\ndst: " << dst
119 << "\nsrcIssue: " << srcIssue << "\ndstIssue: " << dstIssue;
120 j.trace() << "\nNumStrands: " << strands.size();
121 for (auto const& curStrand : strands)
122 {
123 j.trace() << "NumSteps: " << curStrand.size();
124 for (auto const& step : curStrand)
125 {
126 j.trace() << '\n' << *step << '\n';
127 }
128 }
129 }
130
131 const bool srcIsXRP = isXRP(srcIssue.currency);
132 const bool dstIsXRP = isXRP(dstIssue.currency);
133
134 auto const asDeliver = toAmountSpec(deliver);
135
136 // The src account may send either xrp or iou. The dst account may receive
137 // either xrp or iou. Since XRP and IOU amounts are represented by different
138 // types, use templates to tell `flow` about the amount types.
139 if (srcIsXRP && dstIsXRP)
140 {
141 return finishFlow(
142 sb,
143 srcIssue,
144 dstIssue,
145 flow<XRPAmount, XRPAmount>(
146 sb,
147 strands,
148 asDeliver.xrp,
149 partialPayment,
150 offerCrossing,
151 limitQuality,
152 sendMax,
153 j,
154 ammContext,
155 flowDebugInfo));
156 }
157
158 if (srcIsXRP && !dstIsXRP)
159 {
160 return finishFlow(
161 sb,
162 srcIssue,
163 dstIssue,
164 flow<XRPAmount, IOUAmount>(
165 sb,
166 strands,
167 asDeliver.iou,
168 partialPayment,
169 offerCrossing,
170 limitQuality,
171 sendMax,
172 j,
173 ammContext,
174 flowDebugInfo));
175 }
176
177 if (!srcIsXRP && dstIsXRP)
178 {
179 return finishFlow(
180 sb,
181 srcIssue,
182 dstIssue,
183 flow<IOUAmount, XRPAmount>(
184 sb,
185 strands,
186 asDeliver.xrp,
187 partialPayment,
188 offerCrossing,
189 limitQuality,
190 sendMax,
191 j,
192 ammContext,
193 flowDebugInfo));
194 }
195
196 XRPL_ASSERT(!srcIsXRP && !dstIsXRP, "ripple::flow : neither is XRP");
197 return finishFlow(
198 sb,
199 srcIssue,
200 dstIssue,
201 flow<IOUAmount, IOUAmount>(
202 sb,
203 strands,
204 asDeliver.iou,
205 partialPayment,
206 offerCrossing,
207 limitQuality,
208 sendMax,
209 j,
210 ammContext,
211 flowDebugInfo));
212}
213
214} // namespace ripple
A generic endpoint for log messages.
Definition: Journal.h:59
Stream trace() const
Severity stream access functions.
Definition: Journal.h:311
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:487
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:39
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:470
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:106
AmountSpec toAmountSpec(STAmount const &amt)
Definition: AmountSpec.h:169
OfferCrossing
Definition: Steps.h:42
@ tesSUCCESS
Definition: TER.h:242
boost::container::flat_set< uint256 > removableOffers
Definition: RippleCalc.h:70
void setResult(TER const value)
Definition: RippleCalc.h:82