rippled
Loading...
Searching...
No Matches
SHAMapStoreImp.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/ledger/TransactionMaster.h>
21#include <xrpld/app/misc/NetworkOPs.h>
22#include <xrpld/app/misc/SHAMapStoreImp.h>
23#include <xrpld/app/rdb/State.h>
24#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
25#include <xrpld/core/ConfigSections.h>
26#include <xrpld/nodestore/Scheduler.h>
27#include <xrpld/nodestore/detail/DatabaseRotatingImp.h>
28#include <xrpld/shamap/SHAMapMissingNode.h>
29#include <xrpl/beast/core/CurrentThreadName.h>
30
31#include <boost/algorithm/string/predicate.hpp>
32
33namespace ripple {
34void
36 BasicConfig const& config,
37 std::string const& dbName)
38{
40 initStateDB(sqlDb_, config, dbName);
41}
42
45{
47
48 return ripple::getCanDelete(sqlDb_);
49}
50
53{
55
56 return ripple::setCanDelete(sqlDb_, canDelete);
57}
58
61{
63
64 return ripple::getSavedState(sqlDb_);
65}
66
67void
69{
71 ripple::setSavedState(sqlDb_, state);
72}
73
74void
76{
78 ripple::setLastRotated(sqlDb_, seq);
79}
80
81//------------------------------------------------------------------------------
82
84 Application& app,
85 NodeStore::Scheduler& scheduler,
86 beast::Journal journal)
87 : app_(app)
88 , scheduler_(scheduler)
89 , journal_(journal)
90 , working_(true)
91 , canDelete_(std::numeric_limits<LedgerIndex>::max())
92{
93 Config& config{app.config()};
94
95 Section& section{config.section(ConfigSection::nodeDatabase())};
96 if (section.empty())
97 {
98 Throw<std::runtime_error>(
99 "Missing [" + ConfigSection::nodeDatabase() +
100 "] entry in configuration file");
101 }
102
103 // RocksDB only. Use sensible defaults if no values specified.
104 if (boost::iequals(get(section, "type"), "RocksDB"))
105 {
106 if (!section.exists("cache_mb"))
107 {
108 section.set(
109 "cache_mb",
110 std::to_string(config.getValueFor(SizedItem::hashNodeDBCache)));
111 }
112
113 if (!section.exists("filter_bits") && (config.NODE_SIZE >= 2))
114 section.set("filter_bits", "10");
115 }
116
117 get_if_exists(section, "online_delete", deleteInterval_);
118
119 if (deleteInterval_)
120 {
121 // Configuration that affects the behavior of online delete
122 get_if_exists(section, "delete_batch", deleteBatch_);
123 std::uint32_t temp;
124 if (get_if_exists(section, "back_off_milliseconds", temp) ||
125 // Included for backward compaibility with an undocumented setting
126 get_if_exists(section, "backOff", temp))
127 {
129 }
130 if (get_if_exists(section, "age_threshold_seconds", temp))
132 if (get_if_exists(section, "recovery_wait_seconds", temp))
134
135 get_if_exists(section, "advisory_delete", advisoryDelete_);
136
137 auto const minInterval = config.standalone()
140 if (deleteInterval_ < minInterval)
141 {
142 Throw<std::runtime_error>(
143 "online_delete must be at least " +
144 std::to_string(minInterval));
145 }
146
147 if (config.LEDGER_HISTORY > deleteInterval_)
148 {
149 Throw<std::runtime_error>(
150 "online_delete must not be less than ledger_history "
151 "(currently " +
152 std::to_string(config.LEDGER_HISTORY) + ")");
153 }
154
155 state_db_.init(config, dbName_);
156 dbPaths();
157 }
158}
159
162{
164
165 // Provide default values:
166 if (!nscfg.exists("cache_size"))
167 nscfg.set(
168 "cache_size",
170 SizedItem::treeCacheSize, std::nullopt)));
171
172 if (!nscfg.exists("cache_age"))
173 nscfg.set(
174 "cache_age",
176 SizedItem::treeCacheAge, std::nullopt)));
177
179
180 if (deleteInterval_)
181 {
182 SavedState state = state_db_.getState();
183 auto writableBackend = makeBackendRotating(state.writableDb);
184 auto archiveBackend = makeBackendRotating(state.archiveDb);
185 if (!state.writableDb.size())
186 {
187 state.writableDb = writableBackend->getName();
188 state.archiveDb = archiveBackend->getName();
189 state_db_.setState(state);
190 }
191
192 // Create NodeStore with two backends to allow online deletion of
193 // data
194 auto dbr = std::make_unique<NodeStore::DatabaseRotatingImp>(
196 readThreads,
197 std::move(writableBackend),
198 std::move(archiveBackend),
199 nscfg,
201 fdRequired_ += dbr->fdRequired();
202 dbRotating_ = dbr.get();
203 db.reset(dynamic_cast<NodeStore::Database*>(dbr.release()));
204 }
205 else
206 {
208 megabytes(
211 readThreads,
212 nscfg,
214 fdRequired_ += db->fdRequired();
215 }
216 return db;
217}
218
219void
221{
222 {
224 newLedger_ = ledger;
225 working_ = true;
226 }
228}
229
230void
232{
233 if (!working_)
234 return;
235
237 rendezvous_.wait(lock, [&] { return !working_; });
238}
239
240int
242{
243 return fdRequired_;
244}
245
246bool
248{
249 // Copy a single record from node to dbRotating_
251 node.getHash().as_uint256(),
252 0,
254 true);
255 if (!(++nodeCount % checkHealthInterval_))
256 {
257 if (healthWait() == stopping)
258 return false;
259 }
260
261 return true;
262}
263
264void
266{
267 beast::setCurrentThreadName("SHAMapStore");
269 netOPs_ = &app_.getOPs();
273
274 if (advisoryDelete_)
276
277 while (true)
278 {
279 healthy_ = true;
280 std::shared_ptr<Ledger const> validatedLedger;
281
282 {
284 working_ = false;
286 if (stop_)
287 {
288 return;
289 }
290 cond_.wait(lock);
291 if (newLedger_)
292 {
293 validatedLedger = std::move(newLedger_);
294 }
295 else
296 continue;
297 }
298
299 LedgerIndex const validatedSeq = validatedLedger->info().seq;
300 if (!lastRotated)
301 {
302 lastRotated = validatedSeq;
303 state_db_.setLastRotated(lastRotated);
304 }
305
306 bool const readyToRotate =
307 validatedSeq >= lastRotated + deleteInterval_ &&
308 canDelete_ >= lastRotated - 1 && healthWait() == keepGoing;
309
310 // will delete up to (not including) lastRotated
311 if (readyToRotate)
312 {
313 JLOG(journal_.warn())
314 << "rotating validatedSeq " << validatedSeq << " lastRotated "
315 << lastRotated << " deleteInterval " << deleteInterval_
316 << " canDelete_ " << canDelete_ << " state "
317 << app_.getOPs().strOperatingMode(false) << " age "
319
320 clearPrior(lastRotated);
321 if (healthWait() == stopping)
322 return;
323
324 JLOG(journal_.debug()) << "copying ledger " << validatedSeq;
325 std::uint64_t nodeCount = 0;
326
327 try
328 {
329 validatedLedger->stateMap().snapShot(false)->visitNodes(
330 std::bind(
332 this,
333 std::ref(nodeCount),
334 std::placeholders::_1));
335 }
336 catch (SHAMapMissingNode const& e)
337 {
338 JLOG(journal_.error())
339 << "Missing node while copying ledger before rotate: "
340 << e.what();
341 continue;
342 }
343
344 if (healthWait() == stopping)
345 return;
346 // Only log if we completed without a "health" abort
347 JLOG(journal_.debug()) << "copied ledger " << validatedSeq
348 << " nodecount " << nodeCount;
349
350 JLOG(journal_.debug()) << "freshening caches";
352 if (healthWait() == stopping)
353 return;
354 // Only log if we completed without a "health" abort
355 JLOG(journal_.debug()) << validatedSeq << " freshened caches";
356
357 JLOG(journal_.trace()) << "Making a new backend";
358 auto newBackend = makeBackendRotating();
359 JLOG(journal_.debug())
360 << validatedSeq << " new backend " << newBackend->getName();
361
362 clearCaches(validatedSeq);
363 if (healthWait() == stopping)
364 return;
365
366 lastRotated = validatedSeq;
367
369 std::move(newBackend),
370 [&](std::string const& writableName,
371 std::string const& archiveName) {
372 SavedState savedState;
373 savedState.writableDb = writableName;
374 savedState.archiveDb = archiveName;
375 savedState.lastRotated = lastRotated;
376 state_db_.setState(savedState);
377
378 clearCaches(validatedSeq);
379 });
380
381 JLOG(journal_.warn()) << "finished rotation " << validatedSeq;
382 }
383 }
384}
385
386void
388{
390 boost::filesystem::path dbPath = get(section, "path");
391
392 if (boost::filesystem::exists(dbPath))
393 {
394 if (!boost::filesystem::is_directory(dbPath))
395 {
397 << "node db path must be a directory. " << dbPath.string();
398 Throw<std::runtime_error>("node db path must be a directory.");
399 }
400 }
401 else
402 {
403 boost::filesystem::create_directories(dbPath);
404 }
405
406 SavedState state = state_db_.getState();
407
408 {
409 auto update = [&dbPath](std::string& sPath) {
410 if (sPath.empty())
411 return false;
412
413 // Check if configured "path" matches stored directory path
414 using namespace boost::filesystem;
415 auto const stored{path(sPath)};
416 if (stored.parent_path() == dbPath)
417 return false;
418
419 sPath = (dbPath / stored.filename()).string();
420 return true;
421 };
422
423 if (update(state.writableDb))
424 {
425 update(state.archiveDb);
426 state_db_.setState(state);
427 }
428 }
429
430 bool writableDbExists = false;
431 bool archiveDbExists = false;
432
434 for (boost::filesystem::directory_iterator it(dbPath);
435 it != boost::filesystem::directory_iterator();
436 ++it)
437 {
438 if (!state.writableDb.compare(it->path().string()))
439 writableDbExists = true;
440 else if (!state.archiveDb.compare(it->path().string()))
441 archiveDbExists = true;
442 else if (!dbPrefix_.compare(it->path().stem().string()))
443 pathsToDelete.push_back(it->path());
444 }
445
446 if ((!writableDbExists && state.writableDb.size()) ||
447 (!archiveDbExists && state.archiveDb.size()) ||
448 (writableDbExists != archiveDbExists) ||
449 state.writableDb.empty() != state.archiveDb.empty())
450 {
451 boost::filesystem::path stateDbPathName =
452 app_.config().legacy("database_path");
453 stateDbPathName /= dbName_;
454 stateDbPathName += "*";
455
457 << "state db error:\n"
458 << " writableDbExists " << writableDbExists << " archiveDbExists "
459 << archiveDbExists << '\n'
460 << " writableDb '" << state.writableDb << "' archiveDb '"
461 << state.archiveDb << "\n\n"
462 << "The existing data is in a corrupted state.\n"
463 << "To resume operation, remove the files matching "
464 << stateDbPathName.string() << " and contents of the directory "
465 << get(section, "path") << '\n'
466 << "Optionally, you can move those files to another\n"
467 << "location if you wish to analyze or back up the data.\n"
468 << "However, there is no guarantee that the data in its\n"
469 << "existing form is usable.";
470
471 Throw<std::runtime_error>("state db error");
472 }
473
474 // The necessary directories exist. Now, remove any others.
475 for (boost::filesystem::path& p : pathsToDelete)
476 boost::filesystem::remove_all(p);
477}
478
481{
483 boost::filesystem::path newPath;
484
485 if (path.size())
486 {
487 newPath = path;
488 }
489 else
490 {
491 boost::filesystem::path p = get(section, "path");
492 p /= dbPrefix_;
493 p += ".%%%%";
494 newPath = boost::filesystem::unique_path(p);
495 }
496 section.set("path", newPath.string());
497
499 section,
500 megabytes(
504 backend->open();
505 return backend;
506}
507
508void
510 LedgerIndex lastRotated,
511 std::string const& TableName,
512 std::function<std::optional<LedgerIndex>()> const& getMinSeq,
513 std::function<void(LedgerIndex)> const& deleteBeforeSeq)
514{
515 XRPL_ASSERT(
517 "ripple::SHAMapStoreImp::clearSql : nonzero delete interval");
519
520 {
521 JLOG(journal_.trace())
522 << "Begin: Look up lowest value of: " << TableName;
523 auto m = getMinSeq();
524 JLOG(journal_.trace()) << "End: Look up lowest value of: " << TableName;
525 if (!m)
526 return;
527 min = *m;
528 }
529
530 if (min > lastRotated || healthWait() == stopping)
531 return;
532 if (min == lastRotated)
533 {
534 // Micro-optimization mainly to clarify logs
535 JLOG(journal_.trace()) << "Nothing to delete from " << TableName;
536 return;
537 }
538
539 JLOG(journal_.debug()) << "start deleting in: " << TableName << " from "
540 << min << " to " << lastRotated;
541 while (min < lastRotated)
542 {
543 min = std::min(lastRotated, min + deleteBatch_);
544 JLOG(journal_.trace())
545 << "Begin: Delete up to " << deleteBatch_
546 << " rows with LedgerSeq < " << min << " from: " << TableName;
547 deleteBeforeSeq(min);
548 JLOG(journal_.trace())
549 << "End: Delete up to " << deleteBatch_ << " rows with LedgerSeq < "
550 << min << " from: " << TableName;
551 if (healthWait() == stopping)
552 return;
553 if (min < lastRotated)
555 if (healthWait() == stopping)
556 return;
557 }
558 JLOG(journal_.debug()) << "finished deleting from: " << TableName;
559}
560
561void
563{
566}
567
568void
570{
572 return;
574 return;
575}
576
577void
579{
580 // Do not allow ledgers to be acquired from the network
581 // that are about to be deleted.
582 minimumOnline_ = lastRotated + 1;
583 JLOG(journal_.trace()) << "Begin: Clear internal ledgers up to "
584 << lastRotated;
585 ledgerMaster_->clearPriorLedgers(lastRotated);
586 JLOG(journal_.trace()) << "End: Clear internal ledgers up to "
587 << lastRotated;
588 if (healthWait() == stopping)
589 return;
590
591 SQLiteDatabase* const db =
592 dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase());
593
594 if (!db)
595 Throw<std::runtime_error>("Failed to get relational database");
596
597 clearSql(
598 lastRotated,
599 "Ledgers",
600 [db]() -> std::optional<LedgerIndex> { return db->getMinLedgerSeq(); },
601 [db](LedgerIndex min) -> void { db->deleteBeforeLedgerSeq(min); });
602 if (healthWait() == stopping)
603 return;
604
605 if (!app_.config().useTxTables())
606 return;
607
608 clearSql(
609 lastRotated,
610 "Transactions",
611 [&db]() -> std::optional<LedgerIndex> {
612 return db->getTransactionsMinLedgerSeq();
613 },
614 [&db](LedgerIndex min) -> void {
616 });
617 if (healthWait() == stopping)
618 return;
619
620 clearSql(
621 lastRotated,
622 "AccountTransactions",
623 [&db]() -> std::optional<LedgerIndex> {
625 },
626 [&db](LedgerIndex min) -> void {
628 });
629 if (healthWait() == stopping)
630 return;
631}
632
635{
639 while (!stop_ && (mode != OperatingMode::FULL || age > ageThreshold_))
640 {
641 lock.unlock();
642 JLOG(journal_.warn()) << "Waiting " << recoveryWaitTime_.count()
643 << "s for node to stabilize. state: "
644 << app_.getOPs().strOperatingMode(mode, false)
645 << ". age " << age.count() << 's';
648 mode = netOPs_->getOperatingMode();
649 lock.lock();
650 }
651
652 return stop_ ? stopping : keepGoing;
653}
654
655void
657{
658 if (thread_.joinable())
659 {
660 {
662 stop_ = true;
664 }
665 thread_.join();
666 }
667}
668
671{
672 // minimumOnline_ with 0 value is equivalent to unknown/not set.
673 // Don't attempt to acquire ledgers if that value is unknown.
675 return minimumOnline_.load();
676 return app_.getLedgerMaster().minSqlSeq();
677}
678
679//------------------------------------------------------------------------------
680
683 Application& app,
684 NodeStore::Scheduler& scheduler,
685 beast::Journal journal)
686{
687 return std::make_unique<SHAMapStoreImp>(app, scheduler, journal);
688}
689
690} // namespace ripple
T bind(T... args)
A generic endpoint for log messages.
Definition: Journal.h:60
Stream error() const
Definition: Journal.h:346
Stream debug() const
Definition: Journal.h:328
Stream trace() const
Severity stream access functions.
Definition: Journal.h:322
Stream warn() const
Definition: Journal.h:340
virtual Config & config()=0
virtual NetworkOPs & getOPs()=0
virtual Family & getNodeFamily()=0
virtual LedgerMaster & getLedgerMaster()=0
virtual RelationalDatabase & getRelationalDatabase()=0
virtual TransactionMaster & getMasterTransaction()=0
virtual Logs & logs()=0
Holds unparsed configuration information.
Definition: BasicConfig.h:218
Section & section(std::string const &name)
Returns the section with the given name.
void legacy(std::string const &section, std::string value)
Set a value that is not a key/value pair.
bool useTxTables() const
Definition: Config.h:343
int getValueFor(SizedItem item, std::optional< std::size_t > node=std::nullopt) const
Retrieve the default value for the item at the specified node size.
Definition: Config.cpp:1078
virtual std::shared_ptr< FullBelowCache > getFullBelowCache()=0
Return a pointer to the Family Full Below Cache.
virtual std::shared_ptr< TreeNodeCache > getTreeNodeCache()=0
Return a pointer to the Family Tree Node Cache.
void clearLedgerCachePrior(LedgerIndex seq)
void clearPriorLedgers(LedgerIndex seq)
std::optional< LedgerIndex > minSqlSeq()
std::chrono::seconds getValidatedLedgerAge()
beast::Journal journal(std::string const &name)
Definition: Log.cpp:160
virtual OperatingMode getOperatingMode() const =0
virtual std::string strOperatingMode(OperatingMode const mode, bool const admin=false) const =0
virtual void rotate(std::unique_ptr< NodeStore::Backend > &&newBackend, std::function< void(std::string const &writableName, std::string const &archiveName)> const &f)=0
Rotates the backends.
Persistency layer for NodeObject.
Definition: Database.h:50
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition: Database.cpp:240
virtual std::unique_ptr< Backend > make_Backend(Section const &parameters, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal)=0
Create a backend.
virtual std::unique_ptr< Database > make_Database(std::size_t burstSize, Scheduler &scheduler, int readThreads, Section const &backendParameters, beast::Journal journal)=0
Construct a NodeStore database.
static Manager & instance()
Returns the instance of the manager singleton.
Definition: ManagerImp.cpp:116
Scheduling for asynchronous backend activity.
virtual std::optional< LedgerIndex > getMinLedgerSeq()=0
getMinLedgerSeq Returns the minimum ledger sequence in the Ledgers table.
uint256 const & as_uint256() const
Definition: SHAMapHash.h:44
LedgerIndex setCanDelete(LedgerIndex canDelete)
void setState(SavedState const &state)
void init(BasicConfig const &config, std::string const &dbName)
std::condition_variable rendezvous_
std::condition_variable cond_
bool freshenCache(CacheInstance &cache)
void rendezvous() const override
NodeStore::DatabaseRotating * dbRotating_
std::chrono::milliseconds backOff_
void clearSql(LedgerIndex lastRotated, std::string const &TableName, std::function< std::optional< LedgerIndex >()> const &getMinSeq, std::function< void(LedgerIndex)> const &deleteBeforeSeq)
delete from sqlite table in batches to not lock the db excessively.
static constexpr auto nodeStoreName_
void clearPrior(LedgerIndex lastRotated)
std::atomic< LedgerIndex > canDelete_
std::unique_ptr< NodeStore::Backend > makeBackendRotating(std::string path=std::string())
TreeNodeCache * treeNodeCache_
std::uint32_t deleteInterval_
LedgerMaster * ledgerMaster_
void onLedgerClosed(std::shared_ptr< Ledger const > const &ledger) override
Called by LedgerMaster every time a ledger validates.
std::chrono::seconds recoveryWaitTime_
If the node is out of sync during an online_delete healthWait() call, sleep the thread for this time,...
std::string const dbPrefix_
std::uint32_t deleteBatch_
std::chrono::seconds ageThreshold_
std::atomic< LedgerIndex > minimumOnline_
std::uint64_t const checkHealthInterval_
std::unique_ptr< NodeStore::Database > makeNodeStore(int readThreads) override
std::string const dbName_
std::atomic< bool > working_
FullBelowCache * fullBelowCache_
std::optional< LedgerIndex > minimumOnline() const override
The minimum ledger to try and maintain in our database.
HealthResult
This is a health check for online deletion that waits until rippled is stable before returning.
beast::Journal const journal_
NodeStore::Scheduler & scheduler_
static std::uint32_t const minimumDeletionIntervalSA_
int fdRequired() const override
Returns the number of file descriptors that are needed.
bool copyNode(std::uint64_t &nodeCount, SHAMapTreeNode const &node)
std::shared_ptr< Ledger const > newLedger_
static std::uint32_t const minimumDeletionInterval_
void clearCaches(LedgerIndex validatedSeq)
SHAMapStoreImp(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
SHAMapHash const & getHash() const
Return the hash of this node.
virtual std::optional< LedgerIndex > getAccountTransactionsMinLedgerSeq()=0
getAccountTransactionsMinLedgerSeq Returns the minimum ledger sequence stored in the AccountTransacti...
virtual void deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)=0
deleteAccountTransactionsBeforeLedgerSeq Deletes all account transactions with a sequence number less...
virtual std::optional< LedgerIndex > getTransactionsMinLedgerSeq()=0
getTransactionsMinLedgerSeq Returns the minimum ledger sequence stored in the Transactions table.
virtual void deleteBeforeLedgerSeq(LedgerIndex ledgerSeq)=0
deleteBeforeLedgerSeq Deletes all ledgers with a sequence number less than or equal to the given ledg...
virtual void deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)=0
deleteTransactionsBeforeLedgerSeq Deletes all transactions with a sequence number less than or equal ...
Holds a collection of configuration values.
Definition: BasicConfig.h:45
void set(std::string const &key, std::string const &value)
Set a key/value pair.
Definition: BasicConfig.cpp:41
TaggedCache< uint256, Transaction > & getCache()
T compare(T... args)
T count(T... args)
T empty(T... args)
T join(T... args)
T joinable(T... args)
T max(T... args)
T min(T... args)
void setCurrentThreadName(std::string_view newThreadName)
Changes the name of the caller thread.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
LedgerIndex getCanDelete(soci::session &session)
getCanDelete Returns the ledger sequence which can be deleted.
Definition: State.cpp:81
constexpr auto megabytes(T value) noexcept
Definition: ByteUtilities.h:34
SavedState getSavedState(soci::session &session)
getSavedState Returns the saved state.
Definition: State.cpp:99
void setSavedState(soci::session &session, SavedState const &state)
setSavedState Saves the given state.
Definition: State.cpp:111
bool get_if_exists(Section const &section, std::string const &name, T &v)
Definition: BasicConfig.h:386
OperatingMode
Specifies the mode under which the server believes it's operating.
Definition: NetworkOPs.h:66
@ FULL
we have the ledger and can even validate
void initStateDB(soci::session &session, BasicConfig const &config, std::string const &dbName)
initStateDB Opens a session with the State database.
Definition: State.cpp:25
LedgerIndex setCanDelete(soci::session &session, LedgerIndex canDelete)
setCanDelete Updates the ledger sequence which can be deleted.
Definition: State.cpp:91
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
Definition: BasicConfig.h:355
void setLastRotated(soci::session &session, LedgerIndex seq)
setLastRotated Updates the last rotated ledger sequence.
Definition: State.cpp:123
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
STL namespace.
T push_back(T... args)
T ref(T... args)
T reset(T... args)
T size(T... args)
T sleep_for(T... args)
static std::string nodeDatabase()
LedgerIndex lastRotated
Definition: State.h:37
std::string writableDb
Definition: State.h:35
std::string archiveDb
Definition: State.h:36
T to_string(T... args)
T what(T... args)