rippled
Offer.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2014 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 #ifndef RIPPLE_APP_BOOK_OFFER_H_INCLUDED
21 #define RIPPLE_APP_BOOK_OFFER_H_INCLUDED
22 
23 #include <ripple/basics/contract.h>
24 #include <ripple/ledger/View.h>
25 #include <ripple/protocol/Quality.h>
26 #include <ripple/protocol/SField.h>
27 #include <ripple/protocol/STLedgerEntry.h>
28 #include <ostream>
29 #include <stdexcept>
30 
31 namespace ripple {
32 
33 template <class TIn, class TOut>
35 {
36 protected:
39 };
40 
41 template <>
43 {
44 public:
45  explicit TOfferBase() = default;
46 };
47 
48 template <class TIn = STAmount, class TOut = STAmount>
49 class TOffer : private TOfferBase<TIn, TOut>
50 {
51 private:
53  Quality m_quality;
55 
56  TAmounts<TIn, TOut> m_amounts;
57  void
59 
60 public:
61  TOffer() = default;
62 
63  TOffer(SLE::pointer const& entry, Quality quality);
64 
74  Quality
75  quality() const noexcept
76  {
77  return m_quality;
78  }
79 
81  AccountID const&
82  owner() const
83  {
84  return m_account;
85  }
86 
90  TAmounts<TIn, TOut> const&
91  amount() const
92  {
93  return m_amounts;
94  }
95 
97  bool
99  {
100  if (m_amounts.in <= beast::zero)
101  return true;
102  if (m_amounts.out <= beast::zero)
103  return true;
104  return false;
105  }
106 
108  void
109  consume(ApplyView& view, TAmounts<TIn, TOut> const& consumed)
110  {
111  if (consumed.in > m_amounts.in)
112  Throw<std::logic_error>("can't consume more than is available.");
113 
114  if (consumed.out > m_amounts.out)
115  Throw<std::logic_error>("can't produce more than is available.");
116 
117  m_amounts -= consumed;
118  setFieldAmounts();
119  view.update(m_entry);
120  }
121 
123  id() const
124  {
125  return to_string(m_entry->key());
126  }
127 
129  key() const
130  {
131  return m_entry->key();
132  }
133 
134  Issue const&
135  issueIn() const;
136  Issue const&
137  issueOut() const;
138 
139  TAmounts<TIn, TOut>
140  limitOut(
141  TAmounts<TIn, TOut> const& offrAmt,
142  TOut const& limit,
143  bool fixReducedOffers,
144  bool roundUp) const;
145 
146  TAmounts<TIn, TOut>
147  limitIn(TAmounts<TIn, TOut> const& offrAmt, TIn const& limit) const;
148 
149  template <typename... Args>
150  static TER
151  send(Args&&... args);
152 
153  bool
154  isFunded() const
155  {
156  // Offer owner is issuer; they have unlimited funds
157  return m_account == issueOut().account;
158  }
159 
161  adjustRates(std::uint32_t ofrInRate, std::uint32_t ofrOutRate)
162  {
163  // CLOB offer pays the transfer fee
164  return {ofrInRate, ofrOutRate};
165  }
166 };
167 
168 using Offer = TOffer<>;
169 
170 template <class TIn, class TOut>
171 TOffer<TIn, TOut>::TOffer(SLE::pointer const& entry, Quality quality)
172  : m_entry(entry)
173  , m_quality(quality)
174  , m_account(m_entry->getAccountID(sfAccount))
175 {
176  auto const tp = m_entry->getFieldAmount(sfTakerPays);
177  auto const tg = m_entry->getFieldAmount(sfTakerGets);
178  m_amounts.in = toAmount<TIn>(tp);
179  m_amounts.out = toAmount<TOut>(tg);
180  this->issIn_ = tp.issue();
181  this->issOut_ = tg.issue();
182 }
183 
184 template <>
186  SLE::pointer const& entry,
187  Quality quality)
188  : m_entry(entry)
189  , m_quality(quality)
190  , m_account(m_entry->getAccountID(sfAccount))
191  , m_amounts(
192  m_entry->getFieldAmount(sfTakerPays),
193  m_entry->getFieldAmount(sfTakerGets))
194 {
195 }
196 
197 template <class TIn, class TOut>
198 void
200 {
201 #ifdef _MSC_VER
202  assert(0);
203 #else
204  static_assert(sizeof(TOut) == -1, "Must be specialized");
205 #endif
206 }
207 
208 template <class TIn, class TOut>
209 TAmounts<TIn, TOut>
211  TAmounts<TIn, TOut> const& offrAmt,
212  TOut const& limit,
213  bool fixReducedOffers,
214  bool roundUp) const
215 {
216  if (fixReducedOffers)
217  // It turns out that the ceil_out implementation has some slop in
218  // it. ceil_out_strict removes that slop. But removing that slop
219  // affects transaction outcomes, so the change must be made using
220  // an amendment.
221  return quality().ceil_out_strict(offrAmt, limit, roundUp);
222  return m_quality.ceil_out(offrAmt, limit);
223 }
224 
225 template <class TIn, class TOut>
226 TAmounts<TIn, TOut>
227 TOffer<TIn, TOut>::limitIn(TAmounts<TIn, TOut> const& offrAmt, TIn const& limit)
228  const
229 {
230  return m_quality.ceil_in(offrAmt, limit);
231 }
232 
233 template <class TIn, class TOut>
234 template <typename... Args>
235 TER
236 TOffer<TIn, TOut>::send(Args&&... args)
237 {
238  return accountSend(std::forward<Args>(args)...);
239 }
240 
241 template <>
242 inline void
244 {
245  m_entry->setFieldAmount(sfTakerPays, m_amounts.in);
246  m_entry->setFieldAmount(sfTakerGets, m_amounts.out);
247 }
248 
249 template <>
250 inline void
252 {
253  m_entry->setFieldAmount(sfTakerPays, toSTAmount(m_amounts.in, issIn_));
254  m_entry->setFieldAmount(sfTakerGets, toSTAmount(m_amounts.out, issOut_));
255 }
256 
257 template <>
258 inline void
260 {
261  m_entry->setFieldAmount(sfTakerPays, toSTAmount(m_amounts.in, issIn_));
262  m_entry->setFieldAmount(sfTakerGets, toSTAmount(m_amounts.out));
263 }
264 
265 template <>
266 inline void
268 {
269  m_entry->setFieldAmount(sfTakerPays, toSTAmount(m_amounts.in));
270  m_entry->setFieldAmount(sfTakerGets, toSTAmount(m_amounts.out, issOut_));
271 }
272 
273 template <class TIn, class TOut>
274 Issue const&
276 {
277  return this->issIn_;
278 }
279 
280 template <>
281 inline Issue const&
283 {
284  return m_amounts.in.issue();
285 }
286 
287 template <class TIn, class TOut>
288 Issue const&
290 {
291  return this->issOut_;
292 }
293 
294 template <>
295 inline Issue const&
297 {
298  return m_amounts.out.issue();
299 }
300 
301 template <class TIn, class TOut>
302 inline std::ostream&
304 {
305  return os << offer.id();
306 }
307 
308 } // namespace ripple
309 
310 #endif
ripple::TOffer::quality
Quality quality() const noexcept
Returns the quality of the offer.
Definition: Offer.h:75
ripple::TOfferBase
Definition: Offer.h:34
ripple::TOffer::issueOut
Issue const & issueOut() const
Definition: Offer.h:289
ripple::TOffer::m_amounts
TAmounts< TIn, TOut > m_amounts
Definition: Offer.h:56
ripple::Issue
A currency issued by an account.
Definition: Issue.h:35
ripple::TOffer::m_quality
Quality m_quality
Definition: Offer.h:53
std::string
STL class.
ripple::TOffer::limitOut
TAmounts< TIn, TOut > limitOut(TAmounts< TIn, TOut > const &offrAmt, TOut const &limit, bool fixReducedOffers, bool roundUp) const
Definition: Offer.h:210
std::shared_ptr< STLedgerEntry >
ripple::accountSend
TER accountSend(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee)
Definition: View.cpp:1142
std::pair
ripple::TOffer::fully_consumed
bool fully_consumed() const
Returns true if no more funds can flow through this offer.
Definition: Offer.h:98
ripple::ApplyView::update
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
ripple::operator<<
std::ostream & operator<<(std::ostream &os, TOffer< TIn, TOut > const &offer)
Definition: Offer.h:303
ripple::TOffer::id
std::string id() const
Definition: Offer.h:123
ripple::ApplyView
Writeable view to a ledger, for applying a transaction.
Definition: ApplyView.h:134
ripple::TOffer::amount
TAmounts< TIn, TOut > const & amount() const
Returns the in and out amounts.
Definition: Offer.h:91
ripple::TOffer::key
std::optional< uint256 > key() const
Definition: Offer.h:129
stdexcept
ripple::base_uint< 160, detail::AccountIDTag >
ripple::sfTakerPays
const SF_AMOUNT sfTakerPays
ripple::TOffer::m_account
AccountID m_account
Definition: Offer.h:54
ripple::TOffer::TOffer
TOffer()=default
ripple::TOfferBase::issOut_
Issue issOut_
Definition: Offer.h:38
ripple::TOffer::issueIn
Issue const & issueIn() const
Definition: Offer.h:275
std::ostream
STL class.
ripple::TOffer::send
static TER send(Args &&... args)
Definition: Offer.h:236
ripple::toSTAmount
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
Definition: AmountConversions.h:30
ripple::TERSubset< CanCvtToTER >
ripple::TOffer::owner
AccountID const & owner() const
Returns the account id of the offer's owner.
Definition: Offer.h:82
ripple::TOffer::setFieldAmounts
void setFieldAmounts()
Definition: Offer.h:199
ripple::STAmount
Definition: STAmount.h:45
ripple::sfTakerGets
const SF_AMOUNT sfTakerGets
std::uint32_t
ripple::TOffer::m_entry
SLE::pointer m_entry
Definition: Offer.h:52
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::TOffer::consume
void consume(ApplyView &view, TAmounts< TIn, TOut > const &consumed)
Adjusts the offer to indicate that we consumed some (or all) of it.
Definition: Offer.h:109
std::optional
ripple::TOfferBase::issIn_
Issue issIn_
Definition: Offer.h:37
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::TOffer::isFunded
bool isFunded() const
Definition: Offer.h:154
ostream
ripple::TOffer::limitIn
TAmounts< TIn, TOut > limitIn(TAmounts< TIn, TOut > const &offrAmt, TIn const &limit) const
Definition: Offer.h:227
ripple::TOffer::adjustRates
static std::pair< std::uint32_t, std::uint32_t > adjustRates(std::uint32_t ofrInRate, std::uint32_t ofrOutRate)
Definition: Offer.h:161
ripple::TOffer
Definition: Offer.h:49
ripple::Issue::account
AccountID account
Definition: Issue.h:39