xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
libxrpl
peerfinder
Bootcache.cpp
1
#include <xrpl/peerfinder/detail/Bootcache.h>
2
3
#include <xrpl/basics/Log.h>
4
#include <xrpl/beast/net/IPEndpoint.h>
5
#include <xrpl/beast/utility/Journal.h>
6
#include <xrpl/beast/utility/PropertyStream.h>
7
#include <xrpl/beast/utility/instrumentation.h>
8
#include <xrpl/peerfinder/Types.h>
9
#include <xrpl/peerfinder/detail/Store.h>
10
#include <xrpl/peerfinder/detail/Tuning.h>
11
12
#include <
algorithm
>
13
#include <
cstdint
>
14
#include <
cstdlib
>
15
#include <
iomanip
>
16
#include <
ios
>
17
#include <
vector
>
18
19
namespace
xrpl::peer_finder
{
20
21
Bootcache::Bootcache
(
Store
& store,
ClockType
& clock,
beast::Journal
journal)
22
:
store_
(store),
clock_
(clock),
journal_
(journal),
whenUpdate_
(
clock_
.now())
23
24
{
25
}
26
27
Bootcache::~Bootcache
()
28
{
29
update
();
30
}
31
32
bool
33
Bootcache::empty
()
const
34
{
35
return
map_
.empty();
36
}
37
38
Bootcache::MapType::size_type
39
Bootcache::size
()
const
40
{
41
return
map_
.size();
42
}
43
44
Bootcache::const_iterator
45
Bootcache::begin
()
const
46
{
47
return
const_iterator
(
map_
.right.begin());
48
}
49
50
Bootcache::const_iterator
51
Bootcache::cbegin
()
const
52
{
53
return
const_iterator
(
map_
.right.begin());
54
}
55
56
Bootcache::const_iterator
57
Bootcache::end
()
const
58
{
59
return
const_iterator
(
map_
.right.end());
60
}
61
62
Bootcache::const_iterator
63
Bootcache::cend
()
const
64
{
65
return
const_iterator
(
map_
.right.end());
66
}
67
68
void
69
Bootcache::clear
()
70
{
71
map_
.clear();
72
needsUpdate_
=
true
;
73
}
74
75
//--------------------------------------------------------------------------
76
77
void
78
Bootcache::load
()
79
{
80
clear
();
81
auto
const
n(
store_
.load([
this
](
beast::ip::Endpoint
const
& endpoint,
int
valence) {
82
auto const result(this->map_.insert(value_type(endpoint, valence)));
83
if (!result.second)
84
{
85
JLOG(this->journal_.error())
86
<< std::left << std::setw(18) <<
"Bootcache discard "
<< endpoint;
87
}
88
}));
89
90
if
(n > 0)
91
{
92
JLOG(journal_.info()) <<
std::left
<<
std::setw
(18) <<
"Bootcache loaded "
<< n
93
<< ((n > 1) ?
" addresses"
:
" address"
);
94
prune();
95
}
96
}
97
98
bool
99
Bootcache::insert
(
beast::ip::Endpoint
const
& endpoint)
100
{
101
auto
const
result(
map_
.insert(
value_type
(endpoint, 0)));
102
if
(result.second)
103
{
104
JLOG(
journal_
.trace()) <<
std::left
<<
std::setw
(18) <<
"Bootcache insert "
<< endpoint;
105
prune
();
106
flagForUpdate
();
107
}
108
return
result.second;
109
}
110
111
bool
112
Bootcache::insertStatic
(
beast::ip::Endpoint
const
& endpoint)
113
{
114
auto
result(
map_
.insert(
value_type
(endpoint,
kStaticValence
)));
115
116
if
(!result.second && (result.first->right.valence() <
kStaticValence
))
117
{
118
// An existing entry has too low a valence, replace it
119
map_
.erase(result.first);
120
result =
map_
.insert(
value_type
(endpoint,
kStaticValence
));
121
}
122
123
if
(result.second)
124
{
125
JLOG(
journal_
.trace()) <<
std::left
<<
std::setw
(18) <<
"Bootcache insert "
<< endpoint;
126
prune
();
127
flagForUpdate
();
128
}
129
return
result.second;
130
}
131
132
void
133
Bootcache::onSuccess
(
beast::ip::Endpoint
const
& endpoint)
134
{
135
auto
result(
map_
.insert(
value_type
(endpoint, 1)));
136
if
(result.second)
137
{
138
prune
();
139
}
140
else
141
{
142
Entry
entry(result.first->right);
143
entry.valence() =
std::max
(entry.valence(), 0);
144
++entry.valence();
145
map_
.erase(result.first);
146
result =
map_
.insert(
value_type
(endpoint, entry));
147
XRPL_ASSERT(result.second,
"xrpl::peer_finder::Bootcache::onSuccess : endpoint inserted"
);
148
}
149
Entry
const
& entry(result.first->right);
150
JLOG(
journal_
.info()) <<
std::left
<<
std::setw
(18) <<
"Bootcache connect "
<< endpoint
151
<<
" with "
<< entry.valence()
152
<< ((entry.valence() > 1) ?
" successes"
:
" success"
);
153
flagForUpdate
();
154
}
155
156
void
157
Bootcache::onFailure
(
beast::ip::Endpoint
const
& endpoint)
158
{
159
auto
result(
map_
.insert(
value_type
(endpoint, -1)));
160
if
(result.second)
161
{
162
prune
();
163
}
164
else
165
{
166
Entry
entry(result.first->right);
167
entry.valence() =
std::min
(entry.valence(), 0);
168
--entry.valence();
169
map_
.erase(result.first);
170
result =
map_
.insert(
value_type
(endpoint, entry));
171
XRPL_ASSERT(result.second,
"xrpl::peer_finder::Bootcache::onFailure : endpoint inserted"
);
172
}
173
Entry
const
& entry(result.first->right);
174
auto
const
n(std::abs(entry.valence()));
175
JLOG(
journal_
.debug()) <<
std::left
<<
std::setw
(18) <<
"Bootcache failed "
<< endpoint
176
<<
" with "
<< n << ((n > 1) ?
" attempts"
:
" attempt"
);
177
flagForUpdate
();
178
}
179
180
void
181
Bootcache::periodicActivity
()
182
{
183
checkUpdate
();
184
}
185
186
//--------------------------------------------------------------------------
187
188
void
189
Bootcache::onWrite
(
beast::PropertyStream::Map
& map)
190
{
191
beast::PropertyStream::Set
entries(
"entries"
, map);
192
for
(
auto
iter =
map_
.right.begin(); iter !=
map_
.right.end(); ++iter)
193
{
194
beast::PropertyStream::Map
entry(entries);
195
entry[
"endpoint"
] = iter->get_left().toString();
196
entry[
"valence"
] =
std::int32_t
(iter->get_right().valence());
197
}
198
}
199
200
// Checks the cache size and prunes if its over the limit.
201
void
202
Bootcache::prune
()
203
{
204
if
(
size
() <=
tuning::kBootcacheSize
)
205
return
;
206
207
// Calculate the amount to remove
208
auto
count((
size
() *
tuning::kBootcachePrunePercent
) / 100);
209
decltype
(count) pruned(0);
210
211
// Work backwards because bimap doesn't handle
212
// erasing using a reverse iterator very well.
213
//
214
for
(
auto
iter(
map_
.right.end()); count > 0 && iter !=
map_
.right.begin(); ++pruned)
215
{
216
--count;
217
--iter;
218
beast::ip::Endpoint
const
& endpoint(iter->get_left());
219
Entry
const
& entry(iter->get_right());
220
JLOG(
journal_
.trace()) <<
std::left
<<
std::setw
(18) <<
"Bootcache pruned"
<< endpoint
221
<<
" at valence "
<< entry.valence();
222
iter =
map_
.right.erase(iter);
223
}
224
225
JLOG(
journal_
.debug()) <<
std::left
<<
std::setw
(18) <<
"Bootcache pruned "
<< pruned
226
<<
" entries total"
;
227
}
228
229
// Updates the Store with the current set of entries if needed.
230
void
231
Bootcache::update
()
232
{
233
if
(!
needsUpdate_
)
234
return
;
235
std::vector<Store::Entry>
list;
236
list.
reserve
(
map_
.size());
237
for
(
auto
const
& e :
map_
)
238
{
239
Store::Entry
se;
240
se.
endpoint
= e.get_left();
241
se.
valence
= e.get_right().valence();
242
list.
push_back
(se);
243
}
244
store_
.save(list);
245
// Reset the flag and cooldown timer
246
needsUpdate_
=
false
;
247
whenUpdate_
=
clock_
.now() +
tuning::kBootcacheCooldownTime
;
248
}
249
250
// Checks the clock and calls update if we are off the cooldown.
251
void
252
Bootcache::checkUpdate
()
253
{
254
if
(
needsUpdate_
&&
whenUpdate_
<
clock_
.now())
255
update
();
256
}
257
258
// Called when changes to an entry will affect the Store.
259
void
260
Bootcache::flagForUpdate
()
261
{
262
needsUpdate_
=
true
;
263
checkUpdate
();
264
}
265
266
}
// namespace xrpl::peer_finder
algorithm
beast::Journal
A generic endpoint for log messages.
Definition
Journal.h:44
beast::PropertyStream::Map
Definition
PropertyStream.h:207
beast::PropertyStream::Set
Definition
PropertyStream.h:279
beast::ip::Endpoint
A version-independent IP address and port combination.
Definition
IPEndpoint.h:24
xrpl::peer_finder::Bootcache::Entry
Definition
Bootcache.h:39
xrpl::peer_finder::Bootcache::kStaticValence
static constexpr int kStaticValence
Definition
Bootcache.h:101
xrpl::peer_finder::Bootcache::update
void update()
Definition
Bootcache.cpp:231
xrpl::peer_finder::Bootcache::const_iterator
iterator const_iterator
Definition
Bootcache.h:105
xrpl::peer_finder::Bootcache::clear
void clear()
Definition
Bootcache.cpp:69
xrpl::peer_finder::Bootcache::insertStatic
bool insertStatic(beast::ip::Endpoint const &endpoint)
Add a staticallyconfigured address to the cache.
Definition
Bootcache.cpp:112
xrpl::peer_finder::Bootcache::value_type
MapType::value_type value_type
Definition
Bootcache.h:71
xrpl::peer_finder::Bootcache::journal_
beast::Journal journal_
Definition
Bootcache.h:92
xrpl::peer_finder::Bootcache::onWrite
void onWrite(beast::PropertyStream::Map &map)
Write the cache state to the property stream.
Definition
Bootcache.cpp:189
xrpl::peer_finder::Bootcache::load
void load()
Load the persisted data from the Store into the container.
Definition
Bootcache.cpp:78
xrpl::peer_finder::Bootcache::begin
const_iterator begin() const
ip::Endpoint iterators that traverse in decreasing valence.
Definition
Bootcache.cpp:45
xrpl::peer_finder::Bootcache::insert
bool insert(beast::ip::Endpoint const &endpoint)
Add a newly-learned address to the cache.
Definition
Bootcache.cpp:99
xrpl::peer_finder::Bootcache::empty
bool empty() const
Returns true if the cache is empty.
Definition
Bootcache.cpp:33
xrpl::peer_finder::Bootcache::whenUpdate_
ClockType::time_point whenUpdate_
Definition
Bootcache.h:95
xrpl::peer_finder::Bootcache::end
const_iterator end() const
Definition
Bootcache.cpp:57
xrpl::peer_finder::Bootcache::onFailure
void onFailure(beast::ip::Endpoint const &endpoint)
Called when an outbound connection attempt fails to handshake.
Definition
Bootcache.cpp:157
xrpl::peer_finder::Bootcache::cend
const_iterator cend() const
Definition
Bootcache.cpp:63
xrpl::peer_finder::Bootcache::store_
Store & store_
Definition
Bootcache.h:90
xrpl::peer_finder::Bootcache::onSuccess
void onSuccess(beast::ip::Endpoint const &endpoint)
Called when an outbound connection handshake completes.
Definition
Bootcache.cpp:133
xrpl::peer_finder::Bootcache::periodicActivity
void periodicActivity()
Stores the cache in the persistent database on a timer.
Definition
Bootcache.cpp:181
xrpl::peer_finder::Bootcache::~Bootcache
~Bootcache()
Definition
Bootcache.cpp:27
xrpl::peer_finder::Bootcache::cbegin
const_iterator cbegin() const
Definition
Bootcache.cpp:51
xrpl::peer_finder::Bootcache::Bootcache
Bootcache(Store &store, ClockType &clock, beast::Journal journal)
Definition
Bootcache.cpp:21
xrpl::peer_finder::Bootcache::checkUpdate
void checkUpdate()
Definition
Bootcache.cpp:252
xrpl::peer_finder::Bootcache::prune
void prune()
Definition
Bootcache.cpp:202
xrpl::peer_finder::Bootcache::clock_
ClockType & clock_
Definition
Bootcache.h:91
xrpl::peer_finder::Bootcache::flagForUpdate
void flagForUpdate()
Definition
Bootcache.cpp:260
xrpl::peer_finder::Bootcache::size
MapType::size_type size() const
Returns the number of entries in the cache.
Definition
Bootcache.cpp:39
xrpl::peer_finder::Bootcache::needsUpdate_
bool needsUpdate_
Definition
Bootcache.h:98
xrpl::peer_finder::Bootcache::map_
MapType map_
Definition
Bootcache.h:88
xrpl::peer_finder::Store
Abstract persistence for PeerFinder data.
Definition
Store.h:15
cstdint
cstdlib
std::int32_t
iomanip
ios
std::left
T left(T... args)
std::max
T max(T... args)
std::min
T min(T... args)
xrpl::peer_finder::tuning::kBootcachePrunePercent
static constexpr auto kBootcachePrunePercent
Definition
include/xrpl/peerfinder/detail/Tuning.h:75
xrpl::peer_finder::tuning::kBootcacheSize
static constexpr auto kBootcacheSize
Definition
include/xrpl/peerfinder/detail/Tuning.h:72
xrpl::peer_finder::tuning::kBootcacheCooldownTime
static std::chrono::seconds const kBootcacheCooldownTime(60)
xrpl::peer_finder
Definition
include/xrpl/peerfinder/Config.h:12
xrpl::peer_finder::ClockType
beast::AbstractClock< std::chrono::steady_clock > ClockType
Definition
peerfinder/Types.h:13
std::vector::push_back
T push_back(T... args)
std::vector::reserve
T reserve(T... args)
std::setw
T setw(T... args)
xrpl::peer_finder::Store::Entry
Definition
Store.h:26
xrpl::peer_finder::Store::Entry::valence
int valence
Definition
Store.h:30
xrpl::peer_finder::Store::Entry::endpoint
beast::ip::Endpoint endpoint
Definition
Store.h:29
vector
Generated by
1.17.0