From ef284692db4588082eac8106b1f5262bf1ad7534 Mon Sep 17 00:00:00 2001 From: Jingchen Date: Wed, 11 Feb 2026 13:42:31 +0000 Subject: [PATCH 1/3] refactor: Modularize WalletDB and Manifest (#6223) This change modularizes the `WalletDB` and `Manifest`. Note that the wallet db has nothing to do with account wallets and it stores node configuration, which is why it depends on the manifest code. --- .../scripts/levelization/results/loops.txt | 5 +- .../scripts/levelization/results/ordering.txt | 18 +- cmake/XrplCore.cmake | 21 +- cmake/XrplInstall.cmake | 1 + .../xrpl/core}/PeerReservationTable.h | 0 include/xrpl/core/ServiceRegistry.h | 24 ++ include/xrpl/core/StartUpType.h | 16 ++ .../app/main => include/xrpl/rdb}/DBInit.h | 0 .../core => include/xrpl/rdb}/DatabaseCon.h | 16 +- {src/xrpld/core => include/xrpl/rdb}/SociDB.h | 0 .../misc => include/xrpl/server}/Manifest.h | 0 .../app/rdb => include/xrpl/server}/State.h | 8 +- .../app/rdb => include/xrpl/server}/Vacuum.h | 2 +- .../app/rdb => include/xrpl/server}/Wallet.h | 7 +- src/libxrpl/rdb/DatabaseCon.cpp | 92 +++++++ .../core/detail => libxrpl/rdb}/SociDB.cpp | 6 +- .../rdb/detail => libxrpl/server}/State.cpp | 2 +- .../rdb/detail => libxrpl/server}/Vacuum.cpp | 4 +- .../rdb/detail => libxrpl/server}/Wallet.cpp | 3 +- src/test/app/LedgerLoad_test.cpp | 22 +- src/test/app/Manifest_test.cpp | 6 +- src/test/app/ValidatorKeys_test.cpp | 2 +- src/test/core/SociDB_test.cpp | 3 +- src/test/nodestore/Database_test.cpp | 3 +- src/test/rpc/LedgerEntry_test.cpp | 4 +- src/xrpld/app/ledger/Ledger.cpp | 1 - src/xrpld/app/main/Application.cpp | 26 +- src/xrpld/app/main/Application.h | 14 +- src/xrpld/app/main/Main.cpp | 16 +- src/xrpld/app/main/NodeIdentity.cpp | 3 +- src/xrpld/app/misc/SHAMapStoreImp.cpp | 2 +- src/xrpld/app/misc/SHAMapStoreImp.h | 4 +- src/xrpld/app/misc/ValidatorList.h | 2 +- src/xrpld/app/misc/detail/AmendmentTable.cpp | 2 +- src/xrpld/app/misc/detail/Manifest.cpp | 7 +- src/xrpld/app/misc/detail/ValidatorKeys.cpp | 2 +- src/xrpld/app/rdb/PeerFinder.h | 3 +- src/xrpld/app/rdb/RelationalDatabase.h | 8 +- src/xrpld/app/rdb/backend/detail/Node.cpp | 8 +- .../app/rdb/backend/detail/SQLiteDatabase.cpp | 48 ++-- .../app/rdb/detail/RelationalDatabase.cpp | 7 +- src/xrpld/core/Config.h | 8 +- src/xrpld/core/detail/Config.cpp | 146 +++++++++++ src/xrpld/core/detail/DatabaseCon.cpp | 242 ------------------ src/xrpld/overlay/detail/OverlayImpl.cpp | 2 +- .../overlay/detail/PeerReservationTable.cpp | 4 +- src/xrpld/peerfinder/detail/StoreSqdb.h | 3 +- src/xrpld/rpc/InfoSub.h | 3 +- 48 files changed, 435 insertions(+), 391 deletions(-) rename {src/xrpld/overlay => include/xrpl/core}/PeerReservationTable.h (100%) create mode 100644 include/xrpl/core/StartUpType.h rename {src/xrpld/app/main => include/xrpl/rdb}/DBInit.h (100%) rename {src/xrpld/core => include/xrpl/rdb}/DatabaseCon.h (93%) rename {src/xrpld/core => include/xrpl/rdb}/SociDB.h (100%) rename {src/xrpld/app/misc => include/xrpl/server}/Manifest.h (100%) rename {src/xrpld/app/rdb => include/xrpl/server}/State.h (91%) rename {src/xrpld/app/rdb => include/xrpl/server}/Vacuum.h (90%) rename {src/xrpld/app/rdb => include/xrpl/server}/Wallet.h (96%) create mode 100644 src/libxrpl/rdb/DatabaseCon.cpp rename src/{xrpld/core/detail => libxrpl/rdb}/SociDB.cpp (98%) rename src/{xrpld/app/rdb/detail => libxrpl/server}/State.cpp (98%) rename src/{xrpld/app/rdb/detail => libxrpl/server}/Vacuum.cpp (96%) rename src/{xrpld/app/rdb/detail => libxrpl/server}/Wallet.cpp (99%) delete mode 100644 src/xrpld/core/detail/DatabaseCon.cpp diff --git a/.github/scripts/levelization/results/loops.txt b/.github/scripts/levelization/results/loops.txt index d15843ceb0..34842d7f48 100644 --- a/.github/scripts/levelization/results/loops.txt +++ b/.github/scripts/levelization/results/loops.txt @@ -4,14 +4,11 @@ Loop: test.jtx test.toplevel Loop: test.jtx test.unit_test test.unit_test == test.jtx -Loop: xrpld.app xrpld.core - xrpld.app > xrpld.core - Loop: xrpld.app xrpld.overlay xrpld.overlay > xrpld.app Loop: xrpld.app xrpld.peerfinder - xrpld.peerfinder ~= xrpld.app + xrpld.peerfinder == xrpld.app Loop: xrpld.app xrpld.rpc xrpld.rpc > xrpld.app diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index 88a3441fa1..fabc7b49ca 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -17,12 +17,15 @@ libxrpl.nodestore > xrpl.protocol libxrpl.protocol > xrpl.basics libxrpl.protocol > xrpl.json libxrpl.protocol > xrpl.protocol +libxrpl.rdb > xrpl.basics +libxrpl.rdb > xrpl.rdb libxrpl.resource > xrpl.basics libxrpl.resource > xrpl.json libxrpl.resource > xrpl.resource libxrpl.server > xrpl.basics libxrpl.server > xrpl.json libxrpl.server > xrpl.protocol +libxrpl.server > xrpl.rdb libxrpl.server > xrpl.server libxrpl.shamap > xrpl.basics libxrpl.shamap > xrpl.protocol @@ -41,7 +44,9 @@ test.app > xrpl.json test.app > xrpl.ledger test.app > xrpl.nodestore test.app > xrpl.protocol +test.app > xrpl.rdb test.app > xrpl.resource +test.app > xrpl.server test.basics > test.jtx test.basics > test.unit_test test.basics > xrpl.basics @@ -67,6 +72,7 @@ test.core > xrpl.basics test.core > xrpl.core test.core > xrpld.core test.core > xrpl.json +test.core > xrpl.rdb test.core > xrpl.server test.csf > xrpl.basics test.csf > xrpld.consensus @@ -95,8 +101,8 @@ test.nodestore > test.jtx test.nodestore > test.toplevel test.nodestore > test.unit_test test.nodestore > xrpl.basics -test.nodestore > xrpld.core test.nodestore > xrpl.nodestore +test.nodestore > xrpl.rdb test.overlay > test.jtx test.overlay > test.toplevel test.overlay > test.unit_test @@ -154,6 +160,7 @@ tests.libxrpl > xrpl.net xrpl.core > xrpl.basics xrpl.core > xrpl.json xrpl.core > xrpl.ledger +xrpl.core > xrpl.protocol xrpl.json > xrpl.basics xrpl.ledger > xrpl.basics xrpl.ledger > xrpl.protocol @@ -162,12 +169,16 @@ xrpl.nodestore > xrpl.basics xrpl.nodestore > xrpl.protocol xrpl.protocol > xrpl.basics xrpl.protocol > xrpl.json +xrpl.rdb > xrpl.basics +xrpl.rdb > xrpl.core xrpl.resource > xrpl.basics xrpl.resource > xrpl.json xrpl.resource > xrpl.protocol xrpl.server > xrpl.basics +xrpl.server > xrpl.core xrpl.server > xrpl.json xrpl.server > xrpl.protocol +xrpl.server > xrpl.rdb xrpl.shamap > xrpl.basics xrpl.shamap > xrpl.nodestore xrpl.shamap > xrpl.protocol @@ -176,12 +187,15 @@ xrpld.app > xrpl.basics xrpld.app > xrpl.core xrpld.app > xrpld.conditions xrpld.app > xrpld.consensus +xrpld.app > xrpld.core xrpld.app > xrpl.json xrpld.app > xrpl.ledger xrpld.app > xrpl.net xrpld.app > xrpl.nodestore xrpld.app > xrpl.protocol +xrpld.app > xrpl.rdb xrpld.app > xrpl.resource +xrpld.app > xrpl.server xrpld.app > xrpl.shamap xrpld.conditions > xrpl.basics xrpld.conditions > xrpl.protocol @@ -193,6 +207,7 @@ xrpld.core > xrpl.core xrpld.core > xrpl.json xrpld.core > xrpl.net xrpld.core > xrpl.protocol +xrpld.core > xrpl.rdb xrpld.overlay > xrpl.basics xrpld.overlay > xrpl.core xrpld.overlay > xrpld.core @@ -204,6 +219,7 @@ xrpld.overlay > xrpl.server xrpld.peerfinder > xrpl.basics xrpld.peerfinder > xrpld.core xrpld.peerfinder > xrpl.protocol +xrpld.peerfinder > xrpl.rdb xrpld.perflog > xrpl.basics xrpld.perflog > xrpl.core xrpld.perflog > xrpld.rpc diff --git a/cmake/XrplCore.cmake b/cmake/XrplCore.cmake index 57d0e83348..cea19db9bc 100644 --- a/cmake/XrplCore.cmake +++ b/cmake/XrplCore.cmake @@ -84,9 +84,6 @@ add_module(xrpl net) target_link_libraries(xrpl.libxrpl.net PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol xrpl.libxrpl.resource) -add_module(xrpl server) -target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol) - add_module(xrpl nodestore) target_link_libraries(xrpl.libxrpl.nodestore PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol) @@ -94,8 +91,15 @@ add_module(xrpl shamap) target_link_libraries(xrpl.libxrpl.shamap PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.crypto xrpl.libxrpl.protocol xrpl.libxrpl.nodestore) +add_module(xrpl rdb) +target_link_libraries(xrpl.libxrpl.rdb PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.core) + +add_module(xrpl server) +target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol xrpl.libxrpl.core xrpl.libxrpl.rdb) + add_module(xrpl ledger) -target_link_libraries(xrpl.libxrpl.ledger PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol) +target_link_libraries(xrpl.libxrpl.ledger PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol + xrpl.libxrpl.rdb) add_library(xrpl.libxrpl) set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl) @@ -113,13 +117,14 @@ target_link_modules( core crypto json + ledger + net + nodestore protocol + rdb resource server - nodestore - shamap - net - ledger) + shamap) # All headers in libxrpl are in modules. # Uncomment this stanza if you have not yet moved new headers into a module. diff --git a/cmake/XrplInstall.cmake b/cmake/XrplInstall.cmake index 141dc56089..340dca553b 100644 --- a/cmake/XrplInstall.cmake +++ b/cmake/XrplInstall.cmake @@ -23,6 +23,7 @@ install(TARGETS common xrpl.libxrpl.core xrpl.libxrpl.crypto xrpl.libxrpl.json + xrpl.libxrpl.rdb xrpl.libxrpl.ledger xrpl.libxrpl.net xrpl.libxrpl.nodestore diff --git a/src/xrpld/overlay/PeerReservationTable.h b/include/xrpl/core/PeerReservationTable.h similarity index 100% rename from src/xrpld/overlay/PeerReservationTable.h rename to include/xrpl/core/PeerReservationTable.h diff --git a/include/xrpl/core/ServiceRegistry.h b/include/xrpl/core/ServiceRegistry.h index 7147242339..86591a815f 100644 --- a/include/xrpl/core/ServiceRegistry.h +++ b/include/xrpl/core/ServiceRegistry.h @@ -5,6 +5,8 @@ #include #include +#include + namespace xrpl { // Forward declarations @@ -18,6 +20,10 @@ namespace perf { class PerfLog; } +// This is temporary until we migrate all code to use ServiceRegistry. +class Application; + +// Forward declarations class AcceptedLedger; class AmendmentTable; class Cluster; @@ -194,6 +200,24 @@ public: virtual perf::PerfLog& getPerfLog() = 0; + + // Configuration and state + virtual bool + isStopping() const = 0; + + virtual beast::Journal + journal(std::string const& name) = 0; + + virtual boost::asio::io_context& + getIOContext() = 0; + + virtual Logs& + logs() = 0; + + // Temporary: Get the underlying Application for functions that haven't + // been migrated yet. This should be removed once all code is migrated. + virtual Application& + app() = 0; }; } // namespace xrpl diff --git a/include/xrpl/core/StartUpType.h b/include/xrpl/core/StartUpType.h new file mode 100644 index 0000000000..74a1898806 --- /dev/null +++ b/include/xrpl/core/StartUpType.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +namespace xrpl { + +enum class StartUpType { FRESH, NORMAL, LOAD, LOAD_FILE, REPLAY, NETWORK }; + +inline std::ostream& +operator<<(std::ostream& os, StartUpType const& type) +{ + return os << static_cast>(type); +} + +} // namespace xrpl diff --git a/src/xrpld/app/main/DBInit.h b/include/xrpl/rdb/DBInit.h similarity index 100% rename from src/xrpld/app/main/DBInit.h rename to include/xrpl/rdb/DBInit.h diff --git a/src/xrpld/core/DatabaseCon.h b/include/xrpl/rdb/DatabaseCon.h similarity index 93% rename from src/xrpld/core/DatabaseCon.h rename to include/xrpl/rdb/DatabaseCon.h index 89d582257b..37a53044e4 100644 --- a/src/xrpld/core/DatabaseCon.h +++ b/include/xrpl/rdb/DatabaseCon.h @@ -1,10 +1,9 @@ #pragma once -#include -#include -#include - #include +#include +#include +#include #include @@ -68,7 +67,7 @@ public: { explicit Setup() = default; - Config::StartUpType startUp = Config::NORMAL; + StartUpType startUp = StartUpType::NORMAL; bool standAlone = false; boost::filesystem::path dataDir; // Indicates whether or not to return the `globalPragma` @@ -105,8 +104,8 @@ public: beast::Journal journal) // Use temporary files or regular DB files? : DatabaseCon( - setup.standAlone && setup.startUp != Config::LOAD && setup.startUp != Config::LOAD_FILE && - setup.startUp != Config::REPLAY + setup.standAlone && setup.startUp != StartUpType::LOAD && setup.startUp != StartUpType::LOAD_FILE && + setup.startUp != StartUpType::REPLAY ? "" : (setup.dataDir / dbName), setup.commonPragma(), @@ -229,7 +228,4 @@ private: std::shared_ptr checkpointerFromId(std::uintptr_t id); -DatabaseCon::Setup -setup_DatabaseCon(Config const& c, std::optional j = std::nullopt); - } // namespace xrpl diff --git a/src/xrpld/core/SociDB.h b/include/xrpl/rdb/SociDB.h similarity index 100% rename from src/xrpld/core/SociDB.h rename to include/xrpl/rdb/SociDB.h diff --git a/src/xrpld/app/misc/Manifest.h b/include/xrpl/server/Manifest.h similarity index 100% rename from src/xrpld/app/misc/Manifest.h rename to include/xrpl/server/Manifest.h diff --git a/src/xrpld/app/rdb/State.h b/include/xrpl/server/State.h similarity index 91% rename from src/xrpld/app/rdb/State.h rename to include/xrpl/server/State.h index 52118b3cf8..48e11869f4 100644 --- a/src/xrpld/app/rdb/State.h +++ b/include/xrpl/server/State.h @@ -1,10 +1,8 @@ #pragma once -#include -#include -#include -#include -#include +#include +#include +#include #include diff --git a/src/xrpld/app/rdb/Vacuum.h b/include/xrpl/server/Vacuum.h similarity index 90% rename from src/xrpld/app/rdb/Vacuum.h rename to include/xrpl/server/Vacuum.h index f592b4537e..5f80eced87 100644 --- a/src/xrpld/app/rdb/Vacuum.h +++ b/include/xrpl/server/Vacuum.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace xrpl { diff --git a/src/xrpld/app/rdb/Wallet.h b/include/xrpl/server/Wallet.h similarity index 96% rename from src/xrpld/app/rdb/Wallet.h rename to include/xrpl/server/Wallet.h index 141ef53f27..dcfbada8eb 100644 --- a/src/xrpld/app/rdb/Wallet.h +++ b/include/xrpl/server/Wallet.h @@ -1,9 +1,8 @@ #pragma once -#include -#include -#include -#include +#include +#include +#include namespace xrpl { diff --git a/src/libxrpl/rdb/DatabaseCon.cpp b/src/libxrpl/rdb/DatabaseCon.cpp new file mode 100644 index 0000000000..344df85b4a --- /dev/null +++ b/src/libxrpl/rdb/DatabaseCon.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace xrpl { + +class CheckpointersCollection +{ + std::uintptr_t nextId_{0}; + // Mutex protects the CheckpointersCollection + std::mutex mutex_; + // Each checkpointer is given a unique id. All the checkpointers that are + // part of a DatabaseCon are part of this collection. When the DatabaseCon + // is destroyed, its checkpointer is removed from the collection + std::unordered_map> checkpointers_; + +public: + std::shared_ptr + fromId(std::uintptr_t id) + { + std::lock_guard l{mutex_}; + auto it = checkpointers_.find(id); + if (it != checkpointers_.end()) + return it->second; + return {}; + } + + void + erase(std::uintptr_t id) + { + std::lock_guard lock{mutex_}; + checkpointers_.erase(id); + } + + std::shared_ptr + create(std::shared_ptr const& session, JobQueue& jobQueue, Logs& logs) + { + std::lock_guard lock{mutex_}; + auto const id = nextId_++; + auto const r = makeCheckpointer(id, session, jobQueue, logs); + checkpointers_[id] = r; + return r; + } +}; + +CheckpointersCollection checkpointers; + +std::shared_ptr +checkpointerFromId(std::uintptr_t id) +{ + return checkpointers.fromId(id); +} + +DatabaseCon::~DatabaseCon() +{ + if (checkpointer_) + { + checkpointers.erase(checkpointer_->id()); + + std::weak_ptr wk(checkpointer_); + checkpointer_.reset(); + + // The references to our Checkpointer held by 'checkpointer_' and + // 'checkpointers' have been removed, so if the use count is nonzero, a + // checkpoint is currently in progress. Wait for it to end, otherwise + // creating a new DatabaseCon to the same database may fail due to the + // database being locked by our (now old) Checkpointer. + while (wk.use_count()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } +} + +std::unique_ptr const> DatabaseCon::Setup::globalPragma; + +void +DatabaseCon::setupCheckpointing(JobQueue* q, Logs& l) +{ + if (!q) + Throw("No JobQueue"); + checkpointer_ = checkpointers.create(session_, *q, l); +} + +} // namespace xrpl diff --git a/src/xrpld/core/detail/SociDB.cpp b/src/libxrpl/rdb/SociDB.cpp similarity index 98% rename from src/xrpld/core/detail/SociDB.cpp rename to src/libxrpl/rdb/SociDB.cpp index ff2fa1d9c1..2f8c5f1ac6 100644 --- a/src/xrpld/core/detail/SociDB.cpp +++ b/src/libxrpl/rdb/SociDB.cpp @@ -3,12 +3,10 @@ #pragma clang diagnostic ignored "-Wdeprecated" #endif -#include -#include -#include - #include #include +#include +#include #include diff --git a/src/xrpld/app/rdb/detail/State.cpp b/src/libxrpl/server/State.cpp similarity index 98% rename from src/xrpld/app/rdb/detail/State.cpp rename to src/libxrpl/server/State.cpp index ad8944e54d..4e3a1584c2 100644 --- a/src/xrpld/app/rdb/detail/State.cpp +++ b/src/libxrpl/server/State.cpp @@ -1,4 +1,4 @@ -#include +#include namespace xrpl { diff --git a/src/xrpld/app/rdb/detail/Vacuum.cpp b/src/libxrpl/server/Vacuum.cpp similarity index 96% rename from src/xrpld/app/rdb/detail/Vacuum.cpp rename to src/libxrpl/server/Vacuum.cpp index 5aaa04f040..cb31c6fa7a 100644 --- a/src/xrpld/app/rdb/detail/Vacuum.cpp +++ b/src/libxrpl/server/Vacuum.cpp @@ -1,7 +1,9 @@ -#include +#include #include +#include + namespace xrpl { bool diff --git a/src/xrpld/app/rdb/detail/Wallet.cpp b/src/libxrpl/server/Wallet.cpp similarity index 99% rename from src/xrpld/app/rdb/detail/Wallet.cpp rename to src/libxrpl/server/Wallet.cpp index 88a5dcf985..51f1326674 100644 --- a/src/xrpld/app/rdb/detail/Wallet.cpp +++ b/src/libxrpl/server/Wallet.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include diff --git a/src/test/app/LedgerLoad_test.cpp b/src/test/app/LedgerLoad_test.cpp index f27edadd58..b4e84a3123 100644 --- a/src/test/app/LedgerLoad_test.cpp +++ b/src/test/app/LedgerLoad_test.cpp @@ -21,7 +21,7 @@ class LedgerLoad_test : public beast::unit_test::suite std::unique_ptr cfg, std::string const& dbPath, std::string const& ledger, - Config::StartUpType type, + StartUpType type, std::optional trapTxHash) { cfg->START_LEDGER = ledger; @@ -105,7 +105,7 @@ class LedgerLoad_test : public beast::unit_test::suite // create a new env with the ledger file specified for startup Env env( *this, - envconfig(ledgerConfig, sd.dbPath, sd.ledgerFile, Config::LOAD_FILE, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, sd.ledgerFile, StartUpType::LOAD_FILE, std::nullopt), nullptr, beast::severities::kDisabled); auto jrb = env.rpc("ledger", "current", "full")[jss::result]; @@ -123,7 +123,7 @@ class LedgerLoad_test : public beast::unit_test::suite except([&] { Env env( *this, - envconfig(ledgerConfig, sd.dbPath, "", Config::LOAD_FILE, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, "", StartUpType::LOAD_FILE, std::nullopt), nullptr, beast::severities::kDisabled); }); @@ -132,7 +132,7 @@ class LedgerLoad_test : public beast::unit_test::suite except([&] { Env env( *this, - envconfig(ledgerConfig, sd.dbPath, "badfile.json", Config::LOAD_FILE, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, "badfile.json", StartUpType::LOAD_FILE, std::nullopt), nullptr, beast::severities::kDisabled); }); @@ -153,7 +153,7 @@ class LedgerLoad_test : public beast::unit_test::suite except([&] { Env env( *this, - envconfig(ledgerConfig, sd.dbPath, ledgerFileCorrupt.string(), Config::LOAD_FILE, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, ledgerFileCorrupt.string(), StartUpType::LOAD_FILE, std::nullopt), nullptr, beast::severities::kDisabled); }); @@ -170,7 +170,7 @@ class LedgerLoad_test : public beast::unit_test::suite boost::erase_all(ledgerHash, "\""); Env env( *this, - envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::LOAD, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, ledgerHash, StartUpType::LOAD, std::nullopt), nullptr, beast::severities::kDisabled); auto jrb = env.rpc("ledger", "current", "full")[jss::result]; @@ -189,7 +189,7 @@ class LedgerLoad_test : public beast::unit_test::suite boost::erase_all(ledgerHash, "\""); Env env( *this, - envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::REPLAY, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, ledgerHash, StartUpType::REPLAY, std::nullopt), nullptr, beast::severities::kDisabled); auto const jrb = env.rpc("ledger", "current", "full")[jss::result]; @@ -213,7 +213,7 @@ class LedgerLoad_test : public beast::unit_test::suite boost::erase_all(ledgerHash, "\""); Env env( *this, - envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::REPLAY, sd.trapTxHash), + envconfig(ledgerConfig, sd.dbPath, ledgerHash, StartUpType::REPLAY, sd.trapTxHash), nullptr, beast::severities::kDisabled); auto const jrb = env.rpc("ledger", "current", "full")[jss::result]; @@ -241,7 +241,7 @@ class LedgerLoad_test : public beast::unit_test::suite // replay when trapTxHash is set to an invalid transaction Env env( *this, - envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::REPLAY, ~sd.trapTxHash), + envconfig(ledgerConfig, sd.dbPath, ledgerHash, StartUpType::REPLAY, ~sd.trapTxHash), nullptr, beast::severities::kDisabled); BEAST_EXPECT(false); @@ -265,7 +265,7 @@ class LedgerLoad_test : public beast::unit_test::suite // create a new env with the ledger "latest" specified for startup Env env( *this, - envconfig(ledgerConfig, sd.dbPath, "latest", Config::LOAD, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, "latest", StartUpType::LOAD, std::nullopt), nullptr, beast::severities::kDisabled); auto jrb = env.rpc("ledger", "current", "full")[jss::result]; @@ -281,7 +281,7 @@ class LedgerLoad_test : public beast::unit_test::suite // create a new env with specific ledger index at startup Env env( *this, - envconfig(ledgerConfig, sd.dbPath, "43", Config::LOAD, std::nullopt), + envconfig(ledgerConfig, sd.dbPath, "43", StartUpType::LOAD, std::nullopt), nullptr, beast::severities::kDisabled); auto jrb = env.rpc("ledger", "current", "full")[jss::result]; diff --git a/src/test/app/Manifest_test.cpp b/src/test/app/Manifest_test.cpp index 598949f662..5b7e34ad5b 100644 --- a/src/test/app/Manifest_test.cpp +++ b/src/test/app/Manifest_test.cpp @@ -1,15 +1,15 @@ #include -#include -#include #include -#include #include #include #include #include #include +#include +#include +#include #include #include diff --git a/src/test/app/ValidatorKeys_test.cpp b/src/test/app/ValidatorKeys_test.cpp index fac8a4bb7e..c688b2661f 100644 --- a/src/test/app/ValidatorKeys_test.cpp +++ b/src/test/app/ValidatorKeys_test.cpp @@ -1,12 +1,12 @@ #include -#include #include #include #include #include #include +#include #include diff --git a/src/test/core/SociDB_test.cpp b/src/test/core/SociDB_test.cpp index 001022aa95..fe73d42b0a 100644 --- a/src/test/core/SociDB_test.cpp +++ b/src/test/core/SociDB_test.cpp @@ -1,9 +1,8 @@ #include -#include - #include #include +#include #include #include diff --git a/src/test/nodestore/Database_test.cpp b/src/test/nodestore/Database_test.cpp index 03f0c11990..1229923e7d 100644 --- a/src/test/nodestore/Database_test.cpp +++ b/src/test/nodestore/Database_test.cpp @@ -4,11 +4,10 @@ #include #include -#include - #include #include #include +#include namespace xrpl { diff --git a/src/test/rpc/LedgerEntry_test.cpp b/src/test/rpc/LedgerEntry_test.cpp index aa959629b1..5d12e7bb83 100644 --- a/src/test/rpc/LedgerEntry_test.cpp +++ b/src/test/rpc/LedgerEntry_test.cpp @@ -2050,7 +2050,7 @@ class LedgerEntry_test : public beast::unit_test::suite Account const bob{"bob"}; Env env{*this, envconfig([](auto cfg) { - cfg->START_UP = Config::FRESH; + cfg->START_UP = StartUpType::FRESH; return cfg; })}; @@ -2241,7 +2241,7 @@ class LedgerEntry_test : public beast::unit_test::suite Account const bob{"bob"}; Env env{*this, envconfig([](auto cfg) { - cfg->START_UP = Config::FRESH; + cfg->START_UP = StartUpType::FRESH; return cfg; })}; diff --git a/src/xrpld/app/ledger/Ledger.cpp b/src/xrpld/app/ledger/Ledger.cpp index 9ad08f9894..0f1b81d53d 100644 --- a/src/xrpld/app/ledger/Ledger.cpp +++ b/src/xrpld/app/ledger/Ledger.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/src/xrpld/app/main/Application.cpp b/src/xrpld/app/main/Application.cpp index 2c0d3c2b82..5f7a86e2c2 100644 --- a/src/xrpld/app/main/Application.cpp +++ b/src/xrpld/app/main/Application.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -26,11 +25,8 @@ #include #include #include -#include #include -#include #include -#include #include #include #include @@ -40,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +46,9 @@ #include #include #include +#include #include +#include #include #include @@ -1021,6 +1020,12 @@ private: void setMaxDisallowedLedger(); + + Application& + app() override + { + return *this; + } }; //------------------------------------------------------------------------------ @@ -1116,18 +1121,21 @@ ApplicationImp::setup(boost::program_options::variables_map const& cmdline) auto const startUp = config_->START_UP; JLOG(m_journal.debug()) << "startUp: " << startUp; - if (startUp == Config::FRESH) + if (startUp == StartUpType::FRESH) { JLOG(m_journal.info()) << "Starting new Ledger"; startGenesisLedger(); } - else if (startUp == Config::LOAD || startUp == Config::LOAD_FILE || startUp == Config::REPLAY) + else if (startUp == StartUpType::LOAD || startUp == StartUpType::LOAD_FILE || startUp == StartUpType::REPLAY) { JLOG(m_journal.info()) << "Loading specified Ledger"; if (!loadOldLedger( - config_->START_LEDGER, startUp == Config::REPLAY, startUp == Config::LOAD_FILE, config_->TRAP_TX_HASH)) + config_->START_LEDGER, + startUp == StartUpType::REPLAY, + startUp == StartUpType::LOAD_FILE, + config_->TRAP_TX_HASH)) { JLOG(m_journal.error()) << "The specified ledger could not be loaded."; if (config_->FAST_LOAD) @@ -1142,7 +1150,7 @@ ApplicationImp::setup(boost::program_options::variables_map const& cmdline) } } } - else if (startUp == Config::NETWORK) + else if (startUp == StartUpType::NETWORK) { // This should probably become the default once we have a stable // network. @@ -1529,7 +1537,7 @@ void ApplicationImp::startGenesisLedger() { std::vector const initialAmendments = - (config_->START_UP == Config::FRESH) ? m_amendmentTable->getDesired() : std::vector{}; + (config_->START_UP == StartUpType::FRESH) ? m_amendmentTable->getDesired() : std::vector{}; std::shared_ptr const genesis = std::make_shared(create_genesis, *config_, initialAmendments, nodeFamily_); diff --git a/src/xrpld/app/main/Application.h b/src/xrpld/app/main/Application.h index 53cc264ad4..5ecc84c11c 100644 --- a/src/xrpld/app/main/Application.h +++ b/src/xrpld/app/main/Application.h @@ -1,10 +1,10 @@ #pragma once #include -#include #include #include +#include #include #include #include @@ -112,8 +112,6 @@ public: public: Application(); - virtual ~Application() = default; - virtual bool setup(boost::program_options::variables_map const& options) = 0; @@ -127,8 +125,6 @@ public: checkSigs() const = 0; virtual void checkSigs(bool) = 0; - virtual bool - isStopping() const = 0; // // --- @@ -138,14 +134,9 @@ public: virtual std::uint64_t instanceID() const = 0; - virtual Logs& - logs() = 0; virtual Config& config() = 0; - virtual boost::asio::io_context& - getIOContext() = 0; - virtual std::pair const& nodeIdentity() = 0; @@ -158,9 +149,6 @@ public: virtual bool serverOkay(std::string& reason) = 0; - virtual beast::Journal - journal(std::string const& name) = 0; - /* Returns the number of file descriptors the application needs */ virtual int fdRequired() const = 0; diff --git a/src/xrpld/app/main/Main.cpp b/src/xrpld/app/main/Main.cpp index aaf7af95ab..7bdccd12a7 100644 --- a/src/xrpld/app/main/Main.cpp +++ b/src/xrpld/app/main/Main.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -8,6 +7,7 @@ #include #include #include +#include #include #include @@ -601,7 +601,7 @@ run(int argc, char** argv) if (vm.count("start")) { - config->START_UP = Config::FRESH; + config->START_UP = StartUpType::FRESH; } if (vm.count("import")) @@ -612,7 +612,7 @@ run(int argc, char** argv) config->START_LEDGER = vm["ledger"].as(); if (vm.count("replay")) { - config->START_UP = Config::REPLAY; + config->START_UP = StartUpType::REPLAY; if (vm.count("trap_tx_hash")) { uint256 tmp = {}; @@ -631,16 +631,16 @@ run(int argc, char** argv) } } else - config->START_UP = Config::LOAD; + config->START_UP = StartUpType::LOAD; } else if (vm.count("ledgerfile")) { config->START_LEDGER = vm["ledgerfile"].as(); - config->START_UP = Config::LOAD_FILE; + config->START_UP = StartUpType::LOAD_FILE; } else if (vm.count("load") || config->FAST_LOAD) { - config->START_UP = Config::LOAD; + config->START_UP = StartUpType::LOAD; } if (vm.count("trap_tx_hash") && vm.count("replay") == 0) @@ -651,13 +651,13 @@ run(int argc, char** argv) if (vm.count("net") && !config->FAST_LOAD) { - if ((config->START_UP == Config::LOAD) || (config->START_UP == Config::REPLAY)) + if ((config->START_UP == StartUpType::LOAD) || (config->START_UP == StartUpType::REPLAY)) { std::cerr << "Net and load/replay options are incompatible" << std::endl; return -1; } - config->START_UP = Config::NETWORK; + config->START_UP = StartUpType::NETWORK; } if (vm.count("valid")) diff --git a/src/xrpld/app/main/NodeIdentity.cpp b/src/xrpld/app/main/NodeIdentity.cpp index b585b80b5b..3019caeb31 100644 --- a/src/xrpld/app/main/NodeIdentity.cpp +++ b/src/xrpld/app/main/NodeIdentity.cpp @@ -1,9 +1,10 @@ #include #include -#include #include #include +#include + namespace xrpl { std::pair diff --git a/src/xrpld/app/misc/SHAMapStoreImp.cpp b/src/xrpld/app/misc/SHAMapStoreImp.cpp index dbdd682ef8..7f276ca2d8 100644 --- a/src/xrpld/app/misc/SHAMapStoreImp.cpp +++ b/src/xrpld/app/misc/SHAMapStoreImp.cpp @@ -1,13 +1,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/src/xrpld/app/misc/SHAMapStoreImp.h b/src/xrpld/app/misc/SHAMapStoreImp.h index b046a78979..df3c16b24f 100644 --- a/src/xrpld/app/misc/SHAMapStoreImp.h +++ b/src/xrpld/app/misc/SHAMapStoreImp.h @@ -2,11 +2,11 @@ #include #include -#include -#include #include #include +#include +#include #include #include diff --git a/src/xrpld/app/misc/ValidatorList.h b/src/xrpld/app/misc/ValidatorList.h index 4fd610be04..f93ac8a32f 100644 --- a/src/xrpld/app/misc/ValidatorList.h +++ b/src/xrpld/app/misc/ValidatorList.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -9,6 +8,7 @@ #include #include #include +#include #include diff --git a/src/xrpld/app/misc/detail/AmendmentTable.cpp b/src/xrpld/app/misc/detail/AmendmentTable.cpp index 2942c8bde6..3addfd2235 100644 --- a/src/xrpld/app/misc/detail/AmendmentTable.cpp +++ b/src/xrpld/app/misc/detail/AmendmentTable.cpp @@ -1,12 +1,12 @@ #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/src/xrpld/app/misc/detail/Manifest.cpp b/src/xrpld/app/misc/detail/Manifest.cpp index 952814656b..dfcbdbb3ad 100644 --- a/src/xrpld/app/misc/detail/Manifest.cpp +++ b/src/xrpld/app/misc/detail/Manifest.cpp @@ -1,13 +1,12 @@ -#include -#include -#include - #include #include #include #include #include #include +#include +#include +#include #include diff --git a/src/xrpld/app/misc/detail/ValidatorKeys.cpp b/src/xrpld/app/misc/detail/ValidatorKeys.cpp index 675ce4ac6f..8f24f14b40 100644 --- a/src/xrpld/app/misc/detail/ValidatorKeys.cpp +++ b/src/xrpld/app/misc/detail/ValidatorKeys.cpp @@ -1,10 +1,10 @@ -#include #include #include #include #include #include +#include namespace xrpl { ValidatorKeys::ValidatorKeys(Config const& config, beast::Journal j) diff --git a/src/xrpld/app/rdb/PeerFinder.h b/src/xrpld/app/rdb/PeerFinder.h index 2b4080255f..e5ac6dda8c 100644 --- a/src/xrpld/app/rdb/PeerFinder.h +++ b/src/xrpld/app/rdb/PeerFinder.h @@ -1,9 +1,10 @@ #pragma once #include -#include #include +#include + namespace xrpl { /** diff --git a/src/xrpld/app/rdb/RelationalDatabase.h b/src/xrpld/app/rdb/RelationalDatabase.h index c0cc61f757..078b8fe8db 100644 --- a/src/xrpld/app/rdb/RelationalDatabase.h +++ b/src/xrpld/app/rdb/RelationalDatabase.h @@ -1,13 +1,13 @@ #pragma once #include -#include #include #include -#include #include #include +#include +#include #include #include @@ -93,13 +93,13 @@ public: /** * @brief init Creates and returns an appropriate RelationalDatabase * instance based on configuration. - * @param app Application object. + * @param registry The service registry. * @param config Config object. * @param jobQueue JobQueue object. * @return Unique pointer to the interface. */ static std::unique_ptr - init(Application& app, Config const& config, JobQueue& jobQueue); + init(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue); virtual ~RelationalDatabase() = default; diff --git a/src/xrpld/app/rdb/backend/detail/Node.cpp b/src/xrpld/app/rdb/backend/detail/Node.cpp index 90c95f3a2d..1e814c3589 100644 --- a/src/xrpld/app/rdb/backend/detail/Node.cpp +++ b/src/xrpld/app/rdb/backend/detail/Node.cpp @@ -5,12 +5,12 @@ #include #include #include -#include -#include #include #include #include +#include +#include #include @@ -64,8 +64,8 @@ makeLedgerDBs( tx->getSession() << boost::str( boost::format("PRAGMA cache_size=-%d;") % kilobytes(config.getValueFor(SizedItem::txnDBCache))); - if (!setup.standAlone || setup.startUp == Config::LOAD || setup.startUp == Config::LOAD_FILE || - setup.startUp == Config::REPLAY) + if (!setup.standAlone || setup.startUp == StartUpType::LOAD || setup.startUp == StartUpType::LOAD_FILE || + setup.startUp == StartUpType::REPLAY) { // Check if AccountTransactions has primary key std::string cid, name, type; diff --git a/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp b/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp index d65b12dc7f..4f1430ee4c 100644 --- a/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp +++ b/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp @@ -3,21 +3,21 @@ #include #include #include -#include -#include #include +#include +#include namespace xrpl { class SQLiteDatabaseImp final : public SQLiteDatabase { public: - SQLiteDatabaseImp(Application& app, Config const& config, JobQueue& jobQueue) - : app_(app), useTxTables_(config.useTxTables()), j_(app_.journal("SQLiteDatabaseImp")) + SQLiteDatabaseImp(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) + : registry_(registry), useTxTables_(config.useTxTables()), j_(registry.journal("SQLiteDatabaseImp")) { DatabaseCon::Setup const setup = setup_DatabaseCon(config, j_); - if (!makeLedgerDBs(config, setup, DatabaseCon::CheckpointerSetup{&jobQueue, &app_.logs()})) + if (!makeLedgerDBs(config, setup, DatabaseCon::CheckpointerSetup{&jobQueue, ®istry_.logs()})) { std::string_view constexpr error = "Failed to create ledger databases"; @@ -139,7 +139,7 @@ public: closeTransactionDB() override; private: - Application& app_; + ServiceRegistry& registry_; bool const useTxTables_; beast::Journal j_; std::unique_ptr ledgerDb_, txdb_; @@ -370,7 +370,7 @@ SQLiteDatabaseImp::saveValidatedLedger(std::shared_ptr const& ledg { if (existsLedger()) { - if (!detail::saveValidatedLedger(*ledgerDb_, txdb_, app_, ledger, current)) + if (!detail::saveValidatedLedger(*ledgerDb_, txdb_, registry_.app(), ledger, current)) return false; } @@ -506,7 +506,7 @@ SQLiteDatabaseImp::getTxHistory(LedgerIndex startIndex) if (existsTransaction()) { auto db = checkoutTransaction(); - auto const res = detail::getTxHistory(*db, app_, startIndex, 20).first; + auto const res = detail::getTxHistory(*db, registry_.app(), startIndex, 20).first; if (!res.empty()) return res; @@ -521,12 +521,12 @@ SQLiteDatabaseImp::getOldestAccountTxs(AccountTxOptions const& options) if (!useTxTables_) return {}; - LedgerMaster& ledgerMaster = app_.getLedgerMaster(); + LedgerMaster& ledgerMaster = registry_.getLedgerMaster(); if (existsTransaction()) { auto db = checkoutTransaction(); - return detail::getOldestAccountTxs(*db, app_, ledgerMaster, options, j_).first; + return detail::getOldestAccountTxs(*db, registry_.app(), ledgerMaster, options, j_).first; } return {}; @@ -538,12 +538,12 @@ SQLiteDatabaseImp::getNewestAccountTxs(AccountTxOptions const& options) if (!useTxTables_) return {}; - LedgerMaster& ledgerMaster = app_.getLedgerMaster(); + LedgerMaster& ledgerMaster = registry_.getLedgerMaster(); if (existsTransaction()) { auto db = checkoutTransaction(); - return detail::getNewestAccountTxs(*db, app_, ledgerMaster, options, j_).first; + return detail::getNewestAccountTxs(*db, registry_.app(), ledgerMaster, options, j_).first; } return {}; @@ -558,7 +558,7 @@ SQLiteDatabaseImp::getOldestAccountTxsB(AccountTxOptions const& options) if (existsTransaction()) { auto db = checkoutTransaction(); - return detail::getOldestAccountTxsB(*db, app_, options, j_).first; + return detail::getOldestAccountTxsB(*db, registry_.app(), options, j_).first; } return {}; @@ -573,7 +573,7 @@ SQLiteDatabaseImp::getNewestAccountTxsB(AccountTxOptions const& options) if (existsTransaction()) { auto db = checkoutTransaction(); - return detail::getNewestAccountTxsB(*db, app_, options, j_).first; + return detail::getNewestAccountTxsB(*db, registry_.app(), options, j_).first; } return {}; @@ -586,10 +586,9 @@ SQLiteDatabaseImp::oldestAccountTxPage(AccountTxPageOptions const& options) return {}; static std::uint32_t const page_length(200); - auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1); + auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1); AccountTxs ret; - Application& app = app_; - auto onTransaction = [&ret, &app]( + auto onTransaction = [&ret, &app = registry_.app()]( std::uint32_t ledger_index, std::string const& status, Blob&& rawTxn, Blob&& rawMeta) { convertBlobsToTxResult(ret, ledger_index, status, rawTxn, rawMeta, app); }; @@ -611,10 +610,9 @@ SQLiteDatabaseImp::newestAccountTxPage(AccountTxPageOptions const& options) return {}; static std::uint32_t const page_length(200); - auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1); + auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1); AccountTxs ret; - Application& app = app_; - auto onTransaction = [&ret, &app]( + auto onTransaction = [&ret, &app = registry_.app()]( std::uint32_t ledger_index, std::string const& status, Blob&& rawTxn, Blob&& rawMeta) { convertBlobsToTxResult(ret, ledger_index, status, rawTxn, rawMeta, app); }; @@ -636,7 +634,7 @@ SQLiteDatabaseImp::oldestAccountTxPageB(AccountTxPageOptions const& options) return {}; static std::uint32_t const page_length(500); - auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1); + auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1); MetaTxsList ret; auto onTransaction = [&ret](std::uint32_t ledgerIndex, std::string const& status, Blob&& rawTxn, Blob&& rawMeta) { ret.emplace_back(std::move(rawTxn), std::move(rawMeta), ledgerIndex); @@ -659,7 +657,7 @@ SQLiteDatabaseImp::newestAccountTxPageB(AccountTxPageOptions const& options) return {}; static std::uint32_t const page_length(500); - auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1); + auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1); MetaTxsList ret; auto onTransaction = [&ret](std::uint32_t ledgerIndex, std::string const& status, Blob&& rawTxn, Blob&& rawMeta) { ret.emplace_back(std::move(rawTxn), std::move(rawMeta), ledgerIndex); @@ -687,7 +685,7 @@ SQLiteDatabaseImp::getTransaction( if (existsTransaction()) { auto db = checkoutTransaction(); - return detail::getTransaction(*db, app_, id, range, ec); + return detail::getTransaction(*db, registry_.app(), id, range, ec); } return TxSearched::unknown; @@ -769,9 +767,9 @@ SQLiteDatabaseImp::closeTransactionDB() } std::unique_ptr -getSQLiteDatabase(Application& app, Config const& config, JobQueue& jobQueue) +getSQLiteDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) { - return std::make_unique(app, config, jobQueue); + return std::make_unique(registry, config, jobQueue); } } // namespace xrpl diff --git a/src/xrpld/app/rdb/detail/RelationalDatabase.cpp b/src/xrpld/app/rdb/detail/RelationalDatabase.cpp index 2ceb15d1e7..bc65a817a4 100644 --- a/src/xrpld/app/rdb/detail/RelationalDatabase.cpp +++ b/src/xrpld/app/rdb/detail/RelationalDatabase.cpp @@ -1,14 +1,13 @@ -#include #include #include namespace xrpl { extern std::unique_ptr -getSQLiteDatabase(Application& app, Config const& config, JobQueue& jobQueue); +getSQLiteDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue); std::unique_ptr -RelationalDatabase::init(Application& app, Config const& config, JobQueue& jobQueue) +RelationalDatabase::init(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) { bool use_sqlite = false; @@ -31,7 +30,7 @@ RelationalDatabase::init(Application& app, Config const& config, JobQueue& jobQu if (use_sqlite) { - return getSQLiteDatabase(app, config, jobQueue); + return getSQLiteDatabase(registry, config, jobQueue); } return std::unique_ptr(); diff --git a/src/xrpld/core/Config.h b/src/xrpld/core/Config.h index 86b663a212..c40d13c83a 100644 --- a/src/xrpld/core/Config.h +++ b/src/xrpld/core/Config.h @@ -4,7 +4,9 @@ #include #include #include +#include #include // VFALCO Breaks levelization +#include #include // VFALCO FIX: This include should not be here @@ -124,8 +126,7 @@ public: // Entries from [ips_fixed] config stanza std::vector IPS_FIXED; - enum StartUpType { FRESH, NORMAL, LOAD, LOAD_FILE, REPLAY, NETWORK }; - StartUpType START_UP = NORMAL; + StartUpType START_UP = StartUpType::NORMAL; bool START_VALID = false; @@ -355,4 +356,7 @@ public: FeeSetup setup_FeeVote(Section const& section); +DatabaseCon::Setup +setup_DatabaseCon(Config const& c, std::optional j = std::nullopt); + } // namespace xrpl diff --git a/src/xrpld/core/detail/Config.cpp b/src/xrpld/core/detail/Config.cpp index 0a60416af7..4a2bae7c27 100644 --- a/src/xrpld/core/detail/Config.cpp +++ b/src/xrpld/core/detail/Config.cpp @@ -1039,4 +1039,150 @@ setup_FeeVote(Section const& section) return setup; } +DatabaseCon::Setup +setup_DatabaseCon(Config const& c, std::optional j) +{ + DatabaseCon::Setup setup; + + setup.startUp = c.START_UP; + setup.standAlone = c.standalone(); + setup.dataDir = c.legacy("database_path"); + if (!setup.standAlone && setup.dataDir.empty()) + { + Throw("database_path must be set."); + } + + if (!setup.globalPragma) + { + auto const& sqlite = c.section("sqlite"); + auto result = std::make_unique>(); + result->reserve(3); + + // defaults + std::string safety_level; + std::string journal_mode = "wal"; + std::string synchronous = "normal"; + std::string temp_store = "file"; + bool showRiskWarning = false; + + if (set(safety_level, "safety_level", sqlite)) + { + if (boost::iequals(safety_level, "low")) + { + // low safety defaults + journal_mode = "memory"; + synchronous = "off"; + temp_store = "memory"; + showRiskWarning = true; + } + else if (!boost::iequals(safety_level, "high")) + { + Throw("Invalid safety_level value: " + safety_level); + } + } + + { + // #journal_mode Valid values : delete, truncate, persist, + // memory, wal, off + if (set(journal_mode, "journal_mode", sqlite) && !safety_level.empty()) + { + Throw( + "Configuration file may not define both " + "\"safety_level\" and \"journal_mode\""); + } + bool higherRisk = boost::iequals(journal_mode, "memory") || boost::iequals(journal_mode, "off"); + showRiskWarning = showRiskWarning || higherRisk; + if (higherRisk || boost::iequals(journal_mode, "delete") || boost::iequals(journal_mode, "truncate") || + boost::iequals(journal_mode, "persist") || boost::iequals(journal_mode, "wal")) + { + result->emplace_back(boost::str(boost::format(CommonDBPragmaJournal) % journal_mode)); + } + else + { + Throw("Invalid journal_mode value: " + journal_mode); + } + } + + { + // #synchronous Valid values : off, normal, full, extra + if (set(synchronous, "synchronous", sqlite) && !safety_level.empty()) + { + Throw( + "Configuration file may not define both " + "\"safety_level\" and \"synchronous\""); + } + bool higherRisk = boost::iequals(synchronous, "off"); + showRiskWarning = showRiskWarning || higherRisk; + if (higherRisk || boost::iequals(synchronous, "normal") || boost::iequals(synchronous, "full") || + boost::iequals(synchronous, "extra")) + { + result->emplace_back(boost::str(boost::format(CommonDBPragmaSync) % synchronous)); + } + else + { + Throw("Invalid synchronous value: " + synchronous); + } + } + + { + // #temp_store Valid values : default, file, memory + if (set(temp_store, "temp_store", sqlite) && !safety_level.empty()) + { + Throw( + "Configuration file may not define both " + "\"safety_level\" and \"temp_store\""); + } + bool higherRisk = boost::iequals(temp_store, "memory"); + showRiskWarning = showRiskWarning || higherRisk; + if (higherRisk || boost::iequals(temp_store, "default") || boost::iequals(temp_store, "file")) + { + result->emplace_back(boost::str(boost::format(CommonDBPragmaTemp) % temp_store)); + } + else + { + Throw("Invalid temp_store value: " + temp_store); + } + } + + if (showRiskWarning && j && c.LEDGER_HISTORY > SQLITE_TUNING_CUTOFF) + { + JLOG(j->warn()) << "reducing the data integrity guarantees from the " + "default [sqlite] behavior is not recommended for " + "nodes storing large amounts of history, because of the " + "difficulty inherent in rebuilding corrupted data."; + } + XRPL_ASSERT(result->size() == 3, "xrpl::setup_DatabaseCon::globalPragma : result size is 3"); + setup.globalPragma = std::move(result); + } + setup.useGlobalPragma = true; + + auto setPragma = [](std::string& pragma, std::string const& key, int64_t value) { + pragma = "PRAGMA " + key + "=" + std::to_string(value) + ";"; + }; + + // Lgr Pragma + setPragma(setup.lgrPragma[0], "journal_size_limit", 1582080); + + // TX Pragma + int64_t page_size = 4096; + int64_t journal_size_limit = 1582080; + if (c.exists("sqlite")) + { + auto& s = c.section("sqlite"); + set(journal_size_limit, "journal_size_limit", s); + set(page_size, "page_size", s); + if (page_size < 512 || page_size > 65536) + Throw("Invalid page_size. Must be between 512 and 65536."); + + if (page_size & (page_size - 1)) + Throw("Invalid page_size. Must be a power of 2."); + } + + setPragma(setup.txPragma[0], "page_size", page_size); + setPragma(setup.txPragma[1], "journal_size_limit", journal_size_limit); + setPragma(setup.txPragma[2], "max_page_count", 4294967294); + setPragma(setup.txPragma[3], "mmap_size", 17179869184); + + return setup; +} } // namespace xrpl diff --git a/src/xrpld/core/detail/DatabaseCon.cpp b/src/xrpld/core/detail/DatabaseCon.cpp deleted file mode 100644 index 64f87f7a39..0000000000 --- a/src/xrpld/core/detail/DatabaseCon.cpp +++ /dev/null @@ -1,242 +0,0 @@ -#include -#include - -#include -#include - -#include -#include - -#include -#include - -namespace xrpl { - -class CheckpointersCollection -{ - std::uintptr_t nextId_{0}; - // Mutex protects the CheckpointersCollection - std::mutex mutex_; - // Each checkpointer is given a unique id. All the checkpointers that are - // part of a DatabaseCon are part of this collection. When the DatabaseCon - // is destroyed, its checkpointer is removed from the collection - std::unordered_map> checkpointers_; - -public: - std::shared_ptr - fromId(std::uintptr_t id) - { - std::lock_guard l{mutex_}; - auto it = checkpointers_.find(id); - if (it != checkpointers_.end()) - return it->second; - return {}; - } - - void - erase(std::uintptr_t id) - { - std::lock_guard lock{mutex_}; - checkpointers_.erase(id); - } - - std::shared_ptr - create(std::shared_ptr const& session, JobQueue& jobQueue, Logs& logs) - { - std::lock_guard lock{mutex_}; - auto const id = nextId_++; - auto const r = makeCheckpointer(id, session, jobQueue, logs); - checkpointers_[id] = r; - return r; - } -}; - -CheckpointersCollection checkpointers; - -std::shared_ptr -checkpointerFromId(std::uintptr_t id) -{ - return checkpointers.fromId(id); -} - -DatabaseCon::~DatabaseCon() -{ - if (checkpointer_) - { - checkpointers.erase(checkpointer_->id()); - - std::weak_ptr wk(checkpointer_); - checkpointer_.reset(); - - // The references to our Checkpointer held by 'checkpointer_' and - // 'checkpointers' have been removed, so if the use count is nonzero, a - // checkpoint is currently in progress. Wait for it to end, otherwise - // creating a new DatabaseCon to the same database may fail due to the - // database being locked by our (now old) Checkpointer. - while (wk.use_count()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - } -} - -DatabaseCon::Setup -setup_DatabaseCon(Config const& c, std::optional j) -{ - DatabaseCon::Setup setup; - - setup.startUp = c.START_UP; - setup.standAlone = c.standalone(); - setup.dataDir = c.legacy("database_path"); - if (!setup.standAlone && setup.dataDir.empty()) - { - Throw("database_path must be set."); - } - - if (!setup.globalPragma) - { - setup.globalPragma = [&c, &j]() { - auto const& sqlite = c.section("sqlite"); - auto result = std::make_unique>(); - result->reserve(3); - - // defaults - std::string safety_level; - std::string journal_mode = "wal"; - std::string synchronous = "normal"; - std::string temp_store = "file"; - bool showRiskWarning = false; - - if (set(safety_level, "safety_level", sqlite)) - { - if (boost::iequals(safety_level, "low")) - { - // low safety defaults - journal_mode = "memory"; - synchronous = "off"; - temp_store = "memory"; - showRiskWarning = true; - } - else if (!boost::iequals(safety_level, "high")) - { - Throw("Invalid safety_level value: " + safety_level); - } - } - - { - // #journal_mode Valid values : delete, truncate, persist, - // memory, wal, off - if (set(journal_mode, "journal_mode", sqlite) && !safety_level.empty()) - { - Throw( - "Configuration file may not define both " - "\"safety_level\" and \"journal_mode\""); - } - bool higherRisk = boost::iequals(journal_mode, "memory") || boost::iequals(journal_mode, "off"); - showRiskWarning = showRiskWarning || higherRisk; - if (higherRisk || boost::iequals(journal_mode, "delete") || boost::iequals(journal_mode, "truncate") || - boost::iequals(journal_mode, "persist") || boost::iequals(journal_mode, "wal")) - { - result->emplace_back(boost::str(boost::format(CommonDBPragmaJournal) % journal_mode)); - } - else - { - Throw("Invalid journal_mode value: " + journal_mode); - } - } - - { - // #synchronous Valid values : off, normal, full, extra - if (set(synchronous, "synchronous", sqlite) && !safety_level.empty()) - { - Throw( - "Configuration file may not define both " - "\"safety_level\" and \"synchronous\""); - } - bool higherRisk = boost::iequals(synchronous, "off"); - showRiskWarning = showRiskWarning || higherRisk; - if (higherRisk || boost::iequals(synchronous, "normal") || boost::iequals(synchronous, "full") || - boost::iequals(synchronous, "extra")) - { - result->emplace_back(boost::str(boost::format(CommonDBPragmaSync) % synchronous)); - } - else - { - Throw("Invalid synchronous value: " + synchronous); - } - } - - { - // #temp_store Valid values : default, file, memory - if (set(temp_store, "temp_store", sqlite) && !safety_level.empty()) - { - Throw( - "Configuration file may not define both " - "\"safety_level\" and \"temp_store\""); - } - bool higherRisk = boost::iequals(temp_store, "memory"); - showRiskWarning = showRiskWarning || higherRisk; - if (higherRisk || boost::iequals(temp_store, "default") || boost::iequals(temp_store, "file")) - { - result->emplace_back(boost::str(boost::format(CommonDBPragmaTemp) % temp_store)); - } - else - { - Throw("Invalid temp_store value: " + temp_store); - } - } - - if (showRiskWarning && j && c.LEDGER_HISTORY > SQLITE_TUNING_CUTOFF) - { - JLOG(j->warn()) << "reducing the data integrity guarantees from the " - "default [sqlite] behavior is not recommended for " - "nodes storing large amounts of history, because of the " - "difficulty inherent in rebuilding corrupted data."; - } - XRPL_ASSERT(result->size() == 3, "xrpl::setup_DatabaseCon::globalPragma : result size is 3"); - return result; - }(); - } - setup.useGlobalPragma = true; - - auto setPragma = [](std::string& pragma, std::string const& key, int64_t value) { - pragma = "PRAGMA " + key + "=" + std::to_string(value) + ";"; - }; - - // Lgr Pragma - setPragma(setup.lgrPragma[0], "journal_size_limit", 1582080); - - // TX Pragma - int64_t page_size = 4096; - int64_t journal_size_limit = 1582080; - if (c.exists("sqlite")) - { - auto& s = c.section("sqlite"); - set(journal_size_limit, "journal_size_limit", s); - set(page_size, "page_size", s); - if (page_size < 512 || page_size > 65536) - Throw("Invalid page_size. Must be between 512 and 65536."); - - if (page_size & (page_size - 1)) - Throw("Invalid page_size. Must be a power of 2."); - } - - setPragma(setup.txPragma[0], "page_size", page_size); - setPragma(setup.txPragma[1], "journal_size_limit", journal_size_limit); - setPragma(setup.txPragma[2], "max_page_count", 4294967294); - setPragma(setup.txPragma[3], "mmap_size", 17179869184); - - return setup; -} - -std::unique_ptr const> DatabaseCon::Setup::globalPragma; - -void -DatabaseCon::setupCheckpointing(JobQueue* q, Logs& l) -{ - if (!q) - Throw("No JobQueue"); - checkpointer_ = checkpointers.create(session_, *q, l); -} - -} // namespace xrpl diff --git a/src/xrpld/overlay/detail/OverlayImpl.cpp b/src/xrpld/overlay/detail/OverlayImpl.cpp index 350631b8e6..6ac6e454d2 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.cpp +++ b/src/xrpld/overlay/detail/OverlayImpl.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -20,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/src/xrpld/overlay/detail/PeerReservationTable.cpp b/src/xrpld/overlay/detail/PeerReservationTable.cpp index 1e3452ca17..27d9df1129 100644 --- a/src/xrpld/overlay/detail/PeerReservationTable.cpp +++ b/src/xrpld/overlay/detail/PeerReservationTable.cpp @@ -1,10 +1,10 @@ #include -#include -#include +#include #include #include #include +#include #include #include diff --git a/src/xrpld/peerfinder/detail/StoreSqdb.h b/src/xrpld/peerfinder/detail/StoreSqdb.h index f5461d489a..b945ae970b 100644 --- a/src/xrpld/peerfinder/detail/StoreSqdb.h +++ b/src/xrpld/peerfinder/detail/StoreSqdb.h @@ -1,9 +1,10 @@ #pragma once #include -#include #include +#include + namespace xrpl { namespace PeerFinder { diff --git a/src/xrpld/rpc/InfoSub.h b/src/xrpld/rpc/InfoSub.h index 7d4d4f06c8..d49e401bd3 100644 --- a/src/xrpld/rpc/InfoSub.h +++ b/src/xrpld/rpc/InfoSub.h @@ -1,12 +1,11 @@ #pragma once -#include - #include #include #include #include #include +#include namespace xrpl { From 9f17d103480182c785ee4f76458728cb987f1178 Mon Sep 17 00:00:00 2001 From: Jingchen Date: Wed, 11 Feb 2026 16:22:01 +0000 Subject: [PATCH 2/3] refactor: Modularize RelationalDB (#6224) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rdb module was not properly designed, which is fixed in this change. The module had three classes: 1) The abstract class `RelationalDB`. 2) The abstract class `SQLiteDatabase`, which inherited from `RelationalDB` and added some pure virtual methods. 3) The concrete class `SQLiteDatabaseImp`, which inherited from `SQLiteDatabase` and implemented all methods. The updated code simplifies this as follows: * The `SQLiteDatabaseImp` has become `SQLiteDatabase`, and * The former `SQLiteDatabase `has merged with `RelationalDatabase`. --- .../scripts/levelization/results/ordering.txt | 3 + include/xrpl/protocol/LedgerShortcut.h | 22 + include/xrpl/protocol/TxSearched.h | 7 + include/xrpl/rdb/RelationalDatabase.h | 475 ++++++++++++++++++ src/test/app/SHAMapStore_test.cpp | 8 +- src/test/rpc/Transaction_test.cpp | 6 +- src/xrpld/app/ledger/Ledger.cpp | 8 +- src/xrpld/app/ledger/detail/LedgerMaster.cpp | 2 +- src/xrpld/app/main/Application.cpp | 13 +- src/xrpld/app/misc/SHAMapStoreImp.cpp | 17 +- src/xrpld/app/misc/Transaction.h | 3 +- src/xrpld/app/misc/detail/AccountTxPaging.h | 2 +- src/xrpld/app/misc/detail/Transaction.cpp | 11 +- src/xrpld/app/rdb/RelationalDatabase.h | 226 --------- src/xrpld/app/rdb/backend/SQLiteDatabase.h | 298 +++++++++-- src/xrpld/app/rdb/backend/detail/Node.cpp | 2 +- src/xrpld/app/rdb/backend/detail/Node.h | 3 +- .../app/rdb/backend/detail/SQLiteDatabase.cpp | 296 +++-------- .../app/rdb/detail/RelationalDatabase.cpp | 39 -- src/xrpld/overlay/detail/OverlayImpl.cpp | 2 +- .../overlay/detail/PeerReservationTable.cpp | 3 +- src/xrpld/rpc/detail/RPCHelpers.cpp | 2 +- src/xrpld/rpc/detail/RPCLedgerHelpers.h | 3 +- src/xrpld/rpc/handlers/AccountTx.cpp | 16 +- src/xrpld/rpc/handlers/GetCounts.cpp | 11 +- src/xrpld/rpc/handlers/Tx.cpp | 3 +- src/xrpld/rpc/handlers/TxHistory.cpp | 2 +- 27 files changed, 862 insertions(+), 621 deletions(-) create mode 100644 include/xrpl/protocol/LedgerShortcut.h create mode 100644 include/xrpl/protocol/TxSearched.h create mode 100644 include/xrpl/rdb/RelationalDatabase.h delete mode 100644 src/xrpld/app/rdb/RelationalDatabase.h diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index fabc7b49ca..85f2457ea3 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -171,6 +171,7 @@ xrpl.protocol > xrpl.basics xrpl.protocol > xrpl.json xrpl.rdb > xrpl.basics xrpl.rdb > xrpl.core +xrpl.rdb > xrpl.protocol xrpl.resource > xrpl.basics xrpl.resource > xrpl.json xrpl.resource > xrpl.protocol @@ -214,6 +215,7 @@ xrpld.overlay > xrpld.core xrpld.overlay > xrpld.peerfinder xrpld.overlay > xrpl.json xrpld.overlay > xrpl.protocol +xrpld.overlay > xrpl.rdb xrpld.overlay > xrpl.resource xrpld.overlay > xrpl.server xrpld.peerfinder > xrpl.basics @@ -232,6 +234,7 @@ xrpld.rpc > xrpl.ledger xrpld.rpc > xrpl.net xrpld.rpc > xrpl.nodestore xrpld.rpc > xrpl.protocol +xrpld.rpc > xrpl.rdb xrpld.rpc > xrpl.resource xrpld.rpc > xrpl.server xrpld.shamap > xrpl.shamap diff --git a/include/xrpl/protocol/LedgerShortcut.h b/include/xrpl/protocol/LedgerShortcut.h new file mode 100644 index 0000000000..68c31c4c3c --- /dev/null +++ b/include/xrpl/protocol/LedgerShortcut.h @@ -0,0 +1,22 @@ +#pragma once + +namespace xrpl { + +/** + * @brief Enumeration of ledger shortcuts for specifying which ledger to use. + * + * These shortcuts provide a convenient way to reference commonly used ledgers + * without needing to specify their exact hash or sequence number. + */ +enum class LedgerShortcut { + /** The current working ledger (open, not yet closed) */ + Current, + + /** The most recently closed ledger (may not be validated) */ + Closed, + + /** The most recently validated ledger */ + Validated +}; + +} // namespace xrpl diff --git a/include/xrpl/protocol/TxSearched.h b/include/xrpl/protocol/TxSearched.h new file mode 100644 index 0000000000..e085bff315 --- /dev/null +++ b/include/xrpl/protocol/TxSearched.h @@ -0,0 +1,7 @@ +#pragma once + +namespace xrpl { + +enum class TxSearched { all, some, unknown }; + +} diff --git a/include/xrpl/rdb/RelationalDatabase.h b/include/xrpl/rdb/RelationalDatabase.h new file mode 100644 index 0000000000..b80c6c8331 --- /dev/null +++ b/include/xrpl/rdb/RelationalDatabase.h @@ -0,0 +1,475 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl { + +class Transaction; +class Ledger; + +struct LedgerHashPair +{ + uint256 ledgerHash; + uint256 parentHash; +}; + +struct LedgerRange +{ + uint32_t min; + uint32_t max; +}; + +class RelationalDatabase +{ +public: + struct CountMinMax + { + std::size_t numberOfRows; + LedgerIndex minLedgerSequence; + LedgerIndex maxLedgerSequence; + }; + + struct AccountTxMarker + { + std::uint32_t ledgerSeq = 0; + std::uint32_t txnSeq = 0; + }; + + struct AccountTxOptions + { + AccountID const& account; + std::uint32_t minLedger; + std::uint32_t maxLedger; + std::uint32_t offset; + std::uint32_t limit; + bool bUnlimited; + }; + + struct AccountTxPageOptions + { + AccountID const& account; + std::uint32_t minLedger; + std::uint32_t maxLedger; + std::optional marker; + std::uint32_t limit; + bool bAdmin; + }; + + using AccountTx = std::pair, std::shared_ptr>; + using AccountTxs = std::vector; + using txnMetaLedgerType = std::tuple; + using MetaTxsList = std::vector; + + using LedgerSequence = uint32_t; + using LedgerHash = uint256; + using LedgerSpecifier = std::variant; + + struct AccountTxArgs + { + AccountID account; + std::optional ledger; + bool binary = false; + bool forward = false; + uint32_t limit = 0; + std::optional marker; + }; + + struct AccountTxResult + { + std::variant transactions; + LedgerRange ledgerRange; + uint32_t limit; + std::optional marker; + }; + + virtual ~RelationalDatabase() = default; + + /** + * @brief getMinLedgerSeq Returns the minimum ledger sequence in the Ledgers + * table. + * @return Ledger sequence or no value if no ledgers exist. + */ + virtual std::optional + getMinLedgerSeq() = 0; + + /** + * @brief getMaxLedgerSeq Returns the maximum ledger sequence in the Ledgers + * table. + * @return Ledger sequence or none if no ledgers exist. + */ + virtual std::optional + getMaxLedgerSeq() = 0; + + /** + * @brief getLedgerInfoByIndex Returns a ledger by its sequence. + * @param ledgerSeq Ledger sequence. + * @return The ledger if found, otherwise no value. + */ + virtual std::optional + getLedgerInfoByIndex(LedgerIndex ledgerSeq) = 0; + + /** + * @brief getNewestLedgerInfo Returns the info of the newest saved ledger. + * @return Ledger info if found, otherwise no value. + */ + virtual std::optional + getNewestLedgerInfo() = 0; + + /** + * @brief getLedgerInfoByHash Returns the info of the ledger with given + * hash. + * @param ledgerHash Hash of the ledger. + * @return Ledger if found, otherwise no value. + */ + virtual std::optional + getLedgerInfoByHash(uint256 const& ledgerHash) = 0; + + /** + * @brief getHashByIndex Returns the hash of the ledger with the given + * sequence. + * @param ledgerIndex Ledger sequence. + * @return Hash of the ledger. + */ + virtual uint256 + getHashByIndex(LedgerIndex ledgerIndex) = 0; + + /** + * @brief getHashesByIndex Returns the hashes of the ledger and its parent + * as specified by the ledgerIndex. + * @param ledgerIndex Ledger sequence. + * @return Struct LedgerHashPair which contains hashes of the ledger and + * its parent. + */ + virtual std::optional + getHashesByIndex(LedgerIndex ledgerIndex) = 0; + + /** + * @brief getHashesByIndex Returns hashes of each ledger and its parent for + * all ledgers within the provided range. + * @param minSeq Minimum ledger sequence. + * @param maxSeq Maximum ledger sequence. + * @return Container that maps the sequence number of a found ledger to the + * struct LedgerHashPair which contains the hashes of the ledger and + * its parent. + */ + virtual std::map + getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) = 0; + + /** + * @brief getTxHistory Returns the 20 most recent transactions starting from + * the given number. + * @param startIndex First number of returned entry. + * @return Vector of shared pointers to transactions sorted in + * descending order by ledger sequence. + */ + virtual std::vector> + getTxHistory(LedgerIndex startIndex) = 0; + + /** + * @brief getTransactionsMinLedgerSeq Returns the minimum ledger sequence + * stored in the Transactions table. + * @return Ledger sequence or no value if no ledgers exist. + */ + virtual std::optional + getTransactionsMinLedgerSeq() = 0; + + /** + * @brief getAccountTransactionsMinLedgerSeq Returns the minimum ledger + * sequence stored in the AccountTransactions table. + * @return Ledger sequence or no value if no ledgers exist. + */ + virtual std::optional + getAccountTransactionsMinLedgerSeq() = 0; + + /** + * @brief deleteTransactionByLedgerSeq Deletes transactions from the ledger + * with the given sequence. + * @param ledgerSeq Ledger sequence. + */ + virtual void + deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) = 0; + + /** + * @brief deleteBeforeLedgerSeq Deletes all ledgers with a sequence number + * less than or equal to the given ledger sequence. + * @param ledgerSeq Ledger sequence. + */ + virtual void + deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0; + + /** + * @brief deleteTransactionsBeforeLedgerSeq Deletes all transactions with + * a sequence number less than or equal to the given ledger + * sequence. + * @param ledgerSeq Ledger sequence. + */ + virtual void + deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0; + + /** + * @brief deleteAccountTransactionsBeforeLedgerSeq Deletes all account + * transactions with a sequence number less than or equal to the + * given ledger sequence. + * @param ledgerSeq Ledger sequence. + */ + virtual void + deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0; + + /** + * @brief getTransactionCount Returns the number of transactions. + * @return Number of transactions. + */ + virtual std::size_t + getTransactionCount() = 0; + + /** + * @brief getAccountTransactionCount Returns the number of account + * transactions. + * @return Number of account transactions. + */ + virtual std::size_t + getAccountTransactionCount() = 0; + + /** + * @brief getLedgerCountMinMax Returns the minimum ledger sequence, + * maximum ledger sequence and total number of saved ledgers. + * @return Struct CountMinMax which contains the minimum sequence, + * maximum sequence and number of ledgers. + */ + virtual struct CountMinMax + getLedgerCountMinMax() = 0; + + /** + * @brief saveValidatedLedger Saves a ledger into the database. + * @param ledger The ledger. + * @param current True if the ledger is current. + * @return True if saving was successful. + */ + virtual bool + saveValidatedLedger(std::shared_ptr const& ledger, bool current) = 0; + + /** + * @brief getLimitedOldestLedgerInfo Returns the info of the oldest ledger + * whose sequence number is greater than or equal to the given + * sequence number. + * @param ledgerFirstIndex Minimum ledger sequence. + * @return Ledger info if found, otherwise no value. + */ + virtual std::optional + getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) = 0; + + /** + * @brief getLimitedNewestLedgerInfo Returns the info of the newest ledger + * whose sequence number is greater than or equal to the given + * sequence number. + * @param ledgerFirstIndex Minimum ledger sequence. + * @return Ledger info if found, otherwise no value. + */ + virtual std::optional + getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) = 0; + + /** + * @brief getOldestAccountTxs Returns the oldest transactions for the + * account that matches the given criteria starting from the provided + * offset. + * @param options Struct AccountTxOptions which contains the criteria to + * match: the account, ledger search range, the offset of the first + * entry to return, the number of transactions to return, a flag if + * this number is unlimited. + * @return Vector of pairs of found transactions and their metadata + * sorted in ascending order by account sequence. + */ + virtual AccountTxs + getOldestAccountTxs(AccountTxOptions const& options) = 0; + + /** + * @brief getNewestAccountTxs Returns the newest transactions for the + * account that matches the given criteria starting from the provided + * offset. + * @param options Struct AccountTxOptions which contains the criteria to + * match: the account, the ledger search range, the offset of the + * first entry to return, the number of transactions to return, a + * flag if this number unlimited. + * @return Vector of pairs of found transactions and their metadata + * sorted in descending order by account sequence. + */ + virtual AccountTxs + getNewestAccountTxs(AccountTxOptions const& options) = 0; + + /** + * @brief getOldestAccountTxsB Returns the oldest transactions in binary + * form for the account that matches the given criteria starting from + * the provided offset. + * @param options Struct AccountTxOptions which contains the criteria to + * match: the account, the ledger search range, the offset of the + * first entry to return, the number of transactions to return, a + * flag if this number unlimited. + * @return Vector of tuples of found transactions, their metadata and + * account sequences sorted in ascending order by account sequence. + */ + virtual MetaTxsList + getOldestAccountTxsB(AccountTxOptions const& options) = 0; + + /** + * @brief getNewestAccountTxsB Returns the newest transactions in binary + * form for the account that matches the given criteria starting from + * the provided offset. + * @param options Struct AccountTxOptions which contains the criteria to + * match: the account, the ledger search range, the offset of the + * first entry to return, the number of transactions to return, a + * flag if this number is unlimited. + * @return Vector of tuples of found transactions, their metadata and + * account sequences sorted in descending order by account + * sequence. + */ + virtual MetaTxsList + getNewestAccountTxsB(AccountTxOptions const& options) = 0; + + /** + * @brief oldestAccountTxPage Returns the oldest transactions for the + * account that matches the given criteria starting from the + * provided marker. + * @param options Struct AccountTxPageOptions which contains the criteria to + * match: the account, the ledger search range, the marker of first + * returned entry, the number of transactions to return, a flag if + * this number is unlimited. + * @return Vector of pairs of found transactions and their metadata + * sorted in ascending order by account sequence and a marker + * for the next search if the search was not finished. + */ + virtual std::pair> + oldestAccountTxPage(AccountTxPageOptions const& options) = 0; + + /** + * @brief newestAccountTxPage Returns the newest transactions for the + * account that matches the given criteria starting from the provided + * marker. + * @param options Struct AccountTxPageOptions which contains the criteria to + * match: the account, the ledger search range, the marker of the + * first returned entry, the number of transactions to return, a flag + * if this number unlimited. + * @return Vector of pairs of found transactions and their metadata + * sorted in descending order by account sequence and a marker + * for the next search if the search was not finished. + */ + virtual std::pair> + newestAccountTxPage(AccountTxPageOptions const& options) = 0; + + /** + * @brief oldestAccountTxPageB Returns the oldest transactions in binary + * form for the account that matches the given criteria starting from + * the provided marker. + * @param options Struct AccountTxPageOptions which contains criteria to + * match: the account, the ledger search range, the marker of the + * first returned entry, the number of transactions to return, a flag + * if this number unlimited. + * @return Vector of tuples of found transactions, their metadata and + * account sequences sorted in ascending order by account + * sequence and a marker for the next search if the search was not + * finished. + */ + virtual std::pair> + oldestAccountTxPageB(AccountTxPageOptions const& options) = 0; + + /** + * @brief newestAccountTxPageB Returns the newest transactions in binary + * form for the account that matches the given criteria starting from + * the provided marker. + * @param options Struct AccountTxPageOptions which contains the criteria to + * match: the account, the ledger search range, the marker of the + * first returned entry, the number of transactions to return, a flag + * if this number is unlimited. + * @return Vector of tuples of found transactions, their metadata and + * account sequences sorted in descending order by account + * sequence and a marker for the next search if the search was not + * finished. + */ + virtual std::pair> + newestAccountTxPageB(AccountTxPageOptions const& options) = 0; + + /** + * @brief getTransaction Returns the transaction with the given hash. If a + * range is provided but the transaction is not found, then check if + * all ledgers in the range are present in the database. + * @param id Hash of the transaction. + * @param range Range of ledgers to check, if present. + * @param ec Default error code value. + * @return Transaction and its metadata if found, otherwise TxSearched::all + * if a range is provided and all ledgers from the range are present + * in the database, TxSearched::some if a range is provided and not + * all ledgers are present, TxSearched::unknown if the range is not + * provided or a deserializing error occurred. In the last case the + * error code is returned via the ec parameter, in other cases the + * default error code is not changed. + */ + virtual std::variant + getTransaction(uint256 const& id, std::optional> const& range, error_code_i& ec) = 0; + + /** + * @brief getKBUsedAll Returns the amount of space used by all databases. + * @return Space in kilobytes. + */ + virtual uint32_t + getKBUsedAll() = 0; + + /** + * @brief getKBUsedLedger Returns the amount of space space used by the + * ledger database. + * @return Space in kilobytes. + */ + virtual uint32_t + getKBUsedLedger() = 0; + + /** + * @brief getKBUsedTransaction Returns the amount of space used by the + * transaction database. + * @return Space in kilobytes. + */ + virtual uint32_t + getKBUsedTransaction() = 0; + + /** + * @brief Closes the ledger database + */ + virtual void + closeLedgerDB() = 0; + + /** + * @brief Closes the transaction database + */ + virtual void + closeTransactionDB() = 0; +}; + +template +T +rangeCheckedCast(C c) +{ + if ((c > std::numeric_limits::max()) || (!std::numeric_limits::is_signed && c < 0) || + (std::numeric_limits::is_signed && std::numeric_limits::is_signed && + c < std::numeric_limits::lowest())) + { + // This should never happen + // LCOV_EXCL_START + UNREACHABLE("xrpl::rangeCheckedCast : domain error"); + JLOG(debugLog().error()) << "rangeCheckedCast domain error:" + << " value = " << c << " min = " << std::numeric_limits::lowest() + << " max: " << std::numeric_limits::max(); + // LCOV_EXCL_STOP + } + + return static_cast(c); +} + +} // namespace xrpl diff --git a/src/test/app/SHAMapStore_test.cpp b/src/test/app/SHAMapStore_test.cpp index c671d6fc27..9e0a971685 100644 --- a/src/test/app/SHAMapStore_test.cpp +++ b/src/test/app/SHAMapStore_test.cpp @@ -91,8 +91,7 @@ class SHAMapStore_test : public beast::unit_test::suite void ledgerCheck(jtx::Env& env, int const rows, int const first) { - auto const [actualRows, actualFirst, actualLast] = - dynamic_cast(&env.app().getRelationalDatabase())->getLedgerCountMinMax(); + auto const [actualRows, actualFirst, actualLast] = env.app().getRelationalDatabase().getLedgerCountMinMax(); BEAST_EXPECT(actualRows == rows); BEAST_EXPECT(actualFirst == first); @@ -102,14 +101,13 @@ class SHAMapStore_test : public beast::unit_test::suite void transactionCheck(jtx::Env& env, int const rows) { - BEAST_EXPECT(dynamic_cast(&env.app().getRelationalDatabase())->getTransactionCount() == rows); + BEAST_EXPECT(env.app().getRelationalDatabase().getTransactionCount() == rows); } void accountTransactionCheck(jtx::Env& env, int const rows) { - BEAST_EXPECT( - dynamic_cast(&env.app().getRelationalDatabase())->getAccountTransactionCount() == rows); + BEAST_EXPECT(env.app().getRelationalDatabase().getAccountTransactionCount() == rows); } int diff --git a/src/test/rpc/Transaction_test.cpp b/src/test/rpc/Transaction_test.cpp index 3b289d73ca..acc8bccf61 100644 --- a/src/test/rpc/Transaction_test.cpp +++ b/src/test/rpc/Transaction_test.cpp @@ -108,8 +108,7 @@ class Transaction_test : public beast::unit_test::suite auto const deletedLedger = (startLegSeq + endLegSeq) / 2; { // Remove one of the ledgers from the database directly - dynamic_cast(&env.app().getRelationalDatabase()) - ->deleteTransactionByLedgerSeq(deletedLedger); + env.app().getRelationalDatabase().deleteTransactionByLedgerSeq(deletedLedger); } for (int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq) @@ -320,8 +319,7 @@ class Transaction_test : public beast::unit_test::suite auto const deletedLedger = (startLegSeq + endLegSeq) / 2; { // Remove one of the ledgers from the database directly - dynamic_cast(&env.app().getRelationalDatabase()) - ->deleteTransactionByLedgerSeq(deletedLedger); + env.app().getRelationalDatabase().deleteTransactionByLedgerSeq(deletedLedger); } for (int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq) diff --git a/src/xrpld/app/ledger/Ledger.cpp b/src/xrpld/app/ledger/Ledger.cpp index 0f1b81d53d..0f44601679 100644 --- a/src/xrpld/app/ledger/Ledger.cpp +++ b/src/xrpld/app/ledger/Ledger.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -22,6 +21,7 @@ #include #include #include +#include #include #include @@ -904,11 +904,9 @@ saveValidatedLedger(Application& app, std::shared_ptr const& ledge return true; } - auto const db = dynamic_cast(&app.getRelationalDatabase()); - if (!db) - Throw("Failed to get relational database"); + auto& db = app.getRelationalDatabase(); - auto const res = db->saveValidatedLedger(ledger, current); + auto const res = db.saveValidatedLedger(ledger, current); // Clients can now trust the database for // information about this ledger sequence. diff --git a/src/xrpld/app/ledger/detail/LedgerMaster.cpp b/src/xrpld/app/ledger/detail/LedgerMaster.cpp index c4299c1b63..1fd1a8a8b2 100644 --- a/src/xrpld/app/ledger/detail/LedgerMaster.cpp +++ b/src/xrpld/app/ledger/detail/LedgerMaster.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/src/xrpld/app/main/Application.cpp b/src/xrpld/app/main/Application.cpp index 5f7a86e2c2..7a59d586e0 100644 --- a/src/xrpld/app/main/Application.cpp +++ b/src/xrpld/app/main/Application.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -191,7 +191,7 @@ public: boost::asio::steady_timer sweepTimer_; boost::asio::steady_timer entropyTimer_; - std::unique_ptr mRelationalDatabase; + std::optional relationalDatabase_; std::unique_ptr mWalletDB; std::unique_ptr overlay_; std::optional trapTxID_; @@ -730,10 +730,10 @@ public: getRelationalDatabase() override { XRPL_ASSERT( - mRelationalDatabase, + relationalDatabase_, "xrpl::ApplicationImp::getRelationalDatabase : non-null " "relational database"); - return *mRelationalDatabase; + return *relationalDatabase_; } DatabaseCon& @@ -761,7 +761,7 @@ public: try { - mRelationalDatabase = RelationalDatabase::init(*this, *config_, *m_jobQueue); + relationalDatabase_.emplace(setup_RelationalDatabase(*this, *config_, *m_jobQueue)); // wallet database auto setup = setup_DatabaseCon(*config_, m_journal); @@ -872,7 +872,8 @@ public: void doSweep() { - if (!config_->standalone() && !getRelationalDatabase().transactionDbHasSpace(*config_)) + XRPL_ASSERT(relationalDatabase_, "xrpl::ApplicationImp::doSweep : non-null relational database"); + if (!config_->standalone() && !relationalDatabase_->transactionDbHasSpace(*config_)) { signalStop("Out of transaction DB space"); } diff --git a/src/xrpld/app/misc/SHAMapStoreImp.cpp b/src/xrpld/app/misc/SHAMapStoreImp.cpp index 7f276ca2d8..c963d18d2c 100644 --- a/src/xrpld/app/misc/SHAMapStoreImp.cpp +++ b/src/xrpld/app/misc/SHAMapStoreImp.cpp @@ -507,16 +507,13 @@ SHAMapStoreImp::clearPrior(LedgerIndex lastRotated) if (healthWait() == stopping) return; - SQLiteDatabase* const db = dynamic_cast(&app_.getRelationalDatabase()); - - if (!db) - Throw("Failed to get relational database"); + auto& db = app_.getRelationalDatabase(); clearSql( lastRotated, "Ledgers", - [db]() -> std::optional { return db->getMinLedgerSeq(); }, - [db](LedgerIndex min) -> void { db->deleteBeforeLedgerSeq(min); }); + [&db]() -> std::optional { return db.getMinLedgerSeq(); }, + [&db](LedgerIndex min) -> void { db.deleteBeforeLedgerSeq(min); }); if (healthWait() == stopping) return; @@ -526,16 +523,16 @@ SHAMapStoreImp::clearPrior(LedgerIndex lastRotated) clearSql( lastRotated, "Transactions", - [&db]() -> std::optional { return db->getTransactionsMinLedgerSeq(); }, - [&db](LedgerIndex min) -> void { db->deleteTransactionsBeforeLedgerSeq(min); }); + [&db]() -> std::optional { return db.getTransactionsMinLedgerSeq(); }, + [&db](LedgerIndex min) -> void { db.deleteTransactionsBeforeLedgerSeq(min); }); if (healthWait() == stopping) return; clearSql( lastRotated, "AccountTransactions", - [&db]() -> std::optional { return db->getAccountTransactionsMinLedgerSeq(); }, - [&db](LedgerIndex min) -> void { db->deleteAccountTransactionsBeforeLedgerSeq(min); }); + [&db]() -> std::optional { return db.getAccountTransactionsMinLedgerSeq(); }, + [&db](LedgerIndex min) -> void { db.deleteAccountTransactionsBeforeLedgerSeq(min); }); if (healthWait() == stopping) return; } diff --git a/src/xrpld/app/misc/Transaction.h b/src/xrpld/app/misc/Transaction.h index 22f3e9d1fd..0a51e1c021 100644 --- a/src/xrpld/app/misc/Transaction.h +++ b/src/xrpld/app/misc/Transaction.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -35,8 +36,6 @@ enum TransStatus { INCOMPLETE = 8 // needs more signatures }; -enum class TxSearched { all, some, unknown }; - // This class is for constructing and examining transactions. // Transactions are static so manipulation functions are unnecessary. class Transaction : public std::enable_shared_from_this, public CountedObject diff --git a/src/xrpld/app/misc/detail/AccountTxPaging.h b/src/xrpld/app/misc/detail/AccountTxPaging.h index 6dff5c481b..209ca67ab6 100644 --- a/src/xrpld/app/misc/detail/AccountTxPaging.h +++ b/src/xrpld/app/misc/detail/AccountTxPaging.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/src/xrpld/app/misc/detail/Transaction.cpp b/src/xrpld/app/misc/detail/Transaction.cpp index 61a2a36695..8ffbc47b08 100644 --- a/src/xrpld/app/misc/detail/Transaction.cpp +++ b/src/xrpld/app/misc/detail/Transaction.cpp @@ -2,13 +2,13 @@ #include #include #include -#include #include #include #include #include #include +#include namespace xrpl { @@ -113,14 +113,9 @@ Transaction::load( std::optional> const& range, error_code_i& ec) { - auto const db = dynamic_cast(&app.getRelationalDatabase()); + auto& db = app.getRelationalDatabase(); - if (!db) - { - Throw("Failed to get relational database"); - } - - return db->getTransaction(id, range, ec); + return db.getTransaction(id, range, ec); } // options 1 to include the date of the transaction diff --git a/src/xrpld/app/rdb/RelationalDatabase.h b/src/xrpld/app/rdb/RelationalDatabase.h deleted file mode 100644 index 078b8fe8db..0000000000 --- a/src/xrpld/app/rdb/RelationalDatabase.h +++ /dev/null @@ -1,226 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -namespace xrpl { - -struct LedgerHashPair -{ - uint256 ledgerHash; - uint256 parentHash; -}; - -struct LedgerRange -{ - uint32_t min; - uint32_t max; -}; - -class RelationalDatabase -{ -public: - struct CountMinMax - { - std::size_t numberOfRows; - LedgerIndex minLedgerSequence; - LedgerIndex maxLedgerSequence; - }; - - struct AccountTxMarker - { - std::uint32_t ledgerSeq = 0; - std::uint32_t txnSeq = 0; - }; - - struct AccountTxOptions - { - AccountID const& account; - std::uint32_t minLedger; - std::uint32_t maxLedger; - std::uint32_t offset; - std::uint32_t limit; - bool bUnlimited; - }; - - struct AccountTxPageOptions - { - AccountID const& account; - std::uint32_t minLedger; - std::uint32_t maxLedger; - std::optional marker; - std::uint32_t limit; - bool bAdmin; - }; - - using AccountTx = std::pair, std::shared_ptr>; - using AccountTxs = std::vector; - using txnMetaLedgerType = std::tuple; - using MetaTxsList = std::vector; - - using LedgerSequence = uint32_t; - using LedgerHash = uint256; - using LedgerShortcut = RPC::LedgerShortcut; - using LedgerSpecifier = std::variant; - - struct AccountTxArgs - { - AccountID account; - std::optional ledger; - bool binary = false; - bool forward = false; - uint32_t limit = 0; - std::optional marker; - }; - - struct AccountTxResult - { - std::variant transactions; - LedgerRange ledgerRange; - uint32_t limit; - std::optional marker; - }; - - /** - * @brief init Creates and returns an appropriate RelationalDatabase - * instance based on configuration. - * @param registry The service registry. - * @param config Config object. - * @param jobQueue JobQueue object. - * @return Unique pointer to the interface. - */ - static std::unique_ptr - init(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue); - - virtual ~RelationalDatabase() = default; - - /** - * @brief getMinLedgerSeq Returns the minimum ledger sequence in the Ledgers - * table. - * @return Ledger sequence or no value if no ledgers exist. - */ - virtual std::optional - getMinLedgerSeq() = 0; - - /** - * @brief getMaxLedgerSeq Returns the maximum ledger sequence in the Ledgers - * table. - * @return Ledger sequence or none if no ledgers exist. - */ - virtual std::optional - getMaxLedgerSeq() = 0; - - /** - * @brief getLedgerInfoByIndex Returns a ledger by its sequence. - * @param ledgerSeq Ledger sequence. - * @return The ledger if found, otherwise no value. - */ - virtual std::optional - getLedgerInfoByIndex(LedgerIndex ledgerSeq) = 0; - - /** - * @brief getNewestLedgerInfo Returns the info of the newest saved ledger. - * @return Ledger info if found, otherwise no value. - */ - virtual std::optional - getNewestLedgerInfo() = 0; - - /** - * @brief getLedgerInfoByHash Returns the info of the ledger with given - * hash. - * @param ledgerHash Hash of the ledger. - * @return Ledger if found, otherwise no value. - */ - virtual std::optional - getLedgerInfoByHash(uint256 const& ledgerHash) = 0; - - /** - * @brief getHashByIndex Returns the hash of the ledger with the given - * sequence. - * @param ledgerIndex Ledger sequence. - * @return Hash of the ledger. - */ - virtual uint256 - getHashByIndex(LedgerIndex ledgerIndex) = 0; - - /** - * @brief getHashesByIndex Returns the hashes of the ledger and its parent - * as specified by the ledgerIndex. - * @param ledgerIndex Ledger sequence. - * @return Struct LedgerHashPair which contains hashes of the ledger and - * its parent. - */ - virtual std::optional - getHashesByIndex(LedgerIndex ledgerIndex) = 0; - - /** - * @brief getHashesByIndex Returns hashes of each ledger and its parent for - * all ledgers within the provided range. - * @param minSeq Minimum ledger sequence. - * @param maxSeq Maximum ledger sequence. - * @return Container that maps the sequence number of a found ledger to the - * struct LedgerHashPair which contains the hashes of the ledger and - * its parent. - */ - virtual std::map - getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) = 0; - - /** - * @brief getTxHistory Returns the 20 most recent transactions starting from - * the given number. - * @param startIndex First number of returned entry. - * @return Vector of shared pointers to transactions sorted in - * descending order by ledger sequence. - */ - virtual std::vector> - getTxHistory(LedgerIndex startIndex) = 0; - - /** - * @brief ledgerDbHasSpace Checks if the ledger database has available - * space. - * @param config Config object. - * @return True if space is available. - */ - virtual bool - ledgerDbHasSpace(Config const& config) = 0; - - /** - * @brief transactionDbHasSpace Checks if the transaction database has - * available space. - * @param config Config object. - * @return True if space is available. - */ - virtual bool - transactionDbHasSpace(Config const& config) = 0; -}; - -template -T -rangeCheckedCast(C c) -{ - if ((c > std::numeric_limits::max()) || (!std::numeric_limits::is_signed && c < 0) || - (std::numeric_limits::is_signed && std::numeric_limits::is_signed && - c < std::numeric_limits::lowest())) - { - // This should never happen - // LCOV_EXCL_START - UNREACHABLE("xrpl::rangeCheckedCast : domain error"); - JLOG(debugLog().error()) << "rangeCheckedCast domain error:" - << " value = " << c << " min = " << std::numeric_limits::lowest() - << " max: " << std::numeric_limits::max(); - // LCOV_EXCL_STOP - } - - return static_cast(c); -} - -} // namespace xrpl diff --git a/src/xrpld/app/rdb/backend/SQLiteDatabase.h b/src/xrpld/app/rdb/backend/SQLiteDatabase.h index b6dcb2534b..b79b66787e 100644 --- a/src/xrpld/app/rdb/backend/SQLiteDatabase.h +++ b/src/xrpld/app/rdb/backend/SQLiteDatabase.h @@ -1,43 +1,130 @@ #pragma once -#include +#include + +#include namespace xrpl { -class SQLiteDatabase : public RelationalDatabase +class Config; +class JobQueue; +class ServiceRegistry; + +class SQLiteDatabase final : public RelationalDatabase { public: + /** + * @brief getMinLedgerSeq Returns the minimum ledger sequence in the Ledgers + * table. + * @return Ledger sequence or no value if no ledgers exist. + */ + std::optional + getMinLedgerSeq() override; + + /** + * @brief getMaxLedgerSeq Returns the maximum ledger sequence in the Ledgers + * table. + * @return Ledger sequence or none if no ledgers exist. + */ + std::optional + getMaxLedgerSeq() override; + + /** + * @brief getLedgerInfoByIndex Returns a ledger by its sequence. + * @param ledgerSeq Ledger sequence. + * @return The ledger if found, otherwise no value. + */ + std::optional + getLedgerInfoByIndex(LedgerIndex ledgerSeq) override; + + /** + * @brief getNewestLedgerInfo Returns the info of the newest saved ledger. + * @return Ledger info if found, otherwise no value. + */ + std::optional + getNewestLedgerInfo() override; + + /** + * @brief getLedgerInfoByHash Returns the info of the ledger with given + * hash. + * @param ledgerHash Hash of the ledger. + * @return Ledger if found, otherwise no value. + */ + std::optional + getLedgerInfoByHash(uint256 const& ledgerHash) override; + + /** + * @brief getHashByIndex Returns the hash of the ledger with the given + * sequence. + * @param ledgerIndex Ledger sequence. + * @return Hash of the ledger. + */ + uint256 + getHashByIndex(LedgerIndex ledgerIndex) override; + + /** + * @brief getHashesByIndex Returns the hashes of the ledger and its parent + * as specified by the ledgerIndex. + * @param ledgerIndex Ledger sequence. + * @return Struct LedgerHashPair which contains hashes of the ledger and + * its parent. + */ + std::optional + getHashesByIndex(LedgerIndex ledgerIndex) override; + + /** + * @brief getHashesByIndex Returns hashes of each ledger and its parent for + * all ledgers within the provided range. + * @param minSeq Minimum ledger sequence. + * @param maxSeq Maximum ledger sequence. + * @return Container that maps the sequence number of a found ledger to the + * struct LedgerHashPair which contains the hashes of the ledger and + * its parent. + */ + std::map + getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) override; + + /** + * @brief getTxHistory Returns the 20 most recent transactions starting from + * the given number. + * @param startIndex First number of returned entry. + * @return Vector of shared pointers to transactions sorted in + * descending order by ledger sequence. + */ + std::vector> + getTxHistory(LedgerIndex startIndex) override; + /** * @brief getTransactionsMinLedgerSeq Returns the minimum ledger sequence * stored in the Transactions table. * @return Ledger sequence or no value if no ledgers exist. */ - virtual std::optional - getTransactionsMinLedgerSeq() = 0; + std::optional + getTransactionsMinLedgerSeq() override; /** * @brief getAccountTransactionsMinLedgerSeq Returns the minimum ledger * sequence stored in the AccountTransactions table. * @return Ledger sequence or no value if no ledgers exist. */ - virtual std::optional - getAccountTransactionsMinLedgerSeq() = 0; + std::optional + getAccountTransactionsMinLedgerSeq() override; /** * @brief deleteTransactionByLedgerSeq Deletes transactions from the ledger * with the given sequence. * @param ledgerSeq Ledger sequence. */ - virtual void - deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) = 0; + void + deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) override; /** * @brief deleteBeforeLedgerSeq Deletes all ledgers with a sequence number * less than or equal to the given ledger sequence. * @param ledgerSeq Ledger sequence. */ - virtual void - deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0; + void + deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) override; /** * @brief deleteTransactionsBeforeLedgerSeq Deletes all transactions with @@ -45,8 +132,8 @@ public: * sequence. * @param ledgerSeq Ledger sequence. */ - virtual void - deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0; + void + deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override; /** * @brief deleteAccountTransactionsBeforeLedgerSeq Deletes all account @@ -54,23 +141,23 @@ public: * given ledger sequence. * @param ledgerSeq Ledger sequence. */ - virtual void - deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0; + void + deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override; /** * @brief getTransactionCount Returns the number of transactions. * @return Number of transactions. */ - virtual std::size_t - getTransactionCount() = 0; + std::size_t + getTransactionCount() override; /** * @brief getAccountTransactionCount Returns the number of account * transactions. * @return Number of account transactions. */ - virtual std::size_t - getAccountTransactionCount() = 0; + std::size_t + getAccountTransactionCount() override; /** * @brief getLedgerCountMinMax Returns the minimum ledger sequence, @@ -78,8 +165,8 @@ public: * @return Struct CountMinMax which contains the minimum sequence, * maximum sequence and number of ledgers. */ - virtual struct CountMinMax - getLedgerCountMinMax() = 0; + CountMinMax + getLedgerCountMinMax() override; /** * @brief saveValidatedLedger Saves a ledger into the database. @@ -87,8 +174,8 @@ public: * @param current True if the ledger is current. * @return True if saving was successful. */ - virtual bool - saveValidatedLedger(std::shared_ptr const& ledger, bool current) = 0; + bool + saveValidatedLedger(std::shared_ptr const& ledger, bool current) override; /** * @brief getLimitedOldestLedgerInfo Returns the info of the oldest ledger @@ -97,8 +184,8 @@ public: * @param ledgerFirstIndex Minimum ledger sequence. * @return Ledger info if found, otherwise no value. */ - virtual std::optional - getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) = 0; + std::optional + getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) override; /** * @brief getLimitedNewestLedgerInfo Returns the info of the newest ledger @@ -107,8 +194,8 @@ public: * @param ledgerFirstIndex Minimum ledger sequence. * @return Ledger info if found, otherwise no value. */ - virtual std::optional - getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) = 0; + std::optional + getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) override; /** * @brief getOldestAccountTxs Returns the oldest transactions for the @@ -121,8 +208,8 @@ public: * @return Vector of pairs of found transactions and their metadata * sorted in ascending order by account sequence. */ - virtual AccountTxs - getOldestAccountTxs(AccountTxOptions const& options) = 0; + AccountTxs + getOldestAccountTxs(AccountTxOptions const& options) override; /** * @brief getNewestAccountTxs Returns the newest transactions for the @@ -135,8 +222,8 @@ public: * @return Vector of pairs of found transactions and their metadata * sorted in descending order by account sequence. */ - virtual AccountTxs - getNewestAccountTxs(AccountTxOptions const& options) = 0; + AccountTxs + getNewestAccountTxs(AccountTxOptions const& options) override; /** * @brief getOldestAccountTxsB Returns the oldest transactions in binary @@ -149,8 +236,8 @@ public: * @return Vector of tuples of found transactions, their metadata and * account sequences sorted in ascending order by account sequence. */ - virtual MetaTxsList - getOldestAccountTxsB(AccountTxOptions const& options) = 0; + MetaTxsList + getOldestAccountTxsB(AccountTxOptions const& options) override; /** * @brief getNewestAccountTxsB Returns the newest transactions in binary @@ -164,8 +251,8 @@ public: * account sequences sorted in descending order by account * sequence. */ - virtual MetaTxsList - getNewestAccountTxsB(AccountTxOptions const& options) = 0; + MetaTxsList + getNewestAccountTxsB(AccountTxOptions const& options) override; /** * @brief oldestAccountTxPage Returns the oldest transactions for the @@ -179,8 +266,8 @@ public: * sorted in ascending order by account sequence and a marker * for the next search if the search was not finished. */ - virtual std::pair> - oldestAccountTxPage(AccountTxPageOptions const& options) = 0; + std::pair> + oldestAccountTxPage(AccountTxPageOptions const& options) override; /** * @brief newestAccountTxPage Returns the newest transactions for the @@ -194,8 +281,8 @@ public: * sorted in descending order by account sequence and a marker * for the next search if the search was not finished. */ - virtual std::pair> - newestAccountTxPage(AccountTxPageOptions const& options) = 0; + std::pair> + newestAccountTxPage(AccountTxPageOptions const& options) override; /** * @brief oldestAccountTxPageB Returns the oldest transactions in binary @@ -210,8 +297,8 @@ public: * sequence and a marker for the next search if the search was not * finished. */ - virtual std::pair> - oldestAccountTxPageB(AccountTxPageOptions const& options) = 0; + std::pair> + oldestAccountTxPageB(AccountTxPageOptions const& options) override; /** * @brief newestAccountTxPageB Returns the newest transactions in binary @@ -226,8 +313,8 @@ public: * sequence and a marker for the next search if the search was not * finished. */ - virtual std::pair> - newestAccountTxPageB(AccountTxPageOptions const& options) = 0; + std::pair> + newestAccountTxPageB(AccountTxPageOptions const& options) override; /** * @brief getTransaction Returns the transaction with the given hash. If a @@ -244,43 +331,146 @@ public: * error code is returned via the ec parameter, in other cases the * default error code is not changed. */ - virtual std::variant - getTransaction(uint256 const& id, std::optional> const& range, error_code_i& ec) = 0; + std::variant + getTransaction(uint256 const& id, std::optional> const& range, error_code_i& ec) + override; /** * @brief getKBUsedAll Returns the amount of space used by all databases. * @return Space in kilobytes. */ - virtual uint32_t - getKBUsedAll() = 0; + std::uint32_t + getKBUsedAll() override; /** * @brief getKBUsedLedger Returns the amount of space space used by the * ledger database. * @return Space in kilobytes. */ - virtual uint32_t - getKBUsedLedger() = 0; + std::uint32_t + getKBUsedLedger() override; /** * @brief getKBUsedTransaction Returns the amount of space used by the * transaction database. * @return Space in kilobytes. */ - virtual uint32_t - getKBUsedTransaction() = 0; + std::uint32_t + getKBUsedTransaction() override; /** * @brief Closes the ledger database */ - virtual void - closeLedgerDB() = 0; + void + closeLedgerDB() override; /** * @brief Closes the transaction database */ - virtual void - closeTransactionDB() = 0; + void + closeTransactionDB() override; + + SQLiteDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue); + + SQLiteDatabase(SQLiteDatabase const&) = delete; + SQLiteDatabase(SQLiteDatabase&& rhs) noexcept; + + SQLiteDatabase& + operator=(SQLiteDatabase const&) = delete; + SQLiteDatabase& + operator=(SQLiteDatabase&& rhs) = delete; + + /** + * @brief ledgerDbHasSpace Checks if the ledger database has available + * space. + * @param config Config object. + * @return True if space is available. + */ + bool + ledgerDbHasSpace(Config const& config); + + /** + * @brief transactionDbHasSpace Checks if the transaction database has + * available space. + * @param config Config object. + * @return True if space is available. + */ + bool + transactionDbHasSpace(Config const& config); + +private: + ServiceRegistry& registry_; + bool const useTxTables_; + beast::Journal j_; + std::unique_ptr ledgerDb_, txdb_; + + /** + * @brief makeLedgerDBs Opens ledger and transaction databases for the node + * store, and stores their descriptors in private member variables. + * @param config Config object. + * @param setup Path to the databases and other opening parameters. + * @param checkpointerSetup Checkpointer parameters. + * @return True if node databases opened successfully. + */ + bool + makeLedgerDBs( + Config const& config, + DatabaseCon::Setup const& setup, + DatabaseCon::CheckpointerSetup const& checkpointerSetup); + + /** + * @brief existsLedger Checks if the node store ledger database exists. + * @return True if the node store ledger database exists. + */ + bool + existsLedger() + { + return static_cast(ledgerDb_); + } + + /** + * @brief existsTransaction Checks if the node store transaction database + * exists. + * @return True if the node store transaction database exists. + */ + bool + existsTransaction() + { + return static_cast(txdb_); + } + + /** + * @brief checkoutTransaction Checks out and returns node store ledger + * database. + * @return Session to the node store ledger database. + */ + auto + checkoutLedger() + { + return ledgerDb_->checkoutDb(); + } + + /** + * @brief checkoutTransaction Checks out and returns the node store + * transaction database. + * @return Session to the node store transaction database. + */ + auto + checkoutTransaction() + { + return txdb_->checkoutDb(); + } }; +/** + * @brief setup_RelationalDatabase Creates and returns a SQLiteDatabase + * instance based on configuration. + * @param registry The service registry. + * @param config Config object. + * @param jobQueue JobQueue object. + * @return SQLiteDatabase instance. + */ +SQLiteDatabase +setup_RelationalDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue); + } // namespace xrpl diff --git a/src/xrpld/app/rdb/backend/detail/Node.cpp b/src/xrpld/app/rdb/backend/detail/Node.cpp index 1e814c3589..328d07c0ab 100644 --- a/src/xrpld/app/rdb/backend/detail/Node.cpp +++ b/src/xrpld/app/rdb/backend/detail/Node.cpp @@ -3,13 +3,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/src/xrpld/app/rdb/backend/detail/Node.h b/src/xrpld/app/rdb/backend/detail/Node.h index 69c4894bbc..cb49a373bd 100644 --- a/src/xrpld/app/rdb/backend/detail/Node.h +++ b/src/xrpld/app/rdb/backend/detail/Node.h @@ -1,9 +1,10 @@ #pragma once #include -#include #include +#include + namespace xrpl { namespace detail { diff --git a/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp b/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp index 4f1430ee4c..6c3e76a86f 100644 --- a/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp +++ b/src/xrpld/app/rdb/backend/detail/SQLiteDatabase.cpp @@ -10,200 +10,8 @@ namespace xrpl { -class SQLiteDatabaseImp final : public SQLiteDatabase -{ -public: - SQLiteDatabaseImp(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) - : registry_(registry), useTxTables_(config.useTxTables()), j_(registry.journal("SQLiteDatabaseImp")) - { - DatabaseCon::Setup const setup = setup_DatabaseCon(config, j_); - if (!makeLedgerDBs(config, setup, DatabaseCon::CheckpointerSetup{&jobQueue, ®istry_.logs()})) - { - std::string_view constexpr error = "Failed to create ledger databases"; - - JLOG(j_.fatal()) << error; - Throw(error.data()); - } - } - - std::optional - getMinLedgerSeq() override; - - std::optional - getTransactionsMinLedgerSeq() override; - - std::optional - getAccountTransactionsMinLedgerSeq() override; - - std::optional - getMaxLedgerSeq() override; - - void - deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) override; - - void - deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) override; - - void - deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override; - - void - deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override; - - std::size_t - getTransactionCount() override; - - std::size_t - getAccountTransactionCount() override; - - RelationalDatabase::CountMinMax - getLedgerCountMinMax() override; - - bool - saveValidatedLedger(std::shared_ptr const& ledger, bool current) override; - - std::optional - getLedgerInfoByIndex(LedgerIndex ledgerSeq) override; - - std::optional - getNewestLedgerInfo() override; - - std::optional - getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) override; - - std::optional - getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) override; - - std::optional - getLedgerInfoByHash(uint256 const& ledgerHash) override; - - uint256 - getHashByIndex(LedgerIndex ledgerIndex) override; - - std::optional - getHashesByIndex(LedgerIndex ledgerIndex) override; - - std::map - getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) override; - - std::vector> - getTxHistory(LedgerIndex startIndex) override; - - AccountTxs - getOldestAccountTxs(AccountTxOptions const& options) override; - - AccountTxs - getNewestAccountTxs(AccountTxOptions const& options) override; - - MetaTxsList - getOldestAccountTxsB(AccountTxOptions const& options) override; - - MetaTxsList - getNewestAccountTxsB(AccountTxOptions const& options) override; - - std::pair> - oldestAccountTxPage(AccountTxPageOptions const& options) override; - - std::pair> - newestAccountTxPage(AccountTxPageOptions const& options) override; - - std::pair> - oldestAccountTxPageB(AccountTxPageOptions const& options) override; - - std::pair> - newestAccountTxPageB(AccountTxPageOptions const& options) override; - - std::variant - getTransaction(uint256 const& id, std::optional> const& range, error_code_i& ec) - override; - - bool - ledgerDbHasSpace(Config const& config) override; - - bool - transactionDbHasSpace(Config const& config) override; - - std::uint32_t - getKBUsedAll() override; - - std::uint32_t - getKBUsedLedger() override; - - std::uint32_t - getKBUsedTransaction() override; - - void - closeLedgerDB() override; - - void - closeTransactionDB() override; - -private: - ServiceRegistry& registry_; - bool const useTxTables_; - beast::Journal j_; - std::unique_ptr ledgerDb_, txdb_; - - /** - * @brief makeLedgerDBs Opens ledger and transaction databases for the node - * store, and stores their descriptors in private member variables. - * @param config Config object. - * @param setup Path to the databases and other opening parameters. - * @param checkpointerSetup Checkpointer parameters. - * @return True if node databases opened successfully. - */ - bool - makeLedgerDBs( - Config const& config, - DatabaseCon::Setup const& setup, - DatabaseCon::CheckpointerSetup const& checkpointerSetup); - - /** - * @brief existsLedger Checks if the node store ledger database exists. - * @return True if the node store ledger database exists. - */ - bool - existsLedger() - { - return static_cast(ledgerDb_); - } - - /** - * @brief existsTransaction Checks if the node store transaction database - * exists. - * @return True if the node store transaction database exists. - */ - bool - existsTransaction() - { - return static_cast(txdb_); - } - - /** - * @brief checkoutTransaction Checks out and returns node store ledger - * database. - * @return Session to the node store ledger database. - */ - auto - checkoutLedger() - { - return ledgerDb_->checkoutDb(); - } - - /** - * @brief checkoutTransaction Checks out and returns the node store - * transaction database. - * @return Session to the node store transaction database. - */ - auto - checkoutTransaction() - { - return txdb_->checkoutDb(); - } -}; - bool -SQLiteDatabaseImp::makeLedgerDBs( +SQLiteDatabase::makeLedgerDBs( Config const& config, DatabaseCon::Setup const& setup, DatabaseCon::CheckpointerSetup const& checkpointerSetup) @@ -215,7 +23,7 @@ SQLiteDatabaseImp::makeLedgerDBs( } std::optional -SQLiteDatabaseImp::getMinLedgerSeq() +SQLiteDatabase::getMinLedgerSeq() { /* if databases exists, use it */ if (existsLedger()) @@ -229,7 +37,7 @@ SQLiteDatabaseImp::getMinLedgerSeq() } std::optional -SQLiteDatabaseImp::getTransactionsMinLedgerSeq() +SQLiteDatabase::getTransactionsMinLedgerSeq() { if (!useTxTables_) return {}; @@ -244,7 +52,7 @@ SQLiteDatabaseImp::getTransactionsMinLedgerSeq() } std::optional -SQLiteDatabaseImp::getAccountTransactionsMinLedgerSeq() +SQLiteDatabase::getAccountTransactionsMinLedgerSeq() { if (!useTxTables_) return {}; @@ -259,7 +67,7 @@ SQLiteDatabaseImp::getAccountTransactionsMinLedgerSeq() } std::optional -SQLiteDatabaseImp::getMaxLedgerSeq() +SQLiteDatabase::getMaxLedgerSeq() { if (existsLedger()) { @@ -271,7 +79,7 @@ SQLiteDatabaseImp::getMaxLedgerSeq() } void -SQLiteDatabaseImp::deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) +SQLiteDatabase::deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) { if (!useTxTables_) return; @@ -285,7 +93,7 @@ SQLiteDatabaseImp::deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) } void -SQLiteDatabaseImp::deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) +SQLiteDatabase::deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) { if (existsLedger()) { @@ -296,7 +104,7 @@ SQLiteDatabaseImp::deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) } void -SQLiteDatabaseImp::deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) +SQLiteDatabase::deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) { if (!useTxTables_) return; @@ -310,7 +118,7 @@ SQLiteDatabaseImp::deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) } void -SQLiteDatabaseImp::deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) +SQLiteDatabase::deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) { if (!useTxTables_) return; @@ -324,7 +132,7 @@ SQLiteDatabaseImp::deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSe } std::size_t -SQLiteDatabaseImp::getTransactionCount() +SQLiteDatabase::getTransactionCount() { if (!useTxTables_) return 0; @@ -339,7 +147,7 @@ SQLiteDatabaseImp::getTransactionCount() } std::size_t -SQLiteDatabaseImp::getAccountTransactionCount() +SQLiteDatabase::getAccountTransactionCount() { if (!useTxTables_) return 0; @@ -354,7 +162,7 @@ SQLiteDatabaseImp::getAccountTransactionCount() } RelationalDatabase::CountMinMax -SQLiteDatabaseImp::getLedgerCountMinMax() +SQLiteDatabase::getLedgerCountMinMax() { if (existsLedger()) { @@ -366,7 +174,7 @@ SQLiteDatabaseImp::getLedgerCountMinMax() } bool -SQLiteDatabaseImp::saveValidatedLedger(std::shared_ptr const& ledger, bool current) +SQLiteDatabase::saveValidatedLedger(std::shared_ptr const& ledger, bool current) { if (existsLedger()) { @@ -378,7 +186,7 @@ SQLiteDatabaseImp::saveValidatedLedger(std::shared_ptr const& ledg } std::optional -SQLiteDatabaseImp::getLedgerInfoByIndex(LedgerIndex ledgerSeq) +SQLiteDatabase::getLedgerInfoByIndex(LedgerIndex ledgerSeq) { if (existsLedger()) { @@ -393,7 +201,7 @@ SQLiteDatabaseImp::getLedgerInfoByIndex(LedgerIndex ledgerSeq) } std::optional -SQLiteDatabaseImp::getNewestLedgerInfo() +SQLiteDatabase::getNewestLedgerInfo() { if (existsLedger()) { @@ -408,7 +216,7 @@ SQLiteDatabaseImp::getNewestLedgerInfo() } std::optional -SQLiteDatabaseImp::getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) +SQLiteDatabase::getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) { if (existsLedger()) { @@ -423,7 +231,7 @@ SQLiteDatabaseImp::getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) } std::optional -SQLiteDatabaseImp::getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) +SQLiteDatabase::getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) { if (existsLedger()) { @@ -438,7 +246,7 @@ SQLiteDatabaseImp::getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) } std::optional -SQLiteDatabaseImp::getLedgerInfoByHash(uint256 const& ledgerHash) +SQLiteDatabase::getLedgerInfoByHash(uint256 const& ledgerHash) { if (existsLedger()) { @@ -453,7 +261,7 @@ SQLiteDatabaseImp::getLedgerInfoByHash(uint256 const& ledgerHash) } uint256 -SQLiteDatabaseImp::getHashByIndex(LedgerIndex ledgerIndex) +SQLiteDatabase::getHashByIndex(LedgerIndex ledgerIndex) { if (existsLedger()) { @@ -468,7 +276,7 @@ SQLiteDatabaseImp::getHashByIndex(LedgerIndex ledgerIndex) } std::optional -SQLiteDatabaseImp::getHashesByIndex(LedgerIndex ledgerIndex) +SQLiteDatabase::getHashesByIndex(LedgerIndex ledgerIndex) { if (existsLedger()) { @@ -483,7 +291,7 @@ SQLiteDatabaseImp::getHashesByIndex(LedgerIndex ledgerIndex) } std::map -SQLiteDatabaseImp::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) +SQLiteDatabase::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) { if (existsLedger()) { @@ -498,7 +306,7 @@ SQLiteDatabaseImp::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) } std::vector> -SQLiteDatabaseImp::getTxHistory(LedgerIndex startIndex) +SQLiteDatabase::getTxHistory(LedgerIndex startIndex) { if (!useTxTables_) return {}; @@ -516,7 +324,7 @@ SQLiteDatabaseImp::getTxHistory(LedgerIndex startIndex) } RelationalDatabase::AccountTxs -SQLiteDatabaseImp::getOldestAccountTxs(AccountTxOptions const& options) +SQLiteDatabase::getOldestAccountTxs(AccountTxOptions const& options) { if (!useTxTables_) return {}; @@ -533,7 +341,7 @@ SQLiteDatabaseImp::getOldestAccountTxs(AccountTxOptions const& options) } RelationalDatabase::AccountTxs -SQLiteDatabaseImp::getNewestAccountTxs(AccountTxOptions const& options) +SQLiteDatabase::getNewestAccountTxs(AccountTxOptions const& options) { if (!useTxTables_) return {}; @@ -550,7 +358,7 @@ SQLiteDatabaseImp::getNewestAccountTxs(AccountTxOptions const& options) } RelationalDatabase::MetaTxsList -SQLiteDatabaseImp::getOldestAccountTxsB(AccountTxOptions const& options) +SQLiteDatabase::getOldestAccountTxsB(AccountTxOptions const& options) { if (!useTxTables_) return {}; @@ -565,7 +373,7 @@ SQLiteDatabaseImp::getOldestAccountTxsB(AccountTxOptions const& options) } RelationalDatabase::MetaTxsList -SQLiteDatabaseImp::getNewestAccountTxsB(AccountTxOptions const& options) +SQLiteDatabase::getNewestAccountTxsB(AccountTxOptions const& options) { if (!useTxTables_) return {}; @@ -580,7 +388,7 @@ SQLiteDatabaseImp::getNewestAccountTxsB(AccountTxOptions const& options) } std::pair> -SQLiteDatabaseImp::oldestAccountTxPage(AccountTxPageOptions const& options) +SQLiteDatabase::oldestAccountTxPage(AccountTxPageOptions const& options) { if (!useTxTables_) return {}; @@ -604,7 +412,7 @@ SQLiteDatabaseImp::oldestAccountTxPage(AccountTxPageOptions const& options) } std::pair> -SQLiteDatabaseImp::newestAccountTxPage(AccountTxPageOptions const& options) +SQLiteDatabase::newestAccountTxPage(AccountTxPageOptions const& options) { if (!useTxTables_) return {}; @@ -628,7 +436,7 @@ SQLiteDatabaseImp::newestAccountTxPage(AccountTxPageOptions const& options) } std::pair> -SQLiteDatabaseImp::oldestAccountTxPageB(AccountTxPageOptions const& options) +SQLiteDatabase::oldestAccountTxPageB(AccountTxPageOptions const& options) { if (!useTxTables_) return {}; @@ -651,7 +459,7 @@ SQLiteDatabaseImp::oldestAccountTxPageB(AccountTxPageOptions const& options) } std::pair> -SQLiteDatabaseImp::newestAccountTxPageB(AccountTxPageOptions const& options) +SQLiteDatabase::newestAccountTxPageB(AccountTxPageOptions const& options) { if (!useTxTables_) return {}; @@ -674,7 +482,7 @@ SQLiteDatabaseImp::newestAccountTxPageB(AccountTxPageOptions const& options) } std::variant -SQLiteDatabaseImp::getTransaction( +SQLiteDatabase::getTransaction( uint256 const& id, std::optional> const& range, error_code_i& ec) @@ -692,7 +500,7 @@ SQLiteDatabaseImp::getTransaction( } bool -SQLiteDatabaseImp::ledgerDbHasSpace(Config const& config) +SQLiteDatabase::ledgerDbHasSpace(Config const& config) { if (existsLedger()) { @@ -704,7 +512,7 @@ SQLiteDatabaseImp::ledgerDbHasSpace(Config const& config) } bool -SQLiteDatabaseImp::transactionDbHasSpace(Config const& config) +SQLiteDatabase::transactionDbHasSpace(Config const& config) { if (!useTxTables_) return true; @@ -719,7 +527,7 @@ SQLiteDatabaseImp::transactionDbHasSpace(Config const& config) } std::uint32_t -SQLiteDatabaseImp::getKBUsedAll() +SQLiteDatabase::getKBUsedAll() { if (existsLedger()) { @@ -730,7 +538,7 @@ SQLiteDatabaseImp::getKBUsedAll() } std::uint32_t -SQLiteDatabaseImp::getKBUsedLedger() +SQLiteDatabase::getKBUsedLedger() { if (existsLedger()) { @@ -741,7 +549,7 @@ SQLiteDatabaseImp::getKBUsedLedger() } std::uint32_t -SQLiteDatabaseImp::getKBUsedTransaction() +SQLiteDatabase::getKBUsedTransaction() { if (!useTxTables_) return 0; @@ -755,21 +563,43 @@ SQLiteDatabaseImp::getKBUsedTransaction() } void -SQLiteDatabaseImp::closeLedgerDB() +SQLiteDatabase::closeLedgerDB() { ledgerDb_.reset(); } void -SQLiteDatabaseImp::closeTransactionDB() +SQLiteDatabase::closeTransactionDB() { txdb_.reset(); } -std::unique_ptr -getSQLiteDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) +SQLiteDatabase::SQLiteDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) + : registry_(registry), useTxTables_(config.useTxTables()), j_(registry.journal("SQLiteDatabase")) { - return std::make_unique(registry, config, jobQueue); + DatabaseCon::Setup const setup = setup_DatabaseCon(config, j_); + if (!makeLedgerDBs(config, setup, DatabaseCon::CheckpointerSetup{&jobQueue, ®istry_.logs()})) + { + std::string_view constexpr error = "Failed to create ledger databases"; + + JLOG(j_.fatal()) << error; + Throw(error.data()); + } +} + +SQLiteDatabase::SQLiteDatabase(SQLiteDatabase&& rhs) noexcept + : registry_(rhs.registry_) + , useTxTables_(rhs.useTxTables_) + , j_(rhs.j_) + , ledgerDb_(std::move(rhs.ledgerDb_)) + , txdb_(std::move(rhs.txdb_)) +{ +} + +SQLiteDatabase +setup_RelationalDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) +{ + return {registry, config, jobQueue}; } } // namespace xrpl diff --git a/src/xrpld/app/rdb/detail/RelationalDatabase.cpp b/src/xrpld/app/rdb/detail/RelationalDatabase.cpp index bc65a817a4..e69de29bb2 100644 --- a/src/xrpld/app/rdb/detail/RelationalDatabase.cpp +++ b/src/xrpld/app/rdb/detail/RelationalDatabase.cpp @@ -1,39 +0,0 @@ -#include -#include - -namespace xrpl { - -extern std::unique_ptr -getSQLiteDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue); - -std::unique_ptr -RelationalDatabase::init(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue) -{ - bool use_sqlite = false; - - Section const& rdb_section{config.section(SECTION_RELATIONAL_DB)}; - if (!rdb_section.empty()) - { - if (boost::iequals(get(rdb_section, "backend"), "sqlite")) - { - use_sqlite = true; - } - else - { - Throw("Invalid rdb_section backend value: " + get(rdb_section, "backend")); - } - } - else - { - use_sqlite = true; - } - - if (use_sqlite) - { - return getSQLiteDatabase(registry, config, jobQueue); - } - - return std::unique_ptr(); -} - -} // namespace xrpl diff --git a/src/xrpld/overlay/detail/OverlayImpl.cpp b/src/xrpld/overlay/detail/OverlayImpl.cpp index 6ac6e454d2..549bff024e 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.cpp +++ b/src/xrpld/overlay/detail/OverlayImpl.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -18,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/src/xrpld/overlay/detail/PeerReservationTable.cpp b/src/xrpld/overlay/detail/PeerReservationTable.cpp index 27d9df1129..78f29ad155 100644 --- a/src/xrpld/overlay/detail/PeerReservationTable.cpp +++ b/src/xrpld/overlay/detail/PeerReservationTable.cpp @@ -1,9 +1,8 @@ -#include - #include #include #include #include +#include #include #include diff --git a/src/xrpld/rpc/detail/RPCHelpers.cpp b/src/xrpld/rpc/detail/RPCHelpers.cpp index 0c4cffd8ac..4a0339b763 100644 --- a/src/xrpld/rpc/detail/RPCHelpers.cpp +++ b/src/xrpld/rpc/detail/RPCHelpers.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -10,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/src/xrpld/rpc/detail/RPCLedgerHelpers.h b/src/xrpld/rpc/detail/RPCLedgerHelpers.h index 6ea6e3cb78..b2d9df809f 100644 --- a/src/xrpld/rpc/detail/RPCLedgerHelpers.h +++ b/src/xrpld/rpc/detail/RPCLedgerHelpers.h @@ -7,6 +7,7 @@ #include #include +#include #include @@ -19,8 +20,6 @@ namespace RPC { struct JsonContext; -enum class LedgerShortcut { Current, Closed, Validated }; - /** * @brief Retrieves a ledger by its hash. * diff --git a/src/xrpld/rpc/handlers/AccountTx.cpp b/src/xrpld/rpc/handlers/AccountTx.cpp index fbd1a4d08d..8fe43433d3 100644 --- a/src/xrpld/rpc/handlers/AccountTx.cpp +++ b/src/xrpld/rpc/handlers/AccountTx.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -26,8 +27,6 @@ using TxnsDataBinary = RelationalDatabase::MetaTxsList; using TxnDataBinary = RelationalDatabase::txnMetaLedgerType; using AccountTxArgs = RelationalDatabase::AccountTxArgs; using AccountTxResult = RelationalDatabase::AccountTxResult; - -using LedgerShortcut = RelationalDatabase::LedgerShortcut; using LedgerSpecifier = RelationalDatabase::LedgerSpecifier; // parses args into a ledger specifier, or returns a Json object on error @@ -208,22 +207,19 @@ doAccountTxHelp(RPC::Context& context, AccountTxArgs const& args) args.limit, isUnlimited(context.role)}; - auto const db = dynamic_cast(&context.app.getRelationalDatabase()); - - if (!db) - Throw("Failed to get relational database"); + auto& db = context.app.getRelationalDatabase(); if (args.binary) { if (args.forward) { - auto [tx, marker] = db->oldestAccountTxPageB(options); + auto [tx, marker] = db.oldestAccountTxPageB(options); result.transactions = tx; result.marker = marker; } else { - auto [tx, marker] = db->newestAccountTxPageB(options); + auto [tx, marker] = db.newestAccountTxPageB(options); result.transactions = tx; result.marker = marker; } @@ -232,13 +228,13 @@ doAccountTxHelp(RPC::Context& context, AccountTxArgs const& args) { if (args.forward) { - auto [tx, marker] = db->oldestAccountTxPage(options); + auto [tx, marker] = db.oldestAccountTxPage(options); result.transactions = tx; result.marker = marker; } else { - auto [tx, marker] = db->newestAccountTxPage(options); + auto [tx, marker] = db.newestAccountTxPage(options); result.transactions = tx; result.marker = marker; } diff --git a/src/xrpld/rpc/handlers/GetCounts.cpp b/src/xrpld/rpc/handlers/GetCounts.cpp index 2a59be2747..360389ba3a 100644 --- a/src/xrpld/rpc/handlers/GetCounts.cpp +++ b/src/xrpld/rpc/handlers/GetCounts.cpp @@ -49,22 +49,19 @@ getCountsJson(Application& app, int minObjectCount) if (app.config().useTxTables()) { - auto const db = dynamic_cast(&app.getRelationalDatabase()); + auto& db = app.getRelationalDatabase(); - if (!db) - Throw("Failed to get relational database"); - - auto dbKB = db->getKBUsedAll(); + auto dbKB = db.getKBUsedAll(); if (dbKB > 0) ret[jss::dbKBTotal] = dbKB; - dbKB = db->getKBUsedLedger(); + dbKB = db.getKBUsedLedger(); if (dbKB > 0) ret[jss::dbKBLedger] = dbKB; - dbKB = db->getKBUsedTransaction(); + dbKB = db.getKBUsedTransaction(); if (dbKB > 0) ret[jss::dbKBTransaction] = dbKB; diff --git a/src/xrpld/rpc/handlers/Tx.cpp b/src/xrpld/rpc/handlers/Tx.cpp index 5d8778d619..2f8d71c2c8 100644 --- a/src/xrpld/rpc/handlers/Tx.cpp +++ b/src/xrpld/rpc/handlers/Tx.cpp @@ -3,18 +3,19 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include #include #include +#include #include diff --git a/src/xrpld/rpc/handlers/TxHistory.cpp b/src/xrpld/rpc/handlers/TxHistory.cpp index 00894647eb..02ff6fb43c 100644 --- a/src/xrpld/rpc/handlers/TxHistory.cpp +++ b/src/xrpld/rpc/handlers/TxHistory.cpp @@ -2,13 +2,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include namespace xrpl { From 11e8d1f8a206f0c5379ba78bc3aa044adf5a63d7 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:11:26 +0000 Subject: [PATCH 3/3] chore: Fix `gcov` lib coverage build failure on macOS (#6350) For coverage builds, we try to link against the `gcov` library (specific to the environment). But as macOS doesn't have this library and thus doesn't have the coverage tools to generate reports, the coverage builds on that platform were failing on linking. We actually don't need to explicitly force this linking, as the `CodeCoverage` file already has correct detection logic (currently on lines 177-193), which is invoked when the `--coverage` flag is provided: * AppleClang: Uses `xcrun -f llvm-cov` to set `GCOV_TOOL="llvm-cov gcov"`. * Clang: Finds `llvm-cov` to set `GCOV_TOOL="llvm-cov gcov"`. * GCC: Finds `gcov` to set `GCOV_TOOL="gcov"`. The `GCOV_TOOL` is then passed to `gcovr` on line 416, so the correct tool is used for processing coverage data. This change therefore removes the `gcov` suffix from lines 473 and 475 in the `CodeCoverage.cmake` file. --- cmake/CodeCoverage.cmake | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake index 0178d68cc0..fcc4d44133 100644 --- a/cmake/CodeCoverage.cmake +++ b/cmake/CodeCoverage.cmake @@ -466,11 +466,6 @@ function (add_code_coverage_to_target name scope) target_compile_options(${name} ${scope} $<$:${COVERAGE_CXX_COMPILER_FLAGS}> $<$:${COVERAGE_C_COMPILER_FLAGS}>) - target_link_libraries( - ${name} - ${scope} - $<$:${COVERAGE_CXX_LINKER_FLAGS} - gcov> - $<$:${COVERAGE_C_LINKER_FLAGS} - gcov>) + target_link_libraries(${name} ${scope} $<$:${COVERAGE_CXX_LINKER_FLAGS}> + $<$:${COVERAGE_C_LINKER_FLAGS}>) endfunction () # add_code_coverage_to_target