20#include <xrpld/app/ledger/AcceptedLedger.h>
21#include <xrpld/app/ledger/LedgerMaster.h>
22#include <xrpld/app/ledger/LedgerToJson.h>
23#include <xrpld/app/ledger/PendingSaves.h>
24#include <xrpld/app/ledger/TransactionMaster.h>
25#include <xrpld/app/rdb/RelationalDatabase.h>
26#include <xrpld/app/rdb/backend/detail/Node.h>
27#include <xrpld/core/DatabaseCon.h>
28#include <xrpld/core/SociDB.h>
30#include <xrpl/basics/BasicConfig.h>
31#include <xrpl/basics/StringUtilities.h>
32#include <xrpl/json/to_string.h>
34#include <boost/range/adaptor/transformed.hpp>
36#include <soci/sqlite3/soci-sqlite3.h>
51 "Need to modify switch statement if enum is modified");
58 return "Transactions";
60 return "AccountTransactions";
62 UNREACHABLE(
"ripple::detail::to_string : invalid TableType");
75 auto lgr{std::make_unique<DatabaseCon>(
77 lgr->getSession() << boost::str(
78 boost::format(
"PRAGMA cache_size=-%d;") %
84 auto tx{std::make_unique<DatabaseCon>(
86 tx->getSession() << boost::str(
87 boost::format(
"PRAGMA cache_size=-%d;") %
99 (tx->getSession().prepare
100 << (
"PRAGMA table_info(AccountTransactions);"),
105 soci::into(dflt_value, ind),
113 return {std::move(lgr), std::move(tx),
false};
118 return {std::move(lgr), std::move(tx),
true};
121 return {std::move(lgr), {},
true};
129 boost::optional<LedgerIndex> m;
130 session << query, soci::into(m);
139 boost::optional<LedgerIndex> m;
140 session << query, soci::into(m);
147 session <<
"DELETE FROM " <<
to_string(type)
148 <<
" WHERE LedgerSeq == " << ledgerSeq <<
";";
153 soci::session& session,
157 session <<
"DELETE FROM " <<
to_string(type) <<
" WHERE LedgerSeq < "
165 session <<
"SELECT COUNT(*) AS rows "
177 session <<
"SELECT COUNT(*) AS rows, "
178 "MIN(LedgerSeq) AS first, "
179 "MAX(LedgerSeq) AS last "
196 auto j = app.
journal(
"Ledger");
197 auto seq = ledger->info().seq;
200 JLOG(j.trace()) <<
"saveValidatedLedger " << (
current ?
"" :
"fromAcquire ")
203 if (!ledger->info().accountHash.isNonZero())
205 JLOG(j.fatal()) <<
"AH is zero: " <<
getJson({*ledger, {}});
206 UNREACHABLE(
"ripple::detail::saveValidatedLedger : zero account hash");
209 if (ledger->info().accountHash != ledger->stateMap().getHash().as_uint256())
211 JLOG(j.fatal()) <<
"sAL: " << ledger->info().accountHash
212 <<
" != " << ledger->stateMap().getHash();
213 JLOG(j.fatal()) <<
"saveAcceptedLedger: seq=" <<
seq
216 "ripple::detail::saveValidatedLedger : mismatched account hash");
220 ledger->info().txHash == ledger->txMap().getHash().as_uint256(),
221 "ripple::detail::saveValidatedLedger : transaction hash match");
227 addRaw(ledger->info(), s);
238 aLedger = std::make_shared<AcceptedLedger>(ledger, app);
240 ledger->info().hash, aLedger);
245 JLOG(j.warn()) <<
"An accepted ledger was missing nodes";
254 static boost::format deleteLedger(
255 "DELETE FROM Ledgers WHERE LedgerSeq = %u;");
256 static boost::format deleteTrans1(
257 "DELETE FROM Transactions WHERE LedgerSeq = %u;");
258 static boost::format deleteTrans2(
259 "DELETE FROM AccountTransactions WHERE LedgerSeq = %u;");
260 static boost::format deleteAcctTrans(
261 "DELETE FROM AccountTransactions WHERE TransID = '%s';");
265 *db << boost::str(deleteLedger %
seq);
272 soci::transaction tr(*db);
274 *db << boost::str(deleteTrans1 %
seq);
275 *db << boost::str(deleteTrans2 %
seq);
279 for (
auto const& acceptedLedgerTx : *aLedger)
289 auto const& accts = acceptedLedgerTx->getAffected();
294 "INSERT INTO AccountTransactions "
295 "(TransID, Account, LedgerSeq, TxnSeq) VALUES ");
303 for (
auto const& account : accts)
323 JLOG(j.trace()) <<
"ActTx: " << sql;
326 else if (
auto const& sleTxn = acceptedLedgerTx->getTxn();
331 JLOG(j.warn()) <<
"Transaction in ledger " <<
seq
332 <<
" affects no accounts";
338 acceptedLedgerTx->getTxn()->getMetaSQL(
339 seq, acceptedLedgerTx->getEscMeta()) +
345 acceptedLedgerTx->getTxnSeq(),
354 R
"sql(INSERT OR REPLACE INTO Ledgers
355 (LedgerHash,LedgerSeq,PrevHash,TotalCoins,ClosingTime,PrevClosingTime,
356 CloseTimeRes,CloseFlags,AccountSetHash,TransSetHash)
358 (:ledgerHash,:ledgerSeq,:prevHash,:totalCoins,:closingTime,:prevClosingTime,
359 :closeTimeRes,:closeFlags,:accountSetHash,:transSetHash);)sql");
363 soci::transaction tr(*db);
365 auto const hash =
to_string(ledger->info().hash);
366 auto const parentHash =
to_string(ledger->info().parentHash);
368 auto const closeTime =
369 ledger->info().closeTime.time_since_epoch().count();
370 auto const parentCloseTime =
371 ledger->info().parentCloseTime.time_since_epoch().count();
372 auto const closeTimeResolution =
373 ledger->info().closeTimeResolution.count();
374 auto const closeFlags = ledger->info().closeFlags;
375 auto const accountHash =
to_string(ledger->info().accountHash);
376 auto const txHash =
to_string(ledger->info().txHash);
378 *db << addLedger, soci::use(hash), soci::use(
seq),
379 soci::use(parentHash), soci::use(
drops), soci::use(closeTime),
380 soci::use(parentCloseTime), soci::use(closeTimeResolution),
381 soci::use(closeFlags), soci::use(accountHash),
401 soci::session& session,
406 boost::optional<std::string> hash, parentHash, accountHash, txHash;
407 boost::optional<std::uint64_t>
seq,
drops, closeTime, parentCloseTime,
408 closeTimeResolution, closeFlags;
412 "LedgerHash, PrevHash, AccountSetHash, TransSetHash, "
414 "ClosingTime, PrevClosingTime, CloseTimeRes, CloseFlags,"
415 "LedgerSeq FROM Ledgers " +
418 session << sql, soci::into(hash), soci::into(parentHash),
419 soci::into(accountHash), soci::into(txHash), soci::into(
drops),
420 soci::into(closeTime), soci::into(parentCloseTime),
421 soci::into(closeTimeResolution), soci::into(closeFlags),
424 if (!session.got_data())
426 JLOG(j.
debug()) <<
"Ledger not found: " << sqlSuffix;
435 if (hash && !info.hash.parseHex(*hash))
437 JLOG(j.
debug()) <<
"Hash parse error for ledger: " << sqlSuffix;
441 if (parentHash && !info.parentHash.parseHex(*parentHash))
443 JLOG(j.
debug()) <<
"parentHash parse error for ledger: " << sqlSuffix;
447 if (accountHash && !info.accountHash.parseHex(*accountHash))
449 JLOG(j.
debug()) <<
"accountHash parse error for ledger: " << sqlSuffix;
453 if (txHash && !info.txHash.parseHex(*txHash))
455 JLOG(j.
debug()) <<
"txHash parse error for ledger: " << sqlSuffix;
459 info.seq = rangeCheckedCast<std::uint32_t>(seq.value_or(0));
460 info.drops =
drops.value_or(0);
461 info.closeTime = time_point{duration{closeTime.value_or(0)}};
462 info.parentCloseTime = time_point{duration{parentCloseTime.value_or(0)}};
463 info.closeFlags = closeFlags.value_or(0);
464 info.closeTimeResolution = duration{closeTimeResolution.value_or(0)};
471 soci::session& session,
476 s <<
"WHERE LedgerSeq = " << ledgerSeq;
484 s <<
"ORDER BY LedgerSeq DESC LIMIT 1";
490 soci::session& session,
496 " ORDER BY LedgerSeq ASC LIMIT 1";
502 soci::session& session,
508 " ORDER BY LedgerSeq DESC LIMIT 1";
514 soci::session& session,
519 s <<
"WHERE LedgerHash = '" << ledgerHash <<
"'";
529 "SELECT LedgerHash FROM Ledgers INDEXED BY SeqLedger WHERE LedgerSeq='";
536 boost::optional<std::string> lh;
537 session << sql, soci::into(lh);
539 if (!session.got_data() || !lh)
555 soci::session& session,
560 boost::optional<std::string> lhO, phO;
562 session <<
"SELECT LedgerHash,PrevHash FROM Ledgers "
563 "INDEXED BY SeqLedger WHERE LedgerSeq = :ls;",
564 soci::into(lhO), soci::into(phO), soci::use(ledgerIndex);
568 auto stream = j.
trace();
569 JLOG(stream) <<
"Don't have ledger " << ledgerIndex;
573 LedgerHashPair hashes;
574 if (!hashes.ledgerHash.parseHex(*lhO) || !hashes.parentHash.parseHex(*phO))
576 auto stream = j.
trace();
577 JLOG(stream) <<
"Error parse hashes for ledger " << ledgerIndex;
586 soci::session& session,
592 "SELECT LedgerSeq,LedgerHash,PrevHash FROM Ledgers WHERE LedgerSeq >= ";
594 sql.
append(
" AND LedgerSeq <= ");
601 boost::optional<std::string> ph;
603 (session.prepare << sql,
615 JLOG(j.
warn()) <<
"Error parsed hash for ledger seq: " << ls;
619 JLOG(j.
warn()) <<
"Null prev hash for ledger seq: " << ls;
623 JLOG(j.
warn()) <<
"Error parsed prev hash for ledger seq: " << ls;
631 soci::session& session,
638 "SELECT LedgerSeq, Status, RawTxn "
639 "FROM Transactions ORDER BY LedgerSeq DESC LIMIT %u,%u;") %
640 startIndex % quantity);
647 boost::optional<std::uint64_t> ledgerSeq;
648 boost::optional<std::string> status;
649 soci::blob sociRawTxnBlob(session);
654 (session.prepare << sql,
655 soci::into(ledgerSeq),
657 soci::into(sociRawTxnBlob, rti));
662 if (soci::i_ok == rti)
663 convert(sociRawTxnBlob, rawTxn);
668 ledgerSeq, status, rawTxn, app))
700 RelationalDatabase::AccountTxOptions
const& options,
715 else if (options.limit == UINT32_MAX)
717 numberOfResults = binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH;
719 else if (!options.bUnlimited)
722 binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH, options.limit);
726 numberOfResults = options.limit;
732 if (options.maxLedger)
734 maxClause = boost::str(
735 boost::format(
"AND AccountTransactions.LedgerSeq <= '%u'") %
739 if (options.minLedger)
741 minClause = boost::str(
742 boost::format(
"AND AccountTransactions.LedgerSeq >= '%u'") %
750 boost::format(
"SELECT %s FROM AccountTransactions "
751 "WHERE Account = '%s' %s %s LIMIT %u, %u;") %
752 selection %
toBase58(options.account) % maxClause % minClause %
753 options.offset % numberOfResults);
758 "AccountTransactions INNER JOIN Transactions "
759 "ON Transactions.TransID = AccountTransactions.TransID "
760 "WHERE Account = '%s' %s %s "
761 "ORDER BY AccountTransactions.LedgerSeq %s, "
762 "AccountTransactions.TxnSeq %s, AccountTransactions.TransID %s "
764 selection %
toBase58(options.account) % maxClause % minClause %
765 (descending ?
"DESC" :
"ASC") % (descending ?
"DESC" :
"ASC") %
766 (descending ?
"DESC" :
"ASC") % options.offset % numberOfResults);
767 JLOG(j.
trace()) <<
"txSQL query: " << sql;
794 soci::session& session,
797 RelationalDatabase::AccountTxOptions
const& options,
805 "AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
817 boost::optional<std::uint64_t> ledgerSeq;
818 boost::optional<std::string>
status;
819 soci::blob sociTxnBlob(session), sociTxnMetaBlob(session);
820 soci::indicator rti, tmi;
821 Blob rawTxn, txnMeta;
824 (session.prepare << sql,
825 soci::into(ledgerSeq),
827 soci::into(sociTxnBlob, rti),
828 soci::into(sociTxnMetaBlob, tmi));
833 if (soci::i_ok == rti)
838 if (soci::i_ok == tmi)
839 convert(sociTxnMetaBlob, txnMeta);
849 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
852 <<
"Recovering ledger " << seq <<
", txn " << txn->getID();
862 std::make_shared<TxMeta>(
863 txn->getID(), txn->getLedger(), txnMeta));
874 soci::session& session,
877 RelationalDatabase::AccountTxOptions
const& options,
885 soci::session& session,
916 soci::session& session,
918 RelationalDatabase::AccountTxOptions
const& options,
926 "AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
939 boost::optional<std::uint64_t> ledgerSeq;
940 boost::optional<std::string>
status;
941 soci::blob sociTxnBlob(session), sociTxnMetaBlob(session);
942 soci::indicator rti, tmi;
945 (session.prepare << sql,
946 soci::into(ledgerSeq),
948 soci::into(sociTxnBlob, rti),
949 soci::into(sociTxnMetaBlob, tmi));
955 if (soci::i_ok == rti)
958 if (soci::i_ok == tmi)
959 convert(sociTxnMetaBlob, txnMeta);
962 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
964 ret.
emplace_back(std::move(rawTxn), std::move(txnMeta), seq);
974 soci::session& session,
976 RelationalDatabase::AccountTxOptions
const& options,
984 soci::session& session,
1013 soci::session& session,
1018 RelationalDatabase::AccountTxPageOptions
const& options,
1024 bool lookingForMarker = options.marker.has_value();
1028 if (options.limit == 0 || options.limit == UINT32_MAX ||
1029 (options.limit > page_length && !options.bAdmin))
1030 numberOfResults = page_length;
1032 numberOfResults = options.limit;
1042 if (lookingForMarker)
1044 findLedger = options.marker->ledgerSeq;
1045 findSeq = options.marker->txnSeq;
1051 R
"(SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,
1052 Status,RawTxn,TxnMeta
1053 FROM AccountTransactions INNER JOIN Transactions
1054 ON Transactions.TransID = AccountTransactions.TransID
1055 AND AccountTransactions.Account = '%s' WHERE
1062 char const*
const order =
forward ?
"ASC" :
"DESC";
1064 if (findLedger == 0)
1068 prefix + (R
"(AccountTransactions.LedgerSeq BETWEEN %u AND %u
1069 ORDER BY AccountTransactions.LedgerSeq %s,
1070 AccountTransactions.TxnSeq %s
1072 toBase58(options.account) % options.minLedger % options.maxLedger %
1073 order % order % queryLimit);
1079 forward ? findLedger + 1 : options.minLedger;
1081 forward ? options.maxLedger : findLedger - 1;
1083 auto b58acct =
toBase58(options.account);
1086 R
"(SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,
1087 Status,RawTxn,TxnMeta
1088 FROM AccountTransactions, Transactions WHERE
1089 (AccountTransactions.TransID = Transactions.TransID AND
1090 AccountTransactions.Account = '%s' AND
1091 AccountTransactions.LedgerSeq BETWEEN %u AND %u)
1093 SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,Status,RawTxn,TxnMeta
1094 FROM AccountTransactions, Transactions WHERE
1095 (AccountTransactions.TransID = Transactions.TransID AND
1096 AccountTransactions.Account = '%s' AND
1097 AccountTransactions.LedgerSeq = %u AND
1098 AccountTransactions.TxnSeq %s %u)
1099 ORDER BY AccountTransactions.LedgerSeq %s,
1100 AccountTransactions.TxnSeq %s
1103 b58acct % minLedger % maxLedger % b58acct % findLedger % compare %
1104 findSeq % order % order % queryLimit);
1112 boost::optional<std::uint64_t> ledgerSeq;
1113 boost::optional<std::uint32_t> txnSeq;
1114 boost::optional<std::string>
status;
1115 soci::blob txnData(session);
1116 soci::blob txnMeta(session);
1117 soci::indicator dataPresent, metaPresent;
1119 soci::statement st =
1120 (session.prepare << sql,
1121 soci::into(ledgerSeq),
1124 soci::into(txnData, dataPresent),
1125 soci::into(txnMeta, metaPresent));
1131 if (lookingForMarker)
1133 if (findLedger == ledgerSeq.value_or(0) &&
1134 findSeq == txnSeq.value_or(0))
1136 lookingForMarker =
false;
1141 else if (numberOfResults == 0)
1144 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0)),
1149 if (dataPresent == soci::i_ok)
1154 if (metaPresent == soci::i_ok)
1160 if (rawMeta.size() == 0)
1161 onUnsavedLedger(ledgerSeq.value_or(0));
1166 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0)),
1169 std::move(rawMeta));
1183 return {newmarker, total};
1188 soci::session& session,
1197 session, onUnsavedLedger, onTransaction, options, page_length,
true);
1202 soci::session& session,
1211 session, onUnsavedLedger, onTransaction, options, page_length,
false);
1216 soci::session& session,
1223 "SELECT LedgerSeq,Status,RawTxn,TxnMeta "
1224 "FROM Transactions WHERE TransID='";
1230 boost::optional<std::uint64_t> ledgerSeq;
1231 boost::optional<std::string> status;
1232 Blob rawTxn, rawMeta;
1234 soci::blob sociRawTxnBlob(session), sociRawMetaBlob(session);
1235 soci::indicator txn, meta;
1237 session << sql, soci::into(ledgerSeq), soci::into(status),
1238 soci::into(sociRawTxnBlob, txn), soci::into(sociRawMetaBlob, meta);
1240 auto const got_data = session.got_data();
1242 if ((!got_data || txn != soci::i_ok || meta != soci::i_ok) && !
range)
1248 soci::indicator rti;
1251 <<
"SELECT COUNT(DISTINCT LedgerSeq) FROM Transactions WHERE "
1252 "LedgerSeq BETWEEN "
1253 <<
range->first() <<
" AND " <<
range->last() <<
";",
1254 soci::into(count, rti);
1256 if (!session.got_data() || rti != soci::i_ok)
1259 return count == (
range->last() -
range->first() + 1)
1264 convert(sociRawTxnBlob, rawTxn);
1265 convert(sociRawMetaBlob, rawMeta);
1274 return std::pair{std::move(txn),
nullptr};
1277 rangeCheckedCast<std::uint32_t>(ledgerSeq.value());
1279 auto txMeta = std::make_shared<TxMeta>(
id, inLedger, rawMeta);
1281 return std::pair{std::move(txn), std::move(txMeta)};
1285 JLOG(app.journal(
"Ledger").warn())
1286 <<
"Unable to deserialize transaction from raw SQL value. Error: "
1298 boost::filesystem::space_info
space =
1299 boost::filesystem::space(config.legacy(
"database_path"));
1303 JLOG(j.
fatal()) <<
"Remaining free disk space is less than 512MB";
1307 if (config.useTxTables())
1310 boost::filesystem::path dbPath = dbSetup.dataDir /
TxDBName;
1311 boost::system::error_code ec;
1313 boost::filesystem::file_size(dbPath, ec);
1317 <<
"Error checking transaction db file size: " << ec.message();
1321 static auto const pageSize = [&] {
1323 session <<
"PRAGMA page_size;", soci::into(ps);
1326 static auto const maxPages = [&] {
1328 session <<
"PRAGMA max_page_count;", soci::into(mp);
1332 session <<
"PRAGMA page_count;", soci::into(pageCount);
1335 safe_cast<std::uint64_t>(freePages) * pageSize;
1337 <<
"Transaction DB pathname: " << dbPath.string()
1338 <<
"; file size: " << dbSize.
value_or(-1) <<
" bytes"
1339 <<
"; SQLite page size: " << pageSize <<
" bytes"
1340 <<
"; Free pages: " << freePages <<
"; Free space: " << freeSpace
1342 <<
"Note that this does not take into account available disk "
1348 <<
"Free SQLite space for transaction db is less than "
1349 "512MB. To fix this, rippled must be executed with the "
1350 "vacuum parameter before restarting. "
1351 "Note that this activity can take multiple days, "
1352 "depending on database size.";
A generic endpoint for log messages.
Stream trace() const
Severity stream access functions.
virtual Config & config()=0
virtual beast::Journal journal(std::string const &name)=0
virtual NodeStore::Database & getNodeStore()=0
virtual TaggedCache< uint256, AcceptedLedger > & getAcceptedLedgerCache()=0
virtual LedgerMaster & getLedgerMaster()=0
virtual TransactionMaster & getMasterTransaction()=0
virtual PendingSaves & pendingSaves()=0
int getValueFor(SizedItem item, std::optional< std::size_t > node=std::nullopt) const
Retrieve the default value for the item at the specified node size.
LockedSociSession checkoutDb()
void failedSave(std::uint32_t seq, uint256 const &hash)
std::chrono::time_point< NetClock > time_point
std::chrono::duration< rep, period > duration
virtual void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t ledgerSeq)=0
Store the object.
void finishWork(LedgerIndex seq)
Finish working on a ledger.
std::vector< AccountTx > AccountTxs
static std::string const & getMetaSQLInsertReplaceHeader()
bool inLedger(uint256 const &hash, std::uint32_t ledger, std::optional< uint32_t > tseq, std::optional< uint32_t > netID)
static Transaction::pointer transactionFromSQL(boost::optional< std::uint64_t > const &ledgerSeq, boost::optional< std::string > const &status, Blob const &rawTxn, Application &app)
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
T emplace_back(T... args)
int compare(SemanticVersion const &lhs, SemanticVersion const &rhs)
Compare two SemanticVersions against each other.
static std::pair< std::vector< RelationalDatabase::txnMetaLedgerType >, int > getAccountTxsB(soci::session &session, Application &app, RelationalDatabase::AccountTxOptions const &options, bool descending, beast::Journal j)
getAccountTxsB Returns the oldest or newest transactions in binary form for the account that matches ...
RelationalDatabase::CountMinMax getRowsMinMax(soci::session &session, TableType type)
getRowsMinMax Returns minimum ledger sequence, maximum ledger sequence and total number of rows in gi...
uint256 getHashByIndex(soci::session &session, LedgerIndex ledgerIndex)
getHashByIndex Returns hash of ledger with given sequence.
std::optional< LedgerInfo > getLimitedNewestLedgerInfo(soci::session &session, LedgerIndex ledgerFirstIndex, beast::Journal j)
getLimitedNewestLedgerInfo Returns info of newest ledger from ledgers with sequences greather or equa...
static std::string to_string(TableType type)
to_string Returns the name of a table according to its TableType.
std::pair< std::optional< RelationalDatabase::AccountTxMarker >, int > newestAccountTxPage(soci::session &session, std::function< void(std::uint32_t)> const &onUnsavedLedger, std::function< void(std::uint32_t, std::string const &, Blob &&, Blob &&)> const &onTransaction, RelationalDatabase::AccountTxPageOptions const &options, std::uint32_t page_length)
newestAccountTxPage Searches newest transactions for given account which match given criteria startin...
std::optional< LedgerInfo > getNewestLedgerInfo(soci::session &session, beast::Journal j)
getNewestLedgerInfo Returns info of newest saved ledger.
static std::pair< RelationalDatabase::AccountTxs, int > getAccountTxs(soci::session &session, Application &app, LedgerMaster &ledgerMaster, RelationalDatabase::AccountTxOptions const &options, bool descending, beast::Journal j)
getAccountTxs Returns the oldest or newest transactions for the account that matches the given criter...
std::pair< std::optional< RelationalDatabase::AccountTxMarker >, int > oldestAccountTxPage(soci::session &session, std::function< void(std::uint32_t)> const &onUnsavedLedger, std::function< void(std::uint32_t, std::string const &, Blob &&, Blob &&)> const &onTransaction, RelationalDatabase::AccountTxPageOptions const &options, std::uint32_t page_length)
oldestAccountTxPage Searches oldest transactions for given account which match given criteria startin...
DatabasePairValid makeLedgerDBs(Config const &config, DatabaseCon::Setup const &setup, DatabaseCon::CheckpointerSetup const &checkpointerSetup, beast::Journal j)
makeLedgerDBs Opens ledger and transactions databases.
void deleteByLedgerSeq(soci::session &session, TableType type, LedgerIndex ledgerSeq)
deleteByLedgerSeq Deletes all entries in given table for the ledger with given sequence.
std::size_t getRows(soci::session &session, TableType type)
getRows Returns number of rows in given table.
void deleteBeforeLedgerSeq(soci::session &session, TableType type, LedgerIndex ledgerSeq)
deleteBeforeLedgerSeq Deletes all entries in given table for the ledgers with given sequence and all ...
bool saveValidatedLedger(DatabaseCon &ldgDB, DatabaseCon &txnDB, Application &app, std::shared_ptr< Ledger const > const &ledger, bool current)
saveValidatedLedger Saves ledger into database.
std::pair< RelationalDatabase::AccountTxs, int > getOldestAccountTxs(soci::session &session, Application &app, LedgerMaster &ledgerMaster, RelationalDatabase::AccountTxOptions const &options, beast::Journal j)
getOldestAccountTxs Returns oldest transactions for given account which match given criteria starting...
std::pair< std::vector< std::shared_ptr< Transaction > >, int > getTxHistory(soci::session &session, Application &app, LedgerIndex startIndex, int quantity)
getTxHistory Returns given number of most recent transactions starting from given number of entry.
constexpr int TableTypeCount
std::optional< LedgerInfo > getLimitedOldestLedgerInfo(soci::session &session, LedgerIndex ledgerFirstIndex, beast::Journal j)
getLimitedOldestLedgerInfo Returns info of oldest ledger from ledgers with sequences greather or equa...
std::pair< std::vector< RelationalDatabase::txnMetaLedgerType >, int > getOldestAccountTxsB(soci::session &session, Application &app, RelationalDatabase::AccountTxOptions const &options, beast::Journal j)
getOldestAccountTxsB Returns oldest transactions in binary form for given account which match given c...
std::optional< LedgerInfo > getLedgerInfoByIndex(soci::session &session, LedgerIndex ledgerSeq, beast::Journal j)
getLedgerInfoByIndex Returns ledger by its sequence.
bool dbHasSpace(soci::session &session, Config const &config, beast::Journal j)
dbHasSpace Checks if given database has available space.
std::optional< LedgerInfo > getLedgerInfoByHash(soci::session &session, uint256 const &ledgerHash, beast::Journal j)
getLedgerInfoByHash Returns info of ledger with given hash.
static std::string transactionsSQL(Application &app, std::string selection, RelationalDatabase::AccountTxOptions const &options, bool descending, bool binary, bool count, beast::Journal j)
transactionsSQL Returns a SQL query for selecting the oldest or newest transactions in decoded or bin...
std::optional< LedgerIndex > getMinLedgerSeq(soci::session &session, TableType type)
getMinLedgerSeq Returns minimum ledger sequence in given table.
std::pair< RelationalDatabase::AccountTxs, int > getNewestAccountTxs(soci::session &session, Application &app, LedgerMaster &ledgerMaster, RelationalDatabase::AccountTxOptions const &options, beast::Journal j)
getNewestAccountTxs Returns newest transactions for given account which match given criteria starting...
std::pair< std::vector< RelationalDatabase::txnMetaLedgerType >, int > getNewestAccountTxsB(soci::session &session, Application &app, RelationalDatabase::AccountTxOptions const &options, beast::Journal j)
getNewestAccountTxsB Returns newest transactions in binary form for given account which match given c...
static std::optional< LedgerInfo > getLedgerInfo(soci::session &session, std::string const &sqlSuffix, beast::Journal j)
getLedgerInfo Returns the info of the ledger retrieved from the database by using the provided SQL qu...
std::optional< LedgerHashPair > getHashesByIndex(soci::session &session, LedgerIndex ledgerIndex, beast::Journal j)
getHashesByIndex Returns hash of the ledger and hash of parent ledger for the ledger of given sequenc...
std::optional< LedgerIndex > getMaxLedgerSeq(soci::session &session, TableType type)
getMaxLedgerSeq Returns maximum ledger sequence in given table.
static std::pair< std::optional< RelationalDatabase::AccountTxMarker >, int > accountTxPage(soci::session &session, std::function< void(std::uint32_t)> const &onUnsavedLedger, std::function< void(std::uint32_t, std::string const &, Blob &&, Blob &&)> const &onTransaction, RelationalDatabase::AccountTxPageOptions const &options, std::uint32_t page_length, bool forward)
accountTxPage Searches for the oldest or newest transactions for the account that matches the given c...
std::variant< RelationalDatabase::AccountTx, TxSearched > getTransaction(soci::session &session, Application &app, uint256 const &id, std::optional< ClosedInterval< uint32_t > > const &range, error_code_i &ec)
getTransaction Returns transaction with given hash.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::array< char const *, 8 > TxDBInit
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
std::uint32_t LedgerIndex
A ledger index.
constexpr auto megabytes(T value) noexcept
DatabaseCon::Setup setup_DatabaseCon(Config const &c, std::optional< beast::Journal > j=std::nullopt)
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
void convert(soci::blob &from, std::vector< std::uint8_t > &to)
@ current
This was a new validation and was added.
constexpr std::array< char const *, 5 > LgrDBInit
constexpr auto kilobytes(T value) noexcept
std::vector< unsigned char > Blob
Storage for linear binary data.
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
@ ledgerMaster
ledger master data for signing
@ transactionID
transaction plus signature to give transaction ID
void addRaw(LedgerHeader const &, Serializer &, bool includeHash=false)
bool pendSaveValidated(Application &app, std::shared_ptr< Ledger const > const &ledger, bool isSynchronous, bool isCurrent)
Save, or arrange to save, a fully-validated ledger Returns false on error.
std::array< std::string, 1 > lgrPragma
Config::StartUpType startUp
std::array< std::string, 4 > txPragma
LedgerIndex maxLedgerSequence
LedgerIndex minLedgerSequence
Set the sequence number on a JTx.