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  result.meta = meta;
240  result.validated = isValidated(
241  context.ledgerMaster, ledger->info().seq, ledger->info().hash);
242  }
243 
244  return {result, rpcSUCCESS};
245 }
246 
250  TxArgs const& args,
252 {
253  org::xrpl::rpc::v1::GetTransactionResponse response;
254  grpc::Status status = grpc::Status::OK;
255  RPC::Status const& error = res.second;
256  TxResult const& result = res.first;
257  // handle errors
258  if (error.toErrorCode() != rpcSUCCESS)
259  {
260  if (error.toErrorCode() == rpcTXN_NOT_FOUND &&
262  {
263  status = {
264  grpc::StatusCode::NOT_FOUND,
265  "txn not found. searched_all = " +
266  to_string(
267  (result.searchedAll == TxSearched::all ? "true"
268  : "false"))};
269  }
270  else
271  {
272  if (error.toErrorCode() == rpcTXN_NOT_FOUND)
273  status = {grpc::StatusCode::NOT_FOUND, "txn not found"};
274  else
275  status = {grpc::StatusCode::INTERNAL, error.message()};
276  }
277  }
278  // no errors
279  else if (result.txn)
280  {
281  auto& txn = result.txn;
282 
283  std::shared_ptr<STTx const> stTxn = txn->getSTransaction();
284  if (args.binary)
285  {
286  Serializer s = stTxn->getSerializer();
287  response.set_transaction_binary(s.data(), s.size());
288  }
289  else
290  {
291  RPC::convert(*response.mutable_transaction(), stTxn);
292  }
293 
294  response.set_hash(context.params.hash());
295 
296  auto ledgerIndex = txn->getLedger();
297  response.set_ledger_index(ledgerIndex);
298  if (ledgerIndex)
299  {
300  auto ct =
301  context.app.getLedgerMaster().getCloseTimeBySeq(ledgerIndex);
302  if (ct)
303  response.mutable_date()->set_value(
304  ct->time_since_epoch().count());
305  }
306 
307  RPC::convert(
308  *response.mutable_meta()->mutable_transaction_result(),
309  txn->getResult());
310  response.mutable_meta()->mutable_transaction_result()->set_result(
311  transToken(txn->getResult()));
312 
313  // populate binary metadata
314  if (auto blob = std::get_if<Blob>(&result.meta))
315  {
316  assert(args.binary);
317  Slice slice = makeSlice(*blob);
318  response.set_meta_binary(slice.data(), slice.size());
319  }
320  // populate meta data
321  else if (auto m = std::get_if<std::shared_ptr<TxMeta>>(&result.meta))
322  {
323  auto& meta = *m;
324  if (meta)
325  {
326  RPC::convert(*response.mutable_meta(), meta);
327  auto amt =
328  getDeliveredAmount(context, stTxn, *meta, txn->getLedger());
329  if (amt)
330  {
331  RPC::convert(
332  *response.mutable_meta()->mutable_delivered_amount(),
333  *amt);
334  }
335  }
336  }
337  response.set_validated(result.validated);
338  }
339  return {response, status};
340 }
341 
345  TxArgs const& args,
346  RPC::JsonContext const& context)
347 {
348  Json::Value response;
349  RPC::Status const& error = res.second;
350  TxResult const& result = res.first;
351  // handle errors
352  if (error.toErrorCode() != rpcSUCCESS)
353  {
354  if (error.toErrorCode() == rpcTXN_NOT_FOUND &&
356  {
357  response = Json::Value(Json::objectValue);
358  response[jss::searched_all] =
359  (result.searchedAll == TxSearched::all);
360  error.inject(response);
361  }
362  else
363  {
364  error.inject(response);
365  }
366  }
367  // no errors
368  else if (result.txn)
369  {
370  response = result.txn->getJson(JsonOptions::include_date, args.binary);
371 
372  // populate binary metadata
373  if (auto blob = std::get_if<Blob>(&result.meta))
374  {
375  assert(args.binary);
376  response[jss::meta] = strHex(makeSlice(*blob));
377  }
378  // populate meta data
379  else if (auto m = std::get_if<std::shared_ptr<TxMeta>>(&result.meta))
380  {
381  auto& meta = *m;
382  if (meta)
383  {
384  response[jss::meta] = meta->getJson(JsonOptions::none);
385  insertDeliveredAmount(
386  response[jss::meta], context, result.txn, *meta);
387  }
388  }
389  response[jss::validated] = result.validated;
390  }
391  return response;
392 }
393 
396 {
397  if (!context.app.config().useTxTables())
398  return rpcError(rpcNOT_ENABLED);
399 
400  // Deserialize and validate JSON arguments
401 
402  if (!context.params.isMember(jss::transaction))
403  return rpcError(rpcINVALID_PARAMS);
404 
405  TxArgs args;
406 
407  if (!args.hash.parseHex(context.params[jss::transaction].asString()))
408  return rpcError(rpcNOT_IMPL);
409 
410  args.binary = context.params.isMember(jss::binary) &&
411  context.params[jss::binary].asBool();
412 
413  if (context.params.isMember(jss::min_ledger) &&
414  context.params.isMember(jss::max_ledger))
415  {
416  try
417  {
419  context.params[jss::min_ledger].asUInt(),
420  context.params[jss::max_ledger].asUInt());
421  }
422  catch (...)
423  {
424  // One of the calls to `asUInt ()` failed.
426  }
427  }
428 
429  std::pair<TxResult, RPC::Status> res = doTxHelp(context, args);
430  return populateJsonResponse(res, args, context);
431 }
432 
435 {
436  if (!context.app.config().useTxTables())
437  {
438  return {
439  {},
440  {grpc::StatusCode::UNIMPLEMENTED, "Not enabled in configuration."}};
441  }
442 
443  // return values
444  org::xrpl::rpc::v1::GetTransactionResponse response;
445  grpc::Status status = grpc::Status::OK;
446 
447  // input
448  org::xrpl::rpc::v1::GetTransactionRequest& request = context.params;
449 
450  TxArgs args;
451 
452  std::string const& hashBytes = request.hash();
453  args.hash = uint256::fromVoid(hashBytes.data());
454  if (args.hash.size() != hashBytes.size())
455  {
456  grpc::Status errorStatus{
457  grpc::StatusCode::INVALID_ARGUMENT, "ledger hash malformed"};
458  return {response, errorStatus};
459  }
460 
461  args.binary = request.binary();
462 
463  if (request.ledger_range().ledger_index_min() != 0 &&
464  request.ledger_range().ledger_index_max() != 0)
465  {
467  request.ledger_range().ledger_index_min(),
468  request.ledger_range().ledger_index_max());
469  }
470 
471  std::pair<TxResult, RPC::Status> res = doTxHelp(context, args);
472  return populateProtoResponse(res, args, context);
473 }
474 
475 } // namespace ripple
ripple::COMMITTED
@ COMMITTED
Definition: Transaction.h:49
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:291
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
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:331
ripple::LedgerMaster
Definition: LedgerMaster.h:72
ripple::TxSearched
TxSearched
Definition: Transaction.h:56
std::vector< unsigned char >
std::string::size
T size(T... args)
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:578
ripple::Transaction::setLedger
void setLedger(LedgerIndex ledger)
Definition: Transaction.h:134
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:367
ripple::transToken
std::string transToken(TER code)
Definition: TER.cpp:195
ripple::rpcEXCESSIVE_LGR_RANGE
@ rpcEXCESSIVE_LGR_RANGE
Definition: ErrorCodes.h:135
ripple::LedgerInfo::seq
LedgerIndex seq
Definition: ReadView.h:92
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:45
ripple::TxResult
Definition: Tx.cpp:52
ripple::Family::db
virtual NodeStore::Database & db()=0
ripple::SHAMapLeafNode
Definition: SHAMapLeafNode.h:32
ripple::SHAMapHash
Definition: SHAMapTreeNode.h:47
ripple::base_uint::size
constexpr static std::size_t size()
Definition: base_uint.h:426
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:73
ripple::Ledger::info
LedgerInfo const & info() const override
Returns information about the ledger.
Definition: Ledger.h:149
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:267
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::Transaction::Locator
Definition: Transaction.h:310
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:388
ripple::Transaction::getLedger
LedgerIndex getLedger() const
Definition: Transaction.h:95
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:273
ripple::doTxGrpc
std::pair< org::xrpl::rpc::v1::GetTransactionResponse, grpc::Status > doTxGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetTransactionRequest > &context)
Definition: Tx.cpp:434
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:133
ripple::LedgerMaster::getLedgerBySeq
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
Definition: LedgerMaster.cpp:1740
ripple::rpcNOT_ENABLED
@ rpcNOT_ENABLED
Definition: ErrorCodes.h:59
ripple::SerialIter
Definition: Serializer.h:308
ripple::SerialIter::getVL
Blob getVL()
Definition: Serializer.cpp:500
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:344
ripple::NodeStore::Database::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous)
Fetch a node object.
Definition: Database.cpp:145
ripple::range
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:53
ripple::rpcError
Json::Value rpcError(int iError, Json::Value jvResult)
Definition: RPCErr.cpp:29
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:151
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:701
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::base_uint::parseHex
bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:384
ripple::doTxHelp
std::pair< TxResult, RPC::Status > doTxHelp(RPC::Context &context, TxArgs const &args)
Definition: Tx.cpp:171
ripple::LedgerMaster::getCloseTimeBySeq
boost::optional< NetClock::time_point > getCloseTimeBySeq(LedgerIndex ledgerIndex)
Definition: LedgerMaster.cpp:1635
ripple::Transaction::setStatus
void setStatus(TransStatus status, std::uint32_t ledgerSeq)
Definition: Transaction.cpp:61
ripple::base_uint< 256 >::fromVoid
static base_uint fromVoid(void const *data)
Definition: base_uint.h:223
Json::Value::asUInt
UInt asUInt() const
Definition: json_value.cpp:545
ripple::SerialIter::getVLDataLength
int getVLDataLength()
Definition: Serializer.cpp:462
ripple::doTxJson
Json::Value doTxJson(RPC::JsonContext &)
Definition: Tx.cpp:395
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::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::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::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:340
ripple::TxArgs::hash
uint256 hash
Definition: Tx.cpp:62
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
std::string::data
T data(T... args)
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:321
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:349
std::chrono::system_clock::now
T now(T... args)