1#include <xrpld/app/ledger/AcceptedLedger.h>
2#include <xrpld/app/ledger/LedgerMaster.h>
3#include <xrpld/app/ledger/LedgerToJson.h>
4#include <xrpld/app/ledger/PendingSaves.h>
5#include <xrpld/app/ledger/TransactionMaster.h>
6#include <xrpld/app/rdb/RelationalDatabase.h>
7#include <xrpld/app/rdb/backend/detail/Node.h>
8#include <xrpld/core/DatabaseCon.h>
9#include <xrpld/core/SociDB.h>
11#include <xrpl/basics/BasicConfig.h>
12#include <xrpl/basics/StringUtilities.h>
13#include <xrpl/json/to_string.h>
15#include <boost/range/adaptor/transformed.hpp>
17#include <soci/sqlite3/soci-sqlite3.h>
30 static_assert(
TableTypeCount == 3,
"Need to modify switch statement if enum is modified");
37 return "Transactions";
39 return "AccountTransactions";
42 UNREACHABLE(
"xrpl::detail::to_string : invalid TableType");
57 lgr->getSession() << boost::str(
64 tx->getSession() << boost::str(
75 (tx->getSession().prepare << (
"PRAGMA table_info(AccountTransactions);"),
80 soci::into(dflt_value, ind),
88 return {std::move(lgr), std::move(tx),
false};
93 return {std::move(lgr), std::move(tx),
true};
96 return {std::move(lgr), {},
true};
104 boost::optional<LedgerIndex> m;
105 session << query, soci::into(m);
114 boost::optional<LedgerIndex> m;
115 session << query, soci::into(m);
122 session <<
"DELETE FROM " <<
to_string(type) <<
" WHERE LedgerSeq == " << ledgerSeq <<
";";
128 session <<
"DELETE FROM " <<
to_string(type) <<
" WHERE LedgerSeq < " << ledgerSeq <<
";";
135 session <<
"SELECT COUNT(*) AS rows "
147 session <<
"SELECT COUNT(*) AS rows, "
148 "MIN(LedgerSeq) AS first, "
149 "MAX(LedgerSeq) AS last "
165 auto j = app.
journal(
"Ledger");
166 auto seq = ledger->header().seq;
169 JLOG(j.trace()) <<
"saveValidatedLedger " << (
current ?
"" :
"fromAcquire ") << seq;
171 if (!ledger->header().accountHash.isNonZero())
174 JLOG(j.fatal()) <<
"AH is zero: " <<
getJson({*ledger, {}});
175 UNREACHABLE(
"xrpl::detail::saveValidatedLedger : zero account hash");
179 if (ledger->header().accountHash != ledger->stateMap().getHash().as_uint256())
182 JLOG(j.fatal()) <<
"sAL: " << ledger->header().accountHash <<
" != " << ledger->stateMap().getHash();
183 JLOG(j.fatal()) <<
"saveAcceptedLedger: seq=" << seq <<
", current=" <<
current;
184 UNREACHABLE(
"xrpl::detail::saveValidatedLedger : mismatched account hash");
189 ledger->header().txHash == ledger->txMap().getHash().as_uint256(),
190 "xrpl::detail::saveValidatedLedger : transaction hash match");
196 addRaw(ledger->header(), s);
212 JLOG(j.warn()) <<
"An accepted ledger was missing nodes";
221 static boost::format deleteLedger(
"DELETE FROM Ledgers WHERE LedgerSeq = %u;");
222 static boost::format deleteTrans1(
"DELETE FROM Transactions WHERE LedgerSeq = %u;");
223 static boost::format deleteTrans2(
"DELETE FROM AccountTransactions WHERE LedgerSeq = %u;");
224 static boost::format deleteAcctTrans(
"DELETE FROM AccountTransactions WHERE TransID = '%s';");
228 *db << boost::str(deleteLedger % seq);
236 JLOG(j.fatal()) <<
"TxTables db isn't available";
237 Throw<std::runtime_error>(
"TxTables db isn't available");
241 auto db = txnDB->checkoutDb();
243 soci::transaction tr(*db);
245 *db << boost::str(deleteTrans1 % seq);
246 *db << boost::str(deleteTrans2 % seq);
250 for (
auto const& acceptedLedgerTx : *aLedger)
259 auto const& accts = acceptedLedgerTx->getAffected();
264 "INSERT INTO AccountTransactions "
265 "(TransID, Account, LedgerSeq, TxnSeq) VALUES ");
273 for (
auto const& account : accts)
293 JLOG(j.trace()) <<
"ActTx: " << sql;
296 else if (
auto const& sleTxn = acceptedLedgerTx->getTxn(); !
isPseudoTx(*sleTxn))
300 JLOG(j.warn()) <<
"Transaction in ledger " << seq <<
" affects no accounts";
306 acceptedLedgerTx->getTxn()->getMetaSQL(seq, acceptedLedgerTx->getEscMeta()) +
";");
317 R
"sql(INSERT OR REPLACE INTO Ledgers
318 (LedgerHash,LedgerSeq,PrevHash,TotalCoins,ClosingTime,PrevClosingTime,
319 CloseTimeRes,CloseFlags,AccountSetHash,TransSetHash)
321 (:ledgerHash,:ledgerSeq,:prevHash,:totalCoins,:closingTime,:prevClosingTime,
322 :closeTimeRes,:closeFlags,:accountSetHash,:transSetHash);)sql");
326 soci::transaction tr(*db);
328 auto const hash =
to_string(ledger->header().hash);
329 auto const parentHash =
to_string(ledger->header().parentHash);
330 auto const drops =
to_string(ledger->header().drops);
331 auto const closeTime = ledger->header().closeTime.time_since_epoch().count();
332 auto const parentCloseTime = ledger->header().parentCloseTime.time_since_epoch().count();
333 auto const closeTimeResolution = ledger->header().closeTimeResolution.count();
334 auto const closeFlags = ledger->header().closeFlags;
335 auto const accountHash =
to_string(ledger->header().accountHash);
336 auto const txHash =
to_string(ledger->header().txHash);
338 *db << addLedger, soci::use(hash), soci::use(seq), soci::use(parentHash), soci::use(drops),
339 soci::use(closeTime), soci::use(parentCloseTime), soci::use(closeTimeResolution), soci::use(closeFlags),
340 soci::use(accountHash), soci::use(txHash);
361 boost::optional<std::string> hash, parentHash, accountHash, txHash;
362 boost::optional<std::uint64_t> seq, drops, closeTime, parentCloseTime, closeTimeResolution, closeFlags;
366 "LedgerHash, PrevHash, AccountSetHash, TransSetHash, "
368 "ClosingTime, PrevClosingTime, CloseTimeRes, CloseFlags,"
369 "LedgerSeq FROM Ledgers " +
372 session << sql, soci::into(hash), soci::into(parentHash), soci::into(accountHash), soci::into(txHash),
373 soci::into(drops), soci::into(closeTime), soci::into(parentCloseTime), soci::into(closeTimeResolution),
374 soci::into(closeFlags), soci::into(seq);
376 if (!session.got_data())
378 JLOG(j.
debug()) <<
"Ledger not found: " << sqlSuffix;
387 if (hash && !info.hash.parseHex(*hash))
389 JLOG(j.
debug()) <<
"Hash parse error for ledger: " << sqlSuffix;
393 if (parentHash && !info.parentHash.parseHex(*parentHash))
395 JLOG(j.
debug()) <<
"parentHash parse error for ledger: " << sqlSuffix;
399 if (accountHash && !info.accountHash.parseHex(*accountHash))
401 JLOG(j.
debug()) <<
"accountHash parse error for ledger: " << sqlSuffix;
405 if (txHash && !info.txHash.parseHex(*txHash))
407 JLOG(j.
debug()) <<
"txHash parse error for ledger: " << sqlSuffix;
411 info.seq = rangeCheckedCast<std::uint32_t>(seq.value_or(0));
412 info.drops =
drops.value_or(0);
413 info.closeTime = time_point{duration{closeTime.value_or(0)}};
414 info.parentCloseTime = time_point{duration{parentCloseTime.value_or(0)}};
415 info.closeFlags = closeFlags.value_or(0);
416 info.closeTimeResolution = duration{closeTimeResolution.value_or(0)};
425 s <<
"WHERE LedgerSeq = " << ledgerSeq;
433 s <<
"ORDER BY LedgerSeq DESC LIMIT 1";
441 s <<
"WHERE LedgerSeq >= " +
std::to_string(ledgerFirstIndex) +
" ORDER BY LedgerSeq ASC LIMIT 1";
449 s <<
"WHERE LedgerSeq >= " +
std::to_string(ledgerFirstIndex) +
" ORDER BY LedgerSeq DESC LIMIT 1";
457 s <<
"WHERE LedgerHash = '" << ledgerHash <<
"'";
466 std::string sql =
"SELECT LedgerHash FROM Ledgers INDEXED BY SeqLedger WHERE LedgerSeq='";
473 boost::optional<std::string> lh;
474 session << sql, soci::into(lh);
476 if (!session.got_data() || !lh)
494 boost::optional<std::string> lhO, phO;
496 session <<
"SELECT LedgerHash,PrevHash FROM Ledgers "
497 "INDEXED BY SeqLedger WHERE LedgerSeq = :ls;",
498 soci::into(lhO), soci::into(phO), soci::use(ledgerIndex);
502 auto stream = j.
trace();
503 JLOG(stream) <<
"Don't have ledger " << ledgerIndex;
507 LedgerHashPair hashes;
508 if (!hashes.ledgerHash.parseHex(*lhO) || !hashes.parentHash.parseHex(*phO))
510 auto stream = j.
trace();
511 JLOG(stream) <<
"Error parse hashes for ledger " << ledgerIndex;
521 std::string sql =
"SELECT LedgerSeq,LedgerHash,PrevHash FROM Ledgers WHERE LedgerSeq >= ";
523 sql.
append(
" AND LedgerSeq <= ");
530 boost::optional<std::string> ph;
531 soci::statement st = (session.prepare << sql, soci::into(ls), soci::into(lh), soci::into(ph));
540 JLOG(j.
warn()) <<
"Error parsed hash for ledger seq: " << ls;
544 JLOG(j.
warn()) <<
"Null prev hash for ledger seq: " << ls;
548 JLOG(j.
warn()) <<
"Error parsed prev hash for ledger seq: " << ls;
558 boost::format(
"SELECT LedgerSeq, Status, RawTxn "
559 "FROM Transactions ORDER BY LedgerSeq DESC LIMIT %u,%u;") %
560 startIndex % quantity);
567 boost::optional<std::uint64_t> ledgerSeq;
568 boost::optional<std::string> status;
569 soci::blob sociRawTxnBlob(session);
574 (session.prepare << sql, soci::into(ledgerSeq), soci::into(status), soci::into(sociRawTxnBlob, rti));
579 if (soci::i_ok == rti)
580 convert(sociRawTxnBlob, rawTxn);
616 RelationalDatabase::AccountTxOptions
const& options,
631 else if (options.limit == UINT32_MAX)
633 numberOfResults = binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH;
635 else if (!options.bUnlimited)
637 numberOfResults =
std::min(binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH, options.limit);
641 numberOfResults = options.limit;
647 if (options.maxLedger)
649 maxClause = boost::str(boost::format(
"AND AccountTransactions.LedgerSeq <= '%u'") % options.maxLedger);
652 if (options.minLedger)
654 minClause = boost::str(boost::format(
"AND AccountTransactions.LedgerSeq >= '%u'") % options.minLedger);
661 boost::format(
"SELECT %s FROM AccountTransactions "
662 "WHERE Account = '%s' %s %s LIMIT %u, %u;") %
663 selection %
toBase58(options.account) % maxClause % minClause % options.offset % numberOfResults);
666 boost::format(
"SELECT %s FROM "
667 "AccountTransactions INNER JOIN Transactions "
668 "ON Transactions.TransID = AccountTransactions.TransID "
669 "WHERE Account = '%s' %s %s "
670 "ORDER BY AccountTransactions.LedgerSeq %s, "
671 "AccountTransactions.TxnSeq %s, AccountTransactions.TransID %s "
673 selection %
toBase58(options.account) % maxClause % minClause % (descending ?
"DESC" :
"ASC") %
674 (descending ?
"DESC" :
"ASC") % (descending ?
"DESC" :
"ASC") % options.offset % numberOfResults);
675 JLOG(j.
trace()) <<
"txSQL query: " << sql;
702 soci::session& session,
705 RelationalDatabase::AccountTxOptions
const& options,
712 app,
"AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta", options, descending,
false,
false, j);
719 boost::optional<std::uint64_t> ledgerSeq;
720 boost::optional<std::string>
status;
721 soci::blob sociTxnBlob(session), sociTxnMetaBlob(session);
722 soci::indicator rti, tmi;
723 Blob rawTxn, txnMeta;
726 (session.prepare << sql,
727 soci::into(ledgerSeq),
729 soci::into(sociTxnBlob, rti),
730 soci::into(sociTxnMetaBlob, tmi));
735 if (soci::i_ok == rti)
740 if (soci::i_ok == tmi)
741 convert(sociTxnMetaBlob, txnMeta);
749 auto const seq = rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
751 JLOG(j.
warn()) <<
"Recovering ledger " << seq <<
", txn " << txn->getID();
770 soci::session& session,
773 RelationalDatabase::AccountTxOptions
const& options,
781 soci::session& session,
812 soci::session& session,
814 RelationalDatabase::AccountTxOptions
const& options,
821 app,
"AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta", options, descending,
true ,
false, j);
829 boost::optional<std::uint64_t> ledgerSeq;
830 boost::optional<std::string>
status;
831 soci::blob sociTxnBlob(session), sociTxnMetaBlob(session);
832 soci::indicator rti, tmi;
835 (session.prepare << sql,
836 soci::into(ledgerSeq),
838 soci::into(sociTxnBlob, rti),
839 soci::into(sociTxnMetaBlob, tmi));
845 if (soci::i_ok == rti)
848 if (soci::i_ok == tmi)
849 convert(sociTxnMetaBlob, txnMeta);
851 auto const seq = rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
853 ret.
emplace_back(std::move(rawTxn), std::move(txnMeta), seq);
863 soci::session& session,
865 RelationalDatabase::AccountTxOptions
const& options,
873 soci::session& session,
902 soci::session& session,
905 RelationalDatabase::AccountTxPageOptions
const& options,
911 bool lookingForMarker = options.marker.has_value();
915 if (options.limit == 0 || options.limit == UINT32_MAX || (options.limit > page_length && !options.bAdmin))
916 numberOfResults = page_length;
918 numberOfResults = options.limit;
928 if (lookingForMarker)
930 findLedger = options.marker->ledgerSeq;
931 findSeq = options.marker->txnSeq;
937 R
"(SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,
938 Status,RawTxn,TxnMeta
939 FROM AccountTransactions INNER JOIN Transactions
940 ON Transactions.TransID = AccountTransactions.TransID
941 AND AccountTransactions.Account = '%s' WHERE
948 char const*
const order =
forward ?
"ASC" :
"DESC";
953 boost::format(prefix + (R
"(AccountTransactions.LedgerSeq BETWEEN %u AND %u
954 ORDER BY AccountTransactions.LedgerSeq %s,
955 AccountTransactions.TxnSeq %s
957 toBase58(options.account) % options.minLedger % options.maxLedger % order % order % queryLimit);
965 auto b58acct =
toBase58(options.account);
968 R
"(SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,
969 Status,RawTxn,TxnMeta
970 FROM AccountTransactions, Transactions WHERE
971 (AccountTransactions.TransID = Transactions.TransID AND
972 AccountTransactions.Account = '%s' AND
973 AccountTransactions.LedgerSeq BETWEEN %u AND %u)
975 SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,Status,RawTxn,TxnMeta
976 FROM AccountTransactions, Transactions WHERE
977 (AccountTransactions.TransID = Transactions.TransID AND
978 AccountTransactions.Account = '%s' AND
979 AccountTransactions.LedgerSeq = %u AND
980 AccountTransactions.TxnSeq %s %u)
981 ORDER BY AccountTransactions.LedgerSeq %s,
982 AccountTransactions.TxnSeq %s
985 b58acct % minLedger % maxLedger % b58acct % findLedger % compare % findSeq % order % order % queryLimit);
993 boost::optional<std::uint64_t> ledgerSeq;
994 boost::optional<std::uint32_t> txnSeq;
995 boost::optional<std::string>
status;
996 soci::blob txnData(session);
997 soci::blob txnMeta(session);
998 soci::indicator dataPresent, metaPresent;
1000 soci::statement st =
1001 (session.prepare << sql,
1002 soci::into(ledgerSeq),
1005 soci::into(txnData, dataPresent),
1006 soci::into(txnMeta, metaPresent));
1012 if (lookingForMarker)
1014 if (findLedger == ledgerSeq.value_or(0) && findSeq == txnSeq.value_or(0))
1016 lookingForMarker =
false;
1021 else if (numberOfResults == 0)
1023 newmarker = {rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0)), txnSeq.
value_or(0)};
1027 if (dataPresent == soci::i_ok)
1032 if (metaPresent == soci::i_ok)
1038 if (rawMeta.size() == 0)
1039 onUnsavedLedger(ledgerSeq.value_or(0));
1044 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0)),
1047 std::move(rawMeta));
1061 return {newmarker, total};
1066 soci::session& session,
1069 RelationalDatabase::AccountTxPageOptions
const& options,
1072 return accountTxPage(session, onUnsavedLedger, onTransaction, options, page_length,
true);
1077 soci::session& session,
1080 RelationalDatabase::AccountTxPageOptions
const& options,
1083 return accountTxPage(session, onUnsavedLedger, onTransaction, options, page_length,
false);
1088 soci::session& session,
1095 "SELECT LedgerSeq,Status,RawTxn,TxnMeta "
1096 "FROM Transactions WHERE TransID='";
1102 boost::optional<std::uint64_t> ledgerSeq;
1103 boost::optional<std::string>
status;
1104 Blob rawTxn, rawMeta;
1106 soci::blob sociRawTxnBlob(session), sociRawMetaBlob(session);
1107 soci::indicator txn, meta;
1109 session << sql, soci::into(ledgerSeq), soci::into(status), soci::into(sociRawTxnBlob, txn),
1110 soci::into(sociRawMetaBlob, meta);
1112 auto const got_data = session.got_data();
1114 if ((!got_data || txn != soci::i_ok || meta != soci::i_ok) && !
range)
1120 soci::indicator rti;
1122 session <<
"SELECT COUNT(DISTINCT LedgerSeq) FROM Transactions WHERE "
1123 "LedgerSeq BETWEEN "
1124 <<
range->first() <<
" AND " <<
range->last() <<
";",
1125 soci::into(count, rti);
1127 if (!session.got_data() || rti != soci::i_ok)
1133 convert(sociRawTxnBlob, rawTxn);
1134 convert(sociRawMetaBlob, rawMeta);
1142 return std::pair{std::move(txn),
nullptr};
1144 std::uint32_t inLedger = rangeCheckedCast<std::uint32_t>(ledgerSeq.value());
1148 return std::pair{std::move(txn), std::move(txMeta)};
1152 JLOG(app.journal(
"Ledger").warn())
1153 <<
"Unable to deserialize transaction from raw SQL value. Error: " << e.
what();
1164 boost::filesystem::space_info
space = boost::filesystem::space(config.legacy(
"database_path"));
1168 JLOG(j.
fatal()) <<
"Remaining free disk space is less than 512MB";
1172 if (config.useTxTables())
1175 boost::filesystem::path dbPath = dbSetup.dataDir /
TxDBName;
1176 boost::system::error_code ec;
1180 JLOG(j.
error()) <<
"Error checking transaction db file size: " << ec.message();
1184 static auto const pageSize = [&] {
1186 session <<
"PRAGMA page_size;", soci::into(ps);
1189 static auto const maxPages = [&] {
1191 session <<
"PRAGMA max_page_count;", soci::into(mp);
1195 session <<
"PRAGMA page_count;", soci::into(pageCount);
1197 std::uint64_t freeSpace = safe_cast<std::uint64_t>(freePages) * pageSize;
1198 JLOG(j.
info()) <<
"Transaction DB pathname: " << dbPath.string() <<
"; file size: " << dbSize.
value_or(-1)
1200 <<
"; SQLite page size: " << pageSize <<
" bytes"
1201 <<
"; Free pages: " << freePages <<
"; Free space: " << freeSpace <<
" bytes; "
1202 <<
"Note that this does not take into account available disk "
1207 JLOG(j.
fatal()) <<
"Free SQLite space for transaction db is less than "
1208 "512MB. To fix this, rippled must be executed with the "
1209 "vacuum parameter before restarting. "
1210 "Note that this activity can take multiple days, "
1211 "depending on database size.";
A generic endpoint for log messages.
Stream trace() const
Severity stream access functions.
virtual TaggedCache< uint256, AcceptedLedger > & getAcceptedLedgerCache()=0
virtual Config & config()=0
virtual PendingSaves & pendingSaves()=0
virtual LedgerMaster & getLedgerMaster()=0
virtual beast::Journal journal(std::string const &name)=0
virtual NodeStore::Database & getNodeStore()=0
virtual TransactionMaster & getMasterTransaction()=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.
std::optional< LedgerHeader > getLedgerInfoByHash(soci::session &session, uint256 const &ledgerHash, beast::Journal j)
getLedgerInfoByHash Returns info of ledger with given hash.
bool saveValidatedLedger(DatabaseCon &ldgDB, std::unique_ptr< DatabaseCon > const &txnDB, Application &app, std::shared_ptr< Ledger const > const &ledger, bool current)
saveValidatedLedger Saves ledger into database.
void deleteBeforeLedgerSeq(soci::session &session, TableType type, LedgerIndex ledgerSeq)
deleteBeforeLedgerSeq Deletes all entries in given table for the ledgers with given sequence and all ...
std::optional< LedgerIndex > getMinLedgerSeq(soci::session &session, TableType type)
getMinLedgerSeq Returns minimum ledger sequence in given table.
std::optional< LedgerIndex > getMaxLedgerSeq(soci::session &session, TableType type)
getMaxLedgerSeq Returns maximum 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< 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.
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< LedgerHeader > getNewestLedgerInfo(soci::session &session, beast::Journal j)
getNewestLedgerInfo Returns info of newest saved ledger.
std::optional< LedgerHeader > getLimitedOldestLedgerInfo(soci::session &session, LedgerIndex ledgerFirstIndex, beast::Journal j)
getLimitedOldestLedgerInfo Returns info of oldest ledger from ledgers with sequences greater or equal...
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.
DatabasePairValid makeLedgerDBs(Config const &config, DatabaseCon::Setup const &setup, DatabaseCon::CheckpointerSetup const &checkpointerSetup, beast::Journal j)
makeLedgerDBs Opens ledger and transactions databases.
RelationalDatabase::CountMinMax getRowsMinMax(soci::session &session, TableType type)
getRowsMinMax Returns minimum ledger sequence, maximum ledger sequence and total number of rows in gi...
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...
static std::optional< LedgerHeader > 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...
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::size_t getRows(soci::session &session, TableType type)
getRows Returns number of rows in given table.
std::optional< LedgerHeader > getLedgerInfoByIndex(soci::session &session, LedgerIndex ledgerSeq, beast::Journal j)
getLedgerInfoByIndex Returns ledger by its sequence.
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...
uint256 getHashByIndex(soci::session &session, LedgerIndex ledgerIndex)
getHashByIndex Returns hash of ledger with given sequence.
void deleteByLedgerSeq(soci::session &session, TableType type, LedgerIndex ledgerSeq)
deleteByLedgerSeq Deletes all entries in given table for the ledger with given sequence.
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...
bool dbHasSpace(soci::session &session, Config const &config, beast::Journal j)
dbHasSpace Checks if given database has available space.
std::optional< LedgerHeader > getLimitedNewestLedgerInfo(soci::session &session, LedgerIndex ledgerFirstIndex, beast::Journal j)
getLimitedNewestLedgerInfo Returns info of newest ledger from ledgers with sequences greater or equal...
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 ...
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...
static std::string to_string(TableType type)
to_string Returns the name of a table according to its TableType.
constexpr int TableTypeCount
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...
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< 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...
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.
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
constexpr std::array< char const *, 8 > TxDBInit
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
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.
@ current
This was a new validation and was added.
constexpr auto megabytes(T value) noexcept
DatabaseCon::Setup setup_DatabaseCon(Config const &c, std::optional< beast::Journal > j=std::nullopt)
std::uint32_t LedgerIndex
A ledger index.
void addRaw(LedgerHeader const &, Serializer &, bool includeHash=false)
std::vector< unsigned char > Blob
Storage for linear binary data.
constexpr auto kilobytes(T value) noexcept
@ ledgerMaster
ledger master data for signing
@ transactionID
transaction plus signature to give transaction ID
constexpr std::array< char const *, 5 > LgrDBInit
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
void convert(soci::blob &from, std::vector< std::uint8_t > &to)
std::array< std::string, 4 > txPragma
Config::StartUpType startUp
std::array< std::string, 1 > lgrPragma
LedgerIndex minLedgerSequence
LedgerIndex maxLedgerSequence