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