rippled
AccountTx.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2014 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/ledger/LedgerMaster.h>
21 #include <ripple/app/main/Application.h>
22 #include <ripple/app/misc/NetworkOPs.h>
23 #include <ripple/app/misc/Transaction.h>
24 #include <ripple/app/rdb/backend/RelationalDBInterfacePostgres.h>
25 #include <ripple/app/rdb/backend/RelationalDBInterfaceSqlite.h>
26 #include <ripple/core/Pg.h>
27 #include <ripple/json/json_reader.h>
28 #include <ripple/json/json_value.h>
29 #include <ripple/ledger/ReadView.h>
30 #include <ripple/net/RPCErr.h>
31 #include <ripple/protocol/ErrorCodes.h>
32 #include <ripple/protocol/UintTypes.h>
33 #include <ripple/protocol/jss.h>
34 #include <ripple/resource/Fees.h>
35 #include <ripple/rpc/Context.h>
36 #include <ripple/rpc/DeliveredAmount.h>
37 #include <ripple/rpc/Role.h>
38 #include <ripple/rpc/impl/GRPCHelpers.h>
39 #include <ripple/rpc/impl/RPCHelpers.h>
40 
41 #include <grpcpp/grpcpp.h>
42 
43 namespace ripple {
44 
50 
53 
54 // parses args into a ledger specifier, or returns a grpc status object on error
57  org::xrpl::rpc::v1::GetAccountTransactionHistoryRequest const& params)
58 {
59  grpc::Status status;
60  if (params.has_ledger_range())
61  {
62  uint32_t min = params.ledger_range().ledger_index_min();
63  uint32_t max = params.ledger_range().ledger_index_max();
64 
65  // if min is set but not max, need to set max
66  if (min != 0 && max == 0)
67  {
68  max = UINT32_MAX;
69  }
70 
71  return LedgerRange{min, max};
72  }
73  else if (params.has_ledger_specifier())
74  {
75  LedgerSpecifier ledger;
76 
77  auto& specifier = params.ledger_specifier();
78  using LedgerCase = org::xrpl::rpc::v1::LedgerSpecifier::LedgerCase;
79  LedgerCase ledgerCase = specifier.ledger_case();
80 
81  if (ledgerCase == LedgerCase::kShortcut)
82  {
83  using LedgerSpecifier = org::xrpl::rpc::v1::LedgerSpecifier;
84 
85  if (specifier.shortcut() == LedgerSpecifier::SHORTCUT_VALIDATED)
86  ledger = LedgerShortcut::VALIDATED;
87  else if (specifier.shortcut() == LedgerSpecifier::SHORTCUT_CLOSED)
88  ledger = LedgerShortcut::CLOSED;
89  else if (specifier.shortcut() == LedgerSpecifier::SHORTCUT_CURRENT)
90  ledger = LedgerShortcut::CURRENT;
91  else
92  return {};
93  }
94  else if (ledgerCase == LedgerCase::kSequence)
95  {
96  ledger = specifier.sequence();
97  }
98  else if (ledgerCase == LedgerCase::kHash)
99  {
100  if (auto hash = uint256::fromVoidChecked(specifier.hash()))
101  {
102  ledger = *hash;
103  }
104  else
105  {
106  grpc::Status errorStatus{
107  grpc::StatusCode::INVALID_ARGUMENT,
108  "ledger hash malformed"};
109  return errorStatus;
110  }
111  }
112  return ledger;
113  }
115 }
116 
117 // parses args into a ledger specifier, or returns a Json object on error
120 {
121  Json::Value response;
122  if (params.isMember(jss::ledger_index_min) ||
123  params.isMember(jss::ledger_index_max))
124  {
125  uint32_t min = params.isMember(jss::ledger_index_min) &&
126  params[jss::ledger_index_min].asInt() >= 0
127  ? params[jss::ledger_index_min].asUInt()
128  : 0;
129  uint32_t max = params.isMember(jss::ledger_index_max) &&
130  params[jss::ledger_index_max].asInt() >= 0
131  ? params[jss::ledger_index_max].asUInt()
132  : UINT32_MAX;
133 
134  return LedgerRange{min, max};
135  }
136  else if (params.isMember(jss::ledger_hash))
137  {
138  auto& hashValue = params[jss::ledger_hash];
139  if (!hashValue.isString())
140  {
141  RPC::Status status{rpcINVALID_PARAMS, "ledgerHashNotString"};
142  status.inject(response);
143  return response;
144  }
145 
146  LedgerHash hash;
147  if (!hash.parseHex(hashValue.asString()))
148  {
149  RPC::Status status{rpcINVALID_PARAMS, "ledgerHashMalformed"};
150  status.inject(response);
151  return response;
152  }
153  return hash;
154  }
155  else if (params.isMember(jss::ledger_index))
156  {
157  LedgerSpecifier ledger;
158  if (params[jss::ledger_index].isNumeric())
159  ledger = params[jss::ledger_index].asUInt();
160  else
161  {
162  std::string ledgerStr = params[jss::ledger_index].asString();
163 
164  if (ledgerStr == "current" || ledgerStr.empty())
165  ledger = LedgerShortcut::CURRENT;
166  else if (ledgerStr == "closed")
167  ledger = LedgerShortcut::CLOSED;
168  else if (ledgerStr == "validated")
169  ledger = LedgerShortcut::VALIDATED;
170  else
171  {
172  RPC::Status status{
173  rpcINVALID_PARAMS, "ledger_index string malformed"};
174  status.inject(response);
175  return response;
176  }
177  }
178  return ledger;
179  }
181 }
182 
185  RPC::Context& context,
186  std::optional<LedgerSpecifier> const& ledgerSpecifier)
187 {
188  std::uint32_t uValidatedMin;
189  std::uint32_t uValidatedMax;
190  bool bValidated =
191  context.ledgerMaster.getValidatedRange(uValidatedMin, uValidatedMax);
192 
193  if (!bValidated)
194  {
195  // Don't have a validated ledger range.
196  if (context.apiVersion == 1)
197  return rpcLGR_IDXS_INVALID;
198  return rpcNOT_SYNCED;
199  }
200 
201  std::uint32_t uLedgerMin = uValidatedMin;
202  std::uint32_t uLedgerMax = uValidatedMax;
203  // Does request specify a ledger or ledger range?
204  if (ledgerSpecifier)
205  {
206  auto const status = std::visit(
207  [&](auto const& ls) -> RPC::Status {
208  using T = std::decay_t<decltype(ls)>;
209  if constexpr (std::is_same_v<T, LedgerRange>)
210  {
211  if (ls.min > uValidatedMin)
212  {
213  uLedgerMin = ls.min;
214  }
215  if (ls.max < uValidatedMax)
216  {
217  uLedgerMax = ls.max;
218  }
219  if (uLedgerMax < uLedgerMin)
220  {
221  if (context.apiVersion == 1)
222  return rpcLGR_IDXS_INVALID;
223  return rpcINVALID_LGR_RANGE;
224  }
225  }
226  else
227  {
229  auto const status = getLedger(ledgerView, ls, context);
230  if (!ledgerView)
231  {
232  return status;
233  }
234 
235  bool validated = RPC::isValidated(
236  context.ledgerMaster, *ledgerView, context.app);
237 
238  if (!validated || ledgerView->info().seq > uValidatedMax ||
239  ledgerView->info().seq < uValidatedMin)
240  {
241  return rpcLGR_NOT_VALIDATED;
242  }
243  uLedgerMin = uLedgerMax = ledgerView->info().seq;
244  }
245  return RPC::Status::OK;
246  },
247  *ledgerSpecifier);
248 
249  if (status)
250  return status;
251  }
252  return LedgerRange{uLedgerMin, uLedgerMax};
253 }
254 
257 {
259  if (context.app.config().reporting())
260  return dynamic_cast<RelationalDBInterfacePostgres*>(
261  &context.app.getRelationalDBInterface())
262  ->getAccountTx(args);
263 
264  AccountTxResult result;
265 
266  auto lgrRange = getLedgerRange(context, args.ledger);
267  if (auto stat = std::get_if<RPC::Status>(&lgrRange))
268  {
269  // An error occurred getting the requested ledger range
270  return {result, *stat};
271  }
272 
273  result.ledgerRange = std::get<LedgerRange>(lgrRange);
274 
275  result.marker = args.marker;
276 
278  args.account,
279  result.ledgerRange.min,
280  result.ledgerRange.max,
281  result.marker,
282  args.limit,
283  isUnlimited(context.role)};
284 
285  if (args.binary)
286  {
287  if (args.forward)
288  {
289  auto [tx, marker] = dynamic_cast<RelationalDBInterfaceSqlite*>(
290  &context.app.getRelationalDBInterface())
291  ->oldestAccountTxPageB(options);
292  result.transactions = tx;
293  result.marker = marker;
294  }
295  else
296  {
297  auto [tx, marker] = dynamic_cast<RelationalDBInterfaceSqlite*>(
298  &context.app.getRelationalDBInterface())
299  ->newestAccountTxPageB(options);
300  result.transactions = tx;
301  result.marker = marker;
302  }
303  }
304  else
305  {
306  if (args.forward)
307  {
308  auto [tx, marker] = dynamic_cast<RelationalDBInterfaceSqlite*>(
309  &context.app.getRelationalDBInterface())
310  ->oldestAccountTxPage(options);
311  result.transactions = tx;
312  result.marker = marker;
313  }
314  else
315  {
316  auto [tx, marker] = dynamic_cast<RelationalDBInterfaceSqlite*>(
317  &context.app.getRelationalDBInterface())
318  ->newestAccountTxPage(options);
319  result.transactions = tx;
320  result.marker = marker;
321  }
322  }
323 
324  result.limit = args.limit;
325  JLOG(context.j.debug()) << __func__ << " : finished";
326 
327  return {result, rpcSUCCESS};
328 }
329 
330 std::pair<
331  org::xrpl::rpc::v1::GetAccountTransactionHistoryResponse,
332  grpc::Status>
335  AccountTxArgs const& args,
337  org::xrpl::rpc::v1::GetAccountTransactionHistoryRequest> const& context)
338 {
339  org::xrpl::rpc::v1::GetAccountTransactionHistoryResponse response;
340  grpc::Status status = grpc::Status::OK;
341 
342  RPC::Status const& error = res.second;
343  if (error.toErrorCode() != rpcSUCCESS)
344  {
345  if (error.toErrorCode() == rpcLGR_NOT_FOUND)
346  {
347  status = {grpc::StatusCode::NOT_FOUND, error.message()};
348  }
349  else if (error.toErrorCode() == rpcNOT_SYNCED)
350  {
351  status = {grpc::StatusCode::FAILED_PRECONDITION, error.message()};
352  }
353  else
354  {
355  status = {grpc::StatusCode::INVALID_ARGUMENT, error.message()};
356  }
357  }
358  else
359  {
360  AccountTxResult const& result = res.first;
361 
362  // account_tx always returns validated data
363  response.set_validated(true);
364  response.set_limit(result.limit);
365  response.mutable_account()->set_address(
366  context.params.account().address());
367  response.set_ledger_index_min(result.ledgerRange.min);
368  response.set_ledger_index_max(result.ledgerRange.max);
369 
370  if (auto txnsData = std::get_if<TxnsData>(&result.transactions))
371  {
372  assert(!args.binary);
373  for (auto const& [txn, txnMeta] : *txnsData)
374  {
375  if (txn)
376  {
377  auto txnProto = response.add_transactions();
378 
379  RPC::convert(
380  *txnProto->mutable_transaction(),
381  txn->getSTransaction());
382 
383  // account_tx always returns validated data
384  txnProto->set_validated(true);
385  txnProto->set_ledger_index(txn->getLedger());
386  auto& hash = txn->getID();
387  txnProto->set_hash(hash.data(), hash.size());
388  auto closeTime =
389  context.app.getLedgerMaster().getCloseTimeBySeq(
390  txn->getLedger());
391  if (closeTime)
392  txnProto->mutable_date()->set_value(
393  closeTime->time_since_epoch().count());
394  if (txnMeta)
395  {
396  RPC::convert(*txnProto->mutable_meta(), txnMeta);
397  if (!txnProto->meta().has_delivered_amount())
398  {
399  if (auto amt = getDeliveredAmount(
400  context,
401  txn->getSTransaction(),
402  *txnMeta,
403  txn->getLedger()))
404  {
405  RPC::convert(
406  *txnProto->mutable_meta()
407  ->mutable_delivered_amount(),
408  *amt);
409  }
410  }
411  }
412  }
413  }
414  }
415  else
416  {
417  assert(args.binary);
418 
419  for (auto const& binaryData :
420  std::get<TxnsDataBinary>(result.transactions))
421  {
422  auto txnProto = response.add_transactions();
423  Blob const& txnBlob = std::get<0>(binaryData);
424  txnProto->set_transaction_binary(
425  txnBlob.data(), txnBlob.size());
426 
427  Blob const& metaBlob = std::get<1>(binaryData);
428  txnProto->set_meta_binary(metaBlob.data(), metaBlob.size());
429 
430  txnProto->set_ledger_index(std::get<2>(binaryData));
431 
432  // account_tx always returns validated data
433  txnProto->set_validated(true);
434 
435  auto closeTime =
436  context.app.getLedgerMaster().getCloseTimeBySeq(
437  std::get<2>(binaryData));
438  if (closeTime)
439  txnProto->mutable_date()->set_value(
440  closeTime->time_since_epoch().count());
441  }
442  }
443 
444  if (result.marker)
445  {
446  response.mutable_marker()->set_ledger_index(
447  result.marker->ledgerSeq);
448  response.mutable_marker()->set_account_sequence(
449  result.marker->txnSeq);
450  }
451  }
452  return {response, status};
453 }
454 
458  AccountTxArgs const& args,
459  RPC::JsonContext const& context)
460 {
461  Json::Value response;
462  RPC::Status const& error = res.second;
463  if (error.toErrorCode() != rpcSUCCESS)
464  {
465  error.inject(response);
466  }
467  else
468  {
469  AccountTxResult const& result = res.first;
470  response[jss::validated] = true;
471  response[jss::limit] = result.limit;
472  response[jss::account] = context.params[jss::account].asString();
473  response[jss::ledger_index_min] = result.ledgerRange.min;
474  response[jss::ledger_index_max] = result.ledgerRange.max;
475 
476  Json::Value& jvTxns = (response[jss::transactions] = Json::arrayValue);
477 
478  if (auto txnsData = std::get_if<TxnsData>(&result.transactions))
479  {
480  assert(!args.binary);
481  for (auto const& [txn, txnMeta] : *txnsData)
482  {
483  if (txn)
484  {
485  Json::Value& jvObj = jvTxns.append(Json::objectValue);
486 
487  jvObj[jss::tx] = txn->getJson(JsonOptions::include_date);
488  if (txnMeta)
489  {
490  jvObj[jss::meta] =
491  txnMeta->getJson(JsonOptions::include_date);
492  jvObj[jss::validated] = true;
493  insertDeliveredAmount(
494  jvObj[jss::meta], context, txn, *txnMeta);
495  }
496  }
497  }
498  }
499  else
500  {
501  assert(args.binary);
502 
503  for (auto const& binaryData :
504  std::get<TxnsDataBinary>(result.transactions))
505  {
506  Json::Value& jvObj = jvTxns.append(Json::objectValue);
507 
508  jvObj[jss::tx_blob] = strHex(std::get<0>(binaryData));
509  jvObj[jss::meta] = strHex(std::get<1>(binaryData));
510  jvObj[jss::ledger_index] = std::get<2>(binaryData);
511  jvObj[jss::validated] = true;
512  }
513  }
514 
515  if (result.marker)
516  {
517  response[jss::marker] = Json::objectValue;
518  response[jss::marker][jss::ledger] = result.marker->ledgerSeq;
519  response[jss::marker][jss::seq] = result.marker->txnSeq;
520  }
521  if (context.app.config().reporting())
522  response["used_postgres"] = true;
523  }
524 
525  JLOG(context.j.debug()) << __func__ << " : finished";
526  return response;
527 }
528 
529 // {
530 // account: account,
531 // ledger_index_min: ledger_index // optional, defaults to earliest
532 // ledger_index_max: ledger_index, // optional, defaults to latest
533 // binary: boolean, // optional, defaults to false
534 // forward: boolean, // optional, defaults to false
535 // limit: integer, // optional
536 // marker: object {ledger: ledger_index, seq: txn_sequence} // optional,
537 // resume previous query
538 // }
541 {
542  if (!context.app.config().useTxTables())
543  return rpcError(rpcNOT_ENABLED);
544 
545  auto& params = context.params;
546  AccountTxArgs args;
547  Json::Value response;
548 
549  args.limit = params.isMember(jss::limit) ? params[jss::limit].asUInt() : 0;
550  args.binary = params.isMember(jss::binary) && params[jss::binary].asBool();
551  args.forward =
552  params.isMember(jss::forward) && params[jss::forward].asBool();
553 
554  if (!params.isMember(jss::account))
555  return rpcError(rpcINVALID_PARAMS);
556 
557  auto const account =
558  parseBase58<AccountID>(params[jss::account].asString());
559  if (!account)
560  return rpcError(rpcACT_MALFORMED);
561 
562  args.account = *account;
563 
564  auto parseRes = parseLedgerArgs(params);
565  if (auto jv = std::get_if<Json::Value>(&parseRes))
566  {
567  return *jv;
568  }
569  else
570  {
571  args.ledger = std::get<std::optional<LedgerSpecifier>>(parseRes);
572  }
573 
574  if (params.isMember(jss::marker))
575  {
576  auto& token = params[jss::marker];
577  if (!token.isMember(jss::ledger) || !token.isMember(jss::seq) ||
578  !token[jss::ledger].isConvertibleTo(Json::ValueType::uintValue) ||
579  !token[jss::seq].isConvertibleTo(Json::ValueType::uintValue))
580  {
581  RPC::Status status{
583  "invalid marker. Provide ledger index via ledger field, and "
584  "transaction sequence number via seq field"};
585  status.inject(response);
586  return response;
587  }
588  args.marker = {token[jss::ledger].asUInt(), token[jss::seq].asUInt()};
589  }
590 
591  auto res = doAccountTxHelp(context, args);
592  JLOG(context.j.debug()) << __func__ << " populating response";
593  return populateJsonResponse(res, args, context);
594 }
595 
596 std::pair<
597  org::xrpl::rpc::v1::GetAccountTransactionHistoryResponse,
598  grpc::Status>
601  context)
602 {
603  if (!context.app.config().useTxTables())
604  {
605  return {
606  {},
607  {grpc::StatusCode::UNIMPLEMENTED, "Not enabled in configuration."}};
608  }
609 
610  // return values
611  org::xrpl::rpc::v1::GetAccountTransactionHistoryResponse response;
612  grpc::Status status = grpc::Status::OK;
613  AccountTxArgs args;
614 
615  auto& request = context.params;
616 
617  auto const account = parseBase58<AccountID>(request.account().address());
618  if (!account)
619  {
620  return {
621  {},
622  {grpc::StatusCode::INVALID_ARGUMENT, "Could not decode account"}};
623  }
624 
625  args.account = *account;
626  args.limit = request.limit();
627  args.binary = request.binary();
628  args.forward = request.forward();
629 
630  if (request.has_marker())
631  {
632  args.marker = {
633  request.marker().ledger_index(),
634  request.marker().account_sequence()};
635  }
636 
637  auto parseRes = parseLedgerArgs(request);
638  if (auto stat = std::get_if<grpc::Status>(&parseRes))
639  {
640  return {response, *stat};
641  }
642  else
643  {
644  args.ledger = std::get<std::optional<LedgerSpecifier>>(parseRes);
645  }
646 
647  auto res = doAccountTxHelp(context, args);
648  return populateProtoResponse(res, args, context);
649 }
650 
651 } // namespace ripple
ripple::ReadView::info
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
ripple::LedgerMaster::getValidatedRange
bool getValidatedRange(std::uint32_t &minVal, std::uint32_t &maxVal)
Definition: LedgerMaster.cpp:621
ripple::RPC::Status::OK
static constexpr Code OK
Definition: Status.h:46
ripple::JsonOptions::include_date
@ include_date
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::RelationalDBInterface::AccountTxArgs
Definition: RelationalDBInterface.h:96
ripple::getAccountTx
std::pair< AccountTxResult, RPC::Status > getAccountTx(std::shared_ptr< PgPool > const &pgPool, AccountTxArgs const &args, Application &app, beast::Journal j)
getAccountTx Get last account transactions specifies by passed argumenrs structure.
Definition: RelationalDBInterface_postgres.cpp:542
ripple::rpcLGR_IDXS_INVALID
@ rpcLGR_IDXS_INVALID
Definition: ErrorCodes.h:112
std::string
STL class.
std::shared_ptr
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::Resource::feeMediumBurdenRPC
const Charge feeMediumBurdenRPC
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
std::pair
ripple::RPC::LedgerShortcut
LedgerShortcut
Definition: RPCHelpers.h:109
ripple::RPC::Context::loadType
Resource::Charge & loadType
Definition: Context.h:43
std::vector< unsigned char >
std::vector::size
T size(T... args)
ripple::Application::getRelationalDBInterface
virtual RelationalDBInterface & getRelationalDBInterface()=0
ripple::populateProtoResponse
std::pair< org::xrpl::rpc::v1::GetAccountTransactionHistoryResponse, grpc::Status > populateProtoResponse(std::pair< AccountTxResult, RPC::Status > const &res, AccountTxArgs const &args, RPC::GRPCContext< org::xrpl::rpc::v1::GetAccountTransactionHistoryRequest > const &context)
Definition: AccountTx.cpp:333
ripple::RelationalDBInterface::AccountTxResult
Definition: RelationalDBInterface.h:106
ripple::doAccountTxGrpc
std::pair< org::xrpl::rpc::v1::GetAccountTransactionHistoryResponse, grpc::Status > doAccountTxGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetAccountTransactionHistoryRequest > &context)
Definition: AccountTx.cpp:599
ripple::RelationalDBInterface::AccountTxArgs::marker
std::optional< AccountTxMarker > marker
Definition: RelationalDBInterface.h:103
ripple::RPC::Context::ledgerMaster
LedgerMaster & ledgerMaster
Definition: Context.h:45
ripple::newestAccountTxPage
std::pair< std::optional< RelationalDBInterface::AccountTxMarker >, int > newestAccountTxPage(soci::session &session, AccountIDCache const &idCache, std::function< void(std::uint32_t)> const &onUnsavedLedger, std::function< void(std::uint32_t, std::string const &, Blob &&, Blob &&)> const &onTransaction, RelationalDBInterface::AccountTxPageOptions const &options, int limit_used, std::uint32_t page_length)
newestAccountTxPage Searches newest transactions for given account which match given criteria startin...
Definition: RelationalDBInterface_nodes.cpp:1247
std::tuple
ripple::RelationalDBInterface::AccountTxArgs::ledger
std::optional< LedgerSpecifier > ledger
Definition: RelationalDBInterface.h:99
ripple::LedgerInfo::seq
LedgerIndex seq
Definition: ReadView.h:92
ripple::RPC::Context::role
Role role
Definition: Context.h:47
ripple::base_uint< 256 >::fromVoidChecked
static std::optional< base_uint > fromVoidChecked(T const &from)
Definition: base_uint.h:312
ripple::rpcLGR_NOT_FOUND
@ rpcLGR_NOT_FOUND
Definition: ErrorCodes.h:72
ripple::RelationalDBInterfacePostgres
Definition: RelationalDBInterfacePostgres.h:27
ripple::RelationalDBInterface::AccountTxArgs::binary
bool binary
Definition: RelationalDBInterface.h:100
ripple::doAccountTxHelp
std::pair< AccountTxResult, RPC::Status > doAccountTxHelp(RPC::Context &context, AccountTxArgs const &args)
Definition: AccountTx.cpp:256
ripple::RPC::Context::j
const beast::Journal j
Definition: Context.h:41
ripple::getLedgerRange
std::variant< LedgerRange, RPC::Status > getLedgerRange(RPC::Context &context, std::optional< LedgerSpecifier > const &ledgerSpecifier)
Definition: AccountTx.cpp:184
ripple::RelationalDBInterface::LedgerSpecifier
std::variant< LedgerRange, LedgerShortcut, LedgerSequence, LedgerHash > LedgerSpecifier
Definition: RelationalDBInterface.h:94
ripple::RelationalDBInterface::AccountTxResult::transactions
std::variant< AccountTxs, MetaTxsList > transactions
Definition: RelationalDBInterface.h:108
ripple::base_uint< 256 >
ripple::RPC::convert
void convert(org::xrpl::rpc::v1::TransactionResult &to, TER from)
Definition: GRPCHelpers.cpp:961
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::Config::reporting
bool reporting() const
Definition: Config.h:308
ripple::RelationalDBInterface::AccountTxResult::ledgerRange
LedgerRange ledgerRange
Definition: RelationalDBInterface.h:109
ripple::RelationalDBInterface::LedgerShortcut
RPC::LedgerShortcut LedgerShortcut
Definition: RelationalDBInterface.h:92
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::RelationalDBInterfaceSqlite
Definition: RelationalDBInterfaceSqlite.h:27
ripple::Application::config
virtual Config & config()=0
ripple::RPC::GRPCContext
Definition: Context.h:70
ripple::Config::useTxTables
bool useTxTables() const
Definition: Config.h:314
ripple::RPC::Context::app
Application & app
Definition: Context.h:42
ripple::rpcNOT_ENABLED
@ rpcNOT_ENABLED
Definition: ErrorCodes.h:59
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
std::uint32_t
ripple::rpcError
Json::Value rpcError(int iError, Json::Value jvResult)
Definition: RPCErr.cpp:29
ripple::RPC::Status
Status represents the results of an operation that might fail.
Definition: Status.h:39
ripple::RelationalDBInterface::AccountTxArgs::limit
uint32_t limit
Definition: RelationalDBInterface.h:102
std::decay_t
ripple::isUnlimited
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition: Role.cpp:94
ripple::RPC::GRPCContext::params
RequestType params
Definition: Context.h:72
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::populateJsonResponse
Json::Value populateJsonResponse(std::pair< AccountTxResult, RPC::Status > const &res, AccountTxArgs const &args, RPC::JsonContext const &context)
Definition: AccountTx.cpp:456
ripple::RPC::isValidated
bool isValidated(LedgerMaster &ledgerMaster, ReadView const &ledger, Application &app)
Definition: RPCHelpers.cpp:468
ripple::RelationalDBInterface::AccountTxArgs::account
AccountID account
Definition: RelationalDBInterface.h:98
ripple::rpcACT_MALFORMED
@ rpcACT_MALFORMED
Definition: ErrorCodes.h:90
ripple::TxnsData
RelationalDBInterface::AccountTxs TxnsData
Definition: RelationalDBInterface_postgres.cpp:27
ripple::rpcLGR_NOT_VALIDATED
@ rpcLGR_NOT_VALIDATED
Definition: ErrorCodes.h:73
ripple::RelationalDBInterface::MetaTxsList
std::vector< txnMetaLedgerType > MetaTxsList
Definition: RelationalDBInterface.h:88
ripple::doAccountTxJson
Json::Value doAccountTxJson(RPC::JsonContext &context)
Definition: AccountTx.cpp:540
ripple::LedgerRange::max
uint32_t max
Definition: RelationalDBInterface.h:45
Json::Value::asUInt
UInt asUInt() const
Definition: json_value.cpp:545
ripple::RPC::Context::apiVersion
unsigned int apiVersion
Definition: Context.h:50
ripple::RelationalDBInterface::AccountTxResult::limit
uint32_t limit
Definition: RelationalDBInterface.h:110
ripple::RelationalDBInterface::AccountTxResult::marker
std::optional< AccountTxMarker > marker
Definition: RelationalDBInterface.h:111
ripple::oldestAccountTxPage
std::pair< std::optional< RelationalDBInterface::AccountTxMarker >, int > oldestAccountTxPage(soci::session &session, AccountIDCache const &idCache, std::function< void(std::uint32_t)> const &onUnsavedLedger, std::function< void(std::uint32_t, std::string const &, Blob &&, Blob &&)> const &onTransaction, RelationalDBInterface::AccountTxPageOptions const &options, int limit_used, std::uint32_t page_length)
oldestAccountTxPage Searches oldest transactions for given account which match given criteria startin...
Definition: RelationalDBInterface_nodes.cpp:1224
std::visit
T visit(T... args)
std::string::empty
T empty(T... args)
ripple::parseLedgerArgs
std::variant< std::optional< LedgerSpecifier >, grpc::Status > parseLedgerArgs(org::xrpl::rpc::v1::GetAccountTransactionHistoryRequest const &params)
Definition: AccountTx.cpp:56
std::optional
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::RelationalDBInterface::txnMetaLedgerType
std::tuple< Blob, Blob, std::uint32_t > txnMetaLedgerType
Definition: RelationalDBInterface.h:87
Json::Value::asInt
Int asInt() const
Definition: json_value.cpp:503
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
ripple::rpcINVALID_LGR_RANGE
@ rpcINVALID_LGR_RANGE
Definition: ErrorCodes.h:136
ripple::RelationalDBInterface::AccountTxPageOptions
Definition: RelationalDBInterface.h:74
ripple::LedgerRange
Definition: RelationalDBInterface.h:42
ripple::base_uint::parseHex
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:475
ripple::RelationalDBInterface::AccountTxArgs::forward
bool forward
Definition: RelationalDBInterface.h:101
ripple::LedgerRange::min
uint32_t min
Definition: RelationalDBInterface.h:44
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
std::vector::data
T data(T... args)
ripple::RPC::Context
The context of information needed to call an RPC.
Definition: Context.h:39
ripple::TxnsDataBinary
RelationalDBInterface::MetaTxsList TxnsDataBinary
Definition: RelationalDBInterface_postgres.cpp:28
ripple::rpcNOT_SYNCED
@ rpcNOT_SYNCED
Definition: ErrorCodes.h:67
Json::Value
Represents a JSON value.
Definition: json_value.h:145
std::variant
ripple::RelationalDBInterface::AccountTxs
std::vector< AccountTx > AccountTxs
Definition: RelationalDBInterface.h:86
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469