xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
xrpld
app
rdb
detail
xrpld/app/rdb/detail/PeerFinder.cpp
1
#include <xrpld/app/rdb/PeerFinder.h>
2
3
#include <xrpl/basics/Log.h>
4
#include <xrpl/basics/contract.h>
5
#include <xrpl/beast/net/IPEndpoint.h>
6
#include <xrpl/beast/utility/Journal.h>
7
#include <xrpl/config/BasicConfig.h>
8
#include <xrpl/peerfinder/detail/Store.h>
9
#include <xrpl/rdb/SociDB.h>
10
11
#include <boost/optional/optional.hpp>
// IWYU pragma: keep
12
13
#include <soci/boost-optional.h>
// IWYU pragma: keep
14
#include <soci/into.h>
15
#include <soci/session.h>
16
#include <soci/statement.h>
17
#include <soci/transaction.h>
18
#include <soci/use.h>
19
20
#include <
cstddef
>
21
#include <
functional
>
22
#include <
stdexcept
>
23
#include <
vector
>
24
25
namespace
xrpl
{
26
27
void
28
initPeerFinderDB
(soci::session& session,
BasicConfig
const
& config,
beast::Journal
j)
29
{
30
DBConfig
const
sociConfig(config,
"peerfinder"
);
31
sociConfig.
open
(session);
32
33
JLOG(j.
info
()) <<
"Opening database at '"
<< sociConfig.
connectionString
() <<
"'"
;
34
35
soci::transaction tr(session);
36
session <<
"PRAGMA encoding=\"UTF-8\";"
;
37
38
session <<
"CREATE TABLE IF NOT EXISTS SchemaVersion ( "
39
" name TEXT PRIMARY KEY, "
40
" version INTEGER"
41
");"
;
42
43
session <<
"CREATE TABLE IF NOT EXISTS PeerFinder_BootstrapCache ( "
44
" id INTEGER PRIMARY KEY AUTOINCREMENT, "
45
" address TEXT UNIQUE NOT NULL, "
46
" valence INTEGER"
47
");"
;
48
49
session <<
"CREATE INDEX IF NOT EXISTS "
50
" PeerFinder_BootstrapCache_Index ON "
51
"PeerFinder_BootstrapCache "
52
" ( "
53
" address "
54
" ); "
;
55
56
tr.commit();
57
}
58
59
void
60
updatePeerFinderDB
(soci::session& session,
int
currentSchemaVersion,
beast::Journal
j)
61
{
62
soci::transaction tr(session);
63
// get version
64
int
version(0);
65
{
66
// SOCI requires a boost::optional (not std::optional) parameter.
67
boost::optional<int> vO;
68
session <<
"SELECT "
69
" version "
70
"FROM SchemaVersion WHERE "
71
" name = 'PeerFinder';"
,
72
soci::into(vO);
73
74
version = vO.value_or(0);
75
76
JLOG(j.
info
()) <<
"Opened version "
<< version <<
" database"
;
77
}
78
79
{
80
if
(version < currentSchemaVersion)
81
{
82
JLOG(j.
info
()) <<
"Updating database to version "
<< currentSchemaVersion;
83
}
84
else
if
(version > currentSchemaVersion)
85
{
86
Throw<std::runtime_error>
(
"The PeerFinder database version is higher than expected"
);
87
}
88
}
89
90
if
(version < 4)
91
{
92
//
93
// Remove the "uptime" column from the bootstrap table
94
//
95
96
session <<
"CREATE TABLE IF NOT EXISTS "
97
"PeerFinder_BootstrapCache_Next ( "
98
" id INTEGER PRIMARY KEY AUTOINCREMENT, "
99
" address TEXT UNIQUE NOT NULL, "
100
" valence INTEGER"
101
");"
;
102
103
session <<
"CREATE INDEX IF NOT EXISTS "
104
" PeerFinder_BootstrapCache_Next_Index ON "
105
" PeerFinder_BootstrapCache_Next "
106
" ( address ); "
;
107
108
std::size_t
count = 0;
109
session <<
"SELECT COUNT(*) FROM PeerFinder_BootstrapCache;"
, soci::into(count);
110
111
std::vector<peer_finder::Store::Entry>
list;
112
113
{
114
list.
reserve
(count);
115
std::string
s;
116
int
valence = 0;
117
soci::statement st =
118
(session.prepare <<
"SELECT "
119
" address, "
120
" valence "
121
"FROM PeerFinder_BootstrapCache;"
,
122
soci::into(s),
123
soci::into(valence));
124
125
st.execute();
126
while
(st.fetch())
127
{
128
peer_finder::Store::Entry
entry;
129
entry.endpoint =
beast::ip::Endpoint::fromString
(s);
130
if
(!isUnspecified(entry.endpoint))
131
{
132
entry.valence = valence;
133
list.
push_back
(entry);
134
}
135
else
136
{
137
JLOG(j.
error
()) <<
"Bad address string '"
<< s <<
"' in Bootcache table"
;
138
}
139
}
140
}
141
142
if
(!list.
empty
())
143
{
144
std::vector<std::string>
s;
145
std::vector<int>
valence;
146
s.
reserve
(list.
size
());
147
valence.
reserve
(list.
size
());
148
149
for
(
auto
const
& entry : list)
150
{
151
s.
emplace_back
(
to_string
(entry.endpoint));
152
valence.
emplace_back
(entry.valence);
153
}
154
155
session <<
"INSERT INTO PeerFinder_BootstrapCache_Next ( "
156
" address, "
157
" valence "
158
") VALUES ( "
159
" :s, :valence"
160
");"
,
161
soci::use(s), soci::use(valence);
162
}
163
164
session <<
"DROP TABLE IF EXISTS PeerFinder_BootstrapCache;"
;
165
166
session <<
"DROP INDEX IF EXISTS PeerFinder_BootstrapCache_Index;"
;
167
168
session <<
"ALTER TABLE PeerFinder_BootstrapCache_Next "
169
" RENAME TO PeerFinder_BootstrapCache;"
;
170
171
session <<
"CREATE INDEX IF NOT EXISTS "
172
" PeerFinder_BootstrapCache_Index ON "
173
"PeerFinder_BootstrapCache "
174
" ( "
175
" address "
176
" ); "
;
177
}
178
179
if
(version < 3)
180
{
181
//
182
// Remove legacy endpoints from the schema
183
//
184
185
session <<
"DROP TABLE IF EXISTS LegacyEndpoints;"
;
186
187
session <<
"DROP TABLE IF EXISTS PeerFinderLegacyEndpoints;"
;
188
189
session <<
"DROP TABLE IF EXISTS PeerFinder_LegacyEndpoints;"
;
190
191
session <<
"DROP TABLE IF EXISTS PeerFinder_LegacyEndpoints_Index;"
;
192
}
193
194
{
195
int
const
v(currentSchemaVersion);
196
session <<
"INSERT OR REPLACE INTO SchemaVersion ("
197
" name "
198
" ,version "
199
") VALUES ( "
200
" 'PeerFinder', :version "
201
");"
,
202
soci::use(v);
203
}
204
205
tr.commit();
206
}
207
208
void
209
readPeerFinderDB
(soci::session& session,
std::function
<
void
(
std::string
const
&,
int
)>
const
& func)
210
{
211
std::string
s;
212
int
valence = 0;
213
soci::statement st =
214
(session.prepare <<
"SELECT "
215
" address, "
216
" valence "
217
"FROM PeerFinder_BootstrapCache;"
,
218
soci::into(s),
219
soci::into(valence));
220
221
st.execute();
222
while
(st.fetch())
223
{
224
func(s, valence);
225
}
226
}
227
228
void
229
savePeerFinderDB
(soci::session& session,
std::vector<peer_finder::Store::Entry>
const
& v)
230
{
231
soci::transaction tr(session);
232
session <<
"DELETE FROM PeerFinder_BootstrapCache;"
;
233
234
if
(!v.
empty
())
235
{
236
std::vector<std::string>
s;
237
std::vector<int>
valence;
238
s.
reserve
(v.
size
());
239
valence.
reserve
(v.
size
());
240
241
for
(
auto
const
& e : v)
242
{
243
s.
emplace_back
(
to_string
(e.endpoint));
244
valence.
emplace_back
(e.valence);
245
}
246
247
session <<
"INSERT INTO PeerFinder_BootstrapCache ( "
248
" address, "
249
" valence "
250
") VALUES ( "
251
" :s, :valence "
252
");"
,
253
soci::use(s), soci::use(valence);
254
}
255
256
tr.commit();
257
}
258
259
}
// namespace xrpl
std::string
beast::Journal
A generic endpoint for log messages.
Definition
Journal.h:44
beast::Journal::error
Stream error() const
Definition
Journal.h:362
beast::Journal::info
Stream info() const
Definition
Journal.h:350
beast::ip::Endpoint::fromString
static Endpoint fromString(std::string const &s)
Definition
IPEndpoint.cpp:42
xrpl::BasicConfig
Holds unparsed configuration information.
Definition
BasicConfig.h:222
xrpl::DBConfig
DBConfig is used when a client wants to delay opening a soci::session after parsing the config parame...
Definition
SociDB.h:44
xrpl::DBConfig::open
void open(soci::session &s) const
Definition
SociDB.cpp:85
xrpl::DBConfig::connectionString
std::string connectionString() const
Definition
SociDB.cpp:79
cstddef
std::vector::emplace_back
T emplace_back(T... args)
std::vector::empty
T empty(T... args)
std::function
functional
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::savePeerFinderDB
void savePeerFinderDB(soci::session &session, std::vector< peer_finder::Store::Entry > const &v)
savePeerFinderDB Saves a new entry to the peer finder database.
Definition
xrpld/app/rdb/detail/PeerFinder.cpp:229
xrpl::readPeerFinderDB
void readPeerFinderDB(soci::session &session, std::function< void(std::string const &, int)> const &func)
readPeerFinderDB Reads all entries from the peer finder database and invokes the given callback for e...
Definition
xrpld/app/rdb/detail/PeerFinder.cpp:209
xrpl::updatePeerFinderDB
void updatePeerFinderDB(soci::session &session, int currentSchemaVersion, beast::Journal j)
updatePeerFinderDB Updates the peer finder database to a new version.
Definition
xrpld/app/rdb/detail/PeerFinder.cpp:60
xrpl::initPeerFinderDB
void initPeerFinderDB(soci::session &session, BasicConfig const &config, beast::Journal j)
initPeerFinderDB Opens a session with the peer finder database.
Definition
xrpld/app/rdb/detail/PeerFinder.cpp:28
xrpl::to_string
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition
base_uint.h:657
xrpl::Throw
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition
contract.h:52
std::vector::push_back
T push_back(T... args)
std::vector::reserve
T reserve(T... args)
std::vector::size
T size(T... args)
std::size_t
stdexcept
xrpl::peer_finder::Store::Entry
Definition
Store.h:26
vector
Generated by
1.17.0