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