mirror of
https://github.com/XRPLF/rippled.git
synced 2026-02-11 17:32:34 +00:00
Compare commits
1 Commits
vlntb/mall
...
bthomee/xr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6c21fb96f |
@@ -4,11 +4,14 @@ 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
|
||||
|
||||
@@ -17,15 +17,12 @@ 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
|
||||
@@ -44,9 +41,7 @@ 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
|
||||
@@ -72,7 +67,6 @@ 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
|
||||
@@ -101,8 +95,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
|
||||
@@ -160,7 +154,6 @@ 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
|
||||
@@ -169,17 +162,12 @@ 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.rdb > xrpl.protocol
|
||||
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
|
||||
@@ -188,15 +176,12 @@ 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
|
||||
@@ -208,20 +193,17 @@ 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
|
||||
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
|
||||
xrpld.peerfinder > xrpld.core
|
||||
xrpld.peerfinder > xrpl.protocol
|
||||
xrpld.peerfinder > xrpl.rdb
|
||||
xrpld.perflog > xrpl.basics
|
||||
xrpld.perflog > xrpl.core
|
||||
xrpld.perflog > xrpld.rpc
|
||||
@@ -234,7 +216,6 @@ 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
|
||||
|
||||
@@ -84,6 +84,9 @@ 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)
|
||||
|
||||
@@ -91,15 +94,8 @@ 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
|
||||
xrpl.libxrpl.rdb)
|
||||
target_link_libraries(xrpl.libxrpl.ledger PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol)
|
||||
|
||||
add_library(xrpl.libxrpl)
|
||||
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
|
||||
@@ -117,14 +113,13 @@ target_link_modules(
|
||||
core
|
||||
crypto
|
||||
json
|
||||
ledger
|
||||
net
|
||||
nodestore
|
||||
protocol
|
||||
rdb
|
||||
resource
|
||||
server
|
||||
shamap)
|
||||
nodestore
|
||||
shamap
|
||||
net
|
||||
ledger)
|
||||
|
||||
# All headers in libxrpl are in modules.
|
||||
# Uncomment this stanza if you have not yet moved new headers into a module.
|
||||
|
||||
@@ -23,7 +23,6 @@ install(TARGETS common
|
||||
xrpl.libxrpl.core
|
||||
xrpl.libxrpl.crypto
|
||||
xrpl.libxrpl.json
|
||||
xrpl.libxrpl.rdb
|
||||
xrpl.libxrpl.ledger
|
||||
xrpl.libxrpl.net
|
||||
xrpl.libxrpl.nodestore
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// cSpell:ignore ptmalloc
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Allocator interaction note:
|
||||
// - This facility invokes glibc's malloc_trim(0) on Linux/glibc to request that
|
||||
// ptmalloc return free heap pages to the OS.
|
||||
// - If an alternative allocator (e.g. jemalloc or tcmalloc) is linked or
|
||||
// preloaded (LD_PRELOAD), calling glibc's malloc_trim typically has no effect
|
||||
// on the *active* heap. The call is harmless but may not reclaim memory
|
||||
// because those allocators manage their own arenas.
|
||||
// - Only glibc sbrk/arena space is eligible for trimming; large mmap-backed
|
||||
// allocations are usually returned to the OS on free regardless of trimming.
|
||||
// - Call at known reclamation points (e.g., after cache sweeps / online delete)
|
||||
// and consider rate limiting to avoid churn.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct MallocTrimReport
|
||||
{
|
||||
bool supported{false};
|
||||
int trimResult{-1};
|
||||
long rssBeforeKB{-1};
|
||||
long rssAfterKB{-1};
|
||||
long long durationUs{-1};
|
||||
long minfltDelta{-1};
|
||||
long majfltDelta{-1};
|
||||
|
||||
[[nodiscard]] long
|
||||
deltaKB() const noexcept
|
||||
{
|
||||
if (rssBeforeKB < 0 || rssAfterKB < 0)
|
||||
return 0;
|
||||
return rssAfterKB - rssBeforeKB;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Attempt to return freed memory to the operating system.
|
||||
*
|
||||
* On Linux with glibc malloc, this issues ::malloc_trim(0), which may release
|
||||
* free space from ptmalloc arenas back to the kernel. On other platforms, or if
|
||||
* a different allocator is in use, this function is a no-op and the report will
|
||||
* indicate that trimming is unsupported or had no effect.
|
||||
*
|
||||
* @param tag Optional identifier for logging/debugging purposes.
|
||||
* @param journal Journal for diagnostic logging.
|
||||
* @return Report containing before/after metrics and the trim result.
|
||||
*
|
||||
* @note If an alternative allocator (jemalloc/tcmalloc) is linked or preloaded,
|
||||
* calling glibc's malloc_trim may have no effect on the active heap. The
|
||||
* call is harmless but typically does not reclaim memory under those
|
||||
* allocators.
|
||||
*
|
||||
* @note Only memory served from glibc's sbrk/arena heaps is eligible for trim.
|
||||
* Large allocations satisfied via mmap are usually returned on free
|
||||
* independently of trimming.
|
||||
*
|
||||
* @note Intended for use after operations that free significant memory (e.g.,
|
||||
* cache sweeps, ledger cleanup, online delete). Consider rate limiting.
|
||||
*/
|
||||
MallocTrimReport
|
||||
mallocTrim(std::optional<std::string> const& tag, beast::Journal journal);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/ledger/CachedSLEs.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Forward declarations
|
||||
@@ -20,10 +18,6 @@ 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;
|
||||
@@ -200,24 +194,6 @@ 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
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
#include <type_traits>
|
||||
|
||||
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<std::underlying_type_t<StartUpType>>(type);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,22 +0,0 @@
|
||||
#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
|
||||
@@ -14,7 +14,7 @@ namespace xrpl {
|
||||
static inline std::string const&
|
||||
systemName()
|
||||
{
|
||||
static std::string const name = "ripple";
|
||||
static std::string const name = "xrpld";
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class TxSearched { all, some, unknown };
|
||||
|
||||
}
|
||||
@@ -1,475 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/RangeSet.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
#include <xrpl/protocol/LedgerShortcut.h>
|
||||
#include <xrpl/protocol/TxMeta.h>
|
||||
#include <xrpl/protocol/TxSearched.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
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<AccountTxMarker> marker;
|
||||
std::uint32_t limit;
|
||||
bool bAdmin;
|
||||
};
|
||||
|
||||
using AccountTx = std::pair<std::shared_ptr<Transaction>, std::shared_ptr<TxMeta>>;
|
||||
using AccountTxs = std::vector<AccountTx>;
|
||||
using txnMetaLedgerType = std::tuple<Blob, Blob, std::uint32_t>;
|
||||
using MetaTxsList = std::vector<txnMetaLedgerType>;
|
||||
|
||||
using LedgerSequence = uint32_t;
|
||||
using LedgerHash = uint256;
|
||||
using LedgerSpecifier = std::variant<LedgerRange, LedgerShortcut, LedgerSequence, LedgerHash>;
|
||||
|
||||
struct AccountTxArgs
|
||||
{
|
||||
AccountID account;
|
||||
std::optional<LedgerSpecifier> ledger;
|
||||
bool binary = false;
|
||||
bool forward = false;
|
||||
uint32_t limit = 0;
|
||||
std::optional<AccountTxMarker> marker;
|
||||
};
|
||||
|
||||
struct AccountTxResult
|
||||
{
|
||||
std::variant<AccountTxs, MetaTxsList> transactions;
|
||||
LedgerRange ledgerRange;
|
||||
uint32_t limit;
|
||||
std::optional<AccountTxMarker> 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<LedgerIndex>
|
||||
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<LedgerIndex>
|
||||
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<LedgerHeader>
|
||||
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<LedgerHeader>
|
||||
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<LedgerHeader>
|
||||
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<LedgerHashPair>
|
||||
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<LedgerIndex, LedgerHashPair>
|
||||
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<std::shared_ptr<Transaction>>
|
||||
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<LedgerIndex>
|
||||
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<LedgerIndex>
|
||||
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<Ledger const> 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<LedgerHeader>
|
||||
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<LedgerHeader>
|
||||
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<AccountTxs, std::optional<AccountTxMarker>>
|
||||
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<AccountTxs, std::optional<AccountTxMarker>>
|
||||
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<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
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<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
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<AccountTx, TxSearched>
|
||||
getTransaction(uint256 const& id, std::optional<ClosedInterval<uint32_t>> 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 <class T, class C>
|
||||
T
|
||||
rangeCheckedCast(C c)
|
||||
{
|
||||
if ((c > std::numeric_limits<T>::max()) || (!std::numeric_limits<T>::is_signed && c < 0) ||
|
||||
(std::numeric_limits<T>::is_signed && std::numeric_limits<C>::is_signed &&
|
||||
c < std::numeric_limits<T>::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<T>::lowest()
|
||||
<< " max: " << std::numeric_limits<T>::max();
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
return static_cast<T>(c);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,166 +0,0 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/MallocTrim.h>
|
||||
|
||||
#include <boost/predef.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Require RUSAGE_THREAD for thread-scoped page fault tracking
|
||||
#ifndef RUSAGE_THREAD
|
||||
#error "MallocTrim rusage instrumentation requires RUSAGE_THREAD on Linux/glibc"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
bool
|
||||
getRusageThread(struct rusage& ru)
|
||||
{
|
||||
return ::getrusage(RUSAGE_THREAD, &ru) == 0; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// cSpell:ignore statm
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
|
||||
inline int
|
||||
mallocTrimWithPad(std::size_t padBytes)
|
||||
{
|
||||
return ::malloc_trim(padBytes);
|
||||
}
|
||||
|
||||
long
|
||||
parseStatmRSSkB(std::string const& statm)
|
||||
{
|
||||
// /proc/self/statm format: size resident shared text lib data dt
|
||||
// We want the second field (resident) which is in pages
|
||||
std::istringstream iss(statm);
|
||||
long size, resident;
|
||||
if (!(iss >> size >> resident))
|
||||
return -1;
|
||||
|
||||
// Convert pages to KB
|
||||
long const pageSize = ::sysconf(_SC_PAGESIZE);
|
||||
if (pageSize <= 0)
|
||||
return -1;
|
||||
|
||||
return (resident * pageSize) / 1024;
|
||||
}
|
||||
|
||||
#endif // __GLIBC__ && BOOST_OS_LINUX
|
||||
|
||||
} // namespace detail
|
||||
|
||||
MallocTrimReport
|
||||
mallocTrim([[maybe_unused]] std::optional<std::string> const& tag, beast::Journal journal)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
|
||||
MallocTrimReport report;
|
||||
|
||||
#if !(defined(__GLIBC__) && BOOST_OS_LINUX)
|
||||
JLOG(journal.debug()) << "malloc_trim not supported on this platform";
|
||||
#else
|
||||
// Keep glibc malloc_trim padding at 0 (default): 12h Mainnet tests across 0/256KB/1MB/16MB
|
||||
// showed no clear, consistent benefit from custom padding—0 provided the best overall balance
|
||||
// of RSS reduction and trim-latency stability without adding a tuning surface.
|
||||
constexpr std::size_t TRIM_PAD = 0;
|
||||
|
||||
report.supported = true;
|
||||
|
||||
if (journal.debug())
|
||||
{
|
||||
auto readFile = [](std::string const& path) -> std::string {
|
||||
std::ifstream ifs(path, std::ios::binary);
|
||||
if (!ifs.is_open())
|
||||
return {};
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
auto const size = ifs.tellg();
|
||||
if (size < 0)
|
||||
return {};
|
||||
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
std::string result(static_cast<std::size_t>(size), '\0');
|
||||
ifs.read(result.data(), size);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
std::string const tagStr = tag.value_or("default");
|
||||
std::string const statmPath = "/proc/self/statm";
|
||||
|
||||
auto const statmBefore = readFile(statmPath);
|
||||
long const rssBeforeKB = detail::parseStatmRSSkB(statmBefore);
|
||||
|
||||
struct rusage ru0
|
||||
{
|
||||
};
|
||||
bool const have_ru0 = getRusageThread(ru0);
|
||||
|
||||
auto const t0 = std::chrono::steady_clock::now();
|
||||
|
||||
report.trimResult = detail::mallocTrimWithPad(TRIM_PAD);
|
||||
|
||||
auto const t1 = std::chrono::steady_clock::now();
|
||||
|
||||
struct rusage ru1
|
||||
{
|
||||
};
|
||||
bool const have_ru1 = getRusageThread(ru1);
|
||||
|
||||
auto const statmAfter = readFile(statmPath);
|
||||
long const rssAfterKB = detail::parseStatmRSSkB(statmAfter);
|
||||
|
||||
// Populate report fields
|
||||
report.rssBeforeKB = rssBeforeKB;
|
||||
report.rssAfterKB = rssAfterKB;
|
||||
|
||||
long long const durationUs = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count();
|
||||
|
||||
long minfltDelta = -1;
|
||||
long majfltDelta = -1;
|
||||
if (have_ru0 && have_ru1)
|
||||
{
|
||||
minfltDelta = ru1.ru_minflt - ru0.ru_minflt;
|
||||
majfltDelta = ru1.ru_majflt - ru0.ru_majflt;
|
||||
}
|
||||
|
||||
long const deltaKB = (rssBeforeKB < 0 || rssAfterKB < 0) ? 0 : (rssAfterKB - rssBeforeKB);
|
||||
|
||||
JLOG(journal.debug()) << "malloc_trim tag=" << tagStr << " result=" << report.trimResult << " pad=" << TRIM_PAD
|
||||
<< " bytes"
|
||||
<< " rss_before=" << rssBeforeKB << "kB"
|
||||
<< " rss_after=" << rssAfterKB << "kB"
|
||||
<< " delta=" << deltaKB << "kB"
|
||||
<< " duration_us=" << durationUs << " minflt_delta=" << minfltDelta
|
||||
<< " majflt_delta=" << majfltDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
report.trimResult = detail::mallocTrimWithPad(TRIM_PAD);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return report;
|
||||
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,92 +0,0 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
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<std::uintptr_t, std::shared_ptr<Checkpointer>> checkpointers_;
|
||||
|
||||
public:
|
||||
std::shared_ptr<Checkpointer>
|
||||
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<Checkpointer>
|
||||
create(std::shared_ptr<soci::session> 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<Checkpointer>
|
||||
checkpointerFromId(std::uintptr_t id)
|
||||
{
|
||||
return checkpointers.fromId(id);
|
||||
}
|
||||
|
||||
DatabaseCon::~DatabaseCon()
|
||||
{
|
||||
if (checkpointer_)
|
||||
{
|
||||
checkpointers.erase(checkpointer_->id());
|
||||
|
||||
std::weak_ptr<Checkpointer> 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<std::vector<std::string> const> DatabaseCon::Setup::globalPragma;
|
||||
|
||||
void
|
||||
DatabaseCon::setupCheckpointing(JobQueue* q, Logs& l)
|
||||
{
|
||||
if (!q)
|
||||
Throw<std::logic_error>("No JobQueue");
|
||||
checkpointer_ = checkpointers.create(session_, *q, l);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -21,7 +21,7 @@ class LedgerLoad_test : public beast::unit_test::suite
|
||||
std::unique_ptr<Config> cfg,
|
||||
std::string const& dbPath,
|
||||
std::string const& ledger,
|
||||
StartUpType type,
|
||||
Config::StartUpType type,
|
||||
std::optional<uint256> 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, StartUpType::LOAD_FILE, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, sd.ledgerFile, Config::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, "", StartUpType::LOAD_FILE, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, "", Config::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", StartUpType::LOAD_FILE, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, "badfile.json", Config::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(), StartUpType::LOAD_FILE, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, ledgerFileCorrupt.string(), Config::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, StartUpType::LOAD, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::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, StartUpType::REPLAY, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::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, StartUpType::REPLAY, sd.trapTxHash),
|
||||
envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::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, StartUpType::REPLAY, ~sd.trapTxHash),
|
||||
envconfig(ledgerConfig, sd.dbPath, ledgerHash, Config::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", StartUpType::LOAD, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, "latest", Config::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", StartUpType::LOAD, std::nullopt),
|
||||
envconfig(ledgerConfig, sd.dbPath, "43", Config::LOAD, std::nullopt),
|
||||
nullptr,
|
||||
beast::severities::kDisabled);
|
||||
auto jrb = env.rpc("ledger", "current", "full")[jss::result];
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#include <test/jtx.h>
|
||||
|
||||
#include <xrpld/app/main/DBInit.h>
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpld/app/misc/ValidatorList.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
|
||||
#include <xrpl/basics/base64.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/protocol/STExchange.h>
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <xrpl/protocol/Sign.h>
|
||||
#include <xrpl/rdb/DBInit.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
#include <xrpl/server/Wallet.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -91,7 +91,8 @@ class SHAMapStore_test : public beast::unit_test::suite
|
||||
void
|
||||
ledgerCheck(jtx::Env& env, int const rows, int const first)
|
||||
{
|
||||
auto const [actualRows, actualFirst, actualLast] = env.app().getRelationalDatabase().getLedgerCountMinMax();
|
||||
auto const [actualRows, actualFirst, actualLast] =
|
||||
dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())->getLedgerCountMinMax();
|
||||
|
||||
BEAST_EXPECT(actualRows == rows);
|
||||
BEAST_EXPECT(actualFirst == first);
|
||||
@@ -101,13 +102,14 @@ class SHAMapStore_test : public beast::unit_test::suite
|
||||
void
|
||||
transactionCheck(jtx::Env& env, int const rows)
|
||||
{
|
||||
BEAST_EXPECT(env.app().getRelationalDatabase().getTransactionCount() == rows);
|
||||
BEAST_EXPECT(dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())->getTransactionCount() == rows);
|
||||
}
|
||||
|
||||
void
|
||||
accountTransactionCheck(jtx::Env& env, int const rows)
|
||||
{
|
||||
BEAST_EXPECT(env.app().getRelationalDatabase().getAccountTransactionCount() == rows);
|
||||
BEAST_EXPECT(
|
||||
dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())->getAccountTransactionCount() == rows);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include <test/jtx/Env.h>
|
||||
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpld/app/misc/ValidatorKeys.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
|
||||
#include <xrpl/basics/base64.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <test/jtx/TestSuite.h>
|
||||
|
||||
#include <xrpld/core/SociDB.h>
|
||||
|
||||
#include <xrpl/basics/BasicConfig.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
#include <test/nodestore/TestBase.h>
|
||||
#include <test/unit_test/SuiteJournal.h>
|
||||
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
|
||||
#include <xrpl/beast/utility/temp_dir.h>
|
||||
#include <xrpl/nodestore/DummyScheduler.h>
|
||||
#include <xrpl/nodestore/Manager.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
|
||||
@@ -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 = StartUpType::FRESH;
|
||||
cfg->START_UP = Config::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 = StartUpType::FRESH;
|
||||
cfg->START_UP = Config::FRESH;
|
||||
return cfg;
|
||||
})};
|
||||
|
||||
|
||||
@@ -108,7 +108,8 @@ class Transaction_test : public beast::unit_test::suite
|
||||
auto const deletedLedger = (startLegSeq + endLegSeq) / 2;
|
||||
{
|
||||
// Remove one of the ledgers from the database directly
|
||||
env.app().getRelationalDatabase().deleteTransactionByLedgerSeq(deletedLedger);
|
||||
dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())
|
||||
->deleteTransactionByLedgerSeq(deletedLedger);
|
||||
}
|
||||
|
||||
for (int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq)
|
||||
@@ -319,7 +320,8 @@ class Transaction_test : public beast::unit_test::suite
|
||||
auto const deletedLedger = (startLegSeq + endLegSeq) / 2;
|
||||
{
|
||||
// Remove one of the ledgers from the database directly
|
||||
env.app().getRelationalDatabase().deleteTransactionByLedgerSeq(deletedLedger);
|
||||
dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase())
|
||||
->deleteTransactionByLedgerSeq(deletedLedger);
|
||||
}
|
||||
|
||||
for (int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq)
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
#include <xrpl/basics/MallocTrim.h>
|
||||
|
||||
#include <boost/predef.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace xrpl;
|
||||
|
||||
// cSpell:ignore statm
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
namespace xrpl::detail {
|
||||
long
|
||||
parseStatmRSSkB(std::string const& statm);
|
||||
} // namespace xrpl::detail
|
||||
#endif
|
||||
|
||||
TEST(MallocTrimReport, structure)
|
||||
{
|
||||
// Test default construction
|
||||
MallocTrimReport report;
|
||||
EXPECT_EQ(report.supported, false);
|
||||
EXPECT_EQ(report.trimResult, -1);
|
||||
EXPECT_EQ(report.rssBeforeKB, -1);
|
||||
EXPECT_EQ(report.rssAfterKB, -1);
|
||||
EXPECT_EQ(report.deltaKB(), 0);
|
||||
|
||||
// Test deltaKB calculation - memory freed
|
||||
report.rssBeforeKB = 1000;
|
||||
report.rssAfterKB = 800;
|
||||
EXPECT_EQ(report.deltaKB(), -200);
|
||||
|
||||
// Test deltaKB calculation - memory increased
|
||||
report.rssBeforeKB = 500;
|
||||
report.rssAfterKB = 600;
|
||||
EXPECT_EQ(report.deltaKB(), 100);
|
||||
|
||||
// Test deltaKB calculation - no change
|
||||
report.rssBeforeKB = 1234;
|
||||
report.rssAfterKB = 1234;
|
||||
EXPECT_EQ(report.deltaKB(), 0);
|
||||
}
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
TEST(parseStatmRSSkB, standard_format)
|
||||
{
|
||||
using xrpl::detail::parseStatmRSSkB;
|
||||
|
||||
// Test standard format: size resident shared text lib data dt
|
||||
// Assuming 4KB page size: resident=1000 pages = 4000 KB
|
||||
{
|
||||
std::string statm = "25365 1000 2377 0 0 5623 0";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
// Note: actual result depends on system page size
|
||||
// On most systems it's 4KB, so 1000 pages = 4000 KB
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test with newline
|
||||
{
|
||||
std::string statm = "12345 2000 1234 0 0 3456 0\n";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test with tabs
|
||||
{
|
||||
std::string statm = "12345\t2000\t1234\t0\t0\t3456\t0";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test zero resident pages
|
||||
{
|
||||
std::string statm = "25365 0 2377 0 0 5623 0";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, 0);
|
||||
}
|
||||
|
||||
// Test with extra whitespace
|
||||
{
|
||||
std::string statm = " 25365 1000 2377 ";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_GT(result, 0);
|
||||
}
|
||||
|
||||
// Test empty string
|
||||
{
|
||||
std::string statm = "";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
|
||||
// Test malformed data (only one field)
|
||||
{
|
||||
std::string statm = "25365";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
|
||||
// Test malformed data (non-numeric)
|
||||
{
|
||||
std::string statm = "abc def ghi";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
|
||||
// Test malformed data (second field non-numeric)
|
||||
{
|
||||
std::string statm = "25365 abc 2377";
|
||||
long result = parseStatmRSSkB(statm);
|
||||
EXPECT_EQ(result, -1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(mallocTrim, basic_functionality)
|
||||
{
|
||||
beast::Journal journal{beast::Journal::getNullSink()};
|
||||
|
||||
// Test with no tag
|
||||
{
|
||||
MallocTrimReport report = mallocTrim(std::nullopt, journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
// On Linux with glibc, should be supported
|
||||
EXPECT_EQ(report.supported, true);
|
||||
// trimResult should be 0 or 1 (success indicators)
|
||||
EXPECT_GE(report.trimResult, 0);
|
||||
#else
|
||||
// On other platforms, should be unsupported
|
||||
EXPECT_EQ(report.supported, false);
|
||||
EXPECT_EQ(report.trimResult, -1);
|
||||
EXPECT_EQ(report.rssBeforeKB, -1);
|
||||
EXPECT_EQ(report.rssAfterKB, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test with tag
|
||||
{
|
||||
MallocTrimReport report = mallocTrim(std::optional<std::string>("test_tag"), journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
EXPECT_EQ(report.supported, true);
|
||||
EXPECT_GE(report.trimResult, 0);
|
||||
#else
|
||||
EXPECT_EQ(report.supported, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TEST(mallocTrim, debug_logging)
|
||||
{
|
||||
beast::Journal journal{beast::Journal::getNullSink()};
|
||||
|
||||
MallocTrimReport report = mallocTrim(std::optional<std::string>("debug_test"), journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
EXPECT_EQ(report.supported, true);
|
||||
// The function should complete without crashing
|
||||
#else
|
||||
EXPECT_EQ(report.supported, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(mallocTrim, repeated_calls)
|
||||
{
|
||||
beast::Journal journal{beast::Journal::getNullSink()};
|
||||
|
||||
// Call malloc_trim multiple times to ensure it's safe
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
MallocTrimReport report = mallocTrim(std::optional<std::string>("iteration_" + std::to_string(i)), journal);
|
||||
|
||||
#if defined(__GLIBC__) && BOOST_OS_LINUX
|
||||
EXPECT_EQ(report.supported, true);
|
||||
EXPECT_GE(report.trimResult, 0);
|
||||
#else
|
||||
EXPECT_EQ(report.supported, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,10 @@
|
||||
#include <xrpld/app/ledger/PendingSaves.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/HashRouter.h>
|
||||
#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
|
||||
#include <xrpld/consensus/LedgerTiming.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/SociDB.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
@@ -21,7 +23,6 @@
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -904,9 +905,11 @@ saveValidatedLedger(Application& app, std::shared_ptr<Ledger const> const& ledge
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& db = app.getRelationalDatabase();
|
||||
auto const db = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
|
||||
if (!db)
|
||||
Throw<std::runtime_error>("Failed to get relational database");
|
||||
|
||||
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.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <xrpld/app/misc/TxQ.h>
|
||||
#include <xrpld/app/misc/ValidatorList.h>
|
||||
#include <xrpld/app/paths/PathRequests.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/core/TimeKeeper.h>
|
||||
#include <xrpld/overlay/Overlay.h>
|
||||
#include <xrpld/overlay/Peer.h>
|
||||
@@ -28,7 +29,6 @@
|
||||
#include <xrpl/protocol/BuildInfo.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
#include <xrpl/resource/Fees.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <xrpld/app/ledger/TransactionMaster.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/main/BasicApp.h>
|
||||
#include <xrpld/app/main/DBInit.h>
|
||||
#include <xrpld/app/main/GRPCServer.h>
|
||||
#include <xrpld/app/main/LoadManager.h>
|
||||
#include <xrpld/app/main/NodeIdentity.h>
|
||||
@@ -24,20 +25,21 @@
|
||||
#include <xrpld/app/misc/ValidatorKeys.h>
|
||||
#include <xrpld/app/misc/ValidatorSite.h>
|
||||
#include <xrpld/app/paths/PathRequests.h>
|
||||
#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
#include <xrpld/app/tx/apply.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/overlay/Cluster.h>
|
||||
#include <xrpld/overlay/PeerReservationTable.h>
|
||||
#include <xrpld/overlay/PeerSet.h>
|
||||
#include <xrpld/overlay/make_Overlay.h>
|
||||
#include <xrpld/shamap/NodeFamily.h>
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/basics/MallocTrim.h>
|
||||
#include <xrpl/basics/ResolverAsio.h>
|
||||
#include <xrpl/basics/random.h>
|
||||
#include <xrpl/beast/asio/io_latency_probe.h>
|
||||
#include <xrpl/beast/core/LexicalCast.h>
|
||||
#include <xrpl/core/PeerReservationTable.h>
|
||||
#include <xrpl/core/PerfLog.h>
|
||||
#include <xrpl/crypto/csprng.h>
|
||||
#include <xrpl/json/json_reader.h>
|
||||
@@ -47,9 +49,7 @@
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/resource/Fees.h>
|
||||
#include <xrpl/server/Wallet.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
@@ -192,7 +192,7 @@ public:
|
||||
boost::asio::steady_timer sweepTimer_;
|
||||
boost::asio::steady_timer entropyTimer_;
|
||||
|
||||
std::optional<SQLiteDatabase> relationalDatabase_;
|
||||
std::unique_ptr<RelationalDatabase> mRelationalDatabase;
|
||||
std::unique_ptr<DatabaseCon> mWalletDB;
|
||||
std::unique_ptr<Overlay> overlay_;
|
||||
std::optional<uint256> trapTxID_;
|
||||
@@ -731,10 +731,10 @@ public:
|
||||
getRelationalDatabase() override
|
||||
{
|
||||
XRPL_ASSERT(
|
||||
relationalDatabase_,
|
||||
mRelationalDatabase,
|
||||
"xrpl::ApplicationImp::getRelationalDatabase : non-null "
|
||||
"relational database");
|
||||
return *relationalDatabase_;
|
||||
return *mRelationalDatabase;
|
||||
}
|
||||
|
||||
DatabaseCon&
|
||||
@@ -762,7 +762,7 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
relationalDatabase_.emplace(setup_RelationalDatabase(*this, *config_, *m_jobQueue));
|
||||
mRelationalDatabase = RelationalDatabase::init(*this, *config_, *m_jobQueue);
|
||||
|
||||
// wallet database
|
||||
auto setup = setup_DatabaseCon(*config_, m_journal);
|
||||
@@ -873,8 +873,7 @@ public:
|
||||
void
|
||||
doSweep()
|
||||
{
|
||||
XRPL_ASSERT(relationalDatabase_, "xrpl::ApplicationImp::doSweep : non-null relational database");
|
||||
if (!config_->standalone() && !relationalDatabase_->transactionDbHasSpace(*config_))
|
||||
if (!config_->standalone() && !getRelationalDatabase().transactionDbHasSpace(*config_))
|
||||
{
|
||||
signalStop("Out of transaction DB space");
|
||||
}
|
||||
@@ -987,8 +986,6 @@ public:
|
||||
<< "; size after: " << cachedSLEs_.size();
|
||||
}
|
||||
|
||||
mallocTrim(std::optional<std::string>("doSweep"), m_journal);
|
||||
|
||||
// Set timer to do another sweep later.
|
||||
setSweepTimer();
|
||||
}
|
||||
@@ -1024,12 +1021,6 @@ private:
|
||||
|
||||
void
|
||||
setMaxDisallowedLedger();
|
||||
|
||||
Application&
|
||||
app() override
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1125,21 +1116,18 @@ ApplicationImp::setup(boost::program_options::variables_map const& cmdline)
|
||||
|
||||
auto const startUp = config_->START_UP;
|
||||
JLOG(m_journal.debug()) << "startUp: " << startUp;
|
||||
if (startUp == StartUpType::FRESH)
|
||||
if (startUp == Config::FRESH)
|
||||
{
|
||||
JLOG(m_journal.info()) << "Starting new Ledger";
|
||||
|
||||
startGenesisLedger();
|
||||
}
|
||||
else if (startUp == StartUpType::LOAD || startUp == StartUpType::LOAD_FILE || startUp == StartUpType::REPLAY)
|
||||
else if (startUp == Config::LOAD || startUp == Config::LOAD_FILE || startUp == Config::REPLAY)
|
||||
{
|
||||
JLOG(m_journal.info()) << "Loading specified Ledger";
|
||||
|
||||
if (!loadOldLedger(
|
||||
config_->START_LEDGER,
|
||||
startUp == StartUpType::REPLAY,
|
||||
startUp == StartUpType::LOAD_FILE,
|
||||
config_->TRAP_TX_HASH))
|
||||
config_->START_LEDGER, startUp == Config::REPLAY, startUp == Config::LOAD_FILE, config_->TRAP_TX_HASH))
|
||||
{
|
||||
JLOG(m_journal.error()) << "The specified ledger could not be loaded.";
|
||||
if (config_->FAST_LOAD)
|
||||
@@ -1154,7 +1142,7 @@ ApplicationImp::setup(boost::program_options::variables_map const& cmdline)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (startUp == StartUpType::NETWORK)
|
||||
else if (startUp == Config::NETWORK)
|
||||
{
|
||||
// This should probably become the default once we have a stable
|
||||
// network.
|
||||
@@ -1541,7 +1529,7 @@ void
|
||||
ApplicationImp::startGenesisLedger()
|
||||
{
|
||||
std::vector<uint256> const initialAmendments =
|
||||
(config_->START_UP == StartUpType::FRESH) ? m_amendmentTable->getDesired() : std::vector<uint256>{};
|
||||
(config_->START_UP == Config::FRESH) ? m_amendmentTable->getDesired() : std::vector<uint256>{};
|
||||
|
||||
std::shared_ptr<Ledger> const genesis =
|
||||
std::make_shared<Ledger>(create_genesis, *config_, initialAmendments, nodeFamily_);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/overlay/PeerReservationTable.h>
|
||||
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/beast/utility/PropertyStream.h>
|
||||
#include <xrpl/core/PeerReservationTable.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/shamap/TreeNodeCache.h>
|
||||
@@ -112,6 +112,8 @@ public:
|
||||
public:
|
||||
Application();
|
||||
|
||||
virtual ~Application() = default;
|
||||
|
||||
virtual bool
|
||||
setup(boost::program_options::variables_map const& options) = 0;
|
||||
|
||||
@@ -125,6 +127,8 @@ public:
|
||||
checkSigs() const = 0;
|
||||
virtual void
|
||||
checkSigs(bool) = 0;
|
||||
virtual bool
|
||||
isStopping() const = 0;
|
||||
|
||||
//
|
||||
// ---
|
||||
@@ -134,9 +138,14 @@ 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<PublicKey, SecretKey> const&
|
||||
nodeIdentity() = 0;
|
||||
|
||||
@@ -149,6 +158,9 @@ 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;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/rdb/Vacuum.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
#include <xrpld/core/TimeKeeper.h>
|
||||
@@ -7,7 +8,6 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/core/CurrentThreadName.h>
|
||||
#include <xrpl/protocol/BuildInfo.h>
|
||||
#include <xrpl/server/Vacuum.h>
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/process/v1/args.hpp>
|
||||
@@ -601,7 +601,7 @@ run(int argc, char** argv)
|
||||
|
||||
if (vm.count("start"))
|
||||
{
|
||||
config->START_UP = StartUpType::FRESH;
|
||||
config->START_UP = Config::FRESH;
|
||||
}
|
||||
|
||||
if (vm.count("import"))
|
||||
@@ -612,7 +612,7 @@ run(int argc, char** argv)
|
||||
config->START_LEDGER = vm["ledger"].as<std::string>();
|
||||
if (vm.count("replay"))
|
||||
{
|
||||
config->START_UP = StartUpType::REPLAY;
|
||||
config->START_UP = Config::REPLAY;
|
||||
if (vm.count("trap_tx_hash"))
|
||||
{
|
||||
uint256 tmp = {};
|
||||
@@ -631,16 +631,16 @@ run(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
else
|
||||
config->START_UP = StartUpType::LOAD;
|
||||
config->START_UP = Config::LOAD;
|
||||
}
|
||||
else if (vm.count("ledgerfile"))
|
||||
{
|
||||
config->START_LEDGER = vm["ledgerfile"].as<std::string>();
|
||||
config->START_UP = StartUpType::LOAD_FILE;
|
||||
config->START_UP = Config::LOAD_FILE;
|
||||
}
|
||||
else if (vm.count("load") || config->FAST_LOAD)
|
||||
{
|
||||
config->START_UP = StartUpType::LOAD;
|
||||
config->START_UP = Config::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 == StartUpType::LOAD) || (config->START_UP == StartUpType::REPLAY))
|
||||
if ((config->START_UP == Config::LOAD) || (config->START_UP == Config::REPLAY))
|
||||
{
|
||||
std::cerr << "Net and load/replay options are incompatible" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
config->START_UP = StartUpType::NETWORK;
|
||||
config->START_UP = Config::NETWORK;
|
||||
}
|
||||
|
||||
if (vm.count("valid"))
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/main/NodeIdentity.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
|
||||
#include <xrpl/server/Wallet.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
std::pair<PublicKey, SecretKey>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include <xrpld/app/ledger/TransactionMaster.h>
|
||||
#include <xrpld/app/misc/NetworkOPs.h>
|
||||
#include <xrpld/app/misc/SHAMapStoreImp.h>
|
||||
#include <xrpld/app/rdb/State.h>
|
||||
#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
|
||||
#include <xrpl/beast/core/CurrentThreadName.h>
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
#include <xrpl/nodestore/detail/DatabaseRotatingImp.h>
|
||||
#include <xrpl/server/State.h>
|
||||
#include <xrpl/shamap/SHAMapMissingNode.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
@@ -507,13 +507,16 @@ SHAMapStoreImp::clearPrior(LedgerIndex lastRotated)
|
||||
if (healthWait() == stopping)
|
||||
return;
|
||||
|
||||
auto& db = app_.getRelationalDatabase();
|
||||
SQLiteDatabase* const db = dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase());
|
||||
|
||||
if (!db)
|
||||
Throw<std::runtime_error>("Failed to get relational database");
|
||||
|
||||
clearSql(
|
||||
lastRotated,
|
||||
"Ledgers",
|
||||
[&db]() -> std::optional<LedgerIndex> { return db.getMinLedgerSeq(); },
|
||||
[&db](LedgerIndex min) -> void { db.deleteBeforeLedgerSeq(min); });
|
||||
[db]() -> std::optional<LedgerIndex> { return db->getMinLedgerSeq(); },
|
||||
[db](LedgerIndex min) -> void { db->deleteBeforeLedgerSeq(min); });
|
||||
if (healthWait() == stopping)
|
||||
return;
|
||||
|
||||
@@ -523,16 +526,16 @@ SHAMapStoreImp::clearPrior(LedgerIndex lastRotated)
|
||||
clearSql(
|
||||
lastRotated,
|
||||
"Transactions",
|
||||
[&db]() -> std::optional<LedgerIndex> { return db.getTransactionsMinLedgerSeq(); },
|
||||
[&db](LedgerIndex min) -> void { db.deleteTransactionsBeforeLedgerSeq(min); });
|
||||
[&db]() -> std::optional<LedgerIndex> { return db->getTransactionsMinLedgerSeq(); },
|
||||
[&db](LedgerIndex min) -> void { db->deleteTransactionsBeforeLedgerSeq(min); });
|
||||
if (healthWait() == stopping)
|
||||
return;
|
||||
|
||||
clearSql(
|
||||
lastRotated,
|
||||
"AccountTransactions",
|
||||
[&db]() -> std::optional<LedgerIndex> { return db.getAccountTransactionsMinLedgerSeq(); },
|
||||
[&db](LedgerIndex min) -> void { db.deleteAccountTransactionsBeforeLedgerSeq(min); });
|
||||
[&db]() -> std::optional<LedgerIndex> { return db->getAccountTransactionsMinLedgerSeq(); },
|
||||
[&db](LedgerIndex min) -> void { db->deleteAccountTransactionsBeforeLedgerSeq(min); });
|
||||
if (healthWait() == stopping)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/app/misc/SHAMapStore.h>
|
||||
#include <xrpld/app/rdb/State.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
|
||||
#include <xrpl/nodestore/DatabaseRotating.h>
|
||||
#include <xrpl/nodestore/Scheduler.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/server/State.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxMeta.h>
|
||||
#include <xrpl/protocol/TxSearched.h>
|
||||
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
@@ -36,6 +35,8 @@ 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<Transaction>, public CountedObject<Transaction>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpld/core/TimeKeeper.h>
|
||||
#include <xrpld/overlay/Message.h>
|
||||
|
||||
@@ -8,7 +9,6 @@
|
||||
#include <xrpl/crypto/csprng.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/AmendmentTable.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/STValidation.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/server/Wallet.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/basics/base64.h>
|
||||
#include <xrpl/json/json_reader.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/Sign.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
#include <xrpl/server/Wallet.h>
|
||||
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/HashRouter.h>
|
||||
#include <xrpld/app/misc/Transaction.h>
|
||||
#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
|
||||
#include <xrpld/app/tx/apply.h>
|
||||
#include <xrpld/rpc/CTID.h>
|
||||
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -113,9 +113,14 @@ Transaction::load(
|
||||
std::optional<ClosedInterval<uint32_t>> const& range,
|
||||
error_code_i& ec)
|
||||
{
|
||||
auto& db = app.getRelationalDatabase();
|
||||
auto const db = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
|
||||
|
||||
return db.getTransaction(id, range, ec);
|
||||
if (!db)
|
||||
{
|
||||
Throw<std::runtime_error>("Failed to get relational database");
|
||||
}
|
||||
|
||||
return db->getTransaction(id, range, ec);
|
||||
}
|
||||
|
||||
// options 1 to include the date of the transaction
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpld/app/misc/ValidatorKeys.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base64.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
|
||||
namespace xrpl {
|
||||
ValidatorKeys::ValidatorKeys(Config const& config, beast::Journal j)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/peerfinder/detail/Store.h>
|
||||
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
|
||||
226
src/xrpld/app/rdb/RelationalDatabase.h
Normal file
226
src/xrpld/app/rdb/RelationalDatabase.h
Normal file
@@ -0,0 +1,226 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/Transaction.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/rpc/detail/RPCLedgerHelpers.h>
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
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<AccountTxMarker> marker;
|
||||
std::uint32_t limit;
|
||||
bool bAdmin;
|
||||
};
|
||||
|
||||
using AccountTx = std::pair<std::shared_ptr<Transaction>, std::shared_ptr<TxMeta>>;
|
||||
using AccountTxs = std::vector<AccountTx>;
|
||||
using txnMetaLedgerType = std::tuple<Blob, Blob, std::uint32_t>;
|
||||
using MetaTxsList = std::vector<txnMetaLedgerType>;
|
||||
|
||||
using LedgerSequence = uint32_t;
|
||||
using LedgerHash = uint256;
|
||||
using LedgerShortcut = RPC::LedgerShortcut;
|
||||
using LedgerSpecifier = std::variant<LedgerRange, LedgerShortcut, LedgerSequence, LedgerHash>;
|
||||
|
||||
struct AccountTxArgs
|
||||
{
|
||||
AccountID account;
|
||||
std::optional<LedgerSpecifier> ledger;
|
||||
bool binary = false;
|
||||
bool forward = false;
|
||||
uint32_t limit = 0;
|
||||
std::optional<AccountTxMarker> marker;
|
||||
};
|
||||
|
||||
struct AccountTxResult
|
||||
{
|
||||
std::variant<AccountTxs, MetaTxsList> transactions;
|
||||
LedgerRange ledgerRange;
|
||||
uint32_t limit;
|
||||
std::optional<AccountTxMarker> marker;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief init Creates and returns an appropriate RelationalDatabase
|
||||
* instance based on configuration.
|
||||
* @param app Application object.
|
||||
* @param config Config object.
|
||||
* @param jobQueue JobQueue object.
|
||||
* @return Unique pointer to the interface.
|
||||
*/
|
||||
static std::unique_ptr<RelationalDatabase>
|
||||
init(Application& app, 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<LedgerIndex>
|
||||
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<LedgerIndex>
|
||||
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<LedgerHeader>
|
||||
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<LedgerHeader>
|
||||
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<LedgerHeader>
|
||||
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<LedgerHashPair>
|
||||
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<LedgerIndex, LedgerHashPair>
|
||||
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<std::shared_ptr<Transaction>>
|
||||
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 <class T, class C>
|
||||
T
|
||||
rangeCheckedCast(C c)
|
||||
{
|
||||
if ((c > std::numeric_limits<T>::max()) || (!std::numeric_limits<T>::is_signed && c < 0) ||
|
||||
(std::numeric_limits<T>::is_signed && std::numeric_limits<C>::is_signed &&
|
||||
c < std::numeric_limits<T>::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<T>::lowest()
|
||||
<< " max: " << std::numeric_limits<T>::max();
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
return static_cast<T>(c);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/peerfinder/detail/Store.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/core/PeerReservationTable.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/overlay/PeerReservationTable.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -1,130 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
|
||||
#include <memory>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class Config;
|
||||
class JobQueue;
|
||||
class ServiceRegistry;
|
||||
|
||||
class SQLiteDatabase final : public RelationalDatabase
|
||||
class SQLiteDatabase : 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<LedgerIndex>
|
||||
getMinLedgerSeq() override;
|
||||
|
||||
/**
|
||||
* @brief getMaxLedgerSeq Returns the maximum ledger sequence in the Ledgers
|
||||
* table.
|
||||
* @return Ledger sequence or none if no ledgers exist.
|
||||
*/
|
||||
std::optional<LedgerIndex>
|
||||
getMaxLedgerSeq() override;
|
||||
|
||||
/**
|
||||
* @brief getLedgerInfoByIndex Returns a ledger by its sequence.
|
||||
* @param ledgerSeq Ledger sequence.
|
||||
* @return The ledger if found, otherwise no value.
|
||||
*/
|
||||
std::optional<LedgerHeader>
|
||||
getLedgerInfoByIndex(LedgerIndex ledgerSeq) override;
|
||||
|
||||
/**
|
||||
* @brief getNewestLedgerInfo Returns the info of the newest saved ledger.
|
||||
* @return Ledger info if found, otherwise no value.
|
||||
*/
|
||||
std::optional<LedgerHeader>
|
||||
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<LedgerHeader>
|
||||
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<LedgerHashPair>
|
||||
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<LedgerIndex, LedgerHashPair>
|
||||
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<std::shared_ptr<Transaction>>
|
||||
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.
|
||||
*/
|
||||
std::optional<LedgerIndex>
|
||||
getTransactionsMinLedgerSeq() override;
|
||||
virtual std::optional<LedgerIndex>
|
||||
getTransactionsMinLedgerSeq() = 0;
|
||||
|
||||
/**
|
||||
* @brief getAccountTransactionsMinLedgerSeq Returns the minimum ledger
|
||||
* sequence stored in the AccountTransactions table.
|
||||
* @return Ledger sequence or no value if no ledgers exist.
|
||||
*/
|
||||
std::optional<LedgerIndex>
|
||||
getAccountTransactionsMinLedgerSeq() override;
|
||||
virtual std::optional<LedgerIndex>
|
||||
getAccountTransactionsMinLedgerSeq() = 0;
|
||||
|
||||
/**
|
||||
* @brief deleteTransactionByLedgerSeq Deletes transactions from the ledger
|
||||
* with the given sequence.
|
||||
* @param ledgerSeq Ledger sequence.
|
||||
*/
|
||||
void
|
||||
deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) override;
|
||||
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.
|
||||
*/
|
||||
void
|
||||
deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) override;
|
||||
virtual void
|
||||
deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0;
|
||||
|
||||
/**
|
||||
* @brief deleteTransactionsBeforeLedgerSeq Deletes all transactions with
|
||||
@@ -132,8 +45,8 @@ public:
|
||||
* sequence.
|
||||
* @param ledgerSeq Ledger sequence.
|
||||
*/
|
||||
void
|
||||
deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override;
|
||||
virtual void
|
||||
deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0;
|
||||
|
||||
/**
|
||||
* @brief deleteAccountTransactionsBeforeLedgerSeq Deletes all account
|
||||
@@ -141,23 +54,23 @@ public:
|
||||
* given ledger sequence.
|
||||
* @param ledgerSeq Ledger sequence.
|
||||
*/
|
||||
void
|
||||
deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override;
|
||||
virtual void
|
||||
deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) = 0;
|
||||
|
||||
/**
|
||||
* @brief getTransactionCount Returns the number of transactions.
|
||||
* @return Number of transactions.
|
||||
*/
|
||||
std::size_t
|
||||
getTransactionCount() override;
|
||||
virtual std::size_t
|
||||
getTransactionCount() = 0;
|
||||
|
||||
/**
|
||||
* @brief getAccountTransactionCount Returns the number of account
|
||||
* transactions.
|
||||
* @return Number of account transactions.
|
||||
*/
|
||||
std::size_t
|
||||
getAccountTransactionCount() override;
|
||||
virtual std::size_t
|
||||
getAccountTransactionCount() = 0;
|
||||
|
||||
/**
|
||||
* @brief getLedgerCountMinMax Returns the minimum ledger sequence,
|
||||
@@ -165,8 +78,8 @@ public:
|
||||
* @return Struct CountMinMax which contains the minimum sequence,
|
||||
* maximum sequence and number of ledgers.
|
||||
*/
|
||||
CountMinMax
|
||||
getLedgerCountMinMax() override;
|
||||
virtual struct CountMinMax
|
||||
getLedgerCountMinMax() = 0;
|
||||
|
||||
/**
|
||||
* @brief saveValidatedLedger Saves a ledger into the database.
|
||||
@@ -174,8 +87,8 @@ public:
|
||||
* @param current True if the ledger is current.
|
||||
* @return True if saving was successful.
|
||||
*/
|
||||
bool
|
||||
saveValidatedLedger(std::shared_ptr<Ledger const> const& ledger, bool current) override;
|
||||
virtual bool
|
||||
saveValidatedLedger(std::shared_ptr<Ledger const> const& ledger, bool current) = 0;
|
||||
|
||||
/**
|
||||
* @brief getLimitedOldestLedgerInfo Returns the info of the oldest ledger
|
||||
@@ -184,8 +97,8 @@ public:
|
||||
* @param ledgerFirstIndex Minimum ledger sequence.
|
||||
* @return Ledger info if found, otherwise no value.
|
||||
*/
|
||||
std::optional<LedgerHeader>
|
||||
getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) override;
|
||||
virtual std::optional<LedgerHeader>
|
||||
getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) = 0;
|
||||
|
||||
/**
|
||||
* @brief getLimitedNewestLedgerInfo Returns the info of the newest ledger
|
||||
@@ -194,8 +107,8 @@ public:
|
||||
* @param ledgerFirstIndex Minimum ledger sequence.
|
||||
* @return Ledger info if found, otherwise no value.
|
||||
*/
|
||||
std::optional<LedgerHeader>
|
||||
getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) override;
|
||||
virtual std::optional<LedgerHeader>
|
||||
getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) = 0;
|
||||
|
||||
/**
|
||||
* @brief getOldestAccountTxs Returns the oldest transactions for the
|
||||
@@ -208,8 +121,8 @@ public:
|
||||
* @return Vector of pairs of found transactions and their metadata
|
||||
* sorted in ascending order by account sequence.
|
||||
*/
|
||||
AccountTxs
|
||||
getOldestAccountTxs(AccountTxOptions const& options) override;
|
||||
virtual AccountTxs
|
||||
getOldestAccountTxs(AccountTxOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief getNewestAccountTxs Returns the newest transactions for the
|
||||
@@ -222,8 +135,8 @@ public:
|
||||
* @return Vector of pairs of found transactions and their metadata
|
||||
* sorted in descending order by account sequence.
|
||||
*/
|
||||
AccountTxs
|
||||
getNewestAccountTxs(AccountTxOptions const& options) override;
|
||||
virtual AccountTxs
|
||||
getNewestAccountTxs(AccountTxOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief getOldestAccountTxsB Returns the oldest transactions in binary
|
||||
@@ -236,8 +149,8 @@ public:
|
||||
* @return Vector of tuples of found transactions, their metadata and
|
||||
* account sequences sorted in ascending order by account sequence.
|
||||
*/
|
||||
MetaTxsList
|
||||
getOldestAccountTxsB(AccountTxOptions const& options) override;
|
||||
virtual MetaTxsList
|
||||
getOldestAccountTxsB(AccountTxOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief getNewestAccountTxsB Returns the newest transactions in binary
|
||||
@@ -251,8 +164,8 @@ public:
|
||||
* account sequences sorted in descending order by account
|
||||
* sequence.
|
||||
*/
|
||||
MetaTxsList
|
||||
getNewestAccountTxsB(AccountTxOptions const& options) override;
|
||||
virtual MetaTxsList
|
||||
getNewestAccountTxsB(AccountTxOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief oldestAccountTxPage Returns the oldest transactions for the
|
||||
@@ -266,8 +179,8 @@ public:
|
||||
* sorted in ascending order by account sequence and a marker
|
||||
* for the next search if the search was not finished.
|
||||
*/
|
||||
std::pair<AccountTxs, std::optional<AccountTxMarker>>
|
||||
oldestAccountTxPage(AccountTxPageOptions const& options) override;
|
||||
virtual std::pair<AccountTxs, std::optional<AccountTxMarker>>
|
||||
oldestAccountTxPage(AccountTxPageOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief newestAccountTxPage Returns the newest transactions for the
|
||||
@@ -281,8 +194,8 @@ public:
|
||||
* sorted in descending order by account sequence and a marker
|
||||
* for the next search if the search was not finished.
|
||||
*/
|
||||
std::pair<AccountTxs, std::optional<AccountTxMarker>>
|
||||
newestAccountTxPage(AccountTxPageOptions const& options) override;
|
||||
virtual std::pair<AccountTxs, std::optional<AccountTxMarker>>
|
||||
newestAccountTxPage(AccountTxPageOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief oldestAccountTxPageB Returns the oldest transactions in binary
|
||||
@@ -297,8 +210,8 @@ public:
|
||||
* sequence and a marker for the next search if the search was not
|
||||
* finished.
|
||||
*/
|
||||
std::pair<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
oldestAccountTxPageB(AccountTxPageOptions const& options) override;
|
||||
virtual std::pair<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
oldestAccountTxPageB(AccountTxPageOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief newestAccountTxPageB Returns the newest transactions in binary
|
||||
@@ -313,8 +226,8 @@ public:
|
||||
* sequence and a marker for the next search if the search was not
|
||||
* finished.
|
||||
*/
|
||||
std::pair<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
newestAccountTxPageB(AccountTxPageOptions const& options) override;
|
||||
virtual std::pair<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
newestAccountTxPageB(AccountTxPageOptions const& options) = 0;
|
||||
|
||||
/**
|
||||
* @brief getTransaction Returns the transaction with the given hash. If a
|
||||
@@ -331,146 +244,43 @@ public:
|
||||
* error code is returned via the ec parameter, in other cases the
|
||||
* default error code is not changed.
|
||||
*/
|
||||
std::variant<AccountTx, TxSearched>
|
||||
getTransaction(uint256 const& id, std::optional<ClosedInterval<std::uint32_t>> const& range, error_code_i& ec)
|
||||
override;
|
||||
virtual std::variant<AccountTx, TxSearched>
|
||||
getTransaction(uint256 const& id, std::optional<ClosedInterval<uint32_t>> const& range, error_code_i& ec) = 0;
|
||||
|
||||
/**
|
||||
* @brief getKBUsedAll Returns the amount of space used by all databases.
|
||||
* @return Space in kilobytes.
|
||||
*/
|
||||
std::uint32_t
|
||||
getKBUsedAll() override;
|
||||
virtual uint32_t
|
||||
getKBUsedAll() = 0;
|
||||
|
||||
/**
|
||||
* @brief getKBUsedLedger Returns the amount of space space used by the
|
||||
* ledger database.
|
||||
* @return Space in kilobytes.
|
||||
*/
|
||||
std::uint32_t
|
||||
getKBUsedLedger() override;
|
||||
virtual uint32_t
|
||||
getKBUsedLedger() = 0;
|
||||
|
||||
/**
|
||||
* @brief getKBUsedTransaction Returns the amount of space used by the
|
||||
* transaction database.
|
||||
* @return Space in kilobytes.
|
||||
*/
|
||||
std::uint32_t
|
||||
getKBUsedTransaction() override;
|
||||
virtual uint32_t
|
||||
getKBUsedTransaction() = 0;
|
||||
|
||||
/**
|
||||
* @brief Closes the ledger database
|
||||
*/
|
||||
void
|
||||
closeLedgerDB() override;
|
||||
virtual void
|
||||
closeLedgerDB() = 0;
|
||||
|
||||
/**
|
||||
* @brief Closes the transaction database
|
||||
*/
|
||||
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<DatabaseCon> 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<bool>(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<bool>(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();
|
||||
}
|
||||
virtual void
|
||||
closeTransactionDB() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
#include <xrpld/app/ledger/LedgerToJson.h>
|
||||
#include <xrpld/app/ledger/PendingSaves.h>
|
||||
#include <xrpld/app/ledger/TransactionMaster.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/app/rdb/backend/detail/Node.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/core/SociDB.h>
|
||||
|
||||
#include <xrpl/basics/BasicConfig.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
|
||||
@@ -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 == StartUpType::LOAD || setup.startUp == StartUpType::LOAD_FILE ||
|
||||
setup.startUp == StartUpType::REPLAY)
|
||||
if (!setup.standAlone || setup.startUp == Config::LOAD || setup.startUp == Config::LOAD_FILE ||
|
||||
setup.startUp == Config::REPLAY)
|
||||
{
|
||||
// Check if AccountTransactions has primary key
|
||||
std::string cid, name, type;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/ledger/Ledger.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
|
||||
namespace xrpl {
|
||||
namespace detail {
|
||||
|
||||
|
||||
@@ -3,15 +3,207 @@
|
||||
#include <xrpld/app/misc/detail/AccountTxPaging.h>
|
||||
#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
|
||||
#include <xrpld/app/rdb/backend/detail/Node.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/core/SociDB.h>
|
||||
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
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"))
|
||||
{
|
||||
DatabaseCon::Setup const setup = setup_DatabaseCon(config, j_);
|
||||
if (!makeLedgerDBs(config, setup, DatabaseCon::CheckpointerSetup{&jobQueue, &app_.logs()}))
|
||||
{
|
||||
std::string_view constexpr error = "Failed to create ledger databases";
|
||||
|
||||
JLOG(j_.fatal()) << error;
|
||||
Throw<std::runtime_error>(error.data());
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
getMinLedgerSeq() override;
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
getTransactionsMinLedgerSeq() override;
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
getAccountTransactionsMinLedgerSeq() override;
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
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<Ledger const> const& ledger, bool current) override;
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
getLedgerInfoByIndex(LedgerIndex ledgerSeq) override;
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
getNewestLedgerInfo() override;
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) override;
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) override;
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
getLedgerInfoByHash(uint256 const& ledgerHash) override;
|
||||
|
||||
uint256
|
||||
getHashByIndex(LedgerIndex ledgerIndex) override;
|
||||
|
||||
std::optional<LedgerHashPair>
|
||||
getHashesByIndex(LedgerIndex ledgerIndex) override;
|
||||
|
||||
std::map<LedgerIndex, LedgerHashPair>
|
||||
getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) override;
|
||||
|
||||
std::vector<std::shared_ptr<Transaction>>
|
||||
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<AccountTxs, std::optional<AccountTxMarker>>
|
||||
oldestAccountTxPage(AccountTxPageOptions const& options) override;
|
||||
|
||||
std::pair<AccountTxs, std::optional<AccountTxMarker>>
|
||||
newestAccountTxPage(AccountTxPageOptions const& options) override;
|
||||
|
||||
std::pair<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
oldestAccountTxPageB(AccountTxPageOptions const& options) override;
|
||||
|
||||
std::pair<MetaTxsList, std::optional<AccountTxMarker>>
|
||||
newestAccountTxPageB(AccountTxPageOptions const& options) override;
|
||||
|
||||
std::variant<AccountTx, TxSearched>
|
||||
getTransaction(uint256 const& id, std::optional<ClosedInterval<std::uint32_t>> 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:
|
||||
Application& app_;
|
||||
bool const useTxTables_;
|
||||
beast::Journal j_;
|
||||
std::unique_ptr<DatabaseCon> 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<bool>(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<bool>(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
|
||||
SQLiteDatabase::makeLedgerDBs(
|
||||
SQLiteDatabaseImp::makeLedgerDBs(
|
||||
Config const& config,
|
||||
DatabaseCon::Setup const& setup,
|
||||
DatabaseCon::CheckpointerSetup const& checkpointerSetup)
|
||||
@@ -23,7 +215,7 @@ SQLiteDatabase::makeLedgerDBs(
|
||||
}
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
SQLiteDatabase::getMinLedgerSeq()
|
||||
SQLiteDatabaseImp::getMinLedgerSeq()
|
||||
{
|
||||
/* if databases exists, use it */
|
||||
if (existsLedger())
|
||||
@@ -37,7 +229,7 @@ SQLiteDatabase::getMinLedgerSeq()
|
||||
}
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
SQLiteDatabase::getTransactionsMinLedgerSeq()
|
||||
SQLiteDatabaseImp::getTransactionsMinLedgerSeq()
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
@@ -52,7 +244,7 @@ SQLiteDatabase::getTransactionsMinLedgerSeq()
|
||||
}
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
SQLiteDatabase::getAccountTransactionsMinLedgerSeq()
|
||||
SQLiteDatabaseImp::getAccountTransactionsMinLedgerSeq()
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
@@ -67,7 +259,7 @@ SQLiteDatabase::getAccountTransactionsMinLedgerSeq()
|
||||
}
|
||||
|
||||
std::optional<LedgerIndex>
|
||||
SQLiteDatabase::getMaxLedgerSeq()
|
||||
SQLiteDatabaseImp::getMaxLedgerSeq()
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -79,7 +271,7 @@ SQLiteDatabase::getMaxLedgerSeq()
|
||||
}
|
||||
|
||||
void
|
||||
SQLiteDatabase::deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq)
|
||||
SQLiteDatabaseImp::deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return;
|
||||
@@ -93,7 +285,7 @@ SQLiteDatabase::deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq)
|
||||
}
|
||||
|
||||
void
|
||||
SQLiteDatabase::deleteBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
SQLiteDatabaseImp::deleteBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -104,7 +296,7 @@ SQLiteDatabase::deleteBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
}
|
||||
|
||||
void
|
||||
SQLiteDatabase::deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
SQLiteDatabaseImp::deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return;
|
||||
@@ -118,7 +310,7 @@ SQLiteDatabase::deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
}
|
||||
|
||||
void
|
||||
SQLiteDatabase::deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
SQLiteDatabaseImp::deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return;
|
||||
@@ -132,7 +324,7 @@ SQLiteDatabase::deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)
|
||||
}
|
||||
|
||||
std::size_t
|
||||
SQLiteDatabase::getTransactionCount()
|
||||
SQLiteDatabaseImp::getTransactionCount()
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return 0;
|
||||
@@ -147,7 +339,7 @@ SQLiteDatabase::getTransactionCount()
|
||||
}
|
||||
|
||||
std::size_t
|
||||
SQLiteDatabase::getAccountTransactionCount()
|
||||
SQLiteDatabaseImp::getAccountTransactionCount()
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return 0;
|
||||
@@ -162,7 +354,7 @@ SQLiteDatabase::getAccountTransactionCount()
|
||||
}
|
||||
|
||||
RelationalDatabase::CountMinMax
|
||||
SQLiteDatabase::getLedgerCountMinMax()
|
||||
SQLiteDatabaseImp::getLedgerCountMinMax()
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -174,11 +366,11 @@ SQLiteDatabase::getLedgerCountMinMax()
|
||||
}
|
||||
|
||||
bool
|
||||
SQLiteDatabase::saveValidatedLedger(std::shared_ptr<Ledger const> const& ledger, bool current)
|
||||
SQLiteDatabaseImp::saveValidatedLedger(std::shared_ptr<Ledger const> const& ledger, bool current)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
if (!detail::saveValidatedLedger(*ledgerDb_, txdb_, registry_.app(), ledger, current))
|
||||
if (!detail::saveValidatedLedger(*ledgerDb_, txdb_, app_, ledger, current))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -186,7 +378,7 @@ SQLiteDatabase::saveValidatedLedger(std::shared_ptr<Ledger const> const& ledger,
|
||||
}
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
SQLiteDatabase::getLedgerInfoByIndex(LedgerIndex ledgerSeq)
|
||||
SQLiteDatabaseImp::getLedgerInfoByIndex(LedgerIndex ledgerSeq)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -201,7 +393,7 @@ SQLiteDatabase::getLedgerInfoByIndex(LedgerIndex ledgerSeq)
|
||||
}
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
SQLiteDatabase::getNewestLedgerInfo()
|
||||
SQLiteDatabaseImp::getNewestLedgerInfo()
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -216,7 +408,7 @@ SQLiteDatabase::getNewestLedgerInfo()
|
||||
}
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
SQLiteDatabase::getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex)
|
||||
SQLiteDatabaseImp::getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -231,7 +423,7 @@ SQLiteDatabase::getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex)
|
||||
}
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
SQLiteDatabase::getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex)
|
||||
SQLiteDatabaseImp::getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -246,7 +438,7 @@ SQLiteDatabase::getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex)
|
||||
}
|
||||
|
||||
std::optional<LedgerHeader>
|
||||
SQLiteDatabase::getLedgerInfoByHash(uint256 const& ledgerHash)
|
||||
SQLiteDatabaseImp::getLedgerInfoByHash(uint256 const& ledgerHash)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -261,7 +453,7 @@ SQLiteDatabase::getLedgerInfoByHash(uint256 const& ledgerHash)
|
||||
}
|
||||
|
||||
uint256
|
||||
SQLiteDatabase::getHashByIndex(LedgerIndex ledgerIndex)
|
||||
SQLiteDatabaseImp::getHashByIndex(LedgerIndex ledgerIndex)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -276,7 +468,7 @@ SQLiteDatabase::getHashByIndex(LedgerIndex ledgerIndex)
|
||||
}
|
||||
|
||||
std::optional<LedgerHashPair>
|
||||
SQLiteDatabase::getHashesByIndex(LedgerIndex ledgerIndex)
|
||||
SQLiteDatabaseImp::getHashesByIndex(LedgerIndex ledgerIndex)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -291,7 +483,7 @@ SQLiteDatabase::getHashesByIndex(LedgerIndex ledgerIndex)
|
||||
}
|
||||
|
||||
std::map<LedgerIndex, LedgerHashPair>
|
||||
SQLiteDatabase::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq)
|
||||
SQLiteDatabaseImp::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -306,7 +498,7 @@ SQLiteDatabase::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq)
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Transaction>>
|
||||
SQLiteDatabase::getTxHistory(LedgerIndex startIndex)
|
||||
SQLiteDatabaseImp::getTxHistory(LedgerIndex startIndex)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
@@ -314,7 +506,7 @@ SQLiteDatabase::getTxHistory(LedgerIndex startIndex)
|
||||
if (existsTransaction())
|
||||
{
|
||||
auto db = checkoutTransaction();
|
||||
auto const res = detail::getTxHistory(*db, registry_.app(), startIndex, 20).first;
|
||||
auto const res = detail::getTxHistory(*db, app_, startIndex, 20).first;
|
||||
|
||||
if (!res.empty())
|
||||
return res;
|
||||
@@ -324,41 +516,41 @@ SQLiteDatabase::getTxHistory(LedgerIndex startIndex)
|
||||
}
|
||||
|
||||
RelationalDatabase::AccountTxs
|
||||
SQLiteDatabase::getOldestAccountTxs(AccountTxOptions const& options)
|
||||
SQLiteDatabaseImp::getOldestAccountTxs(AccountTxOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
|
||||
LedgerMaster& ledgerMaster = registry_.getLedgerMaster();
|
||||
LedgerMaster& ledgerMaster = app_.getLedgerMaster();
|
||||
|
||||
if (existsTransaction())
|
||||
{
|
||||
auto db = checkoutTransaction();
|
||||
return detail::getOldestAccountTxs(*db, registry_.app(), ledgerMaster, options, j_).first;
|
||||
return detail::getOldestAccountTxs(*db, app_, ledgerMaster, options, j_).first;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
RelationalDatabase::AccountTxs
|
||||
SQLiteDatabase::getNewestAccountTxs(AccountTxOptions const& options)
|
||||
SQLiteDatabaseImp::getNewestAccountTxs(AccountTxOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
|
||||
LedgerMaster& ledgerMaster = registry_.getLedgerMaster();
|
||||
LedgerMaster& ledgerMaster = app_.getLedgerMaster();
|
||||
|
||||
if (existsTransaction())
|
||||
{
|
||||
auto db = checkoutTransaction();
|
||||
return detail::getNewestAccountTxs(*db, registry_.app(), ledgerMaster, options, j_).first;
|
||||
return detail::getNewestAccountTxs(*db, app_, ledgerMaster, options, j_).first;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
RelationalDatabase::MetaTxsList
|
||||
SQLiteDatabase::getOldestAccountTxsB(AccountTxOptions const& options)
|
||||
SQLiteDatabaseImp::getOldestAccountTxsB(AccountTxOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
@@ -366,14 +558,14 @@ SQLiteDatabase::getOldestAccountTxsB(AccountTxOptions const& options)
|
||||
if (existsTransaction())
|
||||
{
|
||||
auto db = checkoutTransaction();
|
||||
return detail::getOldestAccountTxsB(*db, registry_.app(), options, j_).first;
|
||||
return detail::getOldestAccountTxsB(*db, app_, options, j_).first;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
RelationalDatabase::MetaTxsList
|
||||
SQLiteDatabase::getNewestAccountTxsB(AccountTxOptions const& options)
|
||||
SQLiteDatabaseImp::getNewestAccountTxsB(AccountTxOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
@@ -381,22 +573,23 @@ SQLiteDatabase::getNewestAccountTxsB(AccountTxOptions const& options)
|
||||
if (existsTransaction())
|
||||
{
|
||||
auto db = checkoutTransaction();
|
||||
return detail::getNewestAccountTxsB(*db, registry_.app(), options, j_).first;
|
||||
return detail::getNewestAccountTxsB(*db, app_, options, j_).first;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::pair<RelationalDatabase::AccountTxs, std::optional<RelationalDatabase::AccountTxMarker>>
|
||||
SQLiteDatabase::oldestAccountTxPage(AccountTxPageOptions const& options)
|
||||
SQLiteDatabaseImp::oldestAccountTxPage(AccountTxPageOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
|
||||
static std::uint32_t const page_length(200);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1);
|
||||
AccountTxs ret;
|
||||
auto onTransaction = [&ret, &app = registry_.app()](
|
||||
Application& app = app_;
|
||||
auto onTransaction = [&ret, &app](
|
||||
std::uint32_t ledger_index, std::string const& status, Blob&& rawTxn, Blob&& rawMeta) {
|
||||
convertBlobsToTxResult(ret, ledger_index, status, rawTxn, rawMeta, app);
|
||||
};
|
||||
@@ -412,15 +605,16 @@ SQLiteDatabase::oldestAccountTxPage(AccountTxPageOptions const& options)
|
||||
}
|
||||
|
||||
std::pair<RelationalDatabase::AccountTxs, std::optional<RelationalDatabase::AccountTxMarker>>
|
||||
SQLiteDatabase::newestAccountTxPage(AccountTxPageOptions const& options)
|
||||
SQLiteDatabaseImp::newestAccountTxPage(AccountTxPageOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
|
||||
static std::uint32_t const page_length(200);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1);
|
||||
AccountTxs ret;
|
||||
auto onTransaction = [&ret, &app = registry_.app()](
|
||||
Application& app = app_;
|
||||
auto onTransaction = [&ret, &app](
|
||||
std::uint32_t ledger_index, std::string const& status, Blob&& rawTxn, Blob&& rawMeta) {
|
||||
convertBlobsToTxResult(ret, ledger_index, status, rawTxn, rawMeta, app);
|
||||
};
|
||||
@@ -436,13 +630,13 @@ SQLiteDatabase::newestAccountTxPage(AccountTxPageOptions const& options)
|
||||
}
|
||||
|
||||
std::pair<RelationalDatabase::MetaTxsList, std::optional<RelationalDatabase::AccountTxMarker>>
|
||||
SQLiteDatabase::oldestAccountTxPageB(AccountTxPageOptions const& options)
|
||||
SQLiteDatabaseImp::oldestAccountTxPageB(AccountTxPageOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
|
||||
static std::uint32_t const page_length(500);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(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);
|
||||
@@ -459,13 +653,13 @@ SQLiteDatabase::oldestAccountTxPageB(AccountTxPageOptions const& options)
|
||||
}
|
||||
|
||||
std::pair<RelationalDatabase::MetaTxsList, std::optional<RelationalDatabase::AccountTxMarker>>
|
||||
SQLiteDatabase::newestAccountTxPageB(AccountTxPageOptions const& options)
|
||||
SQLiteDatabaseImp::newestAccountTxPageB(AccountTxPageOptions const& options)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return {};
|
||||
|
||||
static std::uint32_t const page_length(500);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(registry_.app()), std::placeholders::_1);
|
||||
auto onUnsavedLedger = std::bind(saveLedgerAsync, std::ref(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);
|
||||
@@ -482,7 +676,7 @@ SQLiteDatabase::newestAccountTxPageB(AccountTxPageOptions const& options)
|
||||
}
|
||||
|
||||
std::variant<RelationalDatabase::AccountTx, TxSearched>
|
||||
SQLiteDatabase::getTransaction(
|
||||
SQLiteDatabaseImp::getTransaction(
|
||||
uint256 const& id,
|
||||
std::optional<ClosedInterval<std::uint32_t>> const& range,
|
||||
error_code_i& ec)
|
||||
@@ -493,14 +687,14 @@ SQLiteDatabase::getTransaction(
|
||||
if (existsTransaction())
|
||||
{
|
||||
auto db = checkoutTransaction();
|
||||
return detail::getTransaction(*db, registry_.app(), id, range, ec);
|
||||
return detail::getTransaction(*db, app_, id, range, ec);
|
||||
}
|
||||
|
||||
return TxSearched::unknown;
|
||||
}
|
||||
|
||||
bool
|
||||
SQLiteDatabase::ledgerDbHasSpace(Config const& config)
|
||||
SQLiteDatabaseImp::ledgerDbHasSpace(Config const& config)
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -512,7 +706,7 @@ SQLiteDatabase::ledgerDbHasSpace(Config const& config)
|
||||
}
|
||||
|
||||
bool
|
||||
SQLiteDatabase::transactionDbHasSpace(Config const& config)
|
||||
SQLiteDatabaseImp::transactionDbHasSpace(Config const& config)
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return true;
|
||||
@@ -527,7 +721,7 @@ SQLiteDatabase::transactionDbHasSpace(Config const& config)
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
SQLiteDatabase::getKBUsedAll()
|
||||
SQLiteDatabaseImp::getKBUsedAll()
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -538,7 +732,7 @@ SQLiteDatabase::getKBUsedAll()
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
SQLiteDatabase::getKBUsedLedger()
|
||||
SQLiteDatabaseImp::getKBUsedLedger()
|
||||
{
|
||||
if (existsLedger())
|
||||
{
|
||||
@@ -549,7 +743,7 @@ SQLiteDatabase::getKBUsedLedger()
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
SQLiteDatabase::getKBUsedTransaction()
|
||||
SQLiteDatabaseImp::getKBUsedTransaction()
|
||||
{
|
||||
if (!useTxTables_)
|
||||
return 0;
|
||||
@@ -563,43 +757,21 @@ SQLiteDatabase::getKBUsedTransaction()
|
||||
}
|
||||
|
||||
void
|
||||
SQLiteDatabase::closeLedgerDB()
|
||||
SQLiteDatabaseImp::closeLedgerDB()
|
||||
{
|
||||
ledgerDb_.reset();
|
||||
}
|
||||
|
||||
void
|
||||
SQLiteDatabase::closeTransactionDB()
|
||||
SQLiteDatabaseImp::closeTransactionDB()
|
||||
{
|
||||
txdb_.reset();
|
||||
}
|
||||
|
||||
SQLiteDatabase::SQLiteDatabase(ServiceRegistry& registry, Config const& config, JobQueue& jobQueue)
|
||||
: registry_(registry), useTxTables_(config.useTxTables()), j_(registry.journal("SQLiteDatabase"))
|
||||
std::unique_ptr<RelationalDatabase>
|
||||
getSQLiteDatabase(Application& app, Config const& config, JobQueue& 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<std::runtime_error>(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};
|
||||
return std::make_unique<SQLiteDatabaseImp>(app, config, jobQueue);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/core/ConfigSections.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
extern std::unique_ptr<RelationalDatabase>
|
||||
getSQLiteDatabase(Application& app, Config const& config, JobQueue& jobQueue);
|
||||
|
||||
std::unique_ptr<RelationalDatabase>
|
||||
RelationalDatabase::init(Application& app, 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<std::runtime_error>("Invalid rdb_section backend value: " + get(rdb_section, "backend"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
use_sqlite = true;
|
||||
}
|
||||
|
||||
if (use_sqlite)
|
||||
{
|
||||
return getSQLiteDatabase(app, config, jobQueue);
|
||||
}
|
||||
|
||||
return std::unique_ptr<RelationalDatabase>();
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <xrpl/server/State.h>
|
||||
#include <xrpld/app/rdb/State.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include <xrpl/server/Vacuum.h>
|
||||
#include <xrpld/app/rdb/Vacuum.h>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
bool
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <xrpl/rdb/DBInit.h>
|
||||
#include <xrpl/server/Wallet.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/net/IPEndpoint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/StartUpType.h>
|
||||
#include <xrpl/protocol/SystemParameters.h> // VFALCO Breaks levelization
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
|
||||
#include <boost/filesystem.hpp> // VFALCO FIX: This include should not be here
|
||||
|
||||
@@ -126,7 +124,8 @@ public:
|
||||
// Entries from [ips_fixed] config stanza
|
||||
std::vector<std::string> IPS_FIXED;
|
||||
|
||||
StartUpType START_UP = StartUpType::NORMAL;
|
||||
enum StartUpType { FRESH, NORMAL, LOAD, LOAD_FILE, REPLAY, NETWORK };
|
||||
StartUpType START_UP = NORMAL;
|
||||
|
||||
bool START_VALID = false;
|
||||
|
||||
@@ -356,7 +355,4 @@ public:
|
||||
FeeSetup
|
||||
setup_FeeVote(Section const& section);
|
||||
|
||||
DatabaseCon::Setup
|
||||
setup_DatabaseCon(Config const& c, std::optional<beast::Journal> j = std::nullopt);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/main/DBInit.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/SociDB.h>
|
||||
|
||||
#include <xrpl/core/PerfLog.h>
|
||||
#include <xrpl/core/StartUpType.h>
|
||||
#include <xrpl/rdb/DBInit.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
{
|
||||
explicit Setup() = default;
|
||||
|
||||
StartUpType startUp = StartUpType::NORMAL;
|
||||
Config::StartUpType startUp = Config::NORMAL;
|
||||
bool standAlone = false;
|
||||
boost::filesystem::path dataDir;
|
||||
// Indicates whether or not to return the `globalPragma`
|
||||
@@ -104,8 +105,8 @@ public:
|
||||
beast::Journal journal)
|
||||
// Use temporary files or regular DB files?
|
||||
: DatabaseCon(
|
||||
setup.standAlone && setup.startUp != StartUpType::LOAD && setup.startUp != StartUpType::LOAD_FILE &&
|
||||
setup.startUp != StartUpType::REPLAY
|
||||
setup.standAlone && setup.startUp != Config::LOAD && setup.startUp != Config::LOAD_FILE &&
|
||||
setup.startUp != Config::REPLAY
|
||||
? ""
|
||||
: (setup.dataDir / dbName),
|
||||
setup.commonPragma(),
|
||||
@@ -228,4 +229,7 @@ private:
|
||||
std::shared_ptr<Checkpointer>
|
||||
checkpointerFromId(std::uintptr_t id);
|
||||
|
||||
DatabaseCon::Setup
|
||||
setup_DatabaseCon(Config const& c, std::optional<beast::Journal> j = std::nullopt);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1039,150 +1039,4 @@ setup_FeeVote(Section const& section)
|
||||
return setup;
|
||||
}
|
||||
|
||||
DatabaseCon::Setup
|
||||
setup_DatabaseCon(Config const& c, std::optional<beast::Journal> 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<std::runtime_error>("database_path must be set.");
|
||||
}
|
||||
|
||||
if (!setup.globalPragma)
|
||||
{
|
||||
auto const& sqlite = c.section("sqlite");
|
||||
auto result = std::make_unique<std::vector<std::string>>();
|
||||
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<std::runtime_error>("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<std::runtime_error>(
|
||||
"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<std::runtime_error>("Invalid journal_mode value: " + journal_mode);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// #synchronous Valid values : off, normal, full, extra
|
||||
if (set(synchronous, "synchronous", sqlite) && !safety_level.empty())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"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<std::runtime_error>("Invalid synchronous value: " + synchronous);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// #temp_store Valid values : default, file, memory
|
||||
if (set(temp_store, "temp_store", sqlite) && !safety_level.empty())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"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<std::runtime_error>("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<std::runtime_error>("Invalid page_size. Must be between 512 and 65536.");
|
||||
|
||||
if (page_size & (page_size - 1))
|
||||
Throw<std::runtime_error>("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
|
||||
|
||||
242
src/xrpld/core/detail/DatabaseCon.cpp
Normal file
242
src/xrpld/core/detail/DatabaseCon.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/core/SociDB.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
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<std::uintptr_t, std::shared_ptr<Checkpointer>> checkpointers_;
|
||||
|
||||
public:
|
||||
std::shared_ptr<Checkpointer>
|
||||
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<Checkpointer>
|
||||
create(std::shared_ptr<soci::session> 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<Checkpointer>
|
||||
checkpointerFromId(std::uintptr_t id)
|
||||
{
|
||||
return checkpointers.fromId(id);
|
||||
}
|
||||
|
||||
DatabaseCon::~DatabaseCon()
|
||||
{
|
||||
if (checkpointer_)
|
||||
{
|
||||
checkpointers.erase(checkpointer_->id());
|
||||
|
||||
std::weak_ptr<Checkpointer> 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<beast::Journal> 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<std::runtime_error>("database_path must be set.");
|
||||
}
|
||||
|
||||
if (!setup.globalPragma)
|
||||
{
|
||||
setup.globalPragma = [&c, &j]() {
|
||||
auto const& sqlite = c.section("sqlite");
|
||||
auto result = std::make_unique<std::vector<std::string>>();
|
||||
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<std::runtime_error>("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<std::runtime_error>(
|
||||
"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<std::runtime_error>("Invalid journal_mode value: " + journal_mode);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// #synchronous Valid values : off, normal, full, extra
|
||||
if (set(synchronous, "synchronous", sqlite) && !safety_level.empty())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"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<std::runtime_error>("Invalid synchronous value: " + synchronous);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// #temp_store Valid values : default, file, memory
|
||||
if (set(temp_store, "temp_store", sqlite) && !safety_level.empty())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"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<std::runtime_error>("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<std::runtime_error>("Invalid page_size. Must be between 512 and 65536.");
|
||||
|
||||
if (page_size & (page_size - 1))
|
||||
Throw<std::runtime_error>("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<std::vector<std::string> const> DatabaseCon::Setup::globalPragma;
|
||||
|
||||
void
|
||||
DatabaseCon::setupCheckpointing(JobQueue* q, Logs& l)
|
||||
{
|
||||
if (!q)
|
||||
Throw<std::logic_error>("No JobQueue");
|
||||
checkpointer_ = checkpointers.create(session_, *q, l);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -3,10 +3,12 @@
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
#endif
|
||||
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/core/DatabaseCon.h>
|
||||
#include <xrpld/core/SociDB.h>
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/rdb/DatabaseCon.h>
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <xrpld/app/misc/NetworkOPs.h>
|
||||
#include <xrpld/app/misc/ValidatorList.h>
|
||||
#include <xrpld/app/misc/ValidatorSite.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
#include <xrpld/overlay/Cluster.h>
|
||||
#include <xrpld/overlay/detail/ConnectAttempt.h>
|
||||
#include <xrpld/overlay/detail/PeerImp.h>
|
||||
@@ -17,9 +19,7 @@
|
||||
#include <xrpl/basics/random.h>
|
||||
#include <xrpl/beast/core/LexicalCast.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
#include <xrpl/server/SimpleWriter.h>
|
||||
#include <xrpl/server/Wallet.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include <xrpl/core/PeerReservationTable.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/app/rdb/Wallet.h>
|
||||
#include <xrpld/overlay/PeerReservationTable.h>
|
||||
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
#include <xrpl/server/Wallet.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/rdb/PeerFinder.h>
|
||||
#include <xrpld/core/SociDB.h>
|
||||
#include <xrpld/peerfinder/detail/Store.h>
|
||||
|
||||
#include <xrpl/rdb/SociDB.h>
|
||||
|
||||
namespace xrpl {
|
||||
namespace PeerFinder {
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/Book.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/resource/Consumer.h>
|
||||
#include <xrpl/server/Manifest.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <xrpld/app/misc/Transaction.h>
|
||||
#include <xrpld/app/paths/TrustLine.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/app/tx/detail/NFTokenUtils.h>
|
||||
#include <xrpld/rpc/Context.h>
|
||||
#include <xrpld/rpc/DeliveredAmount.h>
|
||||
@@ -9,7 +10,6 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/RPCErr.h>
|
||||
#include <xrpl/protocol/nftPageMask.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
#include <xrpl/resource/Fees.h>
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <xrpld/rpc/detail/Tuning.h>
|
||||
|
||||
#include <xrpl/proto/org/xrpl/rpc/v1/xrp_ledger.pb.h>
|
||||
#include <xrpl/protocol/LedgerShortcut.h>
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -20,6 +19,8 @@ namespace RPC {
|
||||
|
||||
struct JsonContext;
|
||||
|
||||
enum class LedgerShortcut { Current, Closed, Validated };
|
||||
|
||||
/**
|
||||
* @brief Retrieves a ledger by its hash.
|
||||
*
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <xrpld/rpc/MPTokenIssuanceID.h>
|
||||
#include <xrpld/rpc/Role.h>
|
||||
#include <xrpld/rpc/detail/RPCHelpers.h>
|
||||
#include <xrpld/rpc/detail/RPCLedgerHelpers.h>
|
||||
#include <xrpld/rpc/detail/Tuning.h>
|
||||
|
||||
#include <xrpl/json/json_value.h>
|
||||
@@ -27,6 +26,8 @@ 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
|
||||
@@ -207,19 +208,22 @@ doAccountTxHelp(RPC::Context& context, AccountTxArgs const& args)
|
||||
args.limit,
|
||||
isUnlimited(context.role)};
|
||||
|
||||
auto& db = context.app.getRelationalDatabase();
|
||||
auto const db = dynamic_cast<SQLiteDatabase*>(&context.app.getRelationalDatabase());
|
||||
|
||||
if (!db)
|
||||
Throw<std::runtime_error>("Failed to get relational database");
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -228,13 +232,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;
|
||||
}
|
||||
|
||||
@@ -49,19 +49,22 @@ getCountsJson(Application& app, int minObjectCount)
|
||||
|
||||
if (app.config().useTxTables())
|
||||
{
|
||||
auto& db = app.getRelationalDatabase();
|
||||
auto const db = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
|
||||
|
||||
auto dbKB = db.getKBUsedAll();
|
||||
if (!db)
|
||||
Throw<std::runtime_error>("Failed to get relational database");
|
||||
|
||||
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;
|
||||
|
||||
@@ -3,19 +3,18 @@
|
||||
#include <xrpld/app/misc/DeliverMax.h>
|
||||
#include <xrpld/app/misc/NetworkOPs.h>
|
||||
#include <xrpld/app/misc/Transaction.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/rpc/CTID.h>
|
||||
#include <xrpld/rpc/Context.h>
|
||||
#include <xrpld/rpc/DeliveredAmount.h>
|
||||
#include <xrpld/rpc/GRPCHandlers.h>
|
||||
#include <xrpld/rpc/MPTokenIssuanceID.h>
|
||||
#include <xrpld/rpc/Status.h>
|
||||
|
||||
#include <xrpl/basics/ToString.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/NFTSyntheticSerializer.h>
|
||||
#include <xrpl/protocol/RPCErr.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
|
||||
#include <regex>
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/DeliverMax.h>
|
||||
#include <xrpld/app/misc/Transaction.h>
|
||||
#include <xrpld/app/rdb/RelationalDatabase.h>
|
||||
#include <xrpld/rpc/Context.h>
|
||||
#include <xrpld/rpc/Role.h>
|
||||
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/RPCErr.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/rdb/RelationalDatabase.h>
|
||||
#include <xrpl/resource/Fees.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
Reference in New Issue
Block a user