@@ -36,24 +36,25 @@ std::string PersistentState::kSQLCreateSCPStatement =
36
36
" state TEXT"
37
37
" ); " ;
38
38
39
- std::string PersistentState::LCLTableName = " storestate" ;
40
- std::string PersistentState::SlotTableName = " slotstate" ;
39
+ std::string PersistentState::kLCLTableName = " storestate" ;
40
+ std::string PersistentState::kSlotTableName = " slotstate" ;
41
41
42
42
PersistentState::PersistentState (Application& app) : mApp (app)
43
43
{
44
44
releaseAssert (threadIsMain ());
45
45
}
46
46
47
47
void
48
- PersistentState::deleteTxSets (std::unordered_set<Hash> hashesToDelete)
48
+ PersistentState::deleteTxSets (std::unordered_set<Hash> hashesToDelete,
49
+ std::string table)
49
50
{
50
51
releaseAssert (threadIsMain ());
51
52
soci::transaction tx (mApp .getDatabase ().getRawSession ());
52
53
for (auto const & hash : hashesToDelete)
53
54
{
54
55
auto name = getStoreStateNameForTxSet (hash);
55
56
auto prep = mApp .getDatabase ().getPreparedStatement (
56
- " DELETE FROM slotstate WHERE statename = :n;" ,
57
+ fmt::format ( " DELETE FROM {} WHERE statename = :n;" , table) ,
57
58
mApp .getDatabase ().getSession ());
58
59
59
60
auto & st = prep.statement ();
@@ -64,6 +65,66 @@ PersistentState::deleteTxSets(std::unordered_set<Hash> hashesToDelete)
64
65
tx.commit ();
65
66
}
66
67
68
+ void
69
+ PersistentState::migrateToSlotStateTable ()
70
+ {
71
+ // No soci::transaction needed, because the migration in Database.cpp wraps
72
+ // everything in one transaction anyway.
73
+ releaseAssert (threadIsMain ());
74
+ auto & db = mApp .getDatabase ();
75
+
76
+ // First, create the new table
77
+ db.getRawSession () << PersistentState::kSQLCreateSCPStatement ;
78
+
79
+ // Migrate all the tx sets
80
+ auto txSets = getTxSetsForAllSlots (kLCLTableName );
81
+ std::unordered_set<Hash> keysToDelete;
82
+ for (auto const & txSet : txSets)
83
+ {
84
+ CLOG_INFO (Herder, " Migrating tx set {} to slotstate" ,
85
+ hexAbbrev (txSet.first ));
86
+ updateDb (getStoreStateNameForTxSet (txSet.first ), txSet.second ,
87
+ db.getSession (), kSlotTableName );
88
+ keysToDelete.insert (txSet.first );
89
+ }
90
+
91
+ // Cleanup tx sets from the previous table
92
+ deleteTxSets (keysToDelete, kLCLTableName );
93
+
94
+ // Migrate all SCP slot data
95
+ auto scpStates = getSCPStateAllSlots (kLCLTableName );
96
+ for (auto const & [i, scpState] : scpStates)
97
+ {
98
+ CLOG_INFO (Herder, " Migrating SCP state for slot {} to slotstate" , i);
99
+ setSCPStateForSlot (i, scpState);
100
+ auto prep = mApp .getDatabase ().getPreparedStatement (
101
+ " DELETE FROM storestate WHERE statename = :n;" ,
102
+ mApp .getDatabase ().getSession ());
103
+
104
+ auto & st = prep.statement ();
105
+ st.exchange (soci::use (getStoreStateName (kLastSCPDataXDR , i)));
106
+ st.define_and_bind ();
107
+ st.execute (true );
108
+ }
109
+
110
+ // Migrate upgrade data
111
+ auto upgrades = getFromDb (getStoreStateName (kLedgerUpgrades ),
112
+ db.getSession (), kLCLTableName );
113
+ if (!upgrades.empty ())
114
+ {
115
+ updateDb (getStoreStateName (kLedgerUpgrades ), upgrades, db.getSession (),
116
+ kSlotTableName );
117
+ auto prep = mApp .getDatabase ().getPreparedStatement (
118
+ " DELETE FROM storestate WHERE statename = :n;" ,
119
+ mApp .getDatabase ().getSession ());
120
+
121
+ auto & st = prep.statement ();
122
+ st.exchange (soci::use (getStoreStateName (kLedgerUpgrades )));
123
+ st.define_and_bind ();
124
+ st.execute (true );
125
+ }
126
+ }
127
+
67
128
void
68
129
PersistentState::dropAll (Database& db)
69
130
{
@@ -72,7 +133,6 @@ PersistentState::dropAll(Database& db)
72
133
soci::statement st = db.getRawSession ().prepare << kSQLCreateStatement ;
73
134
st.execute (true );
74
135
75
- // TODO: add a migration to move data to slotstate
76
136
db.getRawSession () << " DROP TABLE IF EXISTS slotstate;" ;
77
137
soci::statement st2 = db.getRawSession ().prepare << kSQLCreateSCPStatement ;
78
138
st2.execute (true );
@@ -126,7 +186,7 @@ std::string
126
186
PersistentState::getDBForEntry (PersistentState::Entry entry)
127
187
{
128
188
releaseAssert (entry != kLastEntry );
129
- return entry <= kRebuildLedger ? LCLTableName : SlotTableName ;
189
+ return entry <= kRebuildLedger ? kLCLTableName : kSlotTableName ;
130
190
}
131
191
132
192
std::string
@@ -144,21 +204,21 @@ PersistentState::setState(PersistentState::Entry entry,
144
204
updateDb (getStoreStateName (entry), value, session, getDBForEntry (entry));
145
205
}
146
206
147
- std::vector< std::string>
148
- PersistentState::getSCPStateAllSlots ()
207
+ std::unordered_map< uint32_t , std::string>
208
+ PersistentState::getSCPStateAllSlots (std::string table )
149
209
{
150
210
ZoneScoped;
151
211
releaseAssert (threadIsMain ());
152
212
153
213
// Collect all slots persisted
154
- std::vector< std::string> states;
214
+ std::unordered_map< uint32_t , std::string> states;
155
215
for (uint32 i = 0 ; i <= mApp .getConfig ().MAX_SLOTS_TO_REMEMBER ; i++)
156
216
{
157
217
auto val = getFromDb (getStoreStateName (kLastSCPDataXDR , i),
158
- mApp .getDatabase ().getSession (), SlotTableName );
218
+ mApp .getDatabase ().getSession (), table );
159
219
if (!val.empty ())
160
220
{
161
- states.push_back ( val);
221
+ states.emplace (i, val);
162
222
}
163
223
}
164
224
@@ -174,7 +234,7 @@ PersistentState::setSCPStateForSlot(uint64 slot, std::string const& value)
174
234
auto slotIdx = static_cast <uint32>(
175
235
slot % (mApp .getConfig ().MAX_SLOTS_TO_REMEMBER + 1 ));
176
236
updateDb (getStoreStateName (kLastSCPDataXDR , slotIdx), value,
177
- mApp .getDatabase ().getSession (), SlotTableName );
237
+ mApp .getDatabase ().getSession (), kSlotTableName );
178
238
}
179
239
180
240
void
@@ -190,7 +250,7 @@ PersistentState::setSCPStateV1ForSlot(
190
250
for (auto const & txSet : txSets)
191
251
{
192
252
updateDb (getStoreStateNameForTxSet (txSet.first ), txSet.second ,
193
- mApp .getDatabase ().getSession (), SlotTableName );
253
+ mApp .getDatabase ().getSession (), kSlotTableName );
194
254
}
195
255
tx.commit ();
196
256
}
@@ -202,7 +262,7 @@ PersistentState::shouldRebuildForType(LedgerEntryType let)
202
262
releaseAssert (threadIsMain ());
203
263
204
264
return !getFromDb (getStoreStateName (kRebuildLedger , let),
205
- mApp .getDatabase ().getSession (), LCLTableName )
265
+ mApp .getDatabase ().getSession (), kLCLTableName )
206
266
.empty ();
207
267
}
208
268
@@ -213,7 +273,7 @@ PersistentState::clearRebuildForType(LedgerEntryType let)
213
273
releaseAssert (threadIsMain ());
214
274
215
275
updateDb (getStoreStateName (kRebuildLedger , let), " " ,
216
- mApp .getDatabase ().getSession (), LCLTableName );
276
+ mApp .getDatabase ().getSession (), kLCLTableName );
217
277
}
218
278
219
279
void
@@ -230,7 +290,7 @@ PersistentState::setRebuildForType(LedgerEntryType let)
230
290
}
231
291
232
292
updateDb (getStoreStateName (kRebuildLedger , let), " 1" ,
233
- mApp .getDatabase ().getSession (), LCLTableName );
293
+ mApp .getDatabase ().getSession (), kLCLTableName );
234
294
}
235
295
236
296
void
@@ -272,21 +332,23 @@ PersistentState::updateDb(std::string const& entry, std::string const& value,
272
332
}
273
333
}
274
334
275
- std::vector< std::string>
276
- PersistentState::getTxSetsForAllSlots ()
335
+ std::unordered_map<Hash, std::string>
336
+ PersistentState::getTxSetsForAllSlots (std::string table )
277
337
{
278
338
ZoneScoped;
279
339
releaseAssert (threadIsMain ());
280
340
281
- std::vector<std::string> result;
341
+ std::unordered_map<Hash, std::string> result;
342
+ std::string key;
282
343
std::string val;
283
344
284
345
std::string pattern = mapping[kTxSet ] + " %" ;
285
- std::string statementStr =
286
- " SELECT state FROM slotstate WHERE statename LIKE :n;" ;
346
+ std::string statementStr = fmt::format (
347
+ " SELECT statename, state FROM {} WHERE statename LIKE :n;" , table) ;
287
348
auto & db = mApp .getDatabase ();
288
349
auto prep = db.getPreparedStatement (statementStr, db.getSession ());
289
350
auto & st = prep.statement ();
351
+ st.exchange (soci::into (key));
290
352
st.exchange (soci::into (val));
291
353
st.exchange (soci::use (pattern));
292
354
st.define_and_bind ();
@@ -295,9 +357,13 @@ PersistentState::getTxSetsForAllSlots()
295
357
st.execute (true );
296
358
}
297
359
360
+ Hash hash;
361
+ size_t len = binToHex (hash).size ();
362
+
298
363
while (st.got_data ())
299
364
{
300
- result.push_back (val);
365
+ result.emplace (hexToBin256 (key.substr (mapping[kTxSet ].size (), len)),
366
+ val);
301
367
st.fetch ();
302
368
}
303
369
0 commit comments