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.
40 {
41  none = 0x0,
43 };
45 {
47  return static_cast<CashFilter>(
48  safe_cast<ul_t>(lhs) | safe_cast<ul_t>(rhs));
49 }
51 {
53  return static_cast<CashFilter>(
54  safe_cast<ul_t>(lhs) & safe_cast<ul_t>(rhs));
55 }
56 
57 //------------------------------------------------------------------------------
58 
59 // A class to identify differences between two ApplyStateTable instances
60 // for debugging.
61 class CashDiff
62 {
63 public:
64  CashDiff() = delete;
65  CashDiff (CashDiff const&) = delete;
66  CashDiff (CashDiff&& other) noexcept;
67  CashDiff& operator= (CashDiff const&) = delete;
68  ~CashDiff();
69 
70  CashDiff (ReadView const& view,
71  CashFilter lhsFilter, detail::ApplyStateTable const& lhs,
72  CashFilter rhsFilter, detail::ApplyStateTable const& rhs);
73 
74  // Returns the number of cases where lhs and rhs had the same entries
75  // (but not necessarily the same amounts)
76  std::size_t commonCount () const;
77 
78  // Returns the number of entries that were present in rhs but not in lhs.
79  std::size_t rhsOnlyCount () const;
80 
81  // Returns the number of entries that were present in lhs but not in rhs.
82  std::size_t lhsOnlyCount () const;
83 
84  // Returns true is there are any differences to report.
85  bool hasDiff() const;
86 
87  // Checks for the XRP round-to-zero case. Returns zero if not detected.
88  // Otherwise returns -1 if seen on lhs, +1 if seen on rhs.
89  //
90  // For tiny offers of TakerPays IOU and TakerGets XRP, cases have been
91  // observed where XRP rounding allows a tiny amount of IOU to be
92  // removed from an Offer while returning no XRP to the offer owner.
93  // That's because the XRP amount was rounded down to zero drops.
94  //
95  // The person submitting the tiny offer does not, however, get something
96  // for nothing. The transaction's fee is significantly larger than the
97  // value of the received IOU.
98  //
99  // This check should be made before calling rmDust().
100  int xrpRoundToZero() const;
101 
102  // Remove dust-sized differences. Returns true is dust was removed.
103  bool rmDust();
104 
105  // Remove offer deletion differences from a given side. Returns true
106  // if any deleted offers were removed from the differences.
107  bool rmLhsDeletedOffers();
108  bool rmRhsDeletedOffers();
109 
111  {
112  static std::size_t constexpr count_ = 2;
113  static std::size_t constexpr count() { return count_; }
115  STAmount const& takerPays() const { return amounts[0]; }
116  STAmount const& takerGets() const { return amounts[1]; }
118  {
119  assert (i < count());
120  return amounts[i];
121  }
122  friend bool operator< (OfferAmounts const& lhs, OfferAmounts const& rhs)
123  {
124  if (lhs[0] < rhs[0])
125  return true;
126  if (lhs[0] > rhs[0])
127  return false;
128  return lhs[1] < rhs[1];
129  }
130  };
131 
132 private:
133  class Impl;
135 };
136 
137 // Return true if the difference between two STAmounts is "small".
138 //
139 // If v1 and v2 have different issues, then their difference is never dust.
140 // If v1 < v2, smallness is computed as v1 / (v2 - v1).
141 // The e10 argument says at least how big that ratio must be. Default is 10^6.
142 // If both v1 and v2 are XRP, consider any diff of 2 drops or less to be dust.
143 bool diffIsDust (STAmount const& v1, STAmount const& v2, std::uint8_t e10 = 6);
144 
145 } // ripple
146 
147 #endif
ripple::CashDiff::OfferAmounts::count_
static constexpr std::size_t count_
Definition: CashDiff.h:112
ripple::CashDiff::OfferAmounts
Definition: CashDiff.h:110
ripple::operator|
const base_uint< Bits, Tag > operator|(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:526
ripple::diffIsDust
bool diffIsDust(STAmount const &v1, STAmount const &v2, std::uint8_t e10=6)
Definition: CashDiff.cpp:697
ripple::CashDiff
Definition: CashDiff.h:61
ripple::CashFilter::none
@ none
ripple::CashDiff::rmLhsDeletedOffers
bool rmLhsDeletedOffers()
Definition: CashDiff.cpp:683
ripple::CashDiff::OfferAmounts::amounts
STAmount amounts[count_]
Definition: CashDiff.h:114
ripple::CashDiff::impl_
std::unique_ptr< Impl > impl_
Definition: CashDiff.h:133
ripple::CashDiff::CashDiff
CashDiff()=delete
ripple::CashDiff::rmRhsDeletedOffers
bool rmRhsDeletedOffers()
Definition: CashDiff.cpp:688
ripple::CashDiff::hasDiff
bool hasDiff() const
Definition: CashDiff.cpp:668
ripple::CashDiff::rhsOnlyCount
std::size_t rhsOnlyCount() const
Definition: CashDiff.cpp:658
std::underlying_type
ripple::CashDiff::OfferAmounts::count
static constexpr std::size_t count()
Definition: CashDiff.h:113
ripple::CashDiff::OfferAmounts::takerPays
STAmount const & takerPays() const
Definition: CashDiff.h:115
ripple::STAmount
Definition: STAmount.h:42
ripple::CashDiff::OfferAmounts::takerGets
STAmount const & takerGets() const
Definition: CashDiff.h:116
std::uint8_t
ripple::CashDiff::commonCount
std::size_t commonCount() const
Definition: CashDiff.cpp:653
ripple::operator&
const base_uint< Bits, Tag > operator&(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:519
memory
ripple::CashFilter::treatZeroOfferAsDeletion
@ treatZeroOfferAsDeletion
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:186
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:663
ripple::CashDiff::Impl
Definition: CashDiff.cpp:285
ripple::CashDiff::operator=
CashDiff & operator=(CashDiff const &)=delete
ripple::CashDiff::OfferAmounts::operator<
friend bool operator<(OfferAmounts const &lhs, OfferAmounts const &rhs)
Definition: CashDiff.h:122
ripple::CashDiff::OfferAmounts::operator[]
STAmount const & operator[](std::size_t i) const
Definition: CashDiff.h:117
ripple::CashDiff::~CashDiff
~CashDiff()
std::size_t
ripple::CashDiff::xrpRoundToZero
int xrpRoundToZero() const
Definition: CashDiff.cpp:673
ripple::CashDiff::rmDust
bool rmDust()
Definition: CashDiff.cpp:678
std::unique_ptr
STL class.
ripple::CashFilter
CashFilter
Definition: CashDiff.h:39
ripple::detail::ApplyStateTable
Definition: ApplyStateTable.h:36