rippled
Loading...
Searching...
No Matches
ledgers.cpp
1#include <test/csf/ledgers.h>
2
3#include <algorithm>
4
5namespace xrpl {
6namespace test {
7namespace csf {
8
9Ledger::Instance const Ledger::genesis;
10
13{
15 res["id"] = static_cast<ID::value_type>(id());
16 res["seq"] = static_cast<Seq::value_type>(seq());
17 return res;
18}
19
20bool
21Ledger::isAncestor(Ledger const& ancestor) const
22{
23 if (ancestor.seq() < seq())
24 return operator[](ancestor.seq()) == ancestor.id();
25 return false;
26}
27
30{
31 if (s > seq())
32 return {};
33 if (s == seq())
34 return id();
35 return instance_->ancestors[static_cast<Seq::value_type>(s)];
36}
37
39mismatch(Ledger const& a, Ledger const& b)
40{
41 using Seq = Ledger::Seq;
42
43 // end is 1 past end of range
44 Seq start{0};
45 Seq const end = std::min(a.seq() + Seq{1}, b.seq() + Seq{1});
46
47 // Find mismatch in [start,end)
48 // Binary search
49 Seq count = end - start;
50 while (count > Seq{0})
51 {
52 Seq const step = count / Seq{2};
53 Seq curr = start + step;
54 if (a[curr] == b[curr])
55 {
56 // go to second half
57 start = ++curr;
58 count -= step + Seq{1};
59 }
60 else
61 {
62 count = step;
63 }
64 }
65 return start;
66}
67
72
75{
76 return Ledger::ID{static_cast<Ledger::ID::value_type>(instances_.size())};
77}
78
81 Ledger const& parent,
82 TxSetType const& txs,
83 NetClock::duration closeTimeResolution,
84 NetClock::time_point const& consensusCloseTime)
85{
86 using namespace std::chrono_literals;
87 Ledger::Instance next(*parent.instance_);
88 next.txs.insert(txs.begin(), txs.end());
89 next.seq = parent.seq() + Ledger::Seq{1};
90 next.closeTimeResolution = closeTimeResolution;
91 next.closeTimeAgree = consensusCloseTime != NetClock::time_point{};
92 if (next.closeTimeAgree)
93 {
94 next.closeTime = effCloseTime(consensusCloseTime, closeTimeResolution, parent.closeTime());
95 }
96 else
97 {
98 next.closeTime = parent.closeTime() + 1s;
99 }
100
101 next.parentCloseTime = parent.closeTime();
102 next.parentID = parent.id();
103 next.ancestors.push_back(parent.id());
104
105 auto it = instances_.left.find(next);
106 if (it == instances_.left.end())
107 {
108 using Entry = InstanceMap::left_value_type;
109 it = instances_.left.insert(Entry{next, nextID()}).first;
110 }
111 return Ledger(it->second, &(it->first));
112}
113
116{
117 auto const it = instances_.right.find(id);
118 if (it != instances_.right.end())
119 {
120 return Ledger(it->first, &(it->second));
121 }
122 return std::nullopt;
123}
124
127{
128 // Tips always maintains the Ledgers with largest sequence number
129 // along all known chains.
131 tips.reserve(ledgers.size());
132
133 for (Ledger const& ledger : ledgers)
134 {
135 // Three options,
136 // 1. ledger is on a new branch
137 // 2. ledger is on a branch that we have seen tip for
138 // 3. ledger is the new tip for a branch
139 bool found = false;
140 for (auto idx = 0; idx < tips.size() && !found; ++idx)
141 {
142 bool const idxEarlier = tips[idx].seq() < ledger.seq();
143 Ledger const& earlier = idxEarlier ? tips[idx] : ledger;
144 Ledger const& later = idxEarlier ? ledger : tips[idx];
145 if (later.isAncestor(earlier))
146 {
147 tips[idx] = later;
148 found = true;
149 }
150 }
151
152 if (!found)
153 tips.push_back(ledger);
154 }
155 // The size of tips is the number of branches
156 return tips.size();
157}
158} // namespace csf
159} // namespace test
160} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
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
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
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
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
ID operator[](Seq seq) const
Return the id of the ancestor with the given seq (if exists/known)
Definition ledgers.cpp:29
NetClock::time_point closeTime() const
Definition ledgers.h:175
tagged_integer< std::uint32_t, SeqTag > Seq
Definition ledgers.h:48
T is_same_v
T min(T... args)
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
Ledger::Seq mismatch(Ledger const &a, Ledger const &b)
Definition ledgers.cpp:39
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
std::chrono::time_point< Clock, Duration > effCloseTime(std::chrono::time_point< Clock, Duration > closeTime, std::chrono::duration< Rep, Period > resolution, std::chrono::time_point< Clock, Duration > priorCloseTime)
Calculate the effective ledger close time.
T push_back(T... args)
T reserve(T... args)
T size(T... args)
std::vector< Ledger::ID > ancestors
IDs of this ledgers ancestors.
Definition ledgers.h:90
Set the sequence number on a JTx.
Definition seq.h:14