xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
tests
libxrpl
csf
impl
ledgers.cpp
1
#include <csf/ledgers.h>
2
3
#include <xrpl/basics/chrono.h>
4
#include <xrpl/json/json_value.h>
5
#include <xrpl/ledger/LedgerTiming.h>
6
7
#include <csf/Tx.h>
8
9
#include <
algorithm
>
10
#include <
chrono
>
11
#include <
cstddef
>
12
#include <
optional
>
13
#include <
set
>
14
#include <
vector
>
15
16
namespace
xrpl::test::csf
{
17
18
Ledger::Instance
const
Ledger::kGenesis
;
19
20
json::Value
21
Ledger::getJson
()
const
22
{
23
json::Value
res(
json::ValueType::Object
);
24
res[
"id"
] =
static_cast<
ID::value_type
>
(
id
());
25
res[
"seq"
] =
static_cast<
Seq::value_type
>
(
seq
());
26
return
res;
27
}
28
29
bool
30
Ledger::isAncestor
(
Ledger
const
& ancestor)
const
31
{
32
if
(ancestor.
seq
() <
seq
())
33
return
operator[]
(ancestor.
seq
()) == ancestor.
id
();
34
return
false
;
35
}
36
37
Ledger::ID
38
Ledger::operator[]
(
Seq
s)
const
39
{
40
if
(s >
seq
())
41
return
{};
42
if
(s ==
seq
())
43
return
id
();
44
return
instance_
->ancestors[
static_cast<
Seq::value_type
>
(s)];
45
}
46
47
Ledger::Seq
48
mismatch
(
Ledger
const
& a,
Ledger
const
& b)
49
{
50
using
Seq
=
Ledger::Seq
;
51
52
// end is 1 past end of range
53
Seq
start{0};
54
Seq
const
end =
std::min
(a.
seq
() +
Seq
{1}, b.
seq
() +
Seq
{1});
55
56
// Find mismatch in [start,end)
57
// Binary search
58
Seq
count = end - start;
59
while
(count >
Seq
{0})
60
{
61
Seq
const
step = count /
Seq
{2};
62
Seq
curr = start + step;
63
if
(a[curr] == b[curr])
64
{
65
// go to second half
66
start = ++curr;
67
count -= step +
Seq
{1};
68
}
69
else
70
{
71
count = step;
72
}
73
}
74
return
start;
75
}
76
77
LedgerOracle::LedgerOracle
()
78
{
79
instances_
.insert(
InstanceEntry
{
Ledger::kGenesis
,
nextID
()});
80
}
81
82
Ledger::ID
83
LedgerOracle::nextID
()
const
84
{
85
return
Ledger::ID
{
static_cast<
Ledger::ID::value_type
>
(
instances_
.size())};
86
}
87
88
Ledger
89
LedgerOracle::accept
(
90
Ledger
const
& parent,
91
TxSetType
const
& txs,
92
NetClock::duration
closeTimeResolution,
93
NetClock::time_point
const
& consensusCloseTime)
94
{
95
using namespace
std::chrono_literals;
96
Ledger::Instance
next(*parent.
instance_
);
97
next.txs.insert(txs.begin(), txs.end());
98
next.seq = parent.
seq
() +
Ledger::Seq
{1};
99
next.closeTimeResolution = closeTimeResolution;
100
next.closeTimeAgree = consensusCloseTime !=
NetClock::time_point
{};
101
if
(next.closeTimeAgree)
102
{
103
next.closeTime =
effCloseTime
(consensusCloseTime, closeTimeResolution, parent.
closeTime
());
104
}
105
else
106
{
107
next.closeTime = parent.
closeTime
() + 1s;
108
}
109
110
next.parentCloseTime = parent.
closeTime
();
111
next.parentID = parent.
id
();
112
next.ancestors.push_back(parent.
id
());
113
114
auto
it =
instances_
.left.find(next);
115
if
(it ==
instances_
.left.end())
116
{
117
using
Entry = InstanceMap::left_value_type;
118
it =
instances_
.left.insert(Entry{next,
nextID
()}).first;
119
}
120
return
Ledger
(it->second, &(it->first));
121
}
122
123
std::optional<Ledger>
124
LedgerOracle::lookup
(
Ledger::ID
const
&
id
)
const
125
{
126
auto
const
it =
instances_
.right.find(
id
);
127
if
(it !=
instances_
.right.end())
128
{
129
return
Ledger
(it->first, &(it->second));
130
}
131
return
std::nullopt;
132
}
133
134
std::size_t
135
LedgerOracle::branches
(
std::set<Ledger>
const
& ledgers)
136
{
137
// Tips always maintains the Ledgers with largest sequence number
138
// along all known chains.
139
std::vector<Ledger>
tips;
140
tips.
reserve
(ledgers.
size
());
141
142
for
(
Ledger
const
& ledger : ledgers)
143
{
144
// Three options,
145
// 1. ledger is on a new branch
146
// 2. ledger is on a branch that we have seen tip for
147
// 3. ledger is the new tip for a branch
148
bool
found =
false
;
149
for
(
auto
idx = 0; idx < tips.
size
() && !found; ++idx)
150
{
151
bool
const
idxEarlier = tips[idx].seq() < ledger.seq();
152
Ledger
const
& earlier = idxEarlier ? tips[idx] : ledger;
153
Ledger
const
& later = idxEarlier ? ledger : tips[idx];
154
if
(later.
isAncestor
(earlier))
155
{
156
tips[idx] = later;
157
found =
true
;
158
}
159
}
160
161
if
(!found)
162
tips.
push_back
(ledger);
163
}
164
// The size of tips is the number of branches
165
return
tips.
size
();
166
}
167
}
// namespace xrpl::test::csf
algorithm
chrono
json::Value
Represents a JSON value.
Definition
json_value.h:117
xrpl::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition
chrono.h:48
xrpl::NetClock::duration
std::chrono::duration< rep, period > duration
Definition
chrono.h:47
xrpl::TaggedInteger< std::uint32_t, IdTag >::value_type
std::uint32_t value_type
Definition
tagged_integer.h:42
xrpl::test::csf::LedgerOracle::nextID
Ledger::ID nextID() const
Definition
ledgers.cpp:83
xrpl::test::csf::LedgerOracle::InstanceEntry
InstanceMap::value_type InstanceEntry
Definition
ledgers.h:253
xrpl::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:89
xrpl::test::csf::LedgerOracle::LedgerOracle
LedgerOracle()
Definition
ledgers.cpp:77
xrpl::test::csf::LedgerOracle::lookup
std::optional< Ledger > lookup(Ledger::ID const &id) const
Find the ledger with the given ID.
Definition
ledgers.cpp:124
xrpl::test::csf::LedgerOracle::branches
static std::size_t branches(std::set< Ledger > const &ledgers)
Determine the number of distinct branches for the set of ledgers.
Definition
ledgers.cpp:135
xrpl::test::csf::LedgerOracle::instances_
InstanceMap instances_
Definition
ledgers.h:256
xrpl::test::csf::Ledger
A ledger is a set of observed transactions and a sequence number identifying the ledger.
Definition
ledgers.h:48
xrpl::test::csf::Ledger::instance_
Instance const * instance_
Definition
ledgers.h:242
xrpl::test::csf::Ledger::ID
TaggedInteger< std::uint32_t, IdTag > ID
Definition
ledgers.h:56
xrpl::test::csf::Ledger::Seq
TaggedInteger< std::uint32_t, SeqTag > Seq
Definition
ledgers.h:53
xrpl::test::csf::Ledger::isAncestor
bool isAncestor(Ledger const &ancestor) const
Determine whether ancestor is really an ancestor of this ledger.
Definition
ledgers.cpp:30
xrpl::test::csf::Ledger::kGenesis
static Instance const kGenesis
Definition
ledgers.h:148
xrpl::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:38
xrpl::test::csf::Ledger::seq
Seq seq() const
Definition
ledgers.h:172
xrpl::test::csf::Ledger::Ledger
Ledger(ID id, Instance const *i)
Definition
ledgers.h:150
xrpl::test::csf::Ledger::closeTime
NetClock::time_point closeTime() const
Definition
ledgers.h:190
xrpl::test::csf::Ledger::id
ID id() const
Definition
ledgers.h:166
xrpl::test::csf::Ledger::getJson
json::Value getJson() const
Definition
ledgers.cpp:21
cstddef
std::min
T min(T... args)
json::ValueType::Object
@ Object
object value (collection of name/value pairs).
Definition
json_value.h:29
xrpl::test::csf
Definition
Validations.cpp:23
xrpl::test::csf::TxSetType
boost::container::flat_set< Tx > TxSetType
Definition
Tx.h:65
xrpl::test::csf::mismatch
Ledger::Seq mismatch(Ledger const &a, Ledger const &b)
Definition
ledgers.cpp:48
xrpl::effCloseTime
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.
Definition
LedgerTiming.h:145
xrpl::NodeObjectType::Ledger
@ Ledger
Definition
NodeObject.h:20
optional
std::vector::push_back
T push_back(T... args)
std::vector::reserve
T reserve(T... args)
set
std::set::size
T size(T... args)
std::size_t
xrpl::test::csf::Ledger::Instance
Definition
ledgers.h:66
vector
Generated by
1.17.0