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>
32 "Need to modify switch statement if enum is modified");
39 return "Transactions";
41 return "AccountTransactions";
44 UNREACHABLE(
"xrpl::detail::to_string : invalid TableType");
60 lgr->getSession() << boost::str(
61 boost::format(
"PRAGMA cache_size=-%d;") %
69 tx->getSession() << boost::str(
70 boost::format(
"PRAGMA cache_size=-%d;") %
82 (tx->getSession().prepare
83 << (
"PRAGMA table_info(AccountTransactions);"),
88 soci::into(dflt_value, ind),
96 return {std::move(lgr), std::move(tx),
false};
101 return {std::move(lgr), std::move(tx),
true};
104 return {std::move(lgr), {},
true};
112 boost::optional<LedgerIndex> m;
113 session << query, soci::into(m);
122 boost::optional<LedgerIndex> m;
123 session << query, soci::into(m);
130 session <<
"DELETE FROM " <<
to_string(type)
131 <<
" WHERE LedgerSeq == " << ledgerSeq <<
";";
136 soci::session& session,
140 session <<
"DELETE FROM " <<
to_string(type) <<
" WHERE LedgerSeq < "
148 session <<
"SELECT COUNT(*) AS rows "
160 session <<
"SELECT COUNT(*) AS rows, "
161 "MIN(LedgerSeq) AS first, "
162 "MAX(LedgerSeq) AS last "
179 auto j = app.
journal(
"Ledger");
180 auto seq = ledger->header().seq;
183 JLOG(j.trace()) <<
"saveValidatedLedger " << (
current ?
"" :
"fromAcquire ")
186 if (!ledger->header().accountHash.isNonZero())
189 JLOG(j.fatal()) <<
"AH is zero: " <<
getJson({*ledger, {}});
190 UNREACHABLE(
"xrpl::detail::saveValidatedLedger : zero account hash");
194 if (ledger->header().accountHash !=
195 ledger->stateMap().getHash().as_uint256())
198 JLOG(j.fatal()) <<
"sAL: " << ledger->header().accountHash
199 <<
" != " << ledger->stateMap().getHash();
200 JLOG(j.fatal()) <<
"saveAcceptedLedger: seq=" << seq
203 "xrpl::detail::saveValidatedLedger : mismatched account hash");
208 ledger->header().txHash == ledger->txMap().getHash().as_uint256(),
209 "xrpl::detail::saveValidatedLedger : transaction hash match");
215 addRaw(ledger->header(), s);
228 ledger->header().hash, aLedger);
233 JLOG(j.warn()) <<
"An accepted ledger was missing nodes";
242 static boost::format deleteLedger(
243 "DELETE FROM Ledgers WHERE LedgerSeq = %u;");
244 static boost::format deleteTrans1(
245 "DELETE FROM Transactions WHERE LedgerSeq = %u;");
246 static boost::format deleteTrans2(
247 "DELETE FROM AccountTransactions WHERE LedgerSeq = %u;");
248 static boost::format deleteAcctTrans(
249 "DELETE FROM AccountTransactions WHERE TransID = '%s';");
253 *db << boost::str(deleteLedger % seq);
261 JLOG(j.fatal()) <<
"TxTables db isn't available";
262 Throw<std::runtime_error>(
"TxTables db isn't available");
266 auto db = txnDB->checkoutDb();
268 soci::transaction tr(*db);
270 *db << boost::str(deleteTrans1 % seq);
271 *db << boost::str(deleteTrans2 % seq);
275 for (
auto const& acceptedLedgerTx : *aLedger)
285 auto const& accts = acceptedLedgerTx->getAffected();
290 "INSERT INTO AccountTransactions "
291 "(TransID, Account, LedgerSeq, TxnSeq) VALUES ");
299 for (
auto const& account : accts)
319 JLOG(j.trace()) <<
"ActTx: " << sql;
322 else if (
auto const& sleTxn = acceptedLedgerTx->getTxn();
327 JLOG(j.warn()) <<
"Transaction in ledger " << seq
328 <<
" affects no accounts";
334 acceptedLedgerTx->getTxn()->getMetaSQL(
335 seq, acceptedLedgerTx->getEscMeta()) +
341 acceptedLedgerTx->getTxnSeq(),
350 R
"sql(INSERT OR REPLACE INTO Ledgers
351 (LedgerHash,LedgerSeq,PrevHash,TotalCoins,ClosingTime,PrevClosingTime,
352 CloseTimeRes,CloseFlags,AccountSetHash,TransSetHash)
354 (:ledgerHash,:ledgerSeq,:prevHash,:totalCoins,:closingTime,:prevClosingTime,
355 :closeTimeRes,:closeFlags,:accountSetHash,:transSetHash);)sql");
359 soci::transaction tr(*db);
361 auto const hash =
to_string(ledger->header().hash);
362 auto const parentHash =
to_string(ledger->header().parentHash);
363 auto const drops =
to_string(ledger->header().drops);
364 auto const closeTime =
365 ledger->header().closeTime.time_since_epoch().count();
366 auto const parentCloseTime =
367 ledger->header().parentCloseTime.time_since_epoch().count();
368 auto const closeTimeResolution =
369 ledger->header().closeTimeResolution.count();
370 auto const closeFlags = ledger->header().closeFlags;
371 auto const accountHash =
to_string(ledger->header().accountHash);
372 auto const txHash =
to_string(ledger->header().txHash);
374 *db << addLedger, soci::use(hash), soci::use(seq),
375 soci::use(parentHash), soci::use(drops), soci::use(closeTime),
376 soci::use(parentCloseTime), soci::use(closeTimeResolution),
377 soci::use(closeFlags), soci::use(accountHash),
397 soci::session& session,
402 boost::optional<std::string> hash, parentHash, accountHash, txHash;
403 boost::optional<std::uint64_t> seq, drops, closeTime, parentCloseTime,
404 closeTimeResolution, closeFlags;
408 "LedgerHash, PrevHash, AccountSetHash, TransSetHash, "
410 "ClosingTime, PrevClosingTime, CloseTimeRes, CloseFlags,"
411 "LedgerSeq FROM Ledgers " +
414 session << sql, soci::into(hash), soci::into(parentHash),
415 soci::into(accountHash), soci::into(txHash), soci::into(drops),
416 soci::into(closeTime), soci::into(parentCloseTime),
417 soci::into(closeTimeResolution), soci::into(closeFlags),
420 if (!session.got_data())
422 JLOG(j.
debug()) <<
"Ledger not found: " << sqlSuffix;
431 if (hash && !info.hash.parseHex(*hash))
433 JLOG(j.
debug()) <<
"Hash parse error for ledger: " << sqlSuffix;
437 if (parentHash && !info.parentHash.parseHex(*parentHash))
439 JLOG(j.
debug()) <<
"parentHash parse error for ledger: " << sqlSuffix;
443 if (accountHash && !info.accountHash.parseHex(*accountHash))
445 JLOG(j.
debug()) <<
"accountHash parse error for ledger: " << sqlSuffix;
449 if (txHash && !info.txHash.parseHex(*txHash))
451 JLOG(j.
debug()) <<
"txHash parse error for ledger: " << sqlSuffix;
455 info.seq = rangeCheckedCast<std::uint32_t>(seq.value_or(0));
456 info.drops =
drops.value_or(0);
457 info.closeTime = time_point{duration{closeTime.value_or(0)}};
458 info.parentCloseTime = time_point{duration{parentCloseTime.value_or(0)}};
459 info.closeFlags = closeFlags.value_or(0);
460 info.closeTimeResolution = duration{closeTimeResolution.value_or(0)};
467 soci::session& session,
472 s <<
"WHERE LedgerSeq = " << ledgerSeq;
480 s <<
"ORDER BY LedgerSeq DESC LIMIT 1";
486 soci::session& session,
492 " ORDER BY LedgerSeq ASC LIMIT 1";
498 soci::session& session,
504 " ORDER BY LedgerSeq DESC LIMIT 1";
510 soci::session& session,
515 s <<
"WHERE LedgerHash = '" << ledgerHash <<
"'";
525 "SELECT LedgerHash FROM Ledgers INDEXED BY SeqLedger WHERE LedgerSeq='";
532 boost::optional<std::string> lh;
533 session << sql, soci::into(lh);
535 if (!session.got_data() || !lh)
551 soci::session& session,
556 boost::optional<std::string> lhO, phO;
558 session <<
"SELECT LedgerHash,PrevHash FROM Ledgers "
559 "INDEXED BY SeqLedger WHERE LedgerSeq = :ls;",
560 soci::into(lhO), soci::into(phO), soci::use(ledgerIndex);
564 auto stream = j.
trace();
565 JLOG(stream) <<
"Don't have ledger " << ledgerIndex;
569 LedgerHashPair hashes;
570 if (!hashes.ledgerHash.parseHex(*lhO) || !hashes.parentHash.parseHex(*phO))
572 auto stream = j.
trace();
573 JLOG(stream) <<
"Error parse hashes for ledger " << ledgerIndex;
582 soci::session& session,
588 "SELECT LedgerSeq,LedgerHash,PrevHash FROM Ledgers WHERE LedgerSeq >= ";
590 sql.
append(
" AND LedgerSeq <= ");
597 boost::optional<std::string> ph;
599 (session.prepare << sql,
611 JLOG(j.
warn()) <<
"Error parsed hash for ledger seq: " << ls;
615 JLOG(j.
warn()) <<
"Null prev hash for ledger seq: " << ls;
619 JLOG(j.
warn()) <<
"Error parsed prev hash for ledger seq: " << ls;
627 soci::session& session,
634 "SELECT LedgerSeq, Status, RawTxn "
635 "FROM Transactions ORDER BY LedgerSeq DESC LIMIT %u,%u;") %
636 startIndex % quantity);
643 boost::optional<std::uint64_t> ledgerSeq;
644 boost::optional<std::string> status;
645 soci::blob sociRawTxnBlob(session);
650 (session.prepare << sql,
651 soci::into(ledgerSeq),
653 soci::into(sociRawTxnBlob, rti));
658 if (soci::i_ok == rti)
659 convert(sociRawTxnBlob, rawTxn);
664 ledgerSeq, status, rawTxn, app))
696 RelationalDatabase::AccountTxOptions
const& options,
711 else if (options.limit == UINT32_MAX)
713 numberOfResults = binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH;
715 else if (!options.bUnlimited)
718 binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH, options.limit);
722 numberOfResults = options.limit;
728 if (options.maxLedger)
730 maxClause = boost::str(
731 boost::format(
"AND AccountTransactions.LedgerSeq <= '%u'") %
735 if (options.minLedger)
737 minClause = boost::str(
738 boost::format(
"AND AccountTransactions.LedgerSeq >= '%u'") %
746 boost::format(
"SELECT %s FROM AccountTransactions "
747 "WHERE Account = '%s' %s %s LIMIT %u, %u;") %
748 selection %
toBase58(options.account) % maxClause % minClause %
749 options.offset % numberOfResults);
754 "AccountTransactions INNER JOIN Transactions "
755 "ON Transactions.TransID = AccountTransactions.TransID "
756 "WHERE Account = '%s' %s %s "
757 "ORDER BY AccountTransactions.LedgerSeq %s, "
758 "AccountTransactions.TxnSeq %s, AccountTransactions.TransID %s "
760 selection %
toBase58(options.account) % maxClause % minClause %
761 (descending ?
"DESC" :
"ASC") % (descending ?
"DESC" :
"ASC") %
762 (descending ?
"DESC" :
"ASC") % options.offset % numberOfResults);
763 JLOG(j.
trace()) <<
"txSQL query: " << sql;
790 soci::session& session,
793 RelationalDatabase::AccountTxOptions
const& options,
801 "AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
813 boost::optional<std::uint64_t> ledgerSeq;
814 boost::optional<std::string>
status;
815 soci::blob sociTxnBlob(session), sociTxnMetaBlob(session);
816 soci::indicator rti, tmi;
817 Blob rawTxn, txnMeta;
820 (session.prepare << sql,
821 soci::into(ledgerSeq),
823 soci::into(sociTxnBlob, rti),
824 soci::into(sociTxnMetaBlob, tmi));
829 if (soci::i_ok == rti)
834 if (soci::i_ok == tmi)
835 convert(sociTxnMetaBlob, txnMeta);
845 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
848 <<
"Recovering ledger " << seq <<
", txn " << txn->getID();
859 txn->getID(), txn->getLedger(), txnMeta));
870 soci::session& session,
873 RelationalDatabase::AccountTxOptions
const& options,
881 soci::session& session,
912 soci::session& session,
914 RelationalDatabase::AccountTxOptions
const& options,
922 "AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
935 boost::optional<std::uint64_t> ledgerSeq;
936 boost::optional<std::string>
status;
937 soci::blob sociTxnBlob(session), sociTxnMetaBlob(session);
938 soci::indicator rti, tmi;
941 (session.prepare << sql,
942 soci::into(ledgerSeq),
944 soci::into(sociTxnBlob, rti),
945 soci::into(sociTxnMetaBlob, tmi));
951 if (soci::i_ok == rti)
954 if (soci::i_ok == tmi)
955 convert(sociTxnMetaBlob, txnMeta);
958 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
960 ret.
emplace_back(std::move(rawTxn), std::move(txnMeta), seq);
970 soci::session& session,
972 RelationalDatabase::AccountTxOptions
const& options,
980 soci::session& session,
1009 soci::session& session,
1014 RelationalDatabase::AccountTxPageOptions
const& options,
1020 bool lookingForMarker = options.marker.has_value();
1024 if (options.limit == 0 || options.limit == UINT32_MAX ||
1025 (options.limit > page_length && !options.bAdmin))
1026 numberOfResults = page_length;
1028 numberOfResults = options.limit;
1038 if (lookingForMarker)
1040 findLedger = options.marker->ledgerSeq;
1041 findSeq = options.marker->txnSeq;
1047 R
"(SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,
1048 Status,RawTxn,TxnMeta
1049 FROM AccountTransactions INNER JOIN Transactions
1050 ON Transactions.TransID = AccountTransactions.TransID
1051 AND AccountTransactions.Account = '%s' WHERE
1058 char const*
const order =
forward ?
"ASC" :
"DESC";
1060 if (findLedger == 0)
1064 prefix + (R
"(AccountTransactions.LedgerSeq BETWEEN %u AND %u
1065 ORDER BY AccountTransactions.LedgerSeq %s,
1066 AccountTransactions.TxnSeq %s
1068 toBase58(options.account) % options.minLedger % options.maxLedger %
1069 order % order % queryLimit);
1075 forward ? findLedger + 1 : options.minLedger;
1077 forward ? options.maxLedger : findLedger - 1;
1079 auto b58acct =
toBase58(options.account);
1082 R
"(SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,
1083 Status,RawTxn,TxnMeta
1084 FROM AccountTransactions, Transactions WHERE
1085 (AccountTransactions.TransID = Transactions.TransID AND
1086 AccountTransactions.Account = '%s' AND
1087 AccountTransactions.LedgerSeq BETWEEN %u AND %u)
1089 SELECT AccountTransactions.LedgerSeq,AccountTransactions.TxnSeq,Status,RawTxn,TxnMeta
1090 FROM AccountTransactions, Transactions WHERE
1091 (AccountTransactions.TransID = Transactions.TransID AND
1092 AccountTransactions.Account = '%s' AND
1093 AccountTransactions.LedgerSeq = %u AND
1094 AccountTransactions.TxnSeq %s %u)
1095 ORDER BY AccountTransactions.LedgerSeq %s,
1096 AccountTransactions.TxnSeq %s
1099 b58acct % minLedger % maxLedger % b58acct % findLedger % compare %
1100 findSeq % order % order % queryLimit);
1108 boost::optional<std::uint64_t> ledgerSeq;
1109 boost::optional<std::uint32_t> txnSeq;
1110 boost::optional<std::string>
status;
1111 soci::blob txnData(session);
1112 soci::blob txnMeta(session);
1113 soci::indicator dataPresent, metaPresent;
1115 soci::statement st =
1116 (session.prepare << sql,
1117 soci::into(ledgerSeq),
1120 soci::into(txnData, dataPresent),
1121 soci::into(txnMeta, metaPresent));
1127 if (lookingForMarker)
1129 if (findLedger == ledgerSeq.value_or(0) &&
1130 findSeq == txnSeq.value_or(0))
1132 lookingForMarker =
false;
1137 else if (numberOfResults == 0)
1140 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0)),
1145 if (dataPresent == soci::i_ok)
1150 if (metaPresent == soci::i_ok)
1156 if (rawMeta.size() == 0)
1157 onUnsavedLedger(ledgerSeq.value_or(0));
1162 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0)),
1165 std::move(rawMeta));
1179 return {newmarker, total};
1184 soci::session& session,
1193 session, onUnsavedLedger, onTransaction, options, page_length,
true);
1198 soci::session& session,
1207 session, onUnsavedLedger, onTransaction, options, page_length,
false);
1212 soci::session& session,
1219 "SELECT LedgerSeq,Status,RawTxn,TxnMeta "
1220 "FROM Transactions WHERE TransID='";
1226 boost::optional<std::uint64_t> ledgerSeq;
1227 boost::optional<std::string> status;
1228 Blob rawTxn, rawMeta;
1230 soci::blob sociRawTxnBlob(session), sociRawMetaBlob(session);
1231 soci::indicator txn, meta;
1233 session << sql, soci::into(ledgerSeq), soci::into(status),
1234 soci::into(sociRawTxnBlob, txn), soci::into(sociRawMetaBlob, meta);
1236 auto const got_data = session.got_data();
1238 if ((!got_data || txn != soci::i_ok || meta != soci::i_ok) && !
range)
1244 soci::indicator rti;
1247 <<
"SELECT COUNT(DISTINCT LedgerSeq) FROM Transactions WHERE "
1248 "LedgerSeq BETWEEN "
1249 <<
range->first() <<
" AND " <<
range->last() <<
";",
1250 soci::into(count, rti);
1252 if (!session.got_data() || rti != soci::i_ok)
1255 return count == (
range->last() -
range->first() + 1)
1260 convert(sociRawTxnBlob, rawTxn);
1261 convert(sociRawMetaBlob, rawMeta);
1270 return std::pair{std::move(txn),
nullptr};
1273 rangeCheckedCast<std::uint32_t>(ledgerSeq.value());
1277 return std::pair{std::move(txn), std::move(txMeta)};
1281 JLOG(app.journal(
"Ledger").warn())
1282 <<
"Unable to deserialize transaction from raw SQL value. Error: "
1294 boost::filesystem::space_info
space =
1295 boost::filesystem::space(config.legacy(
"database_path"));
1299 JLOG(j.
fatal()) <<
"Remaining free disk space is less than 512MB";
1303 if (config.useTxTables())
1306 boost::filesystem::path dbPath = dbSetup.dataDir /
TxDBName;
1307 boost::system::error_code ec;
1309 boost::filesystem::file_size(dbPath, ec);
1313 <<
"Error checking transaction db file size: " << ec.message();
1317 static auto const pageSize = [&] {
1319 session <<
"PRAGMA page_size;", soci::into(ps);
1322 static auto const maxPages = [&] {
1324 session <<
"PRAGMA max_page_count;", soci::into(mp);
1328 session <<
"PRAGMA page_count;", soci::into(pageCount);
1331 safe_cast<std::uint64_t>(freePages) * pageSize;
1333 <<
"Transaction DB pathname: " << dbPath.string()
1334 <<
"; file size: " << dbSize.
value_or(-1) <<
" bytes"
1335 <<
"; SQLite page size: " << pageSize <<
" bytes"
1336 <<
"; Free pages: " << freePages <<
"; Free space: " << freeSpace
1338 <<
"Note that this does not take into account available disk "
1344 <<
"Free SQLite space for transaction db is less than "
1345 "512MB. To fix this, rippled must be executed with the "
1346 "vacuum parameter before restarting. "
1347 "Note that this activity can take multiple days, "
1348 "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