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