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/tagged_integer.h>
25 #include <ripple/consensus/LedgerTiming.h>
26 #include <ripple/json/json_value.h>
27 #include <boost/bimap/bimap.hpp>
28 #include <boost/optional.hpp>
29 #include <set>
30 #include <test/csf/Tx.h>
31 
32 namespace ripple {
33 namespace test {
34 namespace csf {
35 
57 class Ledger
58 {
59  friend class LedgerOracle;
60 
61 public:
62  struct SeqTag;
64 
65  struct IdTag;
67 
68  struct MakeGenesis
69  {
70  };
71 
72 private:
73  // The instance is the common immutable data that will be assigned a unique
74  // ID by the oracle
75  struct Instance
76  {
78  {
79  }
80 
81  // Sequence number
82  Seq seq{0};
83 
84  // Transactions added to generate this ledger
86 
87  // Resolution used to determine close time
89 
92 
94  bool closeTimeAgree = true;
95 
98 
101 
106 
107  auto
108  asTie() const
109  {
110  return std::tie(
111  seq,
112  txs,
114  closeTime,
116  parentID,
118  }
119 
120  friend bool
121  operator==(Instance const& a, Instance const& b)
122  {
123  return a.asTie() == b.asTie();
124  }
125 
126  friend bool
127  operator!=(Instance const& a, Instance const& b)
128  {
129  return a.asTie() != b.asTie();
130  }
131 
132  friend bool
133  operator<(Instance const& a, Instance const& b)
134  {
135  return a.asTie() < b.asTie();
136  }
137 
138  template <class Hasher>
139  friend void
140  hash_append(Hasher& h, Ledger::Instance const& instance)
141  {
142  using beast::hash_append;
143  hash_append(h, instance.asTie());
144  }
145  };
146 
147  // Single common genesis instance
148  static const Instance genesis;
149 
150  Ledger(ID id, Instance const* i) : id_{id}, instance_{i}
151  {
152  }
153 
154 public:
156  {
157  }
158 
159  // This is required by the generic Consensus for now and should be
160  // migrated to the MakeGenesis approach above.
162  {
163  }
164 
165  ID
166  id() const
167  {
168  return id_;
169  }
170 
171  Seq
172  seq() const
173  {
174  return instance_->seq;
175  }
176 
179  {
181  }
182 
183  bool
184  closeAgree() const
185  {
186  return instance_->closeTimeAgree;
187  }
188 
190  closeTime() const
191  {
192  return instance_->closeTime;
193  }
194 
197  {
198  return instance_->parentCloseTime;
199  }
200 
201  ID
202  parentID() const
203  {
204  return instance_->parentID;
205  }
206 
207  TxSetType const&
208  txs() const
209  {
210  return instance_->txs;
211  }
212 
214  bool
215  isAncestor(Ledger const& ancestor) const;
216 
219  ID
220  operator[](Seq seq) const;
221 
224  friend Ledger::Seq
225  mismatch(Ledger const& a, Ledger const& o);
226 
228  getJson() const;
229 
230  friend bool
231  operator<(Ledger const& a, Ledger const& b)
232  {
233  return a.id() < b.id();
234  }
235 
236 private:
237  ID id_{0};
239 };
240 
244 {
245  using InstanceMap = boost::bimaps::bimap<Ledger::Instance, Ledger::ID>;
246  using InstanceEntry = InstanceMap::value_type;
247 
248  // Set of all known ledgers; note this is never pruned
250 
251  // ID for the next unique ledger
252  Ledger::ID
253  nextID() const;
254 
255 public:
256  LedgerOracle();
257 
259  boost::optional<Ledger>
260  lookup(Ledger::ID const& id) const;
261 
270  Ledger
271  accept(
272  Ledger const& curr,
273  TxSetType const& txs,
274  NetClock::duration closeTimeResolution,
275  NetClock::time_point const& consensusCloseTime);
276 
277  Ledger
278  accept(Ledger const& curr, Tx tx)
279  {
280  using namespace std::chrono_literals;
281  return accept(
282  curr,
283  TxSetType{tx},
284  curr.closeTimeResolution(),
285  curr.closeTime() + 1s);
286  }
287 
298  branches(std::set<Ledger> const& ledgers) const;
299 };
300 
321 {
323  Tx::ID nextTx{0};
326 
328  {
329  ledgers[""] = Ledger{Ledger::MakeGenesis{}};
330  }
331 
337  Ledger const&
339  {
340  auto it = ledgers.find(s);
341  if (it != ledgers.end())
342  return it->second;
343 
344  // enforce that the new suffix has never been seen
345  assert(seen.emplace(s.back()).second);
346 
347  Ledger const& parent = (*this)[s.substr(0, s.size() - 1)];
348  return ledgers.emplace(s, oracle.accept(parent, ++nextTx))
349  .first->second;
350  }
351 };
352 
353 } // namespace csf
354 } // namespace test
355 } // namespace ripple
356 
357 #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:202
ripple::test::csf::Ledger::Instance::asTie
auto asTie() const
Definition: ledgers.h:108
ripple::test::csf::Ledger::Ledger
Ledger()
Definition: ledgers.h:161
ripple::test::csf::LedgerOracle::InstanceEntry
InstanceMap::value_type InstanceEntry
Definition: ledgers.h:246
ripple::test::csf::Ledger::Instance::operator!=
friend bool operator!=(Instance const &a, Instance const &b)
Definition: ledgers.h:127
std::string
STL class.
ripple::test::csf::LedgerOracle::lookup
boost::optional< Ledger > lookup(Ledger::ID const &id) const
Find the ledger with the given ID.
Definition: ledgers.cpp:129
ripple::test::csf::TxSetType
boost::container::flat_set< Tx > TxSetType
Definition: Tx.h:67
ripple::test::csf::Ledger::Ledger
Ledger(MakeGenesis)
Definition: ledgers.h:155
ripple::test::csf::Ledger::Instance::txs
TxSetType txs
Definition: ledgers.h:85
ripple::test::csf::LedgerOracle::nextID
Ledger::ID nextID() const
Definition: ledgers.cpp:91
ripple::test::csf::Ledger::Instance::seq
Seq seq
Definition: ledgers.h:82
ripple::test::csf::LedgerOracle::accept
Ledger accept(Ledger const &curr, Tx tx)
Definition: ledgers.h:278
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:77
ripple::test::csf::LedgerHistoryHelper::ledgers
std::unordered_map< std::string, Ledger > ledgers
Definition: ledgers.h:324
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:75
std::chrono::duration
ripple::test::csf::Ledger::Instance::closeTimeAgree
bool closeTimeAgree
Whether consensus agreed on the close time.
Definition: ledgers.h:94
std::set::emplace
T emplace(T... args)
ripple::test::csf::Ledger::txs
TxSetType const & txs() const
Definition: ledgers.h:208
ripple::test::csf::Ledger::Instance::ancestors
std::vector< Ledger::ID > ancestors
IDs of this ledgers ancestors.
Definition: ledgers.h:105
ripple::test::csf::Ledger
A ledger is a set of observed transactions and a sequence number identifying the ledger.
Definition: ledgers.h:57
ripple::test::csf::Ledger::id_
ID id_
Definition: ledgers.h:237
std::string::back
T back(T... args)
ripple::test::csf::Ledger::seq
Seq seq() const
Definition: ledgers.h:172
ripple::test::csf::Ledger::Instance::parentCloseTime
NetClock::time_point parentCloseTime
Parent ledger close time.
Definition: ledgers.h:100
ripple::test::csf::LedgerOracle::LedgerOracle
LedgerOracle()
Definition: ledgers.cpp:85
ripple::test::csf::LedgerOracle::instances_
InstanceMap instances_
Definition: ledgers.h:249
ripple::test::csf::Ledger::closeTimeResolution
NetClock::duration closeTimeResolution() const
Definition: ledgers.h:178
ripple::test::csf::Ledger::MakeGenesis
Definition: ledgers.h:68
ripple::test::csf::LedgerHistoryHelper::seen
std::set< char > seen
Definition: ledgers.h:325
ripple::test::csf::LedgerHistoryHelper
Helper for writing unit tests with controlled ledger histories.
Definition: ledgers.h:320
std::tie
T tie(T... args)
ripple::test::csf::Ledger::Instance::operator<
friend bool operator<(Instance const &a, Instance const &b)
Definition: ledgers.h:133
ripple::test::csf::Ledger::parentCloseTime
NetClock::time_point parentCloseTime() const
Definition: ledgers.h:196
ripple::test::csf::LedgerOracle
Oracle maintaining unique ledgers for a simulation.
Definition: ledgers.h:243
ripple::test::csf::LedgerOracle::InstanceMap
boost::bimaps::bimap< Ledger::Instance, Ledger::ID > InstanceMap
Definition: ledgers.h:245
ripple::test::csf::LedgerHistoryHelper::oracle
LedgerOracle oracle
Definition: ledgers.h:322
ripple::test::csf::Tx
A single transaction.
Definition: Tx.h:34
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:91
std::uint32_t
ripple::test::csf::Ledger::Ledger
Ledger(ID id, Instance const *i)
Definition: ledgers.h:150
ripple::test::csf::Ledger::Instance::parentID
ID parentID
Parent ledger id.
Definition: ledgers.h:97
ripple::test::csf::Ledger::Instance::operator==
friend bool operator==(Instance const &a, Instance const &b)
Definition: ledgers.h:121
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:190
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:32
ripple::test::csf::Ledger::id
ID id() const
Definition: ledgers.h:166
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:148
ripple::test::csf::Ledger::Instance::hash_append
friend void hash_append(Hasher &h, Ledger::Instance const &instance)
Definition: ledgers.h:140
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:237
ripple::test::csf::Ledger::ID
tagged_integer< std::uint32_t, IdTag > ID
Definition: ledgers.h:66
ripple::test::csf::Ledger::closeAgree
bool closeAgree() const
Definition: ledgers.h:184
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:63
std::size_t
std::unordered_map::end
T end(T... args)
ripple::test::csf::Ledger::instance_
Instance const * instance_
Definition: ledgers.h:238
ripple::tagged_integer< std::uint32_t, SeqTag >
ripple::test::csf::Ledger::Instance::closeTimeResolution
NetClock::duration closeTimeResolution
Definition: ledgers.h:88
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:231
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:338
ripple::test::csf::LedgerHistoryHelper::LedgerHistoryHelper
LedgerHistoryHelper()
Definition: ledgers.h:327
Json::Value
Represents a JSON value.
Definition: json_value.h:145