rippled
Loading...
Searching...
No Matches
ledgers.h
1#pragma once
2
3#include <test/csf/Tx.h>
4
5#include <xrpl/basics/UnorderedContainers.h>
6#include <xrpl/basics/chrono.h>
7#include <xrpl/basics/comparators.h>
8#include <xrpl/basics/tagged_integer.h>
9#include <xrpl/json/json_value.h>
10#include <xrpl/ledger/LedgerTiming.h>
11
12#include <boost/bimap/bimap.hpp>
13
14#include <optional>
15#include <set>
16
17namespace xrpl {
18namespace test {
19namespace csf {
20
42class Ledger
43{
44 friend class LedgerOracle;
45
46public:
47 struct SeqTag;
49
50 struct IdTag;
52
54 {
55 };
56
57private:
58 // The instance is the common immutable data that will be assigned a unique
59 // ID by the oracle
60 struct Instance
61 {
63 {
64 }
65
66 // Sequence number
67 Seq seq{0};
68
69 // Transactions added to generate this ledger
71
72 // Resolution used to determine close time
74
77
79 bool closeTimeAgree = true;
80
83
86
91
92 auto
93 asTie() const
94 {
95 return std::tie(
96 seq,
97 txs,
101 parentID,
103 }
104
105 friend bool
106 operator==(Instance const& a, Instance const& b)
107 {
108 return a.asTie() == b.asTie();
109 }
110
111 friend bool
112 operator!=(Instance const& a, Instance const& b)
113 {
114 return a.asTie() != b.asTie();
115 }
116
117 friend bool
118 operator<(Instance const& a, Instance const& b)
119 {
120 return a.asTie() < b.asTie();
121 }
122
123 template <class Hasher>
124 friend void
125 hash_append(Hasher& h, Ledger::Instance const& instance)
126 {
127 using beast::hash_append;
128 hash_append(h, instance.asTie());
129 }
130 };
131
132 // Single common genesis instance
133 static Instance const genesis;
134
135 Ledger(ID id, Instance const* i) : id_{id}, instance_{i}
136 {
137 }
138
139public:
143
144 // This is required by the generic Consensus for now and should be
145 // migrated to the MakeGenesis approach above.
147 {
148 }
149
150 ID
151 id() const
152 {
153 return id_;
154 }
155
156 Seq
157 seq() const
158 {
159 return instance_->seq;
160 }
161
164 {
166 }
167
168 bool
170 {
172 }
173
175 closeTime() const
176 {
177 return instance_->closeTime;
178 }
179
182 {
184 }
185
186 ID
187 parentID() const
188 {
189 return instance_->parentID;
190 }
191
192 TxSetType const&
193 txs() const
194 {
195 return instance_->txs;
196 }
197
199 bool
200 isAncestor(Ledger const& ancestor) const;
201
204 ID
205 operator[](Seq seq) const;
206
209 friend Ledger::Seq
210 mismatch(Ledger const& a, Ledger const& o);
211
213 getJson() const;
214
215 friend bool
216 operator<(Ledger const& a, Ledger const& b)
217 {
218 return a.id() < b.id();
219 }
220
221private:
222 ID id_{0};
224};
225
229{
230 using InstanceMap = boost::bimaps::bimap<
231 boost::bimaps::set_of<Ledger::Instance, xrpl::less<Ledger::Instance>>,
232 boost::bimaps::set_of<Ledger::ID, xrpl::less<Ledger::ID>>>;
233 using InstanceEntry = InstanceMap::value_type;
234
235 // Set of all known ledgers; note this is never pruned
237
238 // ID for the next unique ledger
240 nextID() const;
241
242public:
243 LedgerOracle();
244
247 lookup(Ledger::ID const& id) const;
248
257 Ledger
258 accept(
259 Ledger const& curr,
260 TxSetType const& txs,
261 NetClock::duration closeTimeResolution,
262 NetClock::time_point const& consensusCloseTime);
263
264 Ledger
265 accept(Ledger const& curr, Tx tx)
266 {
267 using namespace std::chrono_literals;
268 return accept(curr, TxSetType{tx}, curr.closeTimeResolution(), curr.closeTime() + 1s);
269 }
270
280 static std::size_t
281 branches(std::set<Ledger> const& ledgers);
282};
283
304{
309
314
320 Ledger const&
322 {
323 auto it = ledgers.find(s);
324 if (it != ledgers.end())
325 return it->second;
326
327 // enforce that the new suffix has never been seen
328 assert(seen.emplace(s.back()).second);
329
330 Ledger const& parent = (*this)[s.substr(0, s.size() - 1)];
331 return ledgers.emplace(s, oracle.accept(parent, Tx{++nextTx})).first->second;
332 }
333};
334
335} // namespace csf
336} // namespace test
337} // namespace xrpl
T back(T... args)
Represents a JSON value.
Definition json_value.h:130
Oracle maintaining unique ledgers for a simulation.
Definition ledgers.h:229
Ledger::ID nextID() const
Definition ledgers.cpp:74
InstanceMap::value_type InstanceEntry
Definition ledgers.h:233
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:80
boost::bimaps::bimap< boost::bimaps::set_of< Ledger::Instance, xrpl::less< Ledger::Instance > >, boost::bimaps::set_of< Ledger::ID, xrpl::less< Ledger::ID > > > InstanceMap
Definition ledgers.h:232
std::optional< Ledger > lookup(Ledger::ID const &id) const
Find the ledger with the given ID.
Definition ledgers.cpp:115
static std::size_t branches(std::set< Ledger > const &ledgers)
Determine the number of distinct branches for the set of ledgers.
Definition ledgers.cpp:126
Ledger accept(Ledger const &curr, Tx tx)
Definition ledgers.h:265
A ledger is a set of observed transactions and a sequence number identifying the ledger.
Definition ledgers.h:43
Instance const * instance_
Definition ledgers.h:223
friend bool operator<(Ledger const &a, Ledger const &b)
Definition ledgers.h:216
Ledger(MakeGenesis)
Definition ledgers.h:140
bool isAncestor(Ledger const &ancestor) const
Determine whether ancestor is really an ancestor of this ledger.
Definition ledgers.cpp:21
Json::Value getJson() const
Definition ledgers.cpp:12
static Instance const genesis
Definition ledgers.h:133
friend Ledger::Seq mismatch(Ledger const &a, Ledger const &o)
Return the sequence number of the first mismatching ancestor.
Definition ledgers.cpp:39
NetClock::duration closeTimeResolution() const
Definition ledgers.h:163
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:135
bool closeAgree() const
Definition ledgers.h:169
NetClock::time_point parentCloseTime() const
Definition ledgers.h:181
NetClock::time_point closeTime() const
Definition ledgers.h:175
TxSetType const & txs() const
Definition ledgers.h:193
tagged_integer< std::uint32_t, IdTag > ID
Definition ledgers.h:51
tagged_integer< std::uint32_t, SeqTag > Seq
Definition ledgers.h:48
A single transaction.
Definition Tx.h:22
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:59
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
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:304
std::unordered_map< std::string, Ledger > ledgers
Definition ledgers.h:307
Ledger const & operator[](std::string const &s)
Get or create the ledger with the given string history.
Definition ledgers.h:321
friend bool operator==(Instance const &a, Instance const &b)
Definition ledgers.h:106
bool closeTimeAgree
Whether consensus agreed on the close time.
Definition ledgers.h:79
ID parentID
Parent ledger id.
Definition ledgers.h:82
std::vector< Ledger::ID > ancestors
IDs of this ledgers ancestors.
Definition ledgers.h:90
friend bool operator<(Instance const &a, Instance const &b)
Definition ledgers.h:118
friend bool operator!=(Instance const &a, Instance const &b)
Definition ledgers.h:112
friend void hash_append(Hasher &h, Ledger::Instance const &instance)
Definition ledgers.h:125
NetClock::time_point closeTime
When the ledger closed (up to closeTimeResolution)
Definition ledgers.h:76
NetClock::duration closeTimeResolution
Definition ledgers.h:73
NetClock::time_point parentCloseTime
Parent ledger close time.
Definition ledgers.h:85
Set the sequence number on a JTx.
Definition seq.h:14
T substr(T... args)
T tie(T... args)