xrpld
Loading...
Searching...
No Matches
SHAMapStoreImp.cpp
1#include <xrpld/app/misc/SHAMapStoreImp.h>
2
3#include <xrpld/app/ledger/TransactionMaster.h>
4#include <xrpld/app/misc/SHAMapStore.h>
5#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
6#include <xrpld/core/Config.h>
7
8#include <xrpl/basics/ByteUtilities.h>
9#include <xrpl/basics/FileUtilities.h>
10#include <xrpl/basics/Log.h>
11#include <xrpl/basics/contract.h>
12#include <xrpl/beast/core/CurrentThreadName.h>
13#include <xrpl/beast/utility/Journal.h>
14#include <xrpl/beast/utility/instrumentation.h>
15#include <xrpl/config/BasicConfig.h>
16#include <xrpl/config/Constants.h>
17#include <xrpl/ledger/Ledger.h>
18#include <xrpl/nodestore/Database.h>
19#include <xrpl/nodestore/Manager.h>
20#include <xrpl/nodestore/NodeObject.h>
21#include <xrpl/nodestore/Scheduler.h>
22#include <xrpl/nodestore/detail/DatabaseRotatingImp.h>
23#include <xrpl/protocol/Protocol.h>
24#include <xrpl/protocol/Serializer.h>
25#include <xrpl/server/NetworkOPs.h>
26#include <xrpl/server/State.h>
27#include <xrpl/shamap/SHAMapMissingNode.h>
28#include <xrpl/shamap/SHAMapTreeNode.h>
29
30#include <boost/algorithm/string/predicate.hpp>
31
32#include <algorithm>
33#include <cstdint>
34#include <filesystem>
35#include <functional>
36#include <limits>
37#include <memory>
38#include <mutex>
39#include <optional>
40#include <stdexcept>
41#include <string>
42#include <thread>
43#include <utility>
44#include <vector>
45
46namespace xrpl {
47void
49{
50 std::scoped_lock const lock(mutex);
51 initStateDB(sqlDb, config, dbName);
52}
53
61
64{
65 std::scoped_lock const lock(mutex);
66
67 return xrpl::setCanDelete(sqlDb, canDelete);
68}
69
77
78void
84
85void
91
92//------------------------------------------------------------------------------
93
95 Application& app,
96 node_store::Scheduler& scheduler,
97 beast::Journal journal)
98 : app_(app)
99 , scheduler_(scheduler)
100 , journal_(journal)
101 , working_(true)
102 , canDelete_(std::numeric_limits<LedgerIndex>::max())
103{
104 Config& config{app.config()};
105
106 Section& section{config.section(Sections::kNodeDatabase)};
107 if (section.empty())
108 {
109 Throw<std::runtime_error>(
110 std::string("Missing [") + Sections::kNodeDatabase + "] entry in configuration file");
111 }
112
113 // RocksDB only. Use sensible defaults if no values specified.
114 if (boost::iequals(get(section, Keys::kType), "RocksDB"))
115 {
116 if (!section.exists(Keys::kCacheMb))
117 {
118 section.set(
120 }
121
122 if (!section.exists(Keys::kFilterBits) && (config.nodeSize >= 2))
123 section.set(Keys::kFilterBits, "10");
124 }
125
127
128 if (deleteInterval_ != 0u)
129 {
130 // Configuration that affects the behavior of online delete
132 std::uint32_t temp = 0;
133 if (getIfExists(section, Keys::kBackOffMilliseconds, temp) ||
134 // Included for backward compatibility with an undocumented setting
135 getIfExists(section, Keys::kBackOff, temp))
136 {
138 }
139 if (getIfExists(section, Keys::kAgeThresholdSeconds, temp))
141 if (getIfExists(section, Keys::kRecoveryWaitSeconds, temp))
143
145
146 auto const minInterval =
148 if (deleteInterval_ < minInterval)
149 {
151 "online_delete must be at least " + std::to_string(minInterval));
152 }
153
154 if (config.ledgerHistory > deleteInterval_)
155 {
157 "online_delete must not be less than ledger_history "
158 "(currently " +
159 std::to_string(config.ledgerHistory) + ")");
160 }
161
162 stateDb_.init(config, dbName_);
163 dbPaths();
164 }
165}
166
169{
170 auto nscfg = app_.config().section(Sections::kNodeDatabase);
171
172 // Provide default values.
173 if (!nscfg.exists(Keys::kCacheSize))
174 {
175 nscfg.set(
177 std::to_string(app_.config().getValueFor(SizedItem::TreeCacheSize, std::nullopt)));
178 }
179
180 if (!nscfg.exists(Keys::kCacheAge))
181 {
182 nscfg.set(
184 std::to_string(app_.config().getValueFor(SizedItem::TreeCacheAge, std::nullopt)));
185 }
186
188
189 if (deleteInterval_ != 0u)
190 {
191 SavedState state = stateDb_.getState();
192 auto writableBackend = makeBackendRotating(state.writableDb);
193 auto archiveBackend = makeBackendRotating(state.archiveDb);
194 if (state.writableDb.empty())
195 {
196 state.writableDb = writableBackend->getName();
197 state.archiveDb = archiveBackend->getName();
198 stateDb_.setState(state);
199 }
200
201 // Create NodeStore with two backends to allow online deletion of
202 // data
205 readThreads,
206 std::move(writableBackend),
207 std::move(archiveBackend),
208 nscfg,
209 app_.getJournal(kNodeStoreName));
210 fdRequired_ += dbr->fdRequired();
211 dbRotating_ = dbr.get();
212 db.reset(dynamic_cast<node_store::Database*>(dbr.release()));
213 }
214 else
215 {
217 megabytes(app_.config().getValueFor(SizedItem::BurstSize, std::nullopt)),
219 readThreads,
220 nscfg,
221 app_.getJournal(kNodeStoreName));
222 fdRequired_ += db->fdRequired();
223 }
224 return db;
225}
226
227void
229{
230 {
231 std::scoped_lock const lock(mutex_);
232 newLedger_ = ledger;
233 working_ = true;
234 }
235 cond_.notify_one();
236}
237
238void
240{
241 if (!working_)
242 return;
243
245 rendezvous_.wait(lock, [&] { return !working_; });
246}
247
248int
250{
251 return fdRequired_;
252}
253
254bool
256{
257 // Copy a single record from node to dbRotating_
258 auto obj = dbRotating_->fetchNodeObject(
260 if (!obj)
261 {
262 XRPL_ASSERT(node.cowid() == 0, "SHAMapStoreImp::copyNode : rescued node must be clean");
263 // Reachable from the validated state map in memory, but present in
264 // neither backend: its only on-disk copy lived in a backend removed by
265 // an earlier rotation, and it was never rewritten because it is clean
266 // (cowid == 0, so flushDirty skips it). Persist the in-memory body
267 // directly into the writable backend so it survives this rotation
268 // instead of later surfacing as an unresolvable SHAMapMissingNode.
269 auto const hash = node.getHash().asUInt256();
270 Serializer s;
271 node.serializeWithPrefix(s);
272 dbRotating_->store(NodeObjectType::AccountNode, std::move(s.modData()), hash, 0);
273 JLOG(journal_.warn()) << "copyNode: re-stored node missing from both backends, hash="
274 << hash << " type=" << static_cast<int>(node.getType());
275 }
276 if ((++nodeCount % checkHealthInterval_) == 0u)
277 {
279 return false;
280 }
281
282 return true;
283}
284
285void
287{
288 beast::setCurrentThreadName("SHAMapStore");
289 LedgerIndex lastRotated = stateDb_.getState().lastRotated;
290 netOPs_ = &app_.getOPs();
291 ledgerMaster_ = &app_.getLedgerMaster();
292 fullBelowCache_ = &(*app_.getNodeFamily().getFullBelowCache());
293 treeNodeCache_ = &(*app_.getNodeFamily().getTreeNodeCache());
294
295 if (advisoryDelete_)
296 canDelete_ = stateDb_.getCanDelete();
297
298 while (true)
299 {
300 healthy_ = true;
301 std::shared_ptr<Ledger const> validatedLedger;
302
303 {
305 working_ = false;
306 rendezvous_.notify_all();
307 if (stop_)
308 {
309 return;
310 }
311 cond_.wait(lock);
312 if (newLedger_)
313 {
314 validatedLedger = std::move(newLedger_);
315 }
316 else
317 {
318 continue;
319 }
320 }
321
322 LedgerIndex const validatedSeq = validatedLedger->header().seq;
323 if (lastRotated == 0u)
324 {
325 lastRotated = validatedSeq;
326 stateDb_.setLastRotated(lastRotated);
327 }
328
329 bool const readyToRotate = validatedSeq >= lastRotated + deleteInterval_ &&
330 canDelete_ >= lastRotated - 1 && healthWait() == HealthResult::KeepGoing;
331
332 // will delete up to (not including) lastRotated
333 if (readyToRotate)
334 {
335 JLOG(journal_.warn()) << "rotating validatedSeq " << validatedSeq << " lastRotated "
336 << lastRotated << " deleteInterval " << deleteInterval_
337 << " canDelete_ " << canDelete_ << " state "
338 << app_.getOPs().strOperatingMode(false) << " age "
339 << ledgerMaster_->getValidatedLedgerAge().count() << 's';
340
341 clearPrior(lastRotated);
343 return;
344
345 JLOG(journal_.debug()) << "copying ledger " << validatedSeq;
346 std::uint64_t nodeCount = 0;
347
348 try
349 {
350 validatedLedger->stateMap().snapShot(false)->visitNodes(
351 [this, &nodeCount](SHAMapTreeNode const& node) {
352 return copyNode(nodeCount, node);
353 });
354 }
355 catch (SHAMapMissingNode const& e)
356 {
357 JLOG(journal_.error())
358 << "Missing node while copying ledger before rotate: " << e.what();
359 continue;
360 }
361
363 return;
364 // Only log if we completed without a "health" abort
365 JLOG(journal_.debug())
366 << "copied ledger " << validatedSeq << " nodecount " << nodeCount;
367
368 // Close the getKeys()->swap exposure window: from here until
369 // rotate() completes, an ordinary read served by the archive is
370 // copied forward into the writable backend, so a node fetched
371 // from the doomed archive cannot be left RAM-only when the
372 // archive is deleted. RAII so the early returns below (and any
373 // exception) also clear the flag.
374 struct RotationExposureGuard
375 {
377 ~RotationExposureGuard()
378 {
379 db.setRotationInFlight(false);
380 }
381 };
382 RotationExposureGuard const rotationExposureGuard{*dbRotating_};
383 dbRotating_->setRotationInFlight(true);
384
385 JLOG(journal_.debug()) << "freshening caches";
388 return;
389 // Only log if we completed without a "health" abort
390 JLOG(journal_.debug()) << validatedSeq << " freshened caches";
391
392 JLOG(journal_.trace()) << "Making a new backend";
393 auto newBackend = makeBackendRotating();
394 JLOG(journal_.debug()) << validatedSeq << " new backend " << newBackend->getName();
395
396 clearCaches(validatedSeq);
398 return;
399
400 lastRotated = validatedSeq;
401
402 dbRotating_->rotate(
403 std::move(newBackend),
404 [&](std::string const& writableName, std::string const& archiveName) {
405 SavedState savedState;
406 savedState.writableDb = writableName;
407 savedState.archiveDb = archiveName;
408 savedState.lastRotated = lastRotated;
409 stateDb_.setState(savedState);
410
411 clearCaches(validatedSeq);
412 });
413
414 JLOG(journal_.warn()) << "finished rotation " << validatedSeq;
415 }
416 }
417}
418
419void
421{
422 Section const section{app_.config().section(Sections::kNodeDatabase)};
423
424 // Skip creating the directory when an in-memory database is used.
425 if (boost::iequals(get(section, Keys::kType), "memory"))
426 return;
427
428 std::filesystem::path dbPath = get(section, Keys::kPath);
429 if (std::filesystem::exists(dbPath))
430 {
432 {
433 journal_.error() << "node db path must be a directory. " << dbPath.string();
434 Throw<std::runtime_error>("node db path must be a directory.");
435 }
436 }
437 else
438 {
440 }
441
442 SavedState state = stateDb_.getState();
443
444 {
445 auto update = [&dbPath](std::string& sPath) {
446 if (sPath.empty())
447 return false;
448
449 // Check if configured "path" matches stored directory path
450 using namespace std::filesystem;
451 auto const stored{std::filesystem::path(sPath)};
452 if (stored.parent_path() == dbPath)
453 return false;
454
455 sPath = (dbPath / stored.filename()).string();
456 return true;
457 };
458
459 if (update(state.writableDb))
460 {
461 update(state.archiveDb);
462 stateDb_.setState(state);
463 }
464 }
465
466 bool writableDbExists = false;
467 bool archiveDbExists = false;
468
472 ++it)
473 {
474 if (state.writableDb == it->path().string())
475 {
476 writableDbExists = true;
477 }
478 else if (state.archiveDb == it->path().string())
479 {
480 archiveDbExists = true;
481 }
482 else if (dbPrefix_ == it->path().stem().string())
483 {
484 pathsToDelete.push_back(it->path());
485 }
486 }
487
488 if ((!writableDbExists && !state.writableDb.empty()) ||
489 (!archiveDbExists && !state.archiveDb.empty()) || (writableDbExists != archiveDbExists) ||
490 state.writableDb.empty() != state.archiveDb.empty())
491 {
492 std::filesystem::path stateDbPathName = app_.config().legacy(Sections::kDatabasePath);
493 stateDbPathName /= dbName_;
494 stateDbPathName += "*";
495
496 journal_.error() << "state db error:\n"
497 << " writableDbExists " << writableDbExists << " archiveDbExists "
498 << archiveDbExists << '\n'
499 << " writableDb '" << state.writableDb << "' archiveDb '"
500 << state.archiveDb << "\n\n"
501 << "The existing data is in a corrupted state.\n"
502 << "To resume operation, remove the files matching "
503 << stateDbPathName.string() << " and contents of the directory "
504 << get(section, Keys::kPath) << '\n'
505 << "Optionally, you can move those files to another\n"
506 << "location if you wish to analyze or back up the data.\n"
507 << "However, there is no guarantee that the data in its\n"
508 << "existing form is usable.";
509
510 Throw<std::runtime_error>("state db error");
511 }
512
513 // The necessary directories exist. Now, remove any others.
514 for (std::filesystem::path const& p : pathsToDelete)
516}
517
520{
521 Section section{app_.config().section(Sections::kNodeDatabase)};
522 std::filesystem::path newPath;
523
524 if (!path.empty())
525 {
526 newPath = path;
527 }
528 else
529 {
530 newPath = uniqueRandomPath(get(section, Keys::kPath), dbPrefix_ + ".");
531 }
532 section.set(Keys::kPath, newPath.string());
533
535 section,
536 megabytes(app_.config().getValueFor(SizedItem::BurstSize, std::nullopt)),
538 app_.getJournal(kNodeStoreName))};
539 backend->open();
540 return backend;
541}
542
543void
545 LedgerIndex lastRotated,
546 std::string const& tableName,
547 std::function<std::optional<LedgerIndex>()> const& getMinSeq,
548 std::function<void(LedgerIndex)> const& deleteBeforeSeq)
549{
550 XRPL_ASSERT(deleteInterval_, "xrpl::SHAMapStoreImp::clearSql : nonzero delete interval");
552
553 {
554 JLOG(journal_.trace()) << "Begin: Look up lowest value of: " << tableName;
555 auto m = getMinSeq();
556 JLOG(journal_.trace()) << "End: Look up lowest value of: " << tableName;
557 if (!m)
558 return;
559 min = *m;
560 }
561
562 if (min > lastRotated || healthWait() == HealthResult::Stopping)
563 return;
564 if (min == lastRotated)
565 {
566 // Micro-optimization mainly to clarify logs
567 JLOG(journal_.trace()) << "Nothing to delete from " << tableName;
568 return;
569 }
570
571 JLOG(journal_.debug()) << "start deleting in: " << tableName << " from " << min << " to "
572 << lastRotated;
573 while (min < lastRotated)
574 {
575 min = std::min(lastRotated, min + deleteBatch_);
576 JLOG(journal_.trace()) << "Begin: Delete up to " << deleteBatch_
577 << " rows with LedgerSeq < " << min << " from: " << tableName;
578 deleteBeforeSeq(min);
579 JLOG(journal_.trace()) << "End: Delete up to " << deleteBatch_ << " rows with LedgerSeq < "
580 << min << " from: " << tableName;
582 return;
583 if (min < lastRotated)
586 return;
587 }
588 JLOG(journal_.debug()) << "finished deleting from: " << tableName;
589}
590
591void
593{
594 ledgerMaster_->clearLedgerCachePrior(validatedSeq);
595 // Also clear the FullBelowCache so its generation counter is bumped.
596 // This prevents stale "full below" markers from persisting across
597 // backend rotation/online deletion and interfering with SHAMap sync.
598 fullBelowCache_->clear();
599}
600
601void
603{
605 return;
606 if (freshenCache(app_.getMasterTransaction().getCache()))
607 return;
608}
609
610void
612{
613 // Do not allow ledgers to be acquired from the network
614 // that are about to be deleted.
615 minimumOnline_ = lastRotated + 1;
616 JLOG(journal_.trace()) << "Begin: Clear internal ledgers up to " << lastRotated;
617 ledgerMaster_->clearPriorLedgers(lastRotated);
618 JLOG(journal_.trace()) << "End: Clear internal ledgers up to " << lastRotated;
620 return;
621
622 auto& db = app_.getRelationalDatabase();
623
624 clearSql(
625 lastRotated,
626 "Ledgers",
627 [&db]() -> std::optional<LedgerIndex> { return db.getMinLedgerSeq(); },
628 [&db](LedgerIndex min) -> void { db.deleteBeforeLedgerSeq(min); });
630 return;
631
632 if (!app_.config().useTxTables())
633 return;
634
635 clearSql(
636 lastRotated,
637 "Transactions",
638 [&db]() -> std::optional<LedgerIndex> { return db.getTransactionsMinLedgerSeq(); },
639 [&db](LedgerIndex min) -> void { db.deleteTransactionsBeforeLedgerSeq(min); });
641 return;
642
643 clearSql(
644 lastRotated,
645 "AccountTransactions",
646 [&db]() -> std::optional<LedgerIndex> { return db.getAccountTransactionsMinLedgerSeq(); },
647 [&db](LedgerIndex min) -> void { db.deleteAccountTransactionsBeforeLedgerSeq(min); });
649 return;
650}
651
654{
655 auto age = ledgerMaster_->getValidatedLedgerAge();
656 OperatingMode mode = netOPs_->getOperatingMode();
658 while (!stop_ && (mode != OperatingMode::FULL || age > ageThreshold_))
659 {
660 lock.unlock();
661 JLOG(journal_.warn()) << "Waiting " << recoveryWaitTime_.count()
662 << "s for node to stabilize. state: "
663 << app_.getOPs().strOperatingMode(mode, false) << ". age "
664 << age.count() << 's';
666 age = ledgerMaster_->getValidatedLedgerAge();
667 mode = netOPs_->getOperatingMode();
668 lock.lock();
669 }
670
672}
673
674void
676{
677 if (thread_.joinable())
678 {
679 {
681 stop_ = true;
682 cond_.notify_one();
683 }
684 thread_.join();
685 }
686}
687
690{
691 // minimumOnline_ with 0 value is equivalent to unknown/not set.
692 // Don't attempt to acquire ledgers if that value is unknown.
693 if ((deleteInterval_ != 0u) && (minimumOnline_ != 0u))
694 return minimumOnline_.load();
695 return app_.getLedgerMaster().minSqlSeq();
696}
697
698//------------------------------------------------------------------------------
699
702{
703 return std::make_unique<SHAMapStoreImp>(app, scheduler, journal);
704}
705
706} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
virtual Config & config()=0
Holds unparsed configuration information.
Section & section(std::string const &name)
Returns the section with the given name.
bool standalone() const
std::uint32_t ledgerHistory
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.
uint256 const & asUInt256() const
Definition SHAMapHash.h:26
void setState(SavedState const &state)
void init(BasicConfig const &config, std::string const &dbName)
LedgerIndex setCanDelete(LedgerIndex canDelete)
bool copyNode(std::uint64_t &nodeCount, SHAMapTreeNode const &node)
std::atomic< bool > working_
std::condition_variable cond_
std::uint32_t deleteBatch_
std::atomic< LedgerIndex > minimumOnline_
std::chrono::seconds recoveryWaitTime_
If the node is out of sync during an online_delete healthWait() call, sleep the thread for this time,...
FullBelowCache * fullBelowCache_
std::optional< LedgerIndex > minimumOnline() const override
The minimum ledger to try and maintain in our database.
TreeNodeCache * treeNodeCache_
std::uint32_t deleteInterval_
std::unique_ptr< node_store::Database > makeNodeStore(int readThreads) override
static std::uint32_t const kMinimumDeletionIntervalSa
int fdRequired() const override
Returns the number of file descriptors that are needed.
std::chrono::milliseconds backOff_
std::atomic< LedgerIndex > canDelete_
std::shared_ptr< Ledger const > newLedger_
std::string const dbName_
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.
std::condition_variable rendezvous_
std::uint64_t const checkHealthInterval_
HealthResult healthWait()
void clearCaches(LedgerIndex validatedSeq)
std::chrono::seconds ageThreshold_
void rendezvous() const override
LedgerMaster * ledgerMaster_
beast::Journal const journal_
static constexpr auto kNodeStoreName
std::string const dbPrefix_
node_store::Scheduler & scheduler_
HealthResult
This is a health check for online deletion that waits until xrpld is stable before returning.
void onLedgerClosed(std::shared_ptr< Ledger const > const &ledger) override
Called by LedgerMaster every time a ledger validates.
node_store::DatabaseRotating * dbRotating_
std::unique_ptr< node_store::Backend > makeBackendRotating(std::string path=std::string())
static std::uint32_t const kMinimumDeletionInterval
SHAMapStoreImp(Application &app, node_store::Scheduler &scheduler, beast::Journal journal)
bool freshenCache(CacheInstance &cache)
void clearPrior(LedgerIndex lastRotated)
SHAMapHash const & getHash() const
Return the hash of this node.
virtual void serializeWithPrefix(Serializer &) const =0
Serialize the node in a format appropriate for hashing.
virtual SHAMapNodeType getType() const =0
Determines the type of node.
Holds a collection of configuration values.
Definition BasicConfig.h:29
bool empty() const
void set(std::string const &key, std::string const &value)
Set a key/value pair.
bool exists(std::string const &name) const
Returns true if a key with the given name exists.
virtual void setRotationInFlight(bool inFlight)=0
Marks an online-delete rotation as in progress (or completed).
Persistency layer for NodeObject.
Definition Database.h:45
virtual std::unique_ptr< Backend > makeBackend(Section const &parameters, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal)=0
Create a backend.
virtual std::unique_ptr< Database > makeDatabase(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.
Scheduling for asynchronous backend activity.
T create_directories(T... args)
T empty(T... args)
T exists(T... args)
T filename(T... args)
std::uint32_t cowid() const
Returns the SHAMap that owns this node.
T is_directory(T... args)
T lock(T... args)
T make_unique(T... args)
T max(T... args)
T min(T... args)
void setCurrentThreadName(std::string_view newThreadName)
Changes the name of the caller thread.
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
void initStateDB(soci::session &session, BasicConfig const &config, std::string const &dbName)
initStateDB Opens a session with the State database.
Definition State.cpp:22
void setSavedState(soci::session &session, SavedState const &state)
setSavedState Saves the given state.
Definition State.cpp:99
std::uint32_t LedgerIndex
A ledger index.
Definition Protocol.h:370
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
void setLastRotated(soci::session &session, LedgerIndex seq)
setLastRotated Updates the last rotated ledger sequence.
Definition State.cpp:110
std::unique_ptr< SHAMapStore > makeSHAMapStore(Application &app, node_store::Scheduler &scheduler, beast::Journal journal)
std::filesystem::path uniqueRandomPath(std::filesystem::path const &base, std::string const &prefix="", std::size_t maxAttempts=100)
Generate a unique, non-existing path under base whose filename starts with prefix and ends with a ran...
bool getIfExists(Section const &section, std::string const &name, T &v)
SavedState getSavedState(soci::session &session)
getSavedState Returns the saved state.
Definition State.cpp:88
constexpr auto megabytes(T value) noexcept
LedgerIndex setCanDelete(soci::session &session, LedgerIndex canDelete)
setCanDelete Updates the ledger sequence which can be deleted.
Definition State.cpp:80
OperatingMode
Specifies the mode under which the server believes it's operating.
Definition NetworkOPs.h:60
@ FULL
we have the ledger and can even validate
Definition NetworkOPs.h:65
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
LedgerIndex getCanDelete(soci::session &session)
getCanDelete Returns the ledger sequence which can be deleted.
Definition State.cpp:71
T push_back(T... args)
T remove_all(T... args)
T reset(T... args)
T sleep_for(T... args)
static constexpr auto kBackOffMilliseconds
Definition Constants.h:92
static constexpr auto kAdvisoryDelete
Definition Constants.h:89
static constexpr auto kCacheMb
Definition Constants.h:98
static constexpr auto kCacheSize
Definition Constants.h:99
static constexpr auto kBackOff
Definition Constants.h:91
static constexpr auto kAgeThresholdSeconds
Definition Constants.h:90
static constexpr auto kDeleteBatch
Definition Constants.h:104
static constexpr auto kFilterBits
Definition Constants.h:109
static constexpr auto kRecoveryWaitSeconds
Definition Constants.h:148
static constexpr auto kType
Definition Constants.h:173
static constexpr auto kPath
Definition Constants.h:143
static constexpr auto kCacheAge
Definition Constants.h:97
static constexpr auto kOnlineDelete
Definition Constants.h:136
std::string writableDb
Definition State.h:13
LedgerIndex lastRotated
Definition State.h:15
std::string archiveDb
Definition State.h:14
static constexpr auto kNodeDatabase
Definition Constants.h:32
static constexpr auto kDatabasePath
Definition Constants.h:13
T to_string(T... args)
T what(T... args)