rippled
Tx.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/ledger/TransactionMaster.h>
22 #include <ripple/app/misc/NetworkOPs.h>
23 #include <ripple/app/misc/Transaction.h>
24 #include <ripple/basics/ToString.h>
25 #include <ripple/net/RPCErr.h>
26 #include <ripple/protocol/ErrorCodes.h>
27 #include <ripple/protocol/jss.h>
28 #include <ripple/rpc/Context.h>
29 #include <ripple/rpc/DeliveredAmount.h>
30 #include <ripple/rpc/GRPCHandlers.h>
31 #include <ripple/rpc/impl/GRPCHelpers.h>
32 #include <ripple/rpc/impl/RPCHelpers.h>
33 
34 namespace ripple {
35 
36 // {
37 // transaction: <hex>
38 // }
39 
40 static bool
41 isValidated(LedgerMaster& ledgerMaster, std::uint32_t seq, uint256 const& hash)
42 {
43  if (!ledgerMaster.haveLedger(seq))
44  return false;
45 
46  if (seq > ledgerMaster.getValidatedLedger()->info().seq)
47  return false;
48 
49  return ledgerMaster.getHashBySeq(seq) == hash;
50 }
51 
52 struct TxResult
53 {
56  bool validated = false;
58 };
59 
60 struct TxArgs
61 {
63  bool binary = false;
65 };
66 
68 doTxPostgres(RPC::Context& context, TxArgs const& args)
69 {
70  if (!context.app.config().reporting())
71  {
72  assert(false);
73  Throw<std::runtime_error>(
74  "Called doTxPostgres yet not in reporting mode");
75  }
76  TxResult res;
78 
79  JLOG(context.j.debug()) << "Fetching from postgres";
80  Transaction::Locator locator = Transaction::locate(args.hash, context.app);
81 
83  pair;
84  // database returned the nodestore hash. Fetch the txn directly from the
85  // nodestore. Don't traverse the transaction SHAMap
86  if (locator.isFound())
87  {
88  auto start = std::chrono::system_clock::now();
89  // The second argument of fetch is ignored when not using shards
90  if (auto obj = context.app.getNodeFamily().db().fetchNodeObject(
91  locator.getNodestoreHash(), locator.getLedgerSequence()))
92  {
94  makeSlice(obj->getData()),
95  SHAMapHash{locator.getNodestoreHash()});
96  if (!node)
97  {
98  assert(false);
99  return {res, {rpcINTERNAL, "Error making SHAMap node"}};
100  }
101  auto item = (static_cast<SHAMapLeafNode*>(node.get()))->peekItem();
102  if (!item)
103  {
104  assert(false);
105  return {res, {rpcINTERNAL, "Error reading SHAMap node"}};
106  }
107 
108  auto [sttx, meta] = deserializeTxPlusMeta(*item);
109  JLOG(context.j.debug()) << "Successfully fetched from db";
110 
111  if (!sttx || !meta)
112  {
113  assert(false);
114  return {res, {rpcINTERNAL, "Error deserializing SHAMap node"}};
115  }
116  std::string reason;
117  res.txn = std::make_shared<Transaction>(sttx, reason, context.app);
118  res.txn->setLedger(locator.getLedgerSequence());
119  res.txn->setStatus(COMMITTED);
120  if (args.binary)
121  {
122  SerialIter it(item->slice());
123  it.skip(it.getVLDataLength()); // skip transaction
124  Blob blob = it.getVL();
125  res.meta = std::move(blob);
126  }
127  else
128  {
129  res.meta = std::make_shared<TxMeta>(
130  args.hash, res.txn->getLedger(), *meta);
131  }
132  res.validated = true;
133  return {res, rpcSUCCESS};
134  }
135  else
136  {
137  JLOG(context.j.error()) << "Failed to fetch from db";
138  assert(false);
139  return {res, {rpcINTERNAL, "Containing SHAMap node not found"}};
140  }
141  auto end = std::chrono::system_clock::now();
142  JLOG(context.j.debug()) << "tx flat fetch time : "
143  << ((end - start).count() / 1000000000.0);
144  }
145  // database did not find the transaction, and returned the ledger range
146  // that was searched
147  else
148  {
149  if (args.ledgerRange)
150  {
151  auto range = locator.getLedgerRangeSearched();
152  auto min = args.ledgerRange->first;
153  auto max = args.ledgerRange->second;
154  if (min >= range.lower() && max <= range.upper())
155  {
157  }
158  else
159  {
161  }
162  }
163  return {res, rpcTXN_NOT_FOUND};
164  }
165  // database didn't return anything. This shouldn't happen
166  assert(false);
167  return {res, {rpcINTERNAL, "unexpected Postgres response"}};
168 }
169 
171 doTxHelp(RPC::Context& context, TxArgs const& args)
172 {
173  if (context.app.config().reporting())
174  return doTxPostgres(context, args);
175  TxResult result;
176 
178 
179  if (args.ledgerRange)
180  {
181  constexpr uint16_t MAX_RANGE = 1000;
182 
183  if (args.ledgerRange->second < args.ledgerRange->first)
184  return {result, rpcINVALID_LGR_RANGE};
185 
186  if (args.ledgerRange->second - args.ledgerRange->first > MAX_RANGE)
187  return {result, rpcEXCESSIVE_LGR_RANGE};
188 
190  args.ledgerRange->first, args.ledgerRange->second);
191  }
192 
193  auto ec{rpcSUCCESS};
194 
195  using TxPair =
197 
199 
201  if (args.ledgerRange)
202  {
203  v = context.app.getMasterTransaction().fetch(args.hash, range, ec);
204  }
205  else
206  {
207  v = context.app.getMasterTransaction().fetch(args.hash, ec);
208  }
209 
210  if (auto e = std::get_if<TxSearched>(&v))
211  {
212  result.searchedAll = *e;
213  return {result, rpcTXN_NOT_FOUND};
214  }
215 
216  auto [txn, meta] = std::get<TxPair>(v);
217 
218  if (ec == rpcDB_DESERIALIZATION)
219  {
220  return {result, ec};
221  }
222  if (!txn)
223  {
224  return {result, rpcTXN_NOT_FOUND};
225  }
226 
227  // populate transaction data
228  result.txn = txn;
229  if (txn->getLedger() == 0)
230  {
231  return {result, rpcSUCCESS};
232  }
233 
235  context.ledgerMaster.getLedgerBySeq(txn->getLedger());
236 
237  if (ledger && meta)
238  {
239  if (args.binary)
240  {
241  result.meta = meta->getAsObject().getSerializer().getData();
242  }
243  else
244  {
245  result.meta = meta;
246  }
247  result.validated = isValidated(
248  context.ledgerMaster, ledger->info().seq, ledger->info().hash);
249  }
250 
251  return {result, rpcSUCCESS};
252 }
253 
257  TxArgs const& args,
259 {
260  org::xrpl::rpc::v1::GetTransactionResponse response;
261  grpc::Status status = grpc::Status::OK;
262  RPC::Status const& error = res.second;
263  TxResult const& result = res.first;
264  // handle errors
265  if (error.toErrorCode() != rpcSUCCESS)
266  {
267  if (error.toErrorCode() == rpcTXN_NOT_FOUND &&
269  {
270  status = {
271  grpc::StatusCode::NOT_FOUND,
272  "txn not found. searched_all = " +
273  to_string(
274  (result.searchedAll == TxSearched::all ? "true"
275  : "false"))};
276  }
277  else
278  {
279  if (error.toErrorCode() == rpcTXN_NOT_FOUND)
280  status = {grpc::StatusCode::NOT_FOUND, "txn not found"};
281  else
282  status = {grpc::StatusCode::INTERNAL, error.message()};
283  }
284  }
285  // no errors
286  else if (result.txn)
287  {
288  auto& txn = result.txn;
289 
290  std::shared_ptr<STTx const> stTxn = txn->getSTransaction();
291  if (args.binary)
292  {
293  Serializer s = stTxn->getSerializer();
294  response.set_transaction_binary(s.data(), s.size());
295  }
296  else
297  {
298  RPC::convert(*response.mutable_transaction(), stTxn);
299  }
300 
301  response.set_hash(context.params.hash());
302 
303  auto ledgerIndex = txn->getLedger();
304  response.set_ledger_index(ledgerIndex);
305  if (ledgerIndex)
306  {
307  auto ct =
308  context.app.getLedgerMaster().getCloseTimeBySeq(ledgerIndex);
309  if (ct)
310  response.mutable_date()->set_value(
311  ct->time_since_epoch().count());
312  }
313 
314  RPC::convert(
315  *response.mutable_meta()->mutable_transaction_result(),
316  txn->getResult());
317  response.mutable_meta()->mutable_transaction_result()->set_result(
318  transToken(txn->getResult()));
319 
320  // populate binary metadata
321  if (auto blob = std::get_if<Blob>(&result.meta))
322  {
323  assert(args.binary);
324  Slice slice = makeSlice(*blob);
325  response.set_meta_binary(slice.data(), slice.size());
326  }
327  // populate meta data
328  else if (auto m = std::get_if<std::shared_ptr<TxMeta>>(&result.meta))
329  {
330  auto& meta = *m;
331  if (meta)
332  {
333  RPC::convert(*response.mutable_meta(), meta);
334  auto amt =
335  getDeliveredAmount(context, stTxn, *meta, txn->getLedger());
336  if (amt)
337  {
338  RPC::convert(
339  *response.mutable_meta()->mutable_delivered_amount(),
340  *amt);
341  }
342  }
343  }
344  response.set_validated(result.validated);
345  }
346  return {response, status};
347 }
348 
352  TxArgs const& args,
353  RPC::JsonContext const& context)
354 {
355  Json::Value response;
356  RPC::Status const& error = res.second;
357  TxResult const& result = res.first;
358  // handle errors
359  if (error.toErrorCode() != rpcSUCCESS)
360  {
361  if (error.toErrorCode() == rpcTXN_NOT_FOUND &&
363  {
364  response = Json::Value(Json::objectValue);
365  response[jss::searched_all] =
366  (result.searchedAll == TxSearched::all);
367  error.inject(response);
368  }
369  else
370  {
371  error.inject(response);
372  }
373  }
374  // no errors
375  else if (result.txn)
376  {
377  response = result.txn->getJson(JsonOptions::include_date, args.binary);
378 
379  // populate binary metadata
380  if (auto blob = std::get_if<Blob>(&result.meta))
381  {
382  assert(args.binary);
383  response[jss::meta] = strHex(makeSlice(*blob));
384  }
385  // populate meta data
386  else if (auto m = std::get_if<std::shared_ptr<TxMeta>>(&result.meta))
387  {
388  auto& meta = *m;
389  if (meta)
390  {
391  response[jss::meta] = meta->getJson(JsonOptions::none);
392  insertDeliveredAmount(
393  response[jss::meta], context, result.txn, *meta);
394  }
395  }
396  response[jss::validated] = result.validated;
397  }
398  return response;
399 }
400 
403 {
404  if (!context.app.config().useTxTables())
405  return rpcError(rpcNOT_ENABLED);
406 
407  // Deserialize and validate JSON arguments
408 
409  if (!context.params.isMember(jss::transaction))
410  return rpcError(rpcINVALID_PARAMS);
411 
412  TxArgs args;
413 
414  if (!args.hash.parseHex(context.params[jss::transaction].asString()))
415  return rpcError(rpcNOT_IMPL);
416 
417  args.binary = context.params.isMember(jss::binary) &&
418  context.params[jss::binary].asBool();
419 
420  if (context.params.isMember(jss::min_ledger) &&
421  context.params.isMember(jss::max_ledger))
422  {
423  try
424  {
426  context.params[jss::min_ledger].asUInt(),
427  context.params[jss::max_ledger].asUInt());
428  }
429  catch (...)
430  {
431  // One of the calls to `asUInt ()` failed.
433  }
434  }
435 
436  std::pair<TxResult, RPC::Status> res = doTxHelp(context, args);
437  return populateJsonResponse(res, args, context);
438 }
439 
442 {
443  if (!context.app.config().useTxTables())
444  {
445  return {
446  {},
447  {grpc::StatusCode::UNIMPLEMENTED, "Not enabled in configuration."}};
448  }
449 
450  // return values
451  org::xrpl::rpc::v1::GetTransactionResponse response;
452  grpc::Status status = grpc::Status::OK;
453 
454  // input
455  org::xrpl::rpc::v1::GetTransactionRequest& request = context.params;
456 
457  TxArgs args;
458 
459  if (auto hash = uint256::fromVoidChecked(request.hash()))
460  {
461  args.hash = *hash;
462  }
463  else
464  {
465  grpc::Status errorStatus{
466  grpc::StatusCode::INVALID_ARGUMENT, "tx hash malformed"};
467  return {response, errorStatus};
468  }
469 
470  args.binary = request.binary();
471 
472  if (request.ledger_range().ledger_index_min() != 0 &&
473  request.ledger_range().ledger_index_max() != 0)
474  {
476  request.ledger_range().ledger_index_min(),
477  request.ledger_range().ledger_index_max());
478  }
479 
480  std::pair<TxResult, RPC::Status> res = doTxHelp(context, args);
481  return populateProtoResponse(res, args, context);
482 }
483 
484 } // namespace ripple
ripple::COMMITTED
@ COMMITTED
Definition: Transaction.h:50
ripple::TxArgs::binary
bool binary
Definition: Tx.cpp:63
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:79
ripple::JsonOptions::include_date
@ include_date
ripple::Application::getNodeFamily
virtual Family & getNodeFamily()=0
ripple::rpcDB_DESERIALIZATION
@ rpcDB_DESERIALIZATION
Definition: ErrorCodes.h:134
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::HashPrefix::ledgerMaster
@ ledgerMaster
ledger master data for signing
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:240
ripple::TxSearched::unknown
@ unknown
std::string
STL class.
std::shared_ptr< Transaction >
ripple::Transaction::getJson
Json::Value getJson(JsonOptions options, bool binary=false) const
Definition: Transaction.cpp:158
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::rpcError
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
std::pair
ripple::LedgerInfo::hash
uint256 hash
Definition: ReadView.h:100
ripple::TxSearched::all
@ all
ripple::Transaction::Locator::getNodestoreHash
uint256 const & getNodestoreHash()
Definition: Transaction.h:336
ripple::LedgerMaster
Definition: LedgerMaster.h:70
ripple::TxSearched
TxSearched
Definition: Transaction.h:57
std::vector< unsigned char >
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::Transaction::setLedger
void setLedger(LedgerIndex ledger)
Definition: Transaction.h:139
ripple::RPC::Context::ledgerMaster
LedgerMaster & ledgerMaster
Definition: Context.h:45
ripple::Slice::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:96
ripple::STObject::getSerializer
Serializer getSerializer() const
Definition: STObject.h:884
ripple::transToken
std::string transToken(TER code)
Definition: TER.cpp:196
ripple::rpcEXCESSIVE_LGR_RANGE
@ rpcEXCESSIVE_LGR_RANGE
Definition: ErrorCodes.h:135
ripple::LedgerInfo::seq
LedgerIndex seq
Definition: ReadView.h:92
ripple::base_uint< 256 >::fromVoidChecked
static std::optional< base_uint > fromVoidChecked(T const &from)
Definition: base_uint.h:312
ripple::TxResult
Definition: Tx.cpp:52
ripple::Family::db
virtual NodeStore::Database & db()=0
ripple::SHAMapLeafNode
Definition: SHAMapLeafNode.h:32
ripple::SHAMapHash
Definition: SHAMapHash.h:32
Json::Value::asBool
bool asBool() const
Definition: json_value.cpp:619
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:75
ripple::RPC::Context::j
const beast::Journal j
Definition: Context.h:41
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:75
ripple::Ledger::info
LedgerInfo const & info() const override
Returns information about the ledger.
Definition: Ledger.h:148
ripple::RPC::convert
void convert(org::xrpl::rpc::v1::TransactionResult &to, TER from)
Definition: GRPCHelpers.cpp:961
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::Config::reporting
bool reporting() const
Definition: Config.h:316
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::Transaction::Locator
Definition: Transaction.h:315
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::deserializeTxPlusMeta
std::pair< std::shared_ptr< STTx const >, std::shared_ptr< STObject const > > deserializeTxPlusMeta(SHAMapItem const &item)
Deserialize a SHAMapItem containing STTx + STObject metadata.
Definition: Ledger.cpp:389
ripple::Transaction::getLedger
LedgerIndex getLedger() const
Definition: Transaction.h:100
ripple::TxArgs::ledgerRange
std::optional< std::pair< uint32_t, uint32_t > > ledgerRange
Definition: Tx.cpp:64
ripple::JsonOptions::none
@ none
ripple::Application::config
virtual Config & config()=0
ripple::RPC::GRPCContext
Definition: Context.h:70
ripple::Config::useTxTables
bool useTxTables() const
Definition: Config.h:322
ripple::doTxGrpc
std::pair< org::xrpl::rpc::v1::GetTransactionResponse, grpc::Status > doTxGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetTransactionRequest > &context)
Definition: Tx.cpp:441
ripple::rpcTXN_NOT_FOUND
@ rpcTXN_NOT_FOUND
Definition: ErrorCodes.h:80
ripple::RPC::Context::app
Application & app
Definition: Context.h:42
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::Transaction::locate
static Locator locate(uint256 const &id, Application &app)
Definition: Transaction.cpp:135
ripple::LedgerMaster::getLedgerBySeq
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
Definition: LedgerMaster.cpp:1776
ripple::rpcNOT_ENABLED
@ rpcNOT_ENABLED
Definition: ErrorCodes.h:59
ripple::SerialIter
Definition: Serializer.h:310
ripple::SerialIter::getVL
Blob getVL()
Definition: Serializer.cpp:508
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::SerialIter::skip
void skip(int num)
Definition: Serializer.cpp:352
ripple::range
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:53
ripple::TxResult::validated
bool validated
Definition: Tx.cpp:56
ripple::RPC::Status
Status represents the results of an operation that might fail.
Definition: Status.h:39
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
ripple::Serializer
Definition: Serializer.h:39
ripple::SHAMapTreeNode::makeFromPrefix
static std::shared_ptr< SHAMapTreeNode > makeFromPrefix(Slice rawNode, SHAMapHash const &hash)
Definition: SHAMapTreeNode.cpp:148
ripple::TxArgs
Definition: Tx.cpp:60
ripple::rpcNOT_IMPL
@ rpcNOT_IMPL
Definition: ErrorCodes.h:131
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::doTxPostgres
std::pair< TxResult, RPC::Status > doTxPostgres(RPC::Context &context, TxArgs const &args)
Definition: Tx.cpp:68
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::LedgerMaster::getCloseTimeBySeq
std::optional< NetClock::time_point > getCloseTimeBySeq(LedgerIndex ledgerIndex)
Definition: LedgerMaster.cpp:1671
ripple::doTxHelp
std::pair< TxResult, RPC::Status > doTxHelp(RPC::Context &context, TxArgs const &args)
Definition: Tx.cpp:171
ripple::Transaction::setStatus
void setStatus(TransStatus status, std::uint32_t ledgerSeq)
Definition: Transaction.cpp:63
Json::Value::asUInt
UInt asUInt() const
Definition: json_value.cpp:545
ripple::SerialIter::getVLDataLength
int getVLDataLength()
Definition: Serializer.cpp:470
ripple::doTxJson
Json::Value doTxJson(RPC::JsonContext &)
Definition: Tx.cpp:402
std::get_if
T get_if(T... args)
ripple::TxResult::meta
std::variant< std::shared_ptr< TxMeta >, Blob > meta
Definition: Tx.cpp:55
std::optional
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:38
ripple::TransactionMaster::fetch
std::variant< std::pair< std::shared_ptr< Transaction >, std::shared_ptr< TxMeta > >, TxSearched > fetch(uint256 const &, error_code_i &ec)
Definition: TransactionMaster.cpp:60
std::make_pair
T make_pair(T... args)
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
ripple::NodeStore::Database::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition: Database.cpp:158
ripple::rpcINVALID_LGR_RANGE
@ rpcINVALID_LGR_RANGE
Definition: ErrorCodes.h:136
ripple::ClosedInterval
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition: RangeSet.h:44
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::isValidated
static bool isValidated(LedgerMaster &ledgerMaster, std::uint32_t seq, uint256 const &hash)
Definition: Tx.cpp:41
ripple::Transaction::Locator::getLedgerSequence
uint32_t getLedgerSequence()
Definition: Transaction.h:345
ripple::TxArgs::hash
uint256 hash
Definition: Tx.cpp:62
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
ripple::RPC::Context
The context of information needed to call an RPC.
Definition: Context.h:39
ripple::TxResult::searchedAll
TxSearched searchedAll
Definition: Tx.cpp:57
ripple::Transaction::Locator::isFound
bool isFound()
Definition: Transaction.h:326
ripple::TxSearched::some
@ some
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::TxResult::txn
Transaction::pointer txn
Definition: Tx.cpp:54
std::variant
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
ripple::Application::getMasterTransaction
virtual TransactionMaster & getMasterTransaction()=0
ripple::Transaction::Locator::getLedgerRangeSearched
ClosedInterval< uint32_t > const & getLedgerRangeSearched()
Definition: Transaction.h:354
std::chrono::system_clock::now
T now(T... args)