mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-26 14:05:51 +00:00
Relational DB interface
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include <ripple/app/misc/ValidatorKeys.h>
|
||||
#include <ripple/app/misc/ValidatorList.h>
|
||||
#include <ripple/app/misc/impl/AccountTxPaging.h>
|
||||
#include <ripple/app/rdb/RelationalDBInterface.h>
|
||||
#include <ripple/app/reporting/ReportingETL.h>
|
||||
#include <ripple/app/tx/apply.h>
|
||||
#include <ripple/basics/PerfLog.h>
|
||||
@@ -453,66 +454,6 @@ public:
|
||||
std::size_t
|
||||
getLocalTxCount() override;
|
||||
|
||||
// Helper function to generate SQL query to get transactions.
|
||||
std::string
|
||||
transactionsSQL(
|
||||
std::string selection,
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool descending,
|
||||
std::uint32_t offset,
|
||||
int limit,
|
||||
bool binary,
|
||||
bool count,
|
||||
bool bUnlimited);
|
||||
|
||||
// Client information retrieval functions.
|
||||
using NetworkOPs::AccountTxMarker;
|
||||
using NetworkOPs::AccountTxs;
|
||||
AccountTxs
|
||||
getAccountTxs(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool descending,
|
||||
std::uint32_t offset,
|
||||
int limit,
|
||||
bool bUnlimited) override;
|
||||
|
||||
AccountTxs
|
||||
getTxsAccount(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool forward,
|
||||
std::optional<AccountTxMarker>& marker,
|
||||
int limit,
|
||||
bool bUnlimited) override;
|
||||
|
||||
using NetworkOPs::MetaTxsList;
|
||||
using NetworkOPs::txnMetaLedgerType;
|
||||
|
||||
MetaTxsList
|
||||
getAccountTxsB(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool descending,
|
||||
std::uint32_t offset,
|
||||
int limit,
|
||||
bool bUnlimited) override;
|
||||
|
||||
MetaTxsList
|
||||
getTxsAccountB(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool forward,
|
||||
std::optional<AccountTxMarker>& marker,
|
||||
int limit,
|
||||
bool bUnlimited) override;
|
||||
|
||||
//
|
||||
// Monitoring: publisher side.
|
||||
//
|
||||
@@ -2204,306 +2145,6 @@ NetworkOPsImp::setMode(OperatingMode om)
|
||||
pubServer();
|
||||
}
|
||||
|
||||
std::string
|
||||
NetworkOPsImp::transactionsSQL(
|
||||
std::string selection,
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool descending,
|
||||
std::uint32_t offset,
|
||||
int limit,
|
||||
bool binary,
|
||||
bool count,
|
||||
bool bUnlimited)
|
||||
{
|
||||
std::uint32_t NONBINARY_PAGE_LENGTH = 200;
|
||||
std::uint32_t BINARY_PAGE_LENGTH = 500;
|
||||
|
||||
std::uint32_t numberOfResults;
|
||||
|
||||
if (count)
|
||||
{
|
||||
numberOfResults = 1000000000;
|
||||
}
|
||||
else if (limit < 0)
|
||||
{
|
||||
numberOfResults = binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH;
|
||||
}
|
||||
else if (!bUnlimited)
|
||||
{
|
||||
numberOfResults = std::min(
|
||||
binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH,
|
||||
static_cast<std::uint32_t>(limit));
|
||||
}
|
||||
else
|
||||
{
|
||||
numberOfResults = limit;
|
||||
}
|
||||
|
||||
std::string maxClause = "";
|
||||
std::string minClause = "";
|
||||
|
||||
if (maxLedger != -1)
|
||||
{
|
||||
maxClause = boost::str(
|
||||
boost::format("AND AccountTransactions.LedgerSeq <= '%u'") %
|
||||
maxLedger);
|
||||
}
|
||||
|
||||
if (minLedger != -1)
|
||||
{
|
||||
minClause = boost::str(
|
||||
boost::format("AND AccountTransactions.LedgerSeq >= '%u'") %
|
||||
minLedger);
|
||||
}
|
||||
|
||||
std::string sql;
|
||||
|
||||
if (count)
|
||||
sql = boost::str(
|
||||
boost::format("SELECT %s FROM AccountTransactions "
|
||||
"WHERE Account = '%s' %s %s LIMIT %u, %u;") %
|
||||
selection % app_.accountIDCache().toBase58(account) % maxClause %
|
||||
minClause % offset % numberOfResults);
|
||||
else
|
||||
sql = boost::str(
|
||||
boost::format(
|
||||
"SELECT %s FROM "
|
||||
"AccountTransactions INNER JOIN Transactions "
|
||||
"ON Transactions.TransID = AccountTransactions.TransID "
|
||||
"WHERE Account = '%s' %s %s "
|
||||
"ORDER BY AccountTransactions.LedgerSeq %s, "
|
||||
"AccountTransactions.TxnSeq %s, AccountTransactions.TransID %s "
|
||||
"LIMIT %u, %u;") %
|
||||
selection % app_.accountIDCache().toBase58(account) % maxClause %
|
||||
minClause % (descending ? "DESC" : "ASC") %
|
||||
(descending ? "DESC" : "ASC") % (descending ? "DESC" : "ASC") %
|
||||
offset % numberOfResults);
|
||||
JLOG(m_journal.trace()) << "txSQL query: " << sql;
|
||||
return sql;
|
||||
}
|
||||
|
||||
NetworkOPs::AccountTxs
|
||||
NetworkOPsImp::getAccountTxs(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool descending,
|
||||
std::uint32_t offset,
|
||||
int limit,
|
||||
bool bUnlimited)
|
||||
{
|
||||
// can be called with no locks
|
||||
AccountTxs ret;
|
||||
|
||||
std::string sql = transactionsSQL(
|
||||
"AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
|
||||
account,
|
||||
minLedger,
|
||||
maxLedger,
|
||||
descending,
|
||||
offset,
|
||||
limit,
|
||||
false,
|
||||
false,
|
||||
bUnlimited);
|
||||
|
||||
{
|
||||
auto db = app_.getTxnDB().checkoutDb();
|
||||
|
||||
// SOCI requires boost::optional (not std::optional) as parameters.
|
||||
boost::optional<std::uint64_t> ledgerSeq;
|
||||
boost::optional<std::string> status;
|
||||
soci::blob sociTxnBlob(*db), sociTxnMetaBlob(*db);
|
||||
soci::indicator rti, tmi;
|
||||
Blob rawTxn, txnMeta;
|
||||
|
||||
soci::statement st =
|
||||
(db->prepare << sql,
|
||||
soci::into(ledgerSeq),
|
||||
soci::into(status),
|
||||
soci::into(sociTxnBlob, rti),
|
||||
soci::into(sociTxnMetaBlob, tmi));
|
||||
|
||||
st.execute();
|
||||
while (st.fetch())
|
||||
{
|
||||
if (soci::i_ok == rti)
|
||||
convert(sociTxnBlob, rawTxn);
|
||||
else
|
||||
rawTxn.clear();
|
||||
|
||||
if (soci::i_ok == tmi)
|
||||
convert(sociTxnMetaBlob, txnMeta);
|
||||
else
|
||||
txnMeta.clear();
|
||||
|
||||
auto txn = Transaction::transactionFromSQL(
|
||||
ledgerSeq, status, rawTxn, app_);
|
||||
|
||||
if (txnMeta.empty())
|
||||
{ // Work around a bug that could leave the metadata missing
|
||||
auto const seq =
|
||||
rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
|
||||
|
||||
JLOG(m_journal.warn())
|
||||
<< "Recovering ledger " << seq << ", txn " << txn->getID();
|
||||
|
||||
if (auto l = m_ledgerMaster.getLedgerBySeq(seq))
|
||||
pendSaveValidated(app_, l, false, false);
|
||||
}
|
||||
|
||||
if (txn)
|
||||
ret.emplace_back(
|
||||
txn,
|
||||
std::make_shared<TxMeta>(
|
||||
txn->getID(), txn->getLedger(), txnMeta));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<NetworkOPsImp::txnMetaLedgerType>
|
||||
NetworkOPsImp::getAccountTxsB(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool descending,
|
||||
std::uint32_t offset,
|
||||
int limit,
|
||||
bool bUnlimited)
|
||||
{
|
||||
// can be called with no locks
|
||||
std::vector<txnMetaLedgerType> ret;
|
||||
|
||||
std::string sql = transactionsSQL(
|
||||
"AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
|
||||
account,
|
||||
minLedger,
|
||||
maxLedger,
|
||||
descending,
|
||||
offset,
|
||||
limit,
|
||||
true /*binary*/,
|
||||
false,
|
||||
bUnlimited);
|
||||
|
||||
{
|
||||
auto db = app_.getTxnDB().checkoutDb();
|
||||
|
||||
// SOCI requires boost::optional (not std::optional) as parameters.
|
||||
boost::optional<std::uint64_t> ledgerSeq;
|
||||
boost::optional<std::string> status;
|
||||
soci::blob sociTxnBlob(*db), sociTxnMetaBlob(*db);
|
||||
soci::indicator rti, tmi;
|
||||
|
||||
soci::statement st =
|
||||
(db->prepare << sql,
|
||||
soci::into(ledgerSeq),
|
||||
soci::into(status),
|
||||
soci::into(sociTxnBlob, rti),
|
||||
soci::into(sociTxnMetaBlob, tmi));
|
||||
|
||||
st.execute();
|
||||
while (st.fetch())
|
||||
{
|
||||
Blob rawTxn;
|
||||
if (soci::i_ok == rti)
|
||||
convert(sociTxnBlob, rawTxn);
|
||||
Blob txnMeta;
|
||||
if (soci::i_ok == tmi)
|
||||
convert(sociTxnMetaBlob, txnMeta);
|
||||
|
||||
auto const seq =
|
||||
rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
|
||||
|
||||
ret.emplace_back(std::move(rawTxn), std::move(txnMeta), seq);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NetworkOPsImp::AccountTxs
|
||||
NetworkOPsImp::getTxsAccount(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool forward,
|
||||
std::optional<AccountTxMarker>& marker,
|
||||
int limit,
|
||||
bool bUnlimited)
|
||||
{
|
||||
static std::uint32_t const page_length(200);
|
||||
|
||||
Application& app = app_;
|
||||
NetworkOPsImp::AccountTxs ret;
|
||||
|
||||
auto bound = [&ret, &app](
|
||||
std::uint32_t ledger_index,
|
||||
std::string const& status,
|
||||
Blob&& rawTxn,
|
||||
Blob&& rawMeta) {
|
||||
convertBlobsToTxResult(ret, ledger_index, status, rawTxn, rawMeta, app);
|
||||
};
|
||||
|
||||
accountTxPage(
|
||||
app_.getTxnDB(),
|
||||
app_.accountIDCache(),
|
||||
std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1),
|
||||
bound,
|
||||
account,
|
||||
minLedger,
|
||||
maxLedger,
|
||||
forward,
|
||||
marker,
|
||||
limit,
|
||||
bUnlimited,
|
||||
page_length);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NetworkOPsImp::MetaTxsList
|
||||
NetworkOPsImp::getTxsAccountB(
|
||||
AccountID const& account,
|
||||
std::int32_t minLedger,
|
||||
std::int32_t maxLedger,
|
||||
bool forward,
|
||||
std::optional<AccountTxMarker>& marker,
|
||||
int limit,
|
||||
bool bUnlimited)
|
||||
{
|
||||
static const std::uint32_t page_length(500);
|
||||
|
||||
MetaTxsList ret;
|
||||
|
||||
auto bound = [&ret](
|
||||
std::uint32_t ledgerIndex,
|
||||
std::string const& status,
|
||||
Blob&& rawTxn,
|
||||
Blob&& rawMeta) {
|
||||
ret.emplace_back(std::move(rawTxn), std::move(rawMeta), ledgerIndex);
|
||||
};
|
||||
|
||||
accountTxPage(
|
||||
app_.getTxnDB(),
|
||||
app_.accountIDCache(),
|
||||
std::bind(saveLedgerAsync, std::ref(app_), std::placeholders::_1),
|
||||
bound,
|
||||
account,
|
||||
minLedger,
|
||||
maxLedger,
|
||||
forward,
|
||||
marker,
|
||||
limit,
|
||||
bUnlimited,
|
||||
page_length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
NetworkOPsImp::recvValidation(
|
||||
std::shared_ptr<STValidation> const& val,
|
||||
|
||||
Reference in New Issue
Block a user