rippled
CashDiff.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2016 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_LEDGER_CASHDIFF_H_INCLUDED
21 #define RIPPLE_LEDGER_CASHDIFF_H_INCLUDED
22 
23 #include <ripple/basics/safe_cast.h>
24 #include <ripple/protocol/STAmount.h>
25 #include <memory> // std::unique_ptr
26 
27 namespace ripple {
28 
29 class ReadView;
30 
31 namespace detail {
32 
33 class ApplyStateTable;
34 
35 }
36 
37 // Used by CashDiff to specify filters applied while processing differences.
38 // Entries are bit flags that can be ANDed and ORed.
39 enum class CashFilter : std::uint8_t {
40  none = 0x0,
42 };
43 inline CashFilter
45 {
47  return static_cast<CashFilter>(safe_cast<ul_t>(lhs) | safe_cast<ul_t>(rhs));
48 }
49 inline CashFilter
51 {
53  return static_cast<CashFilter>(safe_cast<ul_t>(lhs) & safe_cast<ul_t>(rhs));
54 }
55 
56 //------------------------------------------------------------------------------
57 
58 // A class to identify differences between two ApplyStateTable instances
59 // for debugging.
60 class CashDiff
61 {
62 public:
63  CashDiff() = delete;
64  CashDiff(CashDiff const&) = delete;
65  CashDiff(CashDiff&& other) noexcept;
66  CashDiff&
67  operator=(CashDiff const&) = delete;
68  ~CashDiff();
69 
70  CashDiff(
71  ReadView const& view,
72  CashFilter lhsFilter,
73  detail::ApplyStateTable const& lhs,
74  CashFilter rhsFilter,
75  detail::ApplyStateTable const& rhs);
76 
77  // Returns the number of cases where lhs and rhs had the same entries
78  // (but not necessarily the same amounts)
80  commonCount() const;
81 
82  // Returns the number of entries that were present in rhs but not in lhs.
84  rhsOnlyCount() const;
85 
86  // Returns the number of entries that were present in lhs but not in rhs.
88  lhsOnlyCount() const;
89 
90  // Returns true is there are any differences to report.
91  bool
92  hasDiff() const;
93 
94  // Checks for the XRP round-to-zero case. Returns zero if not detected.
95  // Otherwise returns -1 if seen on lhs, +1 if seen on rhs.
96  //
97  // For tiny offers of TakerPays IOU and TakerGets XRP, cases have been
98  // observed where XRP rounding allows a tiny amount of IOU to be
99  // removed from an Offer while returning no XRP to the offer owner.
100  // That's because the XRP amount was rounded down to zero drops.
101  //
102  // The person submitting the tiny offer does not, however, get something
103  // for nothing. The transaction's fee is significantly larger than the
104  // value of the received IOU.
105  //
106  // This check should be made before calling rmDust().
107  int
108  xrpRoundToZero() const;
109 
110  // Remove dust-sized differences. Returns true is dust was removed.
111  bool
112  rmDust();
113 
114  // Remove offer deletion differences from a given side. Returns true
115  // if any deleted offers were removed from the differences.
116  bool
118  bool
120 
122  {
123  static std::size_t constexpr count_ = 2;
124  static std::size_t constexpr count()
125  {
126  return count_;
127  }
129  STAmount const&
130  takerPays() const
131  {
132  return amounts[0];
133  }
134  STAmount const&
135  takerGets() const
136  {
137  return amounts[1];
138  }
139  STAmount const&
141  {
142  assert(i < count());
143  return amounts[i];
144  }
145  friend bool
146  operator<(OfferAmounts const& lhs, OfferAmounts const& rhs)
147  {
148  if (lhs[0] < rhs[0])
149  return true;
150  if (lhs[0] > rhs[0])
151  return false;
152  return lhs[1] < rhs[1];
153  }
154  };
155 
156 private:
157  class Impl;
159 };
160 
161 // Return true if the difference between two STAmounts is "small".
162 //
163 // If v1 and v2 have different issues, then their difference is never dust.
164 // If v1 < v2, smallness is computed as v1 / (v2 - v1).
165 // The e10 argument says at least how big that ratio must be. Default is 10^6.
166 // If both v1 and v2 are XRP, consider any diff of 2 drops or less to be dust.
167 bool
168 diffIsDust(STAmount const& v1, STAmount const& v2, std::uint8_t e10 = 6);
169 
170 } // namespace ripple
171 
172 #endif
ripple::CashDiff::OfferAmounts::count_
static constexpr std::size_t count_
Definition: CashDiff.h:123
ripple::CashDiff::OfferAmounts
Definition: CashDiff.h:121
ripple::operator|
const base_uint< Bits, Tag > operator|(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:550
ripple::diffIsDust
bool diffIsDust(STAmount const &v1, STAmount const &v2, std::uint8_t e10=6)
Definition: CashDiff.cpp:758
ripple::CashDiff
Definition: CashDiff.h:60
ripple::CashFilter::none
@ none
ripple::CashDiff::rmLhsDeletedOffers
bool rmLhsDeletedOffers()
Definition: CashDiff.cpp:742
ripple::CashDiff::OfferAmounts::amounts
STAmount amounts[count_]
Definition: CashDiff.h:128
ripple::CashDiff::impl_
std::unique_ptr< Impl > impl_
Definition: CashDiff.h:157
ripple::CashDiff::CashDiff
CashDiff()=delete
ripple::CashDiff::rmRhsDeletedOffers
bool rmRhsDeletedOffers()
Definition: CashDiff.cpp:748
ripple::CashDiff::hasDiff
bool hasDiff() const
Definition: CashDiff.cpp:724
ripple::CashDiff::rhsOnlyCount
std::size_t rhsOnlyCount() const
Definition: CashDiff.cpp:712
std::underlying_type
ripple::CashDiff::OfferAmounts::count
static constexpr std::size_t count()
Definition: CashDiff.h:124
ripple::CashDiff::OfferAmounts::takerPays
STAmount const & takerPays() const
Definition: CashDiff.h:130
ripple::STAmount
Definition: STAmount.h:42
ripple::CashDiff::OfferAmounts::takerGets
STAmount const & takerGets() const
Definition: CashDiff.h:135
std::uint8_t
ripple::CashDiff::commonCount
std::size_t commonCount() const
Definition: CashDiff.cpp:706
ripple::operator&
const base_uint< Bits, Tag > operator&(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:543
memory
ripple::CashFilter::treatZeroOfferAsDeletion
@ treatZeroOfferAsDeletion
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:192
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::CashDiff::lhsOnlyCount
std::size_t lhsOnlyCount() const
Definition: CashDiff.cpp:718
ripple::CashDiff::Impl
Definition: CashDiff.cpp:287
ripple::CashDiff::operator=
CashDiff & operator=(CashDiff const &)=delete
ripple::CashDiff::OfferAmounts::operator<
friend bool operator<(OfferAmounts const &lhs, OfferAmounts const &rhs)
Definition: CashDiff.h:146
ripple::CashDiff::OfferAmounts::operator[]
STAmount const & operator[](std::size_t i) const
Definition: CashDiff.h:140
ripple::CashDiff::~CashDiff
~CashDiff()
std::size_t
ripple::CashDiff::xrpRoundToZero
int xrpRoundToZero() const
Definition: CashDiff.cpp:730
ripple::CashDiff::rmDust
bool rmDust()
Definition: CashDiff.cpp:736
std::unique_ptr
STL class.
ripple::CashFilter
CashFilter
Definition: CashDiff.h:39
ripple::detail::ApplyStateTable
Definition: ApplyStateTable.h:36