rippled
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 <ripple/app/paths/AMMContext.h>
21 #include <ripple/app/paths/Credit.h>
22 #include <ripple/app/paths/Flow.h>
23 #include <ripple/app/paths/impl/AmountSpec.h>
24 #include <ripple/app/paths/impl/Steps.h>
25 #include <ripple/app/paths/impl/StrandFlow.h>
26 #include <ripple/basics/IOUAmount.h>
27 #include <ripple/basics/Log.h>
28 #include <ripple/basics/XRPAmount.h>
29 
30 #include <boost/container/flat_set.hpp>
31 
32 #include <numeric>
33 #include <sstream>
34 
35 namespace ripple {
36 
37 template <class FlowResult>
38 static auto
40  PaymentSandbox& sb,
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 
58 path::RippleCalc::Output
60  PaymentSandbox& sb,
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  assert(!srcIsXRP && !dstIsXRP);
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
sstream
ripple::OfferCrossing
OfferCrossing
Definition: Steps.h:42
ripple::Issue
A currency issued by an account.
Definition: Issue.h:35
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:308
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:350
ripple::PaymentSandbox
A wrapper which makes credits unavailable to balances.
Definition: PaymentSandbox.h:112
ripple::path::detail::FlowDebugInfo
Definition: FlowDebugInfo.h:38
ripple::finishFlow
static auto finishFlow(PaymentSandbox &sb, Issue const &srcIssue, Issue const &dstIssue, FlowResult &&f)
Definition: Flow.cpp:39
ripple::Issue::currency
Currency currency
Definition: Issue.h:38
ripple::STPathSet
Definition: STPathSet.h:176
ripple::path::RippleCalc::Output::removableOffers
boost::container::flat_set< uint256 > removableOffers
Definition: RippleCalc.h:70
ripple::flow
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, beast::Journal j, path::detail::FlowDebugInfo *flowDebugInfo)
Make a payment from the src account to the dst account.
Definition: Flow.cpp:59
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:82
ripple::toAmountSpec
AmountSpec toAmountSpec(STAmount const &amt)
Definition: AmountSpec.h:165
ripple::AMMContext
Maintains AMM info per overall payment engine execution and individual iteration.
Definition: AMMContext.h:35
ripple::toSTAmount
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
Definition: AmountConversions.h:30
ripple::STAmount
Definition: STAmount.h:46
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
ripple::path::RippleCalc::Output::actualAmountOut
STAmount actualAmountOut
Definition: RippleCalc.h:63
ripple::path::RippleCalc::Output::actualAmountIn
STAmount actualAmountIn
Definition: RippleCalc.h:60
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::path::RippleCalc::Output
Definition: RippleCalc.h:55
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::toStrands
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:468
ripple::xrpIssue
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition: Issue.h:105
std::optional< Quality >
ripple::path::RippleCalc::Output::setResult
void setResult(TER const value)
Definition: RippleCalc.h:82
numeric
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:236
ripple::AMMContext::setMultiPath
void setMultiPath(bool fs)
Definition: AMMContext.h:70