rippled
Loading...
Searching...
No Matches
ledgers.h
1#ifndef XRPL_TEST_CSF_LEDGERS_H_INCLUDED
2#define XRPL_TEST_CSF_LEDGERS_H_INCLUDED
3
4#include <test/csf/Tx.h>
5
6#include <xrpld/consensus/LedgerTiming.h>
7
8#include <xrpl/basics/UnorderedContainers.h>
9#include <xrpl/basics/chrono.h>
10#include <xrpl/basics/comparators.h>
11#include <xrpl/basics/tagged_integer.h>
12#include <xrpl/json/json_value.h>
13
14#include <boost/bimap/bimap.hpp>
15
16#include <optional>
17#include <set>
18
19namespace ripple {
20namespace test {
21namespace csf {
22
44class Ledger
45{
46 friend class LedgerOracle;
47
48public:
49 struct SeqTag;
51
52 struct IdTag;
54
56 {
57 };
58
59private:
60 // The instance is the common immutable data that will be assigned a unique
61 // ID by the oracle
62 struct Instance
63 {
65 {
66 }
67
68 // Sequence number
69 Seq seq{0};
70
71 // Transactions added to generate this ledger
73
74 // Resolution used to determine close time
76
79
81 bool closeTimeAgree = true;
82
85
88
93
94 auto
95 asTie() const
96 {
97 return std::tie(
98 seq,
99 txs,
101 closeTime,
103 parentID,
105 }
106
107 friend bool
108 operator==(Instance const& a, Instance const& b)
109 {
110 return a.asTie() == b.asTie();
111 }
112
113 friend bool
114 operator!=(Instance const& a, Instance const& b)
115 {
116 return a.asTie() != b.asTie();
117 }
118
119 friend bool
120 operator<(Instance const& a, Instance const& b)
121 {
122 return a.asTie() < b.asTie();
123 }
124
125 template <class Hasher>
126 friend void
127 hash_append(Hasher& h, Ledger::Instance const& instance)
128 {
129 using beast::hash_append;
130 hash_append(h, instance.asTie());
131 }
132 };
133
134 // Single common genesis instance
135 static Instance const genesis;
136
137 Ledger(ID id, Instance const* i) : id_{id}, instance_{i}
138 {
139 }
140
141public:
145
146 // This is required by the generic Consensus for now and should be
147 // migrated to the MakeGenesis approach above.
149 {
150 }
151
152 ID
153 id() const
154 {
155 return id_;
156 }
157
158 Seq
159 seq() const
160 {
161 return instance_->seq;
162 }
163
166 {
168 }
169
170 bool
172 {
174 }
175
177 closeTime() const
178 {
179 return instance_->closeTime;
180 }
181
184 {
186 }
187
188 ID
189 parentID() const
190 {
191 return instance_->parentID;
192 }
193
194 TxSetType const&
195 txs() const
196 {
197 return instance_->txs;
198 }
199
201 bool
202 isAncestor(Ledger const& ancestor) const;
203
206 ID
207 operator[](Seq seq) const;
208
211 friend Ledger::Seq
212 mismatch(Ledger const& a, Ledger const& o);
213
215 getJson() const;
216
217 friend bool
218 operator<(Ledger const& a, Ledger const& b)
219 {
220 return a.id() < b.id();
221 }
222
223private:
224 ID id_{0};
226};
227
231{
232 using InstanceMap = boost::bimaps::bimap<
233 boost::bimaps::set_of<Ledger::Instance, ripple::less<Ledger::Instance>>,
234 boost::bimaps::set_of<Ledger::ID, ripple::less<Ledger::ID>>>;
235 using InstanceEntry = InstanceMap::value_type;
236
237 // Set of all known ledgers; note this is never pruned
239
240 // ID for the next unique ledger
242 nextID() const;
243
244public:
245 LedgerOracle();
246
249 lookup(Ledger::ID const& id) const;
250
259 Ledger
260 accept(
261 Ledger const& curr,
262 TxSetType const& txs,
263 NetClock::duration closeTimeResolution,
264 NetClock::time_point const& consensusCloseTime);
265
266 Ledger
267 accept(Ledger const& curr, Tx tx)
268 {
269 using namespace std::chrono_literals;
270 return accept(
271 curr,
272 TxSetType{tx},
273 curr.closeTimeResolution(),
274 curr.closeTime() + 1s);
275 }
276
287 branches(std::set<Ledger> const& ledgers) const;
288};
289
310{
315
320
326 Ledger const&
328 {
329 auto it = ledgers.find(s);
330 if (it != ledgers.end())
331 return it->second;
332
333 // enforce that the new suffix has never been seen
334 assert(seen.emplace(s.back()).second);
335
336 Ledger const& parent = (*this)[s.substr(0, s.size() - 1)];
337 return ledgers.emplace(s, oracle.accept(parent, Tx{++nextTx}))
338 .first->second;
339 }
340};
341
342} // namespace csf
343} // namespace test
344} // namespace ripple
345
346#endif
T back(T... args)
Represents a JSON value.
Definition json_value.h:130
Oracle maintaining unique ledgers for a simulation.
Definition ledgers.h:231
Ledger accept(Ledger const &curr, Tx tx)
Definition ledgers.h:267
InstanceMap::value_type InstanceEntry
Definition ledgers.h:235
Ledger::ID nextID() const
Definition ledgers.cpp:72
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:78
std::optional< Ledger > lookup(Ledger::ID const &id) const
Find the ledger with the given ID.
Definition ledgers.cpp:110
std::size_t branches(std::set< Ledger > const &ledgers) const
Determine the number of distinct branches for the set of ledgers.
Definition ledgers.cpp:121
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:234
A ledger is a set of observed transactions and a sequence number identifying the ledger.
Definition ledgers.h:45
static Instance const genesis
Definition ledgers.h:135
friend bool operator<(Ledger const &a, Ledger const &b)
Definition ledgers.h:218
NetClock::duration closeTimeResolution() const
Definition ledgers.h:165
NetClock::time_point parentCloseTime() const
Definition ledgers.h:183
friend Ledger::Seq mismatch(Ledger const &a, Ledger const &o)
Return the sequence number of the first mismatching ancestor.
Definition ledgers.cpp:39
NetClock::time_point closeTime() const
Definition ledgers.h:177
Instance const * instance_
Definition ledgers.h:225
Json::Value getJson() const
Definition ledgers.cpp:12
bool closeAgree() const
Definition ledgers.h:171
TxSetType const & txs() const
Definition ledgers.h:195
bool isAncestor(Ledger const &ancestor) const
Determine whether ancestor is really an ancestor of this ledger.
Definition ledgers.cpp:21
ID operator[](Seq seq) const
Return the id of the ancestor with the given seq (if exists/known)
Definition ledgers.cpp:29
Ledger(ID id, Instance const *i)
Definition ledgers.h:137
tagged_integer< std::uint32_t, SeqTag > Seq
Definition ledgers.h:50
tagged_integer< std::uint32_t, IdTag > ID
Definition ledgers.h:53
A single transaction.
Definition Tx.h:23
T emplace(T... args)
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.
boost::container::flat_set< Tx > TxSetType
Definition Tx.h:60
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
auto constexpr ledgerDefaultTimeResolution
Initial resolution of ledger close time.
T size(T... args)
Helper for writing unit tests with controlled ledger histories.
Definition ledgers.h:310
Ledger const & operator[](std::string const &s)
Get or create the ledger with the given string history.
Definition ledgers.h:327
std::unordered_map< std::string, Ledger > ledgers
Definition ledgers.h:313
NetClock::time_point parentCloseTime
Parent ledger close time.
Definition ledgers.h:87
friend bool operator==(Instance const &a, Instance const &b)
Definition ledgers.h:108
NetClock::duration closeTimeResolution
Definition ledgers.h:75
ID parentID
Parent ledger id.
Definition ledgers.h:84
bool closeTimeAgree
Whether consensus agreed on the close time.
Definition ledgers.h:81
friend bool operator<(Instance const &a, Instance const &b)
Definition ledgers.h:120
friend bool operator!=(Instance const &a, Instance const &b)
Definition ledgers.h:114
friend void hash_append(Hasher &h, Ledger::Instance const &instance)
Definition ledgers.h:127
std::vector< Ledger::ID > ancestors
IDs of this ledgers ancestors.
Definition ledgers.h:92
NetClock::time_point closeTime
When the ledger closed (up to closeTimeResolution)
Definition ledgers.h:78
Set the sequence number on a JTx.
Definition seq.h:15
T substr(T... args)
T tie(T... args)