diff --git a/PostgresDatabase_8cpp_source.html b/PostgresDatabase_8cpp_source.html index 6009e5c56a..0a82d81a21 100644 --- a/PostgresDatabase_8cpp_source.html +++ b/PostgresDatabase_8cpp_source.html @@ -236,898 +236,894 @@ $(function() {
175  "total_coins, closing_time, prev_closing_time, close_time_res, "
176  "close_flags, ledger_seq FROM ledgers ";
177 
-
178  uint32_t expNumResults = 1;
-
179 
-
180  if (auto ledgerSeq = std::get_if<uint32_t>(&whichLedger))
-
181  {
-
182  sql << "WHERE ledger_seq = " + std::to_string(*ledgerSeq);
-
183  }
-
184  else if (auto ledgerHash = std::get_if<uint256>(&whichLedger))
-
185  {
-
186  sql << ("WHERE ledger_hash = \'\\x" + strHex(*ledgerHash) + "\'");
-
187  }
-
188  else if (
-
189  auto minAndMax =
-
190  std::get_if<std::pair<uint32_t, uint32_t>>(&whichLedger))
-
191  {
-
192  expNumResults = minAndMax->second - minAndMax->first;
-
193 
-
194  sql
-
195  << ("WHERE ledger_seq >= " + std::to_string(minAndMax->first) +
-
196  " AND ledger_seq <= " + std::to_string(minAndMax->second));
+
178  if (auto ledgerSeq = std::get_if<uint32_t>(&whichLedger))
+
179  {
+
180  sql << "WHERE ledger_seq = " + std::to_string(*ledgerSeq);
+
181  }
+
182  else if (auto ledgerHash = std::get_if<uint256>(&whichLedger))
+
183  {
+
184  sql << ("WHERE ledger_hash = \'\\x" + strHex(*ledgerHash) + "\'");
+
185  }
+
186  else if (
+
187  auto minAndMax =
+
188  std::get_if<std::pair<uint32_t, uint32_t>>(&whichLedger))
+
189  {
+
190  sql
+
191  << ("WHERE ledger_seq >= " + std::to_string(minAndMax->first) +
+
192  " AND ledger_seq <= " + std::to_string(minAndMax->second));
+
193  }
+
194  else
+
195  {
+
196  sql << ("ORDER BY ledger_seq desc LIMIT 1");
197  }
-
198  else
-
199  {
-
200  sql << ("ORDER BY ledger_seq desc LIMIT 1");
-
201  }
-
202  sql << ";";
-
203 
-
204  JLOG(log.trace()) << __func__ << " : sql = " << sql.str();
-
205 
-
206  auto res = PgQuery(pgPool)(sql.str().data());
-
207  if (!res)
-
208  {
-
209  JLOG(log.error()) << __func__ << " : Postgres response is null - sql = "
-
210  << sql.str();
-
211  assert(false);
-
212  return {};
-
213  }
-
214  else if (res.status() != PGRES_TUPLES_OK)
-
215  {
-
216  JLOG(log.error()) << __func__
-
217  << " : Postgres response should have been "
-
218  "PGRES_TUPLES_OK but instead was "
-
219  << res.status() << " - msg = " << res.msg()
-
220  << " - sql = " << sql.str();
-
221  assert(false);
-
222  return {};
-
223  }
-
224 
-
225  JLOG(log.trace()) << __func__ << " Postgres result msg : " << res.msg();
-
226 
-
227  if (res.isNull() || res.ntuples() == 0)
-
228  {
-
229  JLOG(log.debug()) << __func__
-
230  << " : Ledger not found. sql = " << sql.str();
-
231  return {};
-
232  }
-
233  else if (res.ntuples() > 0)
-
234  {
-
235  if (res.nfields() != 10)
-
236  {
-
237  JLOG(log.error()) << __func__
-
238  << " : Wrong number of fields in Postgres "
-
239  "response. Expected 10, but got "
-
240  << res.nfields() << " . sql = " << sql.str();
-
241  assert(false);
-
242  return {};
-
243  }
-
244  }
-
245 
-
246  for (size_t i = 0; i < res.ntuples(); ++i)
-
247  {
-
248  char const* hash = res.c_str(i, 0);
-
249  char const* prevHash = res.c_str(i, 1);
-
250  char const* accountHash = res.c_str(i, 2);
-
251  char const* txHash = res.c_str(i, 3);
-
252  std::int64_t totalCoins = res.asBigInt(i, 4);
-
253  std::int64_t closeTime = res.asBigInt(i, 5);
-
254  std::int64_t parentCloseTime = res.asBigInt(i, 6);
-
255  std::int64_t closeTimeRes = res.asBigInt(i, 7);
-
256  std::int64_t closeFlags = res.asBigInt(i, 8);
-
257  std::int64_t ledgerSeq = res.asBigInt(i, 9);
-
258 
-
259  JLOG(log.trace()) << __func__ << " - Postgres response = " << hash
-
260  << " , " << prevHash << " , " << accountHash << " , "
-
261  << txHash << " , " << totalCoins << ", " << closeTime
-
262  << ", " << parentCloseTime << ", " << closeTimeRes
-
263  << ", " << closeFlags << ", " << ledgerSeq
-
264  << " - sql = " << sql.str();
-
265  JLOG(log.debug()) << __func__
-
266  << " - Successfully fetched ledger with sequence = "
-
267  << ledgerSeq << " from Postgres";
-
268 
-
269  using time_point = NetClock::time_point;
-
270  using duration = NetClock::duration;
-
271 
-
272  LedgerInfo info;
-
273  if (!info.parentHash.parseHex(prevHash + 2))
+
198  sql << ";";
+
199 
+
200  JLOG(log.trace()) << __func__ << " : sql = " << sql.str();
+
201 
+
202  auto res = PgQuery(pgPool)(sql.str().data());
+
203  if (!res)
+
204  {
+
205  JLOG(log.error()) << __func__ << " : Postgres response is null - sql = "
+
206  << sql.str();
+
207  assert(false);
+
208  return {};
+
209  }
+
210  else if (res.status() != PGRES_TUPLES_OK)
+
211  {
+
212  JLOG(log.error()) << __func__
+
213  << " : Postgres response should have been "
+
214  "PGRES_TUPLES_OK but instead was "
+
215  << res.status() << " - msg = " << res.msg()
+
216  << " - sql = " << sql.str();
+
217  assert(false);
+
218  return {};
+
219  }
+
220 
+
221  JLOG(log.trace()) << __func__ << " Postgres result msg : " << res.msg();
+
222 
+
223  if (res.isNull() || res.ntuples() == 0)
+
224  {
+
225  JLOG(log.debug()) << __func__
+
226  << " : Ledger not found. sql = " << sql.str();
+
227  return {};
+
228  }
+
229  else if (res.ntuples() > 0)
+
230  {
+
231  if (res.nfields() != 10)
+
232  {
+
233  JLOG(log.error()) << __func__
+
234  << " : Wrong number of fields in Postgres "
+
235  "response. Expected 10, but got "
+
236  << res.nfields() << " . sql = " << sql.str();
+
237  assert(false);
+
238  return {};
+
239  }
+
240  }
+
241 
+
242  for (size_t i = 0; i < res.ntuples(); ++i)
+
243  {
+
244  char const* hash = res.c_str(i, 0);
+
245  char const* prevHash = res.c_str(i, 1);
+
246  char const* accountHash = res.c_str(i, 2);
+
247  char const* txHash = res.c_str(i, 3);
+
248  std::int64_t totalCoins = res.asBigInt(i, 4);
+
249  std::int64_t closeTime = res.asBigInt(i, 5);
+
250  std::int64_t parentCloseTime = res.asBigInt(i, 6);
+
251  std::int64_t closeTimeRes = res.asBigInt(i, 7);
+
252  std::int64_t closeFlags = res.asBigInt(i, 8);
+
253  std::int64_t ledgerSeq = res.asBigInt(i, 9);
+
254 
+
255  JLOG(log.trace()) << __func__ << " - Postgres response = " << hash
+
256  << " , " << prevHash << " , " << accountHash << " , "
+
257  << txHash << " , " << totalCoins << ", " << closeTime
+
258  << ", " << parentCloseTime << ", " << closeTimeRes
+
259  << ", " << closeFlags << ", " << ledgerSeq
+
260  << " - sql = " << sql.str();
+
261  JLOG(log.debug()) << __func__
+
262  << " - Successfully fetched ledger with sequence = "
+
263  << ledgerSeq << " from Postgres";
+
264 
+
265  using time_point = NetClock::time_point;
+
266  using duration = NetClock::duration;
+
267 
+
268  LedgerInfo info;
+
269  if (!info.parentHash.parseHex(prevHash + 2))
+
270  assert(false);
+
271  if (!info.txHash.parseHex(txHash + 2))
+
272  assert(false);
+
273  if (!info.accountHash.parseHex(accountHash + 2))
274  assert(false);
-
275  if (!info.txHash.parseHex(txHash + 2))
-
276  assert(false);
-
277  if (!info.accountHash.parseHex(accountHash + 2))
-
278  assert(false);
-
279  info.drops = totalCoins;
-
280  info.closeTime = time_point{duration{closeTime}};
-
281  info.parentCloseTime = time_point{duration{parentCloseTime}};
-
282  info.closeFlags = closeFlags;
-
283  info.closeTimeResolution = duration{closeTimeRes};
-
284  info.seq = ledgerSeq;
-
285  if (!info.hash.parseHex(hash + 2))
-
286  assert(false);
-
287  info.validated = true;
-
288  infos.push_back(info);
-
289  }
+
275  info.drops = totalCoins;
+
276  info.closeTime = time_point{duration{closeTime}};
+
277  info.parentCloseTime = time_point{duration{parentCloseTime}};
+
278  info.closeFlags = closeFlags;
+
279  info.closeTimeResolution = duration{closeTimeRes};
+
280  info.seq = ledgerSeq;
+
281  if (!info.hash.parseHex(hash + 2))
+
282  assert(false);
+
283  info.validated = true;
+
284  infos.push_back(info);
+
285  }
+
286 
+
287 #endif
+
288  return infos;
+
289 }
290 
-
291 #endif
-
292  return infos;
-
293 }
-
294 
-
303 static std::optional<LedgerInfo>
-
304 loadLedgerHelper(
-
305  std::shared_ptr<PgPool> const& pgPool,
-
306  std::variant<std::monostate, uint256, uint32_t> const& whichLedger,
-
307  Application& app)
-
308 {
-
309  std::vector<LedgerInfo> infos;
-
310  std::visit(
-
311  [&infos, &app, &pgPool](auto&& arg) {
-
312  infos = loadLedgerInfos(pgPool, arg, app);
-
313  },
-
314  whichLedger);
-
315  assert(infos.size() <= 1);
-
316  if (!infos.size())
-
317  return {};
-
318  return infos[0];
-
319 }
-
320 
-
321 #ifdef RIPPLED_REPORTING
-
322 static bool
-
323 writeToLedgersDB(LedgerInfo const& info, PgQuery& pgQuery, beast::Journal& j)
-
324 {
-
325  JLOG(j.debug()) << __func__;
-
326  auto cmd = boost::format(
-
327  R"(INSERT INTO ledgers
-
328  VALUES (%u,'\x%s', '\x%s',%u,%u,%u,%u,%u,'\x%s','\x%s'))");
-
329 
-
330  auto ledgerInsert = boost::str(
-
331  cmd % info.seq % strHex(info.hash) % strHex(info.parentHash) %
-
332  info.drops.drops() % info.closeTime.time_since_epoch().count() %
-
333  info.parentCloseTime.time_since_epoch().count() %
-
334  info.closeTimeResolution.count() % info.closeFlags %
-
335  strHex(info.accountHash) % strHex(info.txHash));
-
336  JLOG(j.trace()) << __func__ << " : "
-
337  << " : "
-
338  << "query string = " << ledgerInsert;
-
339 
-
340  auto res = pgQuery(ledgerInsert.data());
-
341 
-
342  return res;
-
343 }
-
344 
-
345 enum class DataFormat { binary, expanded };
-
346 static std::variant<TxnsData, TxnsDataBinary>
-
347 flatFetchTransactions(
-
348  Application& app,
-
349  std::vector<uint256>& nodestoreHashes,
-
350  std::vector<uint32_t>& ledgerSequences,
-
351  DataFormat format)
-
352 {
-
353  std::variant<TxnsData, TxnsDataBinary> ret;
-
354  if (format == DataFormat::binary)
-
355  ret = TxnsDataBinary();
-
356  else
-
357  ret = TxnsData();
-
358 
-
359  std::vector<
-
360  std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>>
-
361  txns = flatFetchTransactions(app, nodestoreHashes);
-
362  for (size_t i = 0; i < txns.size(); ++i)
-
363  {
-
364  auto& [txn, meta] = txns[i];
-
365  if (format == DataFormat::binary)
-
366  {
-
367  auto& transactions = std::get<TxnsDataBinary>(ret);
-
368  Serializer txnSer = txn->getSerializer();
-
369  Serializer metaSer = meta->getSerializer();
-
370  // SerialIter it(item->slice());
-
371  Blob txnBlob = txnSer.getData();
-
372  Blob metaBlob = metaSer.getData();
-
373  transactions.push_back(
-
374  std::make_tuple(txnBlob, metaBlob, ledgerSequences[i]));
-
375  }
-
376  else
-
377  {
-
378  auto& transactions = std::get<TxnsData>(ret);
-
379  std::string reason;
-
380  auto txnRet = std::make_shared<Transaction>(txn, reason, app);
-
381  txnRet->setLedger(ledgerSequences[i]);
-
382  txnRet->setStatus(COMMITTED);
-
383  auto txMeta = std::make_shared<TxMeta>(
-
384  txnRet->getID(), ledgerSequences[i], *meta);
-
385  transactions.push_back(std::make_pair(txnRet, txMeta));
-
386  }
-
387  }
-
388  return ret;
-
389 }
-
390 
-
391 static std::pair<AccountTxResult, RPC::Status>
-
392 processAccountTxStoredProcedureResult(
-
393  RelationalDatabase::AccountTxArgs const& args,
-
394  Json::Value& result,
-
395  Application& app,
-
396  beast::Journal j)
-
397 {
-
398  AccountTxResult ret;
-
399  ret.limit = args.limit;
-
400 
-
401  try
-
402  {
-
403  if (result.isMember("transactions"))
-
404  {
-
405  std::vector<uint256> nodestoreHashes;
-
406  std::vector<uint32_t> ledgerSequences;
-
407  for (auto& t : result["transactions"])
-
408  {
-
409  if (t.isMember("ledger_seq") && t.isMember("nodestore_hash"))
-
410  {
-
411  uint32_t ledgerSequence = t["ledger_seq"].asUInt();
-
412  std::string nodestoreHashHex =
-
413  t["nodestore_hash"].asString();
-
414  nodestoreHashHex.erase(0, 2);
-
415  uint256 nodestoreHash;
-
416  if (!nodestoreHash.parseHex(nodestoreHashHex))
-
417  assert(false);
-
418 
-
419  if (nodestoreHash.isNonZero())
-
420  {
-
421  ledgerSequences.push_back(ledgerSequence);
-
422  nodestoreHashes.push_back(nodestoreHash);
-
423  }
-
424  else
-
425  {
-
426  assert(false);
-
427  return {ret, {rpcINTERNAL, "nodestoreHash is zero"}};
-
428  }
-
429  }
-
430  else
-
431  {
-
432  assert(false);
-
433  return {ret, {rpcINTERNAL, "missing postgres fields"}};
-
434  }
-
435  }
-
436 
-
437  assert(nodestoreHashes.size() == ledgerSequences.size());
-
438  ret.transactions = flatFetchTransactions(
-
439  app,
-
440  nodestoreHashes,
-
441  ledgerSequences,
-
442  args.binary ? DataFormat::binary : DataFormat::expanded);
-
443 
-
444  JLOG(j.trace()) << __func__ << " : processed db results";
-
445 
-
446  if (result.isMember("marker"))
-
447  {
-
448  auto& marker = result["marker"];
-
449  assert(marker.isMember("ledger"));
-
450  assert(marker.isMember("seq"));
-
451  ret.marker = {
-
452  marker["ledger"].asUInt(), marker["seq"].asUInt()};
-
453  }
-
454  assert(result.isMember("ledger_index_min"));
-
455  assert(result.isMember("ledger_index_max"));
-
456  ret.ledgerRange = {
-
457  result["ledger_index_min"].asUInt(),
-
458  result["ledger_index_max"].asUInt()};
-
459  return {ret, rpcSUCCESS};
-
460  }
-
461  else if (result.isMember("error"))
-
462  {
-
463  JLOG(j.debug())
-
464  << __func__ << " : error = " << result["error"].asString();
-
465  return {
-
466  ret,
-
467  RPC::Status{rpcINVALID_PARAMS, result["error"].asString()}};
+
299 static std::optional<LedgerInfo>
+
300 loadLedgerHelper(
+
301  std::shared_ptr<PgPool> const& pgPool,
+
302  std::variant<std::monostate, uint256, uint32_t> const& whichLedger,
+
303  Application& app)
+
304 {
+
305  std::vector<LedgerInfo> infos;
+
306  std::visit(
+
307  [&infos, &app, &pgPool](auto&& arg) {
+
308  infos = loadLedgerInfos(pgPool, arg, app);
+
309  },
+
310  whichLedger);
+
311  assert(infos.size() <= 1);
+
312  if (!infos.size())
+
313  return {};
+
314  return infos[0];
+
315 }
+
316 
+
317 #ifdef RIPPLED_REPORTING
+
318 static bool
+
319 writeToLedgersDB(LedgerInfo const& info, PgQuery& pgQuery, beast::Journal& j)
+
320 {
+
321  JLOG(j.debug()) << __func__;
+
322  auto cmd = boost::format(
+
323  R"(INSERT INTO ledgers
+
324  VALUES (%u,'\x%s', '\x%s',%u,%u,%u,%u,%u,'\x%s','\x%s'))");
+
325 
+
326  auto ledgerInsert = boost::str(
+
327  cmd % info.seq % strHex(info.hash) % strHex(info.parentHash) %
+
328  info.drops.drops() % info.closeTime.time_since_epoch().count() %
+
329  info.parentCloseTime.time_since_epoch().count() %
+
330  info.closeTimeResolution.count() % info.closeFlags %
+
331  strHex(info.accountHash) % strHex(info.txHash));
+
332  JLOG(j.trace()) << __func__ << " : "
+
333  << " : "
+
334  << "query string = " << ledgerInsert;
+
335 
+
336  auto res = pgQuery(ledgerInsert.data());
+
337 
+
338  return res;
+
339 }
+
340 
+
341 enum class DataFormat { binary, expanded };
+
342 static std::variant<TxnsData, TxnsDataBinary>
+
343 flatFetchTransactions(
+
344  Application& app,
+
345  std::vector<uint256>& nodestoreHashes,
+
346  std::vector<uint32_t>& ledgerSequences,
+
347  DataFormat format)
+
348 {
+
349  std::variant<TxnsData, TxnsDataBinary> ret;
+
350  if (format == DataFormat::binary)
+
351  ret = TxnsDataBinary();
+
352  else
+
353  ret = TxnsData();
+
354 
+
355  std::vector<
+
356  std::pair<std::shared_ptr<STTx const>, std::shared_ptr<STObject const>>>
+
357  txns = flatFetchTransactions(app, nodestoreHashes);
+
358  for (size_t i = 0; i < txns.size(); ++i)
+
359  {
+
360  auto& [txn, meta] = txns[i];
+
361  if (format == DataFormat::binary)
+
362  {
+
363  auto& transactions = std::get<TxnsDataBinary>(ret);
+
364  Serializer txnSer = txn->getSerializer();
+
365  Serializer metaSer = meta->getSerializer();
+
366  // SerialIter it(item->slice());
+
367  Blob txnBlob = txnSer.getData();
+
368  Blob metaBlob = metaSer.getData();
+
369  transactions.push_back(
+
370  std::make_tuple(txnBlob, metaBlob, ledgerSequences[i]));
+
371  }
+
372  else
+
373  {
+
374  auto& transactions = std::get<TxnsData>(ret);
+
375  std::string reason;
+
376  auto txnRet = std::make_shared<Transaction>(txn, reason, app);
+
377  txnRet->setLedger(ledgerSequences[i]);
+
378  txnRet->setStatus(COMMITTED);
+
379  auto txMeta = std::make_shared<TxMeta>(
+
380  txnRet->getID(), ledgerSequences[i], *meta);
+
381  transactions.push_back(std::make_pair(txnRet, txMeta));
+
382  }
+
383  }
+
384  return ret;
+
385 }
+
386 
+
387 static std::pair<AccountTxResult, RPC::Status>
+
388 processAccountTxStoredProcedureResult(
+
389  RelationalDatabase::AccountTxArgs const& args,
+
390  Json::Value& result,
+
391  Application& app,
+
392  beast::Journal j)
+
393 {
+
394  AccountTxResult ret;
+
395  ret.limit = args.limit;
+
396 
+
397  try
+
398  {
+
399  if (result.isMember("transactions"))
+
400  {
+
401  std::vector<uint256> nodestoreHashes;
+
402  std::vector<uint32_t> ledgerSequences;
+
403  for (auto& t : result["transactions"])
+
404  {
+
405  if (t.isMember("ledger_seq") && t.isMember("nodestore_hash"))
+
406  {
+
407  uint32_t ledgerSequence = t["ledger_seq"].asUInt();
+
408  std::string nodestoreHashHex =
+
409  t["nodestore_hash"].asString();
+
410  nodestoreHashHex.erase(0, 2);
+
411  uint256 nodestoreHash;
+
412  if (!nodestoreHash.parseHex(nodestoreHashHex))
+
413  assert(false);
+
414 
+
415  if (nodestoreHash.isNonZero())
+
416  {
+
417  ledgerSequences.push_back(ledgerSequence);
+
418  nodestoreHashes.push_back(nodestoreHash);
+
419  }
+
420  else
+
421  {
+
422  assert(false);
+
423  return {ret, {rpcINTERNAL, "nodestoreHash is zero"}};
+
424  }
+
425  }
+
426  else
+
427  {
+
428  assert(false);
+
429  return {ret, {rpcINTERNAL, "missing postgres fields"}};
+
430  }
+
431  }
+
432 
+
433  assert(nodestoreHashes.size() == ledgerSequences.size());
+
434  ret.transactions = flatFetchTransactions(
+
435  app,
+
436  nodestoreHashes,
+
437  ledgerSequences,
+
438  args.binary ? DataFormat::binary : DataFormat::expanded);
+
439 
+
440  JLOG(j.trace()) << __func__ << " : processed db results";
+
441 
+
442  if (result.isMember("marker"))
+
443  {
+
444  auto& marker = result["marker"];
+
445  assert(marker.isMember("ledger"));
+
446  assert(marker.isMember("seq"));
+
447  ret.marker = {
+
448  marker["ledger"].asUInt(), marker["seq"].asUInt()};
+
449  }
+
450  assert(result.isMember("ledger_index_min"));
+
451  assert(result.isMember("ledger_index_max"));
+
452  ret.ledgerRange = {
+
453  result["ledger_index_min"].asUInt(),
+
454  result["ledger_index_max"].asUInt()};
+
455  return {ret, rpcSUCCESS};
+
456  }
+
457  else if (result.isMember("error"))
+
458  {
+
459  JLOG(j.debug())
+
460  << __func__ << " : error = " << result["error"].asString();
+
461  return {
+
462  ret,
+
463  RPC::Status{rpcINVALID_PARAMS, result["error"].asString()}};
+
464  }
+
465  else
+
466  {
+
467  return {ret, {rpcINTERNAL, "unexpected Postgres response"}};
468  }
-
469  else
-
470  {
-
471  return {ret, {rpcINTERNAL, "unexpected Postgres response"}};
-
472  }
-
473  }
-
474  catch (std::exception& e)
-
475  {
-
476  JLOG(j.debug()) << __func__ << " : "
-
477  << "Caught exception : " << e.what();
-
478  return {ret, {rpcINTERNAL, e.what()}};
-
479  }
-
480 }
-
481 #endif
-
482 
-
483 void
-
484 PostgresDatabaseImp::sweep()
-
485 {
-
486 #ifdef RIPPLED_REPORTING
-
487  pgPool_->idleSweeper();
-
488 #endif
-
489 }
-
490 
-
491 std::optional<LedgerIndex>
-
492 PostgresDatabaseImp::getMinLedgerSeq()
-
493 {
-
494 #ifdef RIPPLED_REPORTING
-
495  auto seq = PgQuery(pgPool_)("SELECT min_ledger()");
-
496  if (!seq)
-
497  {
-
498  JLOG(j_.error()) << "Error querying minimum ledger sequence.";
-
499  }
-
500  else if (!seq.isNull())
-
501  return seq.asInt();
-
502 #endif
-
503  return {};
-
504 }
-
505 
-
506 std::optional<LedgerIndex>
-
507 PostgresDatabaseImp::getMaxLedgerSeq()
-
508 {
-
509 #ifdef RIPPLED_REPORTING
-
510  auto seq = PgQuery(pgPool_)("SELECT max_ledger()");
-
511  if (seq && !seq.isNull())
-
512  return seq.asBigInt();
-
513 #endif
-
514  return {};
-
515 }
-
516 
-
517 std::string
-
518 PostgresDatabaseImp::getCompleteLedgers()
-
519 {
-
520 #ifdef RIPPLED_REPORTING
-
521  auto range = PgQuery(pgPool_)("SELECT complete_ledgers()");
-
522  if (range)
-
523  return range.c_str();
-
524 #endif
-
525  return "error";
-
526 }
-
527 
-
528 std::chrono::seconds
-
529 PostgresDatabaseImp::getValidatedLedgerAge()
-
530 {
-
531  using namespace std::chrono_literals;
-
532 #ifdef RIPPLED_REPORTING
-
533  auto age = PgQuery(pgPool_)("SELECT age()");
-
534  if (!age || age.isNull())
-
535  JLOG(j_.debug()) << "No ledgers in database";
-
536  else
-
537  return std::chrono::seconds{age.asInt()};
-
538 #endif
-
539  return weeks{2};
-
540 }
-
541 
-
542 bool
-
543 PostgresDatabaseImp::writeLedgerAndTransactions(
-
544  LedgerInfo const& info,
-
545  std::vector<AccountTransactionsData> const& accountTxData)
-
546 {
-
547 #ifdef RIPPLED_REPORTING
-
548  JLOG(j_.debug()) << __func__ << " : "
-
549  << "Beginning write to Postgres";
-
550 
-
551  try
-
552  {
-
553  // Create a PgQuery object to run multiple commands over the same
-
554  // connection in a single transaction block.
-
555  PgQuery pg(pgPool_);
-
556  auto res = pg("BEGIN");
-
557  if (!res || res.status() != PGRES_COMMAND_OK)
-
558  {
-
559  std::stringstream msg;
-
560  msg << "bulkWriteToTable : Postgres insert error: " << res.msg();
-
561  Throw<std::runtime_error>(msg.str());
-
562  }
-
563 
-
564  // Writing to the ledgers db fails if the ledger already exists in the
-
565  // db. In this situation, the ETL process has detected there is another
-
566  // writer, and falls back to only publishing
-
567  if (!writeToLedgersDB(info, pg, j_))
-
568  {
-
569  JLOG(j_.warn()) << __func__ << " : "
-
570  << "Failed to write to ledgers database.";
-
571  return false;
-
572  }
-
573 
-
574  std::stringstream transactionsCopyBuffer;
-
575  std::stringstream accountTransactionsCopyBuffer;
-
576  for (auto const& data : accountTxData)
-
577  {
-
578  std::string txHash = strHex(data.txHash);
-
579  std::string nodestoreHash = strHex(data.nodestoreHash);
-
580  auto idx = data.transactionIndex;
-
581  auto ledgerSeq = data.ledgerSequence;
-
582 
-
583  transactionsCopyBuffer << std::to_string(ledgerSeq) << '\t'
-
584  << std::to_string(idx) << '\t' << "\\\\x"
-
585  << txHash << '\t' << "\\\\x" << nodestoreHash
-
586  << '\n';
-
587 
-
588  for (auto const& a : data.accounts)
-
589  {
-
590  std::string acct = strHex(a);
-
591  accountTransactionsCopyBuffer
-
592  << "\\\\x" << acct << '\t' << std::to_string(ledgerSeq)
-
593  << '\t' << std::to_string(idx) << '\n';
-
594  }
-
595  }
+
469  }
+
470  catch (std::exception& e)
+
471  {
+
472  JLOG(j.debug()) << __func__ << " : "
+
473  << "Caught exception : " << e.what();
+
474  return {ret, {rpcINTERNAL, e.what()}};
+
475  }
+
476 }
+
477 #endif
+
478 
+
479 void
+
480 PostgresDatabaseImp::sweep()
+
481 {
+
482 #ifdef RIPPLED_REPORTING
+
483  pgPool_->idleSweeper();
+
484 #endif
+
485 }
+
486 
+
487 std::optional<LedgerIndex>
+
488 PostgresDatabaseImp::getMinLedgerSeq()
+
489 {
+
490 #ifdef RIPPLED_REPORTING
+
491  auto seq = PgQuery(pgPool_)("SELECT min_ledger()");
+
492  if (!seq)
+
493  {
+
494  JLOG(j_.error()) << "Error querying minimum ledger sequence.";
+
495  }
+
496  else if (!seq.isNull())
+
497  return seq.asInt();
+
498 #endif
+
499  return {};
+
500 }
+
501 
+
502 std::optional<LedgerIndex>
+
503 PostgresDatabaseImp::getMaxLedgerSeq()
+
504 {
+
505 #ifdef RIPPLED_REPORTING
+
506  auto seq = PgQuery(pgPool_)("SELECT max_ledger()");
+
507  if (seq && !seq.isNull())
+
508  return seq.asBigInt();
+
509 #endif
+
510  return {};
+
511 }
+
512 
+
513 std::string
+
514 PostgresDatabaseImp::getCompleteLedgers()
+
515 {
+
516 #ifdef RIPPLED_REPORTING
+
517  auto range = PgQuery(pgPool_)("SELECT complete_ledgers()");
+
518  if (range)
+
519  return range.c_str();
+
520 #endif
+
521  return "error";
+
522 }
+
523 
+
524 std::chrono::seconds
+
525 PostgresDatabaseImp::getValidatedLedgerAge()
+
526 {
+
527  using namespace std::chrono_literals;
+
528 #ifdef RIPPLED_REPORTING
+
529  auto age = PgQuery(pgPool_)("SELECT age()");
+
530  if (!age || age.isNull())
+
531  JLOG(j_.debug()) << "No ledgers in database";
+
532  else
+
533  return std::chrono::seconds{age.asInt()};
+
534 #endif
+
535  return weeks{2};
+
536 }
+
537 
+
538 bool
+
539 PostgresDatabaseImp::writeLedgerAndTransactions(
+
540  LedgerInfo const& info,
+
541  std::vector<AccountTransactionsData> const& accountTxData)
+
542 {
+
543 #ifdef RIPPLED_REPORTING
+
544  JLOG(j_.debug()) << __func__ << " : "
+
545  << "Beginning write to Postgres";
+
546 
+
547  try
+
548  {
+
549  // Create a PgQuery object to run multiple commands over the same
+
550  // connection in a single transaction block.
+
551  PgQuery pg(pgPool_);
+
552  auto res = pg("BEGIN");
+
553  if (!res || res.status() != PGRES_COMMAND_OK)
+
554  {
+
555  std::stringstream msg;
+
556  msg << "bulkWriteToTable : Postgres insert error: " << res.msg();
+
557  Throw<std::runtime_error>(msg.str());
+
558  }
+
559 
+
560  // Writing to the ledgers db fails if the ledger already exists in the
+
561  // db. In this situation, the ETL process has detected there is another
+
562  // writer, and falls back to only publishing
+
563  if (!writeToLedgersDB(info, pg, j_))
+
564  {
+
565  JLOG(j_.warn()) << __func__ << " : "
+
566  << "Failed to write to ledgers database.";
+
567  return false;
+
568  }
+
569 
+
570  std::stringstream transactionsCopyBuffer;
+
571  std::stringstream accountTransactionsCopyBuffer;
+
572  for (auto const& data : accountTxData)
+
573  {
+
574  std::string txHash = strHex(data.txHash);
+
575  std::string nodestoreHash = strHex(data.nodestoreHash);
+
576  auto idx = data.transactionIndex;
+
577  auto ledgerSeq = data.ledgerSequence;
+
578 
+
579  transactionsCopyBuffer << std::to_string(ledgerSeq) << '\t'
+
580  << std::to_string(idx) << '\t' << "\\\\x"
+
581  << txHash << '\t' << "\\\\x" << nodestoreHash
+
582  << '\n';
+
583 
+
584  for (auto const& a : data.accounts)
+
585  {
+
586  std::string acct = strHex(a);
+
587  accountTransactionsCopyBuffer
+
588  << "\\\\x" << acct << '\t' << std::to_string(ledgerSeq)
+
589  << '\t' << std::to_string(idx) << '\n';
+
590  }
+
591  }
+
592 
+
593  pg.bulkInsert("transactions", transactionsCopyBuffer.str());
+
594  pg.bulkInsert(
+
595  "account_transactions", accountTransactionsCopyBuffer.str());
596 
-
597  pg.bulkInsert("transactions", transactionsCopyBuffer.str());
-
598  pg.bulkInsert(
-
599  "account_transactions", accountTransactionsCopyBuffer.str());
-
600 
-
601  res = pg("COMMIT");
-
602  if (!res || res.status() != PGRES_COMMAND_OK)
-
603  {
-
604  std::stringstream msg;
-
605  msg << "bulkWriteToTable : Postgres insert error: " << res.msg();
-
606  assert(false);
-
607  Throw<std::runtime_error>(msg.str());
-
608  }
-
609 
-
610  JLOG(j_.info()) << __func__ << " : "
-
611  << "Successfully wrote to Postgres";
-
612  return true;
-
613  }
-
614  catch (std::exception& e)
-
615  {
-
616  JLOG(j_.error()) << __func__
-
617  << "Caught exception writing to Postgres : "
-
618  << e.what();
-
619  assert(false);
-
620  return false;
-
621  }
-
622 #else
-
623  return false;
-
624 #endif
-
625 }
-
626 
-
627 std::optional<LedgerInfo>
-
628 PostgresDatabaseImp::getLedgerInfoByIndex(LedgerIndex ledgerSeq)
-
629 {
-
630  return loadLedgerHelper(pgPool_, ledgerSeq, app_);
-
631 }
-
632 
-
633 std::optional<LedgerInfo>
-
634 PostgresDatabaseImp::getNewestLedgerInfo()
-
635 {
-
636  return loadLedgerHelper(pgPool_, {}, app_);
-
637 }
-
638 
-
639 std::optional<LedgerInfo>
-
640 PostgresDatabaseImp::getLedgerInfoByHash(uint256 const& ledgerHash)
-
641 {
-
642  return loadLedgerHelper(pgPool_, ledgerHash, app_);
-
643 }
-
644 
-
645 uint256
-
646 PostgresDatabaseImp::getHashByIndex(LedgerIndex ledgerIndex)
-
647 {
-
648  auto infos = loadLedgerInfos(pgPool_, ledgerIndex, app_);
-
649  assert(infos.size() <= 1);
-
650  if (infos.size())
-
651  return infos[0].hash;
-
652  return {};
-
653 }
-
654 
-
655 std::optional<LedgerHashPair>
-
656 PostgresDatabaseImp::getHashesByIndex(LedgerIndex ledgerIndex)
-
657 {
-
658  LedgerHashPair p;
-
659  auto infos = loadLedgerInfos(pgPool_, ledgerIndex, app_);
-
660  assert(infos.size() <= 1);
-
661  if (infos.size())
-
662  {
-
663  p.ledgerHash = infos[0].hash;
-
664  p.parentHash = infos[0].parentHash;
-
665  return p;
-
666  }
-
667  return {};
-
668 }
-
669 
-
670 std::map<LedgerIndex, LedgerHashPair>
-
671 PostgresDatabaseImp::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq)
-
672 {
-
673  std::map<uint32_t, LedgerHashPair> ret;
-
674  auto infos = loadLedgerInfos(pgPool_, std::make_pair(minSeq, maxSeq), app_);
-
675  for (auto& info : infos)
-
676  {
-
677  ret[info.seq] = {info.hash, info.parentHash};
-
678  }
-
679  return ret;
-
680 }
-
681 
-
682 std::vector<uint256>
-
683 PostgresDatabaseImp::getTxHashes(LedgerIndex seq)
-
684 {
-
685  std::vector<uint256> nodestoreHashes;
-
686 
-
687 #ifdef RIPPLED_REPORTING
-
688  auto log = app_.journal("Ledger");
-
689 
-
690  std::string query =
-
691  "SELECT nodestore_hash"
-
692  " FROM transactions "
-
693  " WHERE ledger_seq = " +
-
694  std::to_string(seq);
-
695  auto res = PgQuery(pgPool_)(query.c_str());
-
696 
-
697  if (!res)
-
698  {
-
699  JLOG(log.error()) << __func__
-
700  << " : Postgres response is null - query = " << query;
-
701  assert(false);
-
702  return {};
-
703  }
-
704  else if (res.status() != PGRES_TUPLES_OK)
-
705  {
-
706  JLOG(log.error()) << __func__
-
707  << " : Postgres response should have been "
-
708  "PGRES_TUPLES_OK but instead was "
-
709  << res.status() << " - msg = " << res.msg()
-
710  << " - query = " << query;
-
711  assert(false);
-
712  return {};
-
713  }
-
714 
-
715  JLOG(log.trace()) << __func__ << " Postgres result msg : " << res.msg();
-
716 
-
717  if (res.isNull() || res.ntuples() == 0)
-
718  {
-
719  JLOG(log.debug()) << __func__
-
720  << " : Ledger not found. query = " << query;
-
721  return {};
-
722  }
-
723  else if (res.ntuples() > 0)
-
724  {
-
725  if (res.nfields() != 1)
-
726  {
-
727  JLOG(log.error()) << __func__
-
728  << " : Wrong number of fields in Postgres "
-
729  "response. Expected 1, but got "
-
730  << res.nfields() << " . query = " << query;
-
731  assert(false);
-
732  return {};
-
733  }
-
734  }
-
735 
-
736  JLOG(log.trace()) << __func__ << " : result = " << res.c_str()
-
737  << " : query = " << query;
-
738  for (size_t i = 0; i < res.ntuples(); ++i)
-
739  {
-
740  char const* nodestoreHash = res.c_str(i, 0);
-
741  uint256 hash;
-
742  if (!hash.parseHex(nodestoreHash + 2))
-
743  assert(false);
+
597  res = pg("COMMIT");
+
598  if (!res || res.status() != PGRES_COMMAND_OK)
+
599  {
+
600  std::stringstream msg;
+
601  msg << "bulkWriteToTable : Postgres insert error: " << res.msg();
+
602  assert(false);
+
603  Throw<std::runtime_error>(msg.str());
+
604  }
+
605 
+
606  JLOG(j_.info()) << __func__ << " : "
+
607  << "Successfully wrote to Postgres";
+
608  return true;
+
609  }
+
610  catch (std::exception& e)
+
611  {
+
612  JLOG(j_.error()) << __func__
+
613  << "Caught exception writing to Postgres : "
+
614  << e.what();
+
615  assert(false);
+
616  return false;
+
617  }
+
618 #else
+
619  return false;
+
620 #endif
+
621 }
+
622 
+
623 std::optional<LedgerInfo>
+
624 PostgresDatabaseImp::getLedgerInfoByIndex(LedgerIndex ledgerSeq)
+
625 {
+
626  return loadLedgerHelper(pgPool_, ledgerSeq, app_);
+
627 }
+
628 
+
629 std::optional<LedgerInfo>
+
630 PostgresDatabaseImp::getNewestLedgerInfo()
+
631 {
+
632  return loadLedgerHelper(pgPool_, {}, app_);
+
633 }
+
634 
+
635 std::optional<LedgerInfo>
+
636 PostgresDatabaseImp::getLedgerInfoByHash(uint256 const& ledgerHash)
+
637 {
+
638  return loadLedgerHelper(pgPool_, ledgerHash, app_);
+
639 }
+
640 
+
641 uint256
+
642 PostgresDatabaseImp::getHashByIndex(LedgerIndex ledgerIndex)
+
643 {
+
644  auto infos = loadLedgerInfos(pgPool_, ledgerIndex, app_);
+
645  assert(infos.size() <= 1);
+
646  if (infos.size())
+
647  return infos[0].hash;
+
648  return {};
+
649 }
+
650 
+
651 std::optional<LedgerHashPair>
+
652 PostgresDatabaseImp::getHashesByIndex(LedgerIndex ledgerIndex)
+
653 {
+
654  LedgerHashPair p;
+
655  auto infos = loadLedgerInfos(pgPool_, ledgerIndex, app_);
+
656  assert(infos.size() <= 1);
+
657  if (infos.size())
+
658  {
+
659  p.ledgerHash = infos[0].hash;
+
660  p.parentHash = infos[0].parentHash;
+
661  return p;
+
662  }
+
663  return {};
+
664 }
+
665 
+
666 std::map<LedgerIndex, LedgerHashPair>
+
667 PostgresDatabaseImp::getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq)
+
668 {
+
669  std::map<uint32_t, LedgerHashPair> ret;
+
670  auto infos = loadLedgerInfos(pgPool_, std::make_pair(minSeq, maxSeq), app_);
+
671  for (auto& info : infos)
+
672  {
+
673  ret[info.seq] = {info.hash, info.parentHash};
+
674  }
+
675  return ret;
+
676 }
+
677 
+
678 std::vector<uint256>
+
679 PostgresDatabaseImp::getTxHashes(LedgerIndex seq)
+
680 {
+
681  std::vector<uint256> nodestoreHashes;
+
682 
+
683 #ifdef RIPPLED_REPORTING
+
684  auto log = app_.journal("Ledger");
+
685 
+
686  std::string query =
+
687  "SELECT nodestore_hash"
+
688  " FROM transactions "
+
689  " WHERE ledger_seq = " +
+
690  std::to_string(seq);
+
691  auto res = PgQuery(pgPool_)(query.c_str());
+
692 
+
693  if (!res)
+
694  {
+
695  JLOG(log.error()) << __func__
+
696  << " : Postgres response is null - query = " << query;
+
697  assert(false);
+
698  return {};
+
699  }
+
700  else if (res.status() != PGRES_TUPLES_OK)
+
701  {
+
702  JLOG(log.error()) << __func__
+
703  << " : Postgres response should have been "
+
704  "PGRES_TUPLES_OK but instead was "
+
705  << res.status() << " - msg = " << res.msg()
+
706  << " - query = " << query;
+
707  assert(false);
+
708  return {};
+
709  }
+
710 
+
711  JLOG(log.trace()) << __func__ << " Postgres result msg : " << res.msg();
+
712 
+
713  if (res.isNull() || res.ntuples() == 0)
+
714  {
+
715  JLOG(log.debug()) << __func__
+
716  << " : Ledger not found. query = " << query;
+
717  return {};
+
718  }
+
719  else if (res.ntuples() > 0)
+
720  {
+
721  if (res.nfields() != 1)
+
722  {
+
723  JLOG(log.error()) << __func__
+
724  << " : Wrong number of fields in Postgres "
+
725  "response. Expected 1, but got "
+
726  << res.nfields() << " . query = " << query;
+
727  assert(false);
+
728  return {};
+
729  }
+
730  }
+
731 
+
732  JLOG(log.trace()) << __func__ << " : result = " << res.c_str()
+
733  << " : query = " << query;
+
734  for (size_t i = 0; i < res.ntuples(); ++i)
+
735  {
+
736  char const* nodestoreHash = res.c_str(i, 0);
+
737  uint256 hash;
+
738  if (!hash.parseHex(nodestoreHash + 2))
+
739  assert(false);
+
740 
+
741  nodestoreHashes.push_back(hash);
+
742  }
+
743 #endif
744 
-
745  nodestoreHashes.push_back(hash);
-
746  }
-
747 #endif
-
748 
-
749  return nodestoreHashes;
-
750 }
-
751 
-
752 std::vector<std::shared_ptr<Transaction>>
-
753 PostgresDatabaseImp::getTxHistory(LedgerIndex startIndex)
-
754 {
-
755  std::vector<std::shared_ptr<Transaction>> ret;
-
756 
-
757 #ifdef RIPPLED_REPORTING
-
758  if (!app_.config().reporting())
-
759  {
-
760  assert(false);
-
761  Throw<std::runtime_error>(
-
762  "called getTxHistory but not in reporting mode");
-
763  }
-
764 
-
765  std::string sql = boost::str(
-
766  boost::format("SELECT nodestore_hash, ledger_seq "
-
767  " FROM transactions"
-
768  " ORDER BY ledger_seq DESC LIMIT 20 "
-
769  "OFFSET %u;") %
-
770  startIndex);
-
771 
-
772  auto res = PgQuery(pgPool_)(sql.data());
-
773 
-
774  if (!res)
-
775  {
-
776  JLOG(j_.error()) << __func__
-
777  << " : Postgres response is null - sql = " << sql;
-
778  assert(false);
-
779  return {};
-
780  }
-
781  else if (res.status() != PGRES_TUPLES_OK)
-
782  {
-
783  JLOG(j_.error()) << __func__
-
784  << " : Postgres response should have been "
-
785  "PGRES_TUPLES_OK but instead was "
-
786  << res.status() << " - msg = " << res.msg()
-
787  << " - sql = " << sql;
-
788  assert(false);
-
789  return {};
-
790  }
-
791 
-
792  JLOG(j_.trace()) << __func__ << " Postgres result msg : " << res.msg();
-
793 
-
794  if (res.isNull() || res.ntuples() == 0)
-
795  {
-
796  JLOG(j_.debug()) << __func__ << " : Empty postgres response";
-
797  assert(false);
-
798  return {};
-
799  }
-
800  else if (res.ntuples() > 0)
-
801  {
-
802  if (res.nfields() != 2)
-
803  {
-
804  JLOG(j_.error()) << __func__
-
805  << " : Wrong number of fields in Postgres "
-
806  "response. Expected 1, but got "
-
807  << res.nfields() << " . sql = " << sql;
-
808  assert(false);
-
809  return {};
-
810  }
-
811  }
-
812 
-
813  JLOG(j_.trace()) << __func__ << " : Postgres result = " << res.c_str();
-
814 
-
815  std::vector<uint256> nodestoreHashes;
-
816  std::vector<uint32_t> ledgerSequences;
-
817  for (size_t i = 0; i < res.ntuples(); ++i)
-
818  {
-
819  uint256 hash;
-
820  if (!hash.parseHex(res.c_str(i, 0) + 2))
-
821  assert(false);
-
822  nodestoreHashes.push_back(hash);
-
823  ledgerSequences.push_back(res.asBigInt(i, 1));
-
824  }
-
825 
-
826  auto txns = flatFetchTransactions(app_, nodestoreHashes);
-
827  for (size_t i = 0; i < txns.size(); ++i)
-
828  {
-
829  auto const& [sttx, meta] = txns[i];
-
830  assert(sttx);
-
831 
-
832  std::string reason;
-
833  auto txn = std::make_shared<Transaction>(sttx, reason, app_);
-
834  txn->setLedger(ledgerSequences[i]);
-
835  txn->setStatus(COMMITTED);
-
836  ret.push_back(txn);
-
837  }
+
745  return nodestoreHashes;
+
746 }
+
747 
+
748 std::vector<std::shared_ptr<Transaction>>
+
749 PostgresDatabaseImp::getTxHistory(LedgerIndex startIndex)
+
750 {
+
751  std::vector<std::shared_ptr<Transaction>> ret;
+
752 
+
753 #ifdef RIPPLED_REPORTING
+
754  if (!app_.config().reporting())
+
755  {
+
756  assert(false);
+
757  Throw<std::runtime_error>(
+
758  "called getTxHistory but not in reporting mode");
+
759  }
+
760 
+
761  std::string sql = boost::str(
+
762  boost::format("SELECT nodestore_hash, ledger_seq "
+
763  " FROM transactions"
+
764  " ORDER BY ledger_seq DESC LIMIT 20 "
+
765  "OFFSET %u;") %
+
766  startIndex);
+
767 
+
768  auto res = PgQuery(pgPool_)(sql.data());
+
769 
+
770  if (!res)
+
771  {
+
772  JLOG(j_.error()) << __func__
+
773  << " : Postgres response is null - sql = " << sql;
+
774  assert(false);
+
775  return {};
+
776  }
+
777  else if (res.status() != PGRES_TUPLES_OK)
+
778  {
+
779  JLOG(j_.error()) << __func__
+
780  << " : Postgres response should have been "
+
781  "PGRES_TUPLES_OK but instead was "
+
782  << res.status() << " - msg = " << res.msg()
+
783  << " - sql = " << sql;
+
784  assert(false);
+
785  return {};
+
786  }
+
787 
+
788  JLOG(j_.trace()) << __func__ << " Postgres result msg : " << res.msg();
+
789 
+
790  if (res.isNull() || res.ntuples() == 0)
+
791  {
+
792  JLOG(j_.debug()) << __func__ << " : Empty postgres response";
+
793  assert(false);
+
794  return {};
+
795  }
+
796  else if (res.ntuples() > 0)
+
797  {
+
798  if (res.nfields() != 2)
+
799  {
+
800  JLOG(j_.error()) << __func__
+
801  << " : Wrong number of fields in Postgres "
+
802  "response. Expected 1, but got "
+
803  << res.nfields() << " . sql = " << sql;
+
804  assert(false);
+
805  return {};
+
806  }
+
807  }
+
808 
+
809  JLOG(j_.trace()) << __func__ << " : Postgres result = " << res.c_str();
+
810 
+
811  std::vector<uint256> nodestoreHashes;
+
812  std::vector<uint32_t> ledgerSequences;
+
813  for (size_t i = 0; i < res.ntuples(); ++i)
+
814  {
+
815  uint256 hash;
+
816  if (!hash.parseHex(res.c_str(i, 0) + 2))
+
817  assert(false);
+
818  nodestoreHashes.push_back(hash);
+
819  ledgerSequences.push_back(res.asBigInt(i, 1));
+
820  }
+
821 
+
822  auto txns = flatFetchTransactions(app_, nodestoreHashes);
+
823  for (size_t i = 0; i < txns.size(); ++i)
+
824  {
+
825  auto const& [sttx, meta] = txns[i];
+
826  assert(sttx);
+
827 
+
828  std::string reason;
+
829  auto txn = std::make_shared<Transaction>(sttx, reason, app_);
+
830  txn->setLedger(ledgerSequences[i]);
+
831  txn->setStatus(COMMITTED);
+
832  ret.push_back(txn);
+
833  }
+
834 
+
835 #endif
+
836  return ret;
+
837 }
838 
-
839 #endif
-
840  return ret;
-
841 }
-
842 
-
843 std::pair<AccountTxResult, RPC::Status>
-
844 PostgresDatabaseImp::getAccountTx(AccountTxArgs const& args)
-
845 {
-
846 #ifdef RIPPLED_REPORTING
-
847  pg_params dbParams;
-
848 
-
849  char const*& command = dbParams.first;
-
850  std::vector<std::optional<std::string>>& values = dbParams.second;
-
851  command =
-
852  "SELECT account_tx($1::bytea, $2::bool, "
-
853  "$3::bigint, $4::bigint, $5::bigint, $6::bytea, "
-
854  "$7::bigint, $8::bool, $9::bigint, $10::bigint)";
-
855  values.resize(10);
-
856  values[0] = "\\x" + strHex(args.account);
-
857  values[1] = args.forward ? "true" : "false";
-
858 
-
859  static std::uint32_t const page_length(200);
-
860  if (args.limit == 0 || args.limit > page_length)
-
861  values[2] = std::to_string(page_length);
-
862  else
-
863  values[2] = std::to_string(args.limit);
-
864 
-
865  if (args.ledger)
-
866  {
-
867  if (auto range = std::get_if<LedgerRange>(&args.ledger.value()))
-
868  {
-
869  values[3] = std::to_string(range->min);
-
870  values[4] = std::to_string(range->max);
+
839 std::pair<AccountTxResult, RPC::Status>
+
840 PostgresDatabaseImp::getAccountTx(AccountTxArgs const& args)
+
841 {
+
842 #ifdef RIPPLED_REPORTING
+
843  pg_params dbParams;
+
844 
+
845  char const*& command = dbParams.first;
+
846  std::vector<std::optional<std::string>>& values = dbParams.second;
+
847  command =
+
848  "SELECT account_tx($1::bytea, $2::bool, "
+
849  "$3::bigint, $4::bigint, $5::bigint, $6::bytea, "
+
850  "$7::bigint, $8::bool, $9::bigint, $10::bigint)";
+
851  values.resize(10);
+
852  values[0] = "\\x" + strHex(args.account);
+
853  values[1] = args.forward ? "true" : "false";
+
854 
+
855  static std::uint32_t const page_length(200);
+
856  if (args.limit == 0 || args.limit > page_length)
+
857  values[2] = std::to_string(page_length);
+
858  else
+
859  values[2] = std::to_string(args.limit);
+
860 
+
861  if (args.ledger)
+
862  {
+
863  if (auto range = std::get_if<LedgerRange>(&args.ledger.value()))
+
864  {
+
865  values[3] = std::to_string(range->min);
+
866  values[4] = std::to_string(range->max);
+
867  }
+
868  else if (auto hash = std::get_if<LedgerHash>(&args.ledger.value()))
+
869  {
+
870  values[5] = ("\\x" + strHex(*hash));
871  }
-
872  else if (auto hash = std::get_if<LedgerHash>(&args.ledger.value()))
-
873  {
-
874  values[5] = ("\\x" + strHex(*hash));
-
875  }
-
876  else if (
-
877  auto sequence = std::get_if<LedgerSequence>(&args.ledger.value()))
+
872  else if (
+
873  auto sequence = std::get_if<LedgerSequence>(&args.ledger.value()))
+
874  {
+
875  values[6] = std::to_string(*sequence);
+
876  }
+
877  else if (std::get_if<LedgerShortcut>(&args.ledger.value()))
878  {
-
879  values[6] = std::to_string(*sequence);
-
880  }
-
881  else if (std::get_if<LedgerShortcut>(&args.ledger.value()))
-
882  {
-
883  // current, closed and validated are all treated as validated
-
884  values[7] = "true";
-
885  }
-
886  else
-
887  {
-
888  JLOG(j_.error()) << "doAccountTxStoredProcedure - "
-
889  << "Error parsing ledger args";
-
890  return {};
-
891  }
-
892  }
-
893 
-
894  if (args.marker)
-
895  {
-
896  values[8] = std::to_string(args.marker->ledgerSeq);
-
897  values[9] = std::to_string(args.marker->txnSeq);
-
898  }
-
899  for (size_t i = 0; i < values.size(); ++i)
-
900  {
-
901  JLOG(j_.trace()) << "value " << std::to_string(i) << " = "
-
902  << (values[i] ? values[i].value() : "null");
-
903  }
-
904 
-
905  auto res = PgQuery(pgPool_)(dbParams);
-
906  if (!res)
-
907  {
-
908  JLOG(j_.error()) << __func__
-
909  << " : Postgres response is null - account = "
-
910  << strHex(args.account);
-
911  assert(false);
-
912  return {{}, {rpcINTERNAL, "Postgres error"}};
-
913  }
-
914  else if (res.status() != PGRES_TUPLES_OK)
-
915  {
-
916  JLOG(j_.error()) << __func__
-
917  << " : Postgres response should have been "
-
918  "PGRES_TUPLES_OK but instead was "
-
919  << res.status() << " - msg = " << res.msg()
-
920  << " - account = " << strHex(args.account);
-
921  assert(false);
-
922  return {{}, {rpcINTERNAL, "Postgres error"}};
-
923  }
-
924 
-
925  JLOG(j_.trace()) << __func__ << " Postgres result msg : " << res.msg();
-
926  if (res.isNull() || res.ntuples() == 0)
-
927  {
-
928  JLOG(j_.debug()) << __func__
-
929  << " : No data returned from Postgres : account = "
-
930  << strHex(args.account);
+
879  // current, closed and validated are all treated as validated
+
880  values[7] = "true";
+
881  }
+
882  else
+
883  {
+
884  JLOG(j_.error()) << "doAccountTxStoredProcedure - "
+
885  << "Error parsing ledger args";
+
886  return {};
+
887  }
+
888  }
+
889 
+
890  if (args.marker)
+
891  {
+
892  values[8] = std::to_string(args.marker->ledgerSeq);
+
893  values[9] = std::to_string(args.marker->txnSeq);
+
894  }
+
895  for (size_t i = 0; i < values.size(); ++i)
+
896  {
+
897  JLOG(j_.trace()) << "value " << std::to_string(i) << " = "
+
898  << (values[i] ? values[i].value() : "null");
+
899  }
+
900 
+
901  auto res = PgQuery(pgPool_)(dbParams);
+
902  if (!res)
+
903  {
+
904  JLOG(j_.error()) << __func__
+
905  << " : Postgres response is null - account = "
+
906  << strHex(args.account);
+
907  assert(false);
+
908  return {{}, {rpcINTERNAL, "Postgres error"}};
+
909  }
+
910  else if (res.status() != PGRES_TUPLES_OK)
+
911  {
+
912  JLOG(j_.error()) << __func__
+
913  << " : Postgres response should have been "
+
914  "PGRES_TUPLES_OK but instead was "
+
915  << res.status() << " - msg = " << res.msg()
+
916  << " - account = " << strHex(args.account);
+
917  assert(false);
+
918  return {{}, {rpcINTERNAL, "Postgres error"}};
+
919  }
+
920 
+
921  JLOG(j_.trace()) << __func__ << " Postgres result msg : " << res.msg();
+
922  if (res.isNull() || res.ntuples() == 0)
+
923  {
+
924  JLOG(j_.debug()) << __func__
+
925  << " : No data returned from Postgres : account = "
+
926  << strHex(args.account);
+
927 
+
928  assert(false);
+
929  return {{}, {rpcINTERNAL, "Postgres error"}};
+
930  }
931 
-
932  assert(false);
-
933  return {{}, {rpcINTERNAL, "Postgres error"}};
-
934  }
-
935 
-
936  char const* resultStr = res.c_str();
-
937  JLOG(j_.trace()) << __func__ << " : "
-
938  << "postgres result = " << resultStr
-
939  << " : account = " << strHex(args.account);
-
940 
-
941  Json::Value v;
-
942  Json::Reader reader;
-
943  bool success = reader.parse(resultStr, resultStr + strlen(resultStr), v);
-
944  if (success)
-
945  {
-
946  return processAccountTxStoredProcedureResult(args, v, app_, j_);
-
947  }
-
948 #endif
-
949  // This shouldn't happen. Postgres should return a parseable error
-
950  assert(false);
-
951  return {{}, {rpcINTERNAL, "Failed to deserialize Postgres result"}};
-
952 }
-
953 
-
954 Transaction::Locator
-
955 PostgresDatabaseImp::locateTransaction(uint256 const& id)
-
956 {
-
957 #ifdef RIPPLED_REPORTING
-
958  auto baseCmd = boost::format(R"(SELECT tx('%s');)");
-
959 
-
960  std::string txHash = "\\x" + strHex(id);
-
961  std::string sql = boost::str(baseCmd % txHash);
-
962 
-
963  auto res = PgQuery(pgPool_)(sql.data());
-
964 
-
965  if (!res)
-
966  {
-
967  JLOG(app_.journal("Transaction").error())
-
968  << __func__
-
969  << " : Postgres response is null - tx ID = " << strHex(id);
-
970  assert(false);
-
971  return {};
-
972  }
-
973  else if (res.status() != PGRES_TUPLES_OK)
-
974  {
-
975  JLOG(app_.journal("Transaction").error())
-
976  << __func__
-
977  << " : Postgres response should have been "
-
978  "PGRES_TUPLES_OK but instead was "
-
979  << res.status() << " - msg = " << res.msg()
-
980  << " - tx ID = " << strHex(id);
-
981  assert(false);
-
982  return {};
-
983  }
-
984 
-
985  JLOG(app_.journal("Transaction").trace())
-
986  << __func__ << " Postgres result msg : " << res.msg();
-
987  if (res.isNull() || res.ntuples() == 0)
-
988  {
-
989  JLOG(app_.journal("Transaction").debug())
-
990  << __func__
-
991  << " : No data returned from Postgres : tx ID = " << strHex(id);
-
992  // This shouldn't happen
-
993  assert(false);
-
994  return {};
-
995  }
+
932  char const* resultStr = res.c_str();
+
933  JLOG(j_.trace()) << __func__ << " : "
+
934  << "postgres result = " << resultStr
+
935  << " : account = " << strHex(args.account);
+
936 
+
937  Json::Value v;
+
938  Json::Reader reader;
+
939  bool success = reader.parse(resultStr, resultStr + strlen(resultStr), v);
+
940  if (success)
+
941  {
+
942  return processAccountTxStoredProcedureResult(args, v, app_, j_);
+
943  }
+
944 #endif
+
945  // This shouldn't happen. Postgres should return a parseable error
+
946  assert(false);
+
947  return {{}, {rpcINTERNAL, "Failed to deserialize Postgres result"}};
+
948 }
+
949 
+
950 Transaction::Locator
+
951 PostgresDatabaseImp::locateTransaction(uint256 const& id)
+
952 {
+
953 #ifdef RIPPLED_REPORTING
+
954  auto baseCmd = boost::format(R"(SELECT tx('%s');)");
+
955 
+
956  std::string txHash = "\\x" + strHex(id);
+
957  std::string sql = boost::str(baseCmd % txHash);
+
958 
+
959  auto res = PgQuery(pgPool_)(sql.data());
+
960 
+
961  if (!res)
+
962  {
+
963  JLOG(app_.journal("Transaction").error())
+
964  << __func__
+
965  << " : Postgres response is null - tx ID = " << strHex(id);
+
966  assert(false);
+
967  return {};
+
968  }
+
969  else if (res.status() != PGRES_TUPLES_OK)
+
970  {
+
971  JLOG(app_.journal("Transaction").error())
+
972  << __func__
+
973  << " : Postgres response should have been "
+
974  "PGRES_TUPLES_OK but instead was "
+
975  << res.status() << " - msg = " << res.msg()
+
976  << " - tx ID = " << strHex(id);
+
977  assert(false);
+
978  return {};
+
979  }
+
980 
+
981  JLOG(app_.journal("Transaction").trace())
+
982  << __func__ << " Postgres result msg : " << res.msg();
+
983  if (res.isNull() || res.ntuples() == 0)
+
984  {
+
985  JLOG(app_.journal("Transaction").debug())
+
986  << __func__
+
987  << " : No data returned from Postgres : tx ID = " << strHex(id);
+
988  // This shouldn't happen
+
989  assert(false);
+
990  return {};
+
991  }
+
992 
+
993  char const* resultStr = res.c_str();
+
994  JLOG(app_.journal("Transaction").debug())
+
995  << "postgres result = " << resultStr;
996 
-
997  char const* resultStr = res.c_str();
-
998  JLOG(app_.journal("Transaction").debug())
-
999  << "postgres result = " << resultStr;
-
1000 
-
1001  Json::Value v;
-
1002  Json::Reader reader;
-
1003  bool success = reader.parse(resultStr, resultStr + strlen(resultStr), v);
-
1004  if (success)
-
1005  {
-
1006  if (v.isMember("nodestore_hash") && v.isMember("ledger_seq"))
-
1007  {
-
1008  uint256 nodestoreHash;
-
1009  if (!nodestoreHash.parseHex(
-
1010  v["nodestore_hash"].asString().substr(2)))
-
1011  assert(false);
-
1012  uint32_t ledgerSeq = v["ledger_seq"].asUInt();
-
1013  if (nodestoreHash.isNonZero())
-
1014  return {std::make_pair(nodestoreHash, ledgerSeq)};
-
1015  }
-
1016  if (v.isMember("min_seq") && v.isMember("max_seq"))
-
1017  {
-
1018  return {ClosedInterval<uint32_t>(
-
1019  v["min_seq"].asUInt(), v["max_seq"].asUInt())};
-
1020  }
-
1021  }
-
1022 #endif
-
1023  // Shouldn' happen. Postgres should return the ledger range searched if
-
1024  // the transaction was not found
-
1025  assert(false);
-
1026  Throw<std::runtime_error>(
-
1027  "Transaction::Locate - Invalid Postgres response");
-
1028  return {};
-
1029 }
-
1030 
-
1031 bool
-
1032 PostgresDatabaseImp::dbHasSpace(Config const& config)
-
1033 {
-
1034  /* Postgres server could be running on a different machine. */
-
1035 
-
1036  return true;
-
1037 }
-
1038 
-
1039 bool
-
1040 PostgresDatabaseImp::ledgerDbHasSpace(Config const& config)
-
1041 {
-
1042  return dbHasSpace(config);
-
1043 }
-
1044 
-
1045 bool
-
1046 PostgresDatabaseImp::transactionDbHasSpace(Config const& config)
-
1047 {
-
1048  return dbHasSpace(config);
-
1049 }
-
1050 
-
1051 std::unique_ptr<RelationalDatabase>
-
1052 getPostgresDatabase(Application& app, Config const& config, JobQueue& jobQueue)
-
1053 {
-
1054  return std::make_unique<PostgresDatabaseImp>(app, config, jobQueue);
-
1055 }
-
1056 
-
1057 bool
-
1058 PostgresDatabaseImp::isCaughtUp(std::string& reason)
-
1059 {
-
1060 #ifdef RIPPLED_REPORTING
-
1061  using namespace std::chrono_literals;
-
1062  auto age = PgQuery(pgPool_)("SELECT age()");
-
1063  if (!age || age.isNull())
-
1064  {
-
1065  reason = "No ledgers in database";
-
1066  return false;
-
1067  }
-
1068  if (std::chrono::seconds{age.asInt()} > 3min)
-
1069  {
-
1070  reason = "No recently-published ledger";
-
1071  return false;
-
1072  }
-
1073 #endif
-
1074  return true;
-
1075 }
-
1076 
-
1077 } // namespace ripple
+
997  Json::Value v;
+
998  Json::Reader reader;
+
999  bool success = reader.parse(resultStr, resultStr + strlen(resultStr), v);
+
1000  if (success)
+
1001  {
+
1002  if (v.isMember("nodestore_hash") && v.isMember("ledger_seq"))
+
1003  {
+
1004  uint256 nodestoreHash;
+
1005  if (!nodestoreHash.parseHex(
+
1006  v["nodestore_hash"].asString().substr(2)))
+
1007  assert(false);
+
1008  uint32_t ledgerSeq = v["ledger_seq"].asUInt();
+
1009  if (nodestoreHash.isNonZero())
+
1010  return {std::make_pair(nodestoreHash, ledgerSeq)};
+
1011  }
+
1012  if (v.isMember("min_seq") && v.isMember("max_seq"))
+
1013  {
+
1014  return {ClosedInterval<uint32_t>(
+
1015  v["min_seq"].asUInt(), v["max_seq"].asUInt())};
+
1016  }
+
1017  }
+
1018 #endif
+
1019  // Shouldn' happen. Postgres should return the ledger range searched if
+
1020  // the transaction was not found
+
1021  assert(false);
+
1022  Throw<std::runtime_error>(
+
1023  "Transaction::Locate - Invalid Postgres response");
+
1024  return {};
+
1025 }
+
1026 
+
1027 bool
+
1028 PostgresDatabaseImp::dbHasSpace(Config const& config)
+
1029 {
+
1030  /* Postgres server could be running on a different machine. */
+
1031 
+
1032  return true;
+
1033 }
+
1034 
+
1035 bool
+
1036 PostgresDatabaseImp::ledgerDbHasSpace(Config const& config)
+
1037 {
+
1038  return dbHasSpace(config);
+
1039 }
+
1040 
+
1041 bool
+
1042 PostgresDatabaseImp::transactionDbHasSpace(Config const& config)
+
1043 {
+
1044  return dbHasSpace(config);
+
1045 }
+
1046 
+
1047 std::unique_ptr<RelationalDatabase>
+
1048 getPostgresDatabase(Application& app, Config const& config, JobQueue& jobQueue)
+
1049 {
+
1050  return std::make_unique<PostgresDatabaseImp>(app, config, jobQueue);
+
1051 }
+
1052 
+
1053 bool
+
1054 PostgresDatabaseImp::isCaughtUp(std::string& reason)
+
1055 {
+
1056 #ifdef RIPPLED_REPORTING
+
1057  using namespace std::chrono_literals;
+
1058  auto age = PgQuery(pgPool_)("SELECT age()");
+
1059  if (!age || age.isNull())
+
1060  {
+
1061  reason = "No ledgers in database";
+
1062  return false;
+
1063  }
+
1064  if (std::chrono::seconds{age.asInt()} > 3min)
+
1065  {
+
1066  reason = "No recently-published ledger";
+
1067  return false;
+
1068  }
+
1069 #endif
+
1070  return true;
+
1071 }
+
1072 
+
1073 } // namespace ripple
ripple::COMMITTED
@ COMMITTED
Definition: Transaction.h:50
ripple::loadLedgerInfos
static std::vector< LedgerInfo > loadLedgerInfos(std::shared_ptr< PgPool > const &pgPool, std::variant< std::monostate, uint256, uint32_t, std::pair< uint32_t, uint32_t >> const &whichLedger, Application &app)
loadLedgerInfos Loads the ledger info for the specified ledger/s from the database
Definition: PostgresDatabase.cpp:160
@@ -1139,14 +1135,14 @@ $(function() {
std::string
STL class.
std::shared_ptr< PgPool >
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
-
ripple::PostgresDatabaseImp::locateTransaction
Transaction::Locator locateTransaction(uint256 const &id) override
locateTransaction Returns information used to locate a transaction.
Definition: PostgresDatabase.cpp:955
+
ripple::PostgresDatabaseImp::locateTransaction
Transaction::Locator locateTransaction(uint256 const &id) override
locateTransaction Returns information used to locate a transaction.
Definition: PostgresDatabase.cpp:951
ripple::LedgerHeader::closeFlags
int closeFlags
Definition: LedgerHeader.h:63
std::exception
STL class.
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:537
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:308
ripple::RelationalDatabase::AccountTxArgs
Definition: RelationalDatabase.h:96
std::pair
-
ripple::PostgresDatabaseImp::transactionDbHasSpace
bool transactionDbHasSpace(Config const &config) override
transactionDbHasSpace Checks if the transaction database has available space.
Definition: PostgresDatabase.cpp:1046
+
ripple::PostgresDatabaseImp::transactionDbHasSpace
bool transactionDbHasSpace(Config const &config) override
transactionDbHasSpace Checks if the transaction database has available space.
Definition: PostgresDatabase.cpp:1042
ripple::PostgresDatabaseImp::stop
void stop() override
Definition: PostgresDatabase.cpp:74
std::vector
STL class.
std::vector::size
T size(T... args)
@@ -1157,16 +1153,16 @@ $(function() {
ripple::LedgerInfo
LedgerHeader LedgerInfo
Definition: LedgerHeader.h:79
std::stringstream
STL class.
beast::Journal::warn
Stream warn() const
Definition: Journal.h:326
-
ripple::PostgresDatabaseImp::getValidatedLedgerAge
std::chrono::seconds getValidatedLedgerAge() override
getValidatedLedgerAge Returns the age of the last validated ledger.
Definition: PostgresDatabase.cpp:529
+
ripple::PostgresDatabaseImp::getValidatedLedgerAge
std::chrono::seconds getValidatedLedgerAge() override
getValidatedLedgerAge Returns the age of the last validated ledger.
Definition: PostgresDatabase.cpp:525
std::monostate
ripple::LedgerHeader::accountHash
uint256 accountHash
Definition: LedgerHeader.h:51
Json::Reader
Unserialize a JSON document into a Value.
Definition: json_reader.h:36
ripple::RelationalDatabase::AccountTxArgs::account
AccountID account
Definition: RelationalDatabase.h:98
-
ripple::PostgresDatabaseImp::getNewestLedgerInfo
std::optional< LedgerInfo > getNewestLedgerInfo() override
getNewestLedgerInfo Returns the info of the newest saved ledger.
Definition: PostgresDatabase.cpp:634
+
ripple::PostgresDatabaseImp::getNewestLedgerInfo
std::optional< LedgerInfo > getNewestLedgerInfo() override
getNewestLedgerInfo Returns the info of the newest saved ledger.
Definition: PostgresDatabase.cpp:630
ripple::LedgerHeader::txHash
uint256 txHash
Definition: LedgerHeader.h:50
ripple::RelationalDatabase::AccountTxResult
Definition: RelationalDatabase.h:106
ripple::PostgresDatabaseImp::PostgresDatabaseImp
PostgresDatabaseImp(Application &app, Config const &config, JobQueue &jobQueue)
Definition: PostgresDatabase.cpp:52
-
ripple::PostgresDatabaseImp::getMinLedgerSeq
std::optional< LedgerIndex > getMinLedgerSeq() override
getMinLedgerSeq Returns the minimum ledger sequence in the Ledgers table.
Definition: PostgresDatabase.cpp:492
+
ripple::PostgresDatabaseImp::getMinLedgerSeq
std::optional< LedgerIndex > getMinLedgerSeq() override
getMinLedgerSeq Returns the minimum ledger sequence in the Ledgers table.
Definition: PostgresDatabase.cpp:488
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:550
std::vector::push_back
T push_back(T... args)
ripple::LedgerHeader::hash
uint256 hash
Definition: LedgerHeader.h:49
@@ -1174,8 +1170,8 @@ $(function() {
ripple::LedgerHeader::parentCloseTime
NetClock::time_point parentCloseTime
Definition: LedgerHeader.h:42
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::Config::reporting
bool reporting() const
Definition: Config.h:351
-
ripple::PostgresDatabaseImp::getHashesByIndex
std::optional< LedgerHashPair > getHashesByIndex(LedgerIndex ledgerIndex) override
getHashesByIndex Returns the hashes of the ledger and its parent as specified by the ledgerIndex.
Definition: PostgresDatabase.cpp:656
-
ripple::PostgresDatabaseImp::getAccountTx
std::pair< AccountTxResult, RPC::Status > getAccountTx(AccountTxArgs const &args) override
getAccountTx Get the last account transactions specified by the AccountTxArgs struct.
Definition: PostgresDatabase.cpp:844
+
ripple::PostgresDatabaseImp::getHashesByIndex
std::optional< LedgerHashPair > getHashesByIndex(LedgerIndex ledgerIndex) override
getHashesByIndex Returns the hashes of the ledger and its parent as specified by the ledgerIndex.
Definition: PostgresDatabase.cpp:652
+
ripple::PostgresDatabaseImp::getAccountTx
std::pair< AccountTxResult, RPC::Status > getAccountTx(AccountTxArgs const &args) override
getAccountTx Get the last account transactions specified by the AccountTxArgs struct.
Definition: PostgresDatabase.cpp:840
ripple::LedgerHashPair::ledgerHash
uint256 ledgerHash
Definition: RelationalDatabase.h:38
ripple::PostgresDatabaseImp::app_
Application & app_
Definition: PostgresDatabase.cpp:141
ripple::Transaction::Locator
Definition: Transaction.h:315
@@ -1186,23 +1182,23 @@ $(function() {
ripple::RelationalDatabase::AccountTxArgs::marker
std::optional< AccountTxMarker > marker
Definition: RelationalDatabase.h:103
ripple::RelationalDatabase::AccountTxArgs::limit
uint32_t limit
Definition: RelationalDatabase.h:102
std::string::c_str
T c_str(T... args)
-
ripple::PostgresDatabaseImp::dbHasSpace
bool dbHasSpace(Config const &config)
Definition: PostgresDatabase.cpp:1032
+
ripple::PostgresDatabaseImp::dbHasSpace
bool dbHasSpace(Config const &config)
Definition: PostgresDatabase.cpp:1028
std::to_string
T to_string(T... args)
beast::Journal::error
Stream error() const
Definition: Journal.h:332
beast::Journal::info
Stream info() const
Definition: Journal.h:320
-
ripple::PostgresDatabaseImp::getHashByIndex
uint256 getHashByIndex(LedgerIndex ledgerIndex) override
getHashByIndex Returns the hash of the ledger with the given sequence.
Definition: PostgresDatabase.cpp:646
+
ripple::PostgresDatabaseImp::getHashByIndex
uint256 getHashByIndex(LedgerIndex ledgerIndex) override
getHashByIndex Returns the hash of the ledger with the given sequence.
Definition: PostgresDatabase.cpp:642
std::string::erase
T erase(T... args)
-
ripple::getPostgresDatabase
std::unique_ptr< RelationalDatabase > getPostgresDatabase(Application &app, Config const &config, JobQueue &jobQueue)
Definition: PostgresDatabase.cpp:1052
+
ripple::getPostgresDatabase
std::unique_ptr< RelationalDatabase > getPostgresDatabase(Application &app, Config const &config, JobQueue &jobQueue)
Definition: PostgresDatabase.cpp:1048
ripple::TxnsDataBinary
RelationalDatabase::MetaTxsList TxnsDataBinary
Definition: PostgresDatabase.cpp:47
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
-
ripple::PostgresDatabaseImp::getTxHistory
std::vector< std::shared_ptr< Transaction > > getTxHistory(LedgerIndex startIndex) override
getTxHistory Returns the 20 most recent transactions starting from the given number.
Definition: PostgresDatabase.cpp:753
+
ripple::PostgresDatabaseImp::getTxHistory
std::vector< std::shared_ptr< Transaction > > getTxHistory(LedgerIndex startIndex) override
getTxHistory Returns the 20 most recent transactions starting from the given number.
Definition: PostgresDatabase.cpp:749
std::map
STL class.
-
ripple::PostgresDatabaseImp::getMaxLedgerSeq
std::optional< LedgerIndex > getMaxLedgerSeq() override
getMaxLedgerSeq Returns the maximum ledger sequence in the Ledgers table.
Definition: PostgresDatabase.cpp:507
+
ripple::PostgresDatabaseImp::getMaxLedgerSeq
std::optional< LedgerIndex > getMaxLedgerSeq() override
getMaxLedgerSeq Returns the maximum ledger sequence in the Ledgers table.
Definition: PostgresDatabase.cpp:503
ripple::range
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:54
-
ripple::PostgresDatabaseImp::getLedgerInfoByIndex
std::optional< LedgerInfo > getLedgerInfoByIndex(LedgerIndex ledgerSeq) override
getLedgerInfoByIndex Returns a ledger by its sequence.
Definition: PostgresDatabase.cpp:628
-
ripple::PostgresDatabaseImp::getTxHashes
std::vector< uint256 > getTxHashes(LedgerIndex seq) override
getTxHashes Returns a vector of the hashes of transactions belonging to the ledger with the provided ...
Definition: PostgresDatabase.cpp:683
+
ripple::PostgresDatabaseImp::getLedgerInfoByIndex
std::optional< LedgerInfo > getLedgerInfoByIndex(LedgerIndex ledgerSeq) override
getLedgerInfoByIndex Returns a ledger by its sequence.
Definition: PostgresDatabase.cpp:624
+
ripple::PostgresDatabaseImp::getTxHashes
std::vector< uint256 > getTxHashes(LedgerIndex seq) override
getTxHashes Returns a vector of the hashes of transactions belonging to the ledger with the provided ...
Definition: PostgresDatabase.cpp:679
ripple::LedgerHeader::closeTime
NetClock::time_point closeTime
Definition: LedgerHeader.h:72
ripple::AccountTxResult
RelationalDatabase::AccountTxResult AccountTxResult
Definition: PostgresDatabase.cpp:45
ripple::LedgerHeader
Information about the notional ledger backing the view.
Definition: LedgerHeader.h:33
@@ -1210,25 +1206,25 @@ $(function() {
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
ripple::RelationalDatabase::AccountTxArgs::forward
bool forward
Definition: RelationalDatabase.h:101
std::string::substr
T substr(T... args)
-
ripple::PostgresDatabaseImp::isCaughtUp
bool isCaughtUp(std::string &reason) override
isCaughtUp returns whether the database is caught up with the network
Definition: PostgresDatabase.cpp:1058
+
ripple::PostgresDatabaseImp::isCaughtUp
bool isCaughtUp(std::string &reason) override
isCaughtUp returns whether the database is caught up with the network
Definition: PostgresDatabase.cpp:1054
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::LedgerHeader::validated
bool validated
Definition: LedgerHeader.h:59
ripple::LedgerHeader::drops
XRPAmount drops
Definition: LedgerHeader.h:54
ripple::LedgerHeader::closeTimeResolution
NetClock::duration closeTimeResolution
Definition: LedgerHeader.h:66
-
ripple::PostgresDatabaseImp::getCompleteLedgers
std::string getCompleteLedgers() override
getCompleteLedgers Returns a string which contains a list of completed ledgers.
Definition: PostgresDatabase.cpp:518
+
ripple::PostgresDatabaseImp::getCompleteLedgers
std::string getCompleteLedgers() override
getCompleteLedgers Returns a string which contains a list of completed ledgers.
Definition: PostgresDatabase.cpp:514
Json::Value::asUInt
UInt asUInt() const
Definition: json_value.cpp:545
ripple::PostgresDatabase
Definition: PostgresDatabase.h:27
Json::Reader::parse
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
Definition: json_reader.cpp:74
ripple::LedgerHashPair::parentHash
uint256 parentHash
Definition: RelationalDatabase.h:39
std::get_if
T get_if(T... args)
-
ripple::PostgresDatabaseImp::getLedgerInfoByHash
std::optional< LedgerInfo > getLedgerInfoByHash(uint256 const &ledgerHash) override
getLedgerInfoByHash Returns the info of the ledger with given hash.
Definition: PostgresDatabase.cpp:640
+
ripple::PostgresDatabaseImp::getLedgerInfoByHash
std::optional< LedgerInfo > getLedgerInfoByHash(uint256 const &ledgerHash) override
getLedgerInfoByHash Returns the info of the ledger with given hash.
Definition: PostgresDatabase.cpp:636
std::visit
T visit(T... args)
ripple::PostgresDatabaseImp::pgPool_
std::shared_ptr< PgPool > pgPool_
Definition: PostgresDatabase.cpp:143
std::optional< LedgerIndex >
std::stringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:314
-
ripple::PostgresDatabaseImp::sweep
void sweep() override
sweep Sweeps the database.
Definition: PostgresDatabase.cpp:484
+
ripple::PostgresDatabaseImp::sweep
void sweep() override
sweep Sweeps the database.
Definition: PostgresDatabase.cpp:480
std::make_pair
T make_pair(T... args)
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
ripple::TxnsData
RelationalDatabase::AccountTxs TxnsData
Definition: PostgresDatabase.cpp:46
@@ -1239,7 +1235,7 @@ $(function() {
ripple::Config::reportingReadOnly
bool reportingReadOnly() const
Definition: Config.h:363
std::unique_ptr
STL class.
ripple::loadLedgerHelper
std::shared_ptr< Ledger > loadLedgerHelper(LedgerInfo const &info, Application &app, bool acquire)
Definition: Ledger.cpp:1076
-
ripple::PostgresDatabaseImp::ledgerDbHasSpace
bool ledgerDbHasSpace(Config const &config) override
ledgerDbHasSpace Checks if the ledger database has available space.
Definition: PostgresDatabase.cpp:1040
+
ripple::PostgresDatabaseImp::ledgerDbHasSpace
bool ledgerDbHasSpace(Config const &config) override
ledgerDbHasSpace Checks if the ledger database has available space.
Definition: PostgresDatabase.cpp:1036
ripple::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:56
std::string::data
T data(T... args)
std::exception::what
T what(T... args)
@@ -1248,7 +1244,7 @@ $(function() {
std::variant
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
ripple::flatFetchTransactions
std::vector< std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > > flatFetchTransactions(Application &app, std::vector< uint256 > &nodestoreHashes)
Definition: Ledger.cpp:1151
-
ripple::PostgresDatabaseImp::writeLedgerAndTransactions
bool writeLedgerAndTransactions(LedgerInfo const &info, std::vector< AccountTransactionsData > const &accountTxData) override
writeLedgerAndTransactions Writes new ledger and transaction data into the database.
Definition: PostgresDatabase.cpp:543
+
ripple::PostgresDatabaseImp::writeLedgerAndTransactions
bool writeLedgerAndTransactions(LedgerInfo const &info, std::vector< AccountTransactionsData > const &accountTxData) override
writeLedgerAndTransactions Writes new ledger and transaction data into the database.
Definition: PostgresDatabase.cpp:539