diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index 6250f844ea..a210a08410 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -172,6 +172,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 @@ -215,6 +216,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 @@ -233,6 +235,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 {