rippled
ledgers.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2017 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 #ifndef RIPPLE_TEST_CSF_LEDGERS_H_INCLUDED
20 #define RIPPLE_TEST_CSF_LEDGERS_H_INCLUDED
21 
22 #include <ripple/basics/UnorderedContainers.h>
23 #include <ripple/basics/chrono.h>
24 #include <ripple/basics/comparators.h>
25 #include <ripple/basics/tagged_integer.h>
26 #include <ripple/consensus/LedgerTiming.h>
27 #include <ripple/json/json_value.h>
28 #include <boost/bimap/bimap.hpp>
29 #include <optional>
30 #include <set>
31 #include <test/csf/Tx.h>
32 
33 namespace ripple {
34 namespace test {
35 namespace csf {
36 
58 class Ledger
59 {
60  friend class LedgerOracle;
61 
62 public:
63  struct SeqTag;
65 
66  struct IdTag;
68 
69  struct MakeGenesis
70  {
71  };
72 
73 private:
74  // The instance is the common immutable data that will be assigned a unique
75  // ID by the oracle
76  struct Instance
77  {
79  {
80  }
81 
82  // Sequence number
83  Seq seq{0};
84 
85  // Transactions added to generate this ledger
87 
88  // Resolution used to determine close time
90 
93 
95  bool closeTimeAgree = true;
96 
99 
102 
107 
108  auto
109  asTie() const
110  {
111  return std::tie(
112  seq,
113  txs,
115  closeTime,
117  parentID,
119  }
120 
121  friend bool
122  operator==(Instance const& a, Instance const& b)
123  {
124  return a.asTie() == b.asTie();
125  }
126 
127  friend bool
128  operator!=(Instance const& a, Instance const& b)
129  {
130  return a.asTie() != b.asTie();
131  }
132 
133  friend bool
134  operator<(Instance const& a, Instance const& b)
135  {
136  return a.asTie() < b.asTie();
137  }
138 
139  template <class Hasher>
140  friend void
141  hash_append(Hasher& h, Ledger::Instance const& instance)
142  {
143  using beast::hash_append;
144  hash_append(h, instance.asTie());
145  }
146  };
147 
148  // Single common genesis instance
149  static const Instance genesis;
150 
151  Ledger(ID id, Instance const* i) : id_{id}, instance_{i}
152  {
153  }
154 
155 public:
157  {
158  }
159 
160  // This is required by the generic Consensus for now and should be
161  // migrated to the MakeGenesis approach above.
163  {
164  }
165 
166  ID
167  id() const
168  {
169  return id_;
170  }
171 
172  Seq
173  seq() const
174  {
175  return instance_->seq;
176  }
177 
180  {
182  }
183 
184  bool
185  closeAgree() const
186  {
187  return instance_->closeTimeAgree;
188  }
189 
191  closeTime() const
192  {
193  return instance_->closeTime;
194  }
195 
198  {
199  return instance_->parentCloseTime;
200  }
201 
202  ID
203  parentID() const
204  {
205  return instance_->parentID;
206  }
207 
208  TxSetType const&
209  txs() const
210  {
211  return instance_->txs;
212  }
213 
215  bool
216  isAncestor(Ledger const& ancestor) const;
217 
220  ID
221  operator[](Seq seq) const;
222 
225  friend Ledger::Seq
226  mismatch(Ledger const& a, Ledger const& o);
227 
229  getJson() const;
230 
231  friend bool
232  operator<(Ledger const& a, Ledger const& b)
233  {
234  return a.id() < b.id();
235  }
236 
237 private:
238  ID id_{0};
240 };
241 
245 {
246  using InstanceMap = boost::bimaps::bimap<
247  boost::bimaps::set_of<Ledger::Instance, ripple::less<Ledger::Instance>>,
248  boost::bimaps::set_of<Ledger::ID, ripple::less<Ledger::ID>>>;
249  using InstanceEntry = InstanceMap::value_type;
250 
251  // Set of all known ledgers; note this is never pruned
253 
254  // ID for the next unique ledger
255  Ledger::ID
256  nextID() const;
257 
258 public:
259  LedgerOracle();
260 
263  lookup(Ledger::ID const& id) const;
264 
273  Ledger
274  accept(
275  Ledger const& curr,
276  TxSetType const& txs,
277  NetClock::duration closeTimeResolution,
278  NetClock::time_point const& consensusCloseTime);
279 
280  Ledger
281  accept(Ledger const& curr, Tx tx)
282  {
283  using namespace std::chrono_literals;
284  return accept(
285  curr,
286  TxSetType{tx},
287  curr.closeTimeResolution(),
288  curr.closeTime() + 1s);
289  }
290 
301  branches(std::set<Ledger> const& ledgers) const;
302 };
303 
324 {
326  Tx::ID nextTx{0};
329 
331  {
332  ledgers[""] = Ledger{Ledger::MakeGenesis{}};
333  }
334 
340  Ledger const&
342  {
343  auto it = ledgers.find(s);
344  if (it != ledgers.end())
345  return it->second;
346 
347  // enforce that the new suffix has never been seen
348  assert(seen.emplace(s.back()).second);
349 
350  Ledger const& parent = (*this)[s.substr(0, s.size() - 1)];
351  return ledgers.emplace(s, oracle.accept(parent, Tx{++nextTx}))
352  .first->second;
353  }
354 };
355 
356 } // namespace csf
357 } // namespace test
358 } // namespace ripple
359 
360 #endif
ripple::test::csf::Ledger::getJson
Json::Value getJson() const
Definition: ledgers.cpp:31
ripple::test::csf::Ledger::parentID
ID parentID() const
Definition: ledgers.h:203
ripple::test::csf::Ledger::Instance::asTie
auto asTie() const
Definition: ledgers.h:109
ripple::test::csf::Ledger::Ledger
Ledger()
Definition: ledgers.h:162
ripple::test::csf::LedgerOracle::InstanceEntry
InstanceMap::value_type InstanceEntry
Definition: ledgers.h:249
ripple::test::csf::Ledger::Instance::operator!=
friend bool operator!=(Instance const &a, Instance const &b)
Definition: ledgers.h:128
std::string
STL class.
ripple::test::csf::TxSetType
boost::container::flat_set< Tx > TxSetType
Definition: Tx.h:73
ripple::test::csf::Ledger::Ledger
Ledger(MakeGenesis)
Definition: ledgers.h:156
ripple::test::csf::Ledger::Instance::txs
TxSetType txs
Definition: ledgers.h:86
ripple::test::csf::LedgerOracle::nextID
Ledger::ID nextID() const
Definition: ledgers.cpp:91
ripple::test::csf::Ledger::Instance::seq
Seq seq
Definition: ledgers.h:83
ripple::test::csf::LedgerOracle::accept
Ledger accept(Ledger const &curr, Tx tx)
Definition: ledgers.h:281
ripple::test::csf::LedgerOracle::accept
Ledger accept(Ledger const &curr, TxSetType const &txs, NetClock::duration closeTimeResolution, NetClock::time_point const &consensusCloseTime)
Accept the given txs and generate a new ledger.
Definition: ledgers.cpp:97
ripple::test::csf::Ledger::Instance::Instance
Instance()
Definition: ledgers.h:78
ripple::test::csf::LedgerHistoryHelper::ledgers
std::unordered_map< std::string, Ledger > ledgers
Definition: ledgers.h:327
std::vector
STL class.
std::unordered_map::find
T find(T... args)
std::string::size
T size(T... args)
ripple::test::csf::Ledger::Instance
Definition: ledgers.h:76
std::chrono::duration
ripple::test::csf::Ledger::Instance::closeTimeAgree
bool closeTimeAgree
Whether consensus agreed on the close time.
Definition: ledgers.h:95
std::set::emplace
T emplace(T... args)
ripple::test::csf::Ledger::txs
TxSetType const & txs() const
Definition: ledgers.h:209
ripple::test::csf::Ledger::Instance::ancestors
std::vector< Ledger::ID > ancestors
IDs of this ledgers ancestors.
Definition: ledgers.h:106
ripple::test::csf::Ledger
A ledger is a set of observed transactions and a sequence number identifying the ledger.
Definition: ledgers.h:58
ripple::test::csf::Ledger::id_
ID id_
Definition: ledgers.h:238
std::string::back
T back(T... args)
ripple::test::csf::Ledger::seq
Seq seq() const
Definition: ledgers.h:173
ripple::test::csf::Ledger::Instance::parentCloseTime
NetClock::time_point parentCloseTime
Parent ledger close time.
Definition: ledgers.h:101
ripple::test::csf::LedgerOracle::LedgerOracle
LedgerOracle()
Definition: ledgers.cpp:85
ripple::test::csf::LedgerOracle::instances_
InstanceMap instances_
Definition: ledgers.h:252
ripple::test::csf::Ledger::closeTimeResolution
NetClock::duration closeTimeResolution() const
Definition: ledgers.h:179
ripple::test::csf::Ledger::MakeGenesis
Definition: ledgers.h:69
ripple::test::csf::LedgerHistoryHelper::seen
std::set< char > seen
Definition: ledgers.h:328
ripple::test::csf::LedgerHistoryHelper
Helper for writing unit tests with controlled ledger histories.
Definition: ledgers.h:323
std::tie
T tie(T... args)
ripple::test::csf::LedgerOracle::lookup
std::optional< Ledger > lookup(Ledger::ID const &id) const
Find the ledger with the given ID.
Definition: ledgers.cpp:129
ripple::test::csf::Ledger::Instance::operator<
friend bool operator<(Instance const &a, Instance const &b)
Definition: ledgers.h:134
ripple::test::csf::Ledger::parentCloseTime
NetClock::time_point parentCloseTime() const
Definition: ledgers.h:197
ripple::test::csf::LedgerOracle
Oracle maintaining unique ledgers for a simulation.
Definition: ledgers.h:244
ripple::test::csf::LedgerHistoryHelper::oracle
LedgerOracle oracle
Definition: ledgers.h:325
ripple::test::csf::Tx
A single transaction.
Definition: Tx.h:35
ripple::test::csf::Ledger::operator[]
ID operator[](Seq seq) const
Return the id of the ancestor with the given seq (if exists/known)
Definition: ledgers.cpp:48
std::chrono::time_point
ripple::test::csf::Ledger::Instance::closeTime
NetClock::time_point closeTime
When the ledger closed (up to closeTimeResolution)
Definition: ledgers.h:92
std::uint32_t
ripple::test::csf::Ledger::Ledger
Ledger(ID id, Instance const *i)
Definition: ledgers.h:151
ripple::test::csf::Ledger::Instance::parentID
ID parentID
Parent ledger id.
Definition: ledgers.h:98
ripple::test::csf::Ledger::Instance::operator==
friend bool operator==(Instance const &a, Instance const &b)
Definition: ledgers.h:122
ripple::test::csf::Ledger::mismatch
friend Ledger::Seq mismatch(Ledger const &a, Ledger const &o)
Return the sequence number of the first mismatching ancestor.
Definition: ledgers.cpp:58
std::string::substr
T substr(T... args)
ripple::test::csf::Ledger::closeTime
NetClock::time_point closeTime() const
Definition: ledgers.h:191
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:33
ripple::test::csf::Ledger::id
ID id() const
Definition: ledgers.h:167
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::csf::Ledger::genesis
static const Instance genesis
Definition: ledgers.h:149
ripple::test::csf::Ledger::Instance::hash_append
friend void hash_append(Hasher &h, Ledger::Instance const &instance)
Definition: ledgers.h:141
ripple::test::csf::LedgerOracle::branches
std::size_t branches(std::set< Ledger > const &ledgers) const
Determine the number of distinct branches for the set of ledgers.
Definition: ledgers.cpp:140
beast::hash_append
std::enable_if_t< is_contiguously_hashable< T, Hasher >::value > hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
Definition: hash_append.h:236
ripple::test::csf::Ledger::ID
tagged_integer< std::uint32_t, IdTag > ID
Definition: ledgers.h:67
ripple::test::csf::Ledger::closeAgree
bool closeAgree() const
Definition: ledgers.h:185
ripple::test::csf::Ledger::isAncestor
bool isAncestor(Ledger const &ancestor) const
Determine whether ancestor is really an ancestor of this ledger.
Definition: ledgers.cpp:40
ripple::test::csf::Ledger::Seq
tagged_integer< std::uint32_t, SeqTag > Seq
Definition: ledgers.h:64
optional
std::size_t
std::unordered_map::end
T end(T... args)
ripple::test::csf::Ledger::instance_
Instance const * instance_
Definition: ledgers.h:239
ripple::tagged_integer< std::uint32_t, SeqTag >
ripple::test::csf::Ledger::Instance::closeTimeResolution
NetClock::duration closeTimeResolution
Definition: ledgers.h:89
ripple::ledgerDefaultTimeResolution
constexpr auto ledgerDefaultTimeResolution
Initial resolution of ledger close time.
Definition: LedgerTiming.h:44
std::unordered_map
STL class.
ripple::test::csf::Ledger::operator<
friend bool operator<(Ledger const &a, Ledger const &b)
Definition: ledgers.h:232
set
ripple::test::csf::LedgerHistoryHelper::operator[]
Ledger const & operator[](std::string const &s)
Get or create the ledger with the given string history.
Definition: ledgers.h:341
ripple::test::csf::LedgerHistoryHelper::LedgerHistoryHelper
LedgerHistoryHelper()
Definition: ledgers.h:330
ripple::test::csf::LedgerOracle::InstanceMap
boost::bimaps::bimap< boost::bimaps::set_of< Ledger::Instance, ripple::less< Ledger::Instance > >, boost::bimaps::set_of< Ledger::ID, ripple::less< Ledger::ID > >> InstanceMap
Definition: ledgers.h:248
Json::Value
Represents a JSON value.
Definition: json_value.h:145