rippled
LedgerEntry.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/main/Application.h>
21 #include <ripple/basics/StringUtilities.h>
22 #include <ripple/basics/strHex.h>
23 #include <ripple/json/json_errors.h>
24 #include <ripple/ledger/ReadView.h>
25 #include <ripple/net/RPCErr.h>
26 #include <ripple/protocol/ErrorCodes.h>
27 #include <ripple/protocol/Indexes.h>
28 #include <ripple/protocol/STXChainBridge.h>
29 #include <ripple/protocol/jss.h>
30 #include <ripple/rpc/Context.h>
31 #include <ripple/rpc/GRPCHandlers.h>
32 #include <ripple/rpc/impl/RPCHelpers.h>
33 
34 namespace ripple {
35 
36 // {
37 // ledger_hash : <ledger>
38 // ledger_index : <ledger_index>
39 // ...
40 // }
43 {
45  auto jvResult = RPC::lookupLedger(lpLedger, context);
46 
47  if (!lpLedger)
48  return jvResult;
49 
50  uint256 uNodeIndex;
51  bool bNodeBinary = false;
52  LedgerEntryType expectedType = ltANY;
53 
54  try
55  {
56  if (context.params.isMember(jss::index))
57  {
58  if (!uNodeIndex.parseHex(context.params[jss::index].asString()))
59  {
60  uNodeIndex = beast::zero;
61  jvResult[jss::error] = "malformedRequest";
62  }
63  }
64  else if (context.params.isMember(jss::account_root))
65  {
66  expectedType = ltACCOUNT_ROOT;
67  auto const account = parseBase58<AccountID>(
68  context.params[jss::account_root].asString());
69  if (!account || account->isZero())
70  jvResult[jss::error] = "malformedAddress";
71  else
72  uNodeIndex = keylet::account(*account).key;
73  }
74  else if (context.params.isMember(jss::check))
75  {
76  expectedType = ltCHECK;
77  if (!uNodeIndex.parseHex(context.params[jss::check].asString()))
78  {
79  uNodeIndex = beast::zero;
80  jvResult[jss::error] = "malformedRequest";
81  }
82  }
83  else if (context.params.isMember(jss::deposit_preauth))
84  {
85  expectedType = ltDEPOSIT_PREAUTH;
86 
87  if (!context.params[jss::deposit_preauth].isObject())
88  {
89  if (!context.params[jss::deposit_preauth].isString() ||
90  !uNodeIndex.parseHex(
91  context.params[jss::deposit_preauth].asString()))
92  {
93  uNodeIndex = beast::zero;
94  jvResult[jss::error] = "malformedRequest";
95  }
96  }
97  else if (
98  !context.params[jss::deposit_preauth].isMember(jss::owner) ||
99  !context.params[jss::deposit_preauth][jss::owner].isString() ||
100  !context.params[jss::deposit_preauth].isMember(
101  jss::authorized) ||
102  !context.params[jss::deposit_preauth][jss::authorized]
103  .isString())
104  {
105  jvResult[jss::error] = "malformedRequest";
106  }
107  else
108  {
109  auto const owner = parseBase58<AccountID>(
110  context.params[jss::deposit_preauth][jss::owner]
111  .asString());
112 
113  auto const authorized = parseBase58<AccountID>(
114  context.params[jss::deposit_preauth][jss::authorized]
115  .asString());
116 
117  if (!owner)
118  jvResult[jss::error] = "malformedOwner";
119  else if (!authorized)
120  jvResult[jss::error] = "malformedAuthorized";
121  else
122  uNodeIndex =
124  }
125  }
126  else if (context.params.isMember(jss::directory))
127  {
128  expectedType = ltDIR_NODE;
129  if (context.params[jss::directory].isNull())
130  {
131  jvResult[jss::error] = "malformedRequest";
132  }
133  else if (!context.params[jss::directory].isObject())
134  {
135  if (!uNodeIndex.parseHex(
136  context.params[jss::directory].asString()))
137  {
138  uNodeIndex = beast::zero;
139  jvResult[jss::error] = "malformedRequest";
140  }
141  }
142  else if (
143  context.params[jss::directory].isMember(jss::sub_index) &&
144  !context.params[jss::directory][jss::sub_index].isIntegral())
145  {
146  jvResult[jss::error] = "malformedRequest";
147  }
148  else
149  {
150  std::uint64_t uSubIndex =
151  context.params[jss::directory].isMember(jss::sub_index)
152  ? context.params[jss::directory][jss::sub_index].asUInt()
153  : 0;
154 
155  if (context.params[jss::directory].isMember(jss::dir_root))
156  {
157  uint256 uDirRoot;
158 
159  if (context.params[jss::directory].isMember(jss::owner))
160  {
161  // May not specify both dir_root and owner.
162  jvResult[jss::error] = "malformedRequest";
163  }
164  else if (!uDirRoot.parseHex(
165  context.params[jss::directory][jss::dir_root]
166  .asString()))
167  {
168  uNodeIndex = beast::zero;
169  jvResult[jss::error] = "malformedRequest";
170  }
171  else
172  {
173  uNodeIndex = keylet::page(uDirRoot, uSubIndex).key;
174  }
175  }
176  else if (context.params[jss::directory].isMember(jss::owner))
177  {
178  auto const ownerID = parseBase58<AccountID>(
179  context.params[jss::directory][jss::owner].asString());
180 
181  if (!ownerID)
182  {
183  jvResult[jss::error] = "malformedAddress";
184  }
185  else
186  {
187  uNodeIndex =
188  keylet::page(keylet::ownerDir(*ownerID), uSubIndex)
189  .key;
190  }
191  }
192  else
193  {
194  jvResult[jss::error] = "malformedRequest";
195  }
196  }
197  }
198  else if (context.params.isMember(jss::escrow))
199  {
200  expectedType = ltESCROW;
201  if (!context.params[jss::escrow].isObject())
202  {
203  if (!uNodeIndex.parseHex(
204  context.params[jss::escrow].asString()))
205  {
206  uNodeIndex = beast::zero;
207  jvResult[jss::error] = "malformedRequest";
208  }
209  }
210  else if (
211  !context.params[jss::escrow].isMember(jss::owner) ||
212  !context.params[jss::escrow].isMember(jss::seq) ||
213  !context.params[jss::escrow][jss::seq].isIntegral())
214  {
215  jvResult[jss::error] = "malformedRequest";
216  }
217  else
218  {
219  auto const id = parseBase58<AccountID>(
220  context.params[jss::escrow][jss::owner].asString());
221  if (!id)
222  jvResult[jss::error] = "malformedOwner";
223  else
224  uNodeIndex =
226  *id, context.params[jss::escrow][jss::seq].asUInt())
227  .key;
228  }
229  }
230  else if (context.params.isMember(jss::offer))
231  {
232  expectedType = ltOFFER;
233  if (!context.params[jss::offer].isObject())
234  {
235  if (!uNodeIndex.parseHex(context.params[jss::offer].asString()))
236  {
237  uNodeIndex = beast::zero;
238  jvResult[jss::error] = "malformedRequest";
239  }
240  }
241  else if (
242  !context.params[jss::offer].isMember(jss::account) ||
243  !context.params[jss::offer].isMember(jss::seq) ||
244  !context.params[jss::offer][jss::seq].isIntegral())
245  {
246  jvResult[jss::error] = "malformedRequest";
247  }
248  else
249  {
250  auto const id = parseBase58<AccountID>(
251  context.params[jss::offer][jss::account].asString());
252  if (!id)
253  jvResult[jss::error] = "malformedAddress";
254  else
255  uNodeIndex =
257  *id, context.params[jss::offer][jss::seq].asUInt())
258  .key;
259  }
260  }
261  else if (context.params.isMember(jss::payment_channel))
262  {
263  expectedType = ltPAYCHAN;
264 
265  if (!uNodeIndex.parseHex(
266  context.params[jss::payment_channel].asString()))
267  {
268  uNodeIndex = beast::zero;
269  jvResult[jss::error] = "malformedRequest";
270  }
271  }
272  else if (context.params.isMember(jss::ripple_state))
273  {
274  expectedType = ltRIPPLE_STATE;
275  Currency uCurrency;
276  Json::Value jvRippleState = context.params[jss::ripple_state];
277 
278  if (!jvRippleState.isObject() ||
279  !jvRippleState.isMember(jss::currency) ||
280  !jvRippleState.isMember(jss::accounts) ||
281  !jvRippleState[jss::accounts].isArray() ||
282  2 != jvRippleState[jss::accounts].size() ||
283  !jvRippleState[jss::accounts][0u].isString() ||
284  !jvRippleState[jss::accounts][1u].isString() ||
285  (jvRippleState[jss::accounts][0u].asString() ==
286  jvRippleState[jss::accounts][1u].asString()))
287  {
288  jvResult[jss::error] = "malformedRequest";
289  }
290  else
291  {
292  auto const id1 = parseBase58<AccountID>(
293  jvRippleState[jss::accounts][0u].asString());
294  auto const id2 = parseBase58<AccountID>(
295  jvRippleState[jss::accounts][1u].asString());
296  if (!id1 || !id2)
297  {
298  jvResult[jss::error] = "malformedAddress";
299  }
300  else if (!to_currency(
301  uCurrency,
302  jvRippleState[jss::currency].asString()))
303  {
304  jvResult[jss::error] = "malformedCurrency";
305  }
306  else
307  {
308  uNodeIndex = keylet::line(*id1, *id2, uCurrency).key;
309  }
310  }
311  }
312  else if (context.params.isMember(jss::ticket))
313  {
314  expectedType = ltTICKET;
315  if (!context.params[jss::ticket].isObject())
316  {
317  if (!uNodeIndex.parseHex(
318  context.params[jss::ticket].asString()))
319  {
320  uNodeIndex = beast::zero;
321  jvResult[jss::error] = "malformedRequest";
322  }
323  }
324  else if (
325  !context.params[jss::ticket].isMember(jss::account) ||
326  !context.params[jss::ticket].isMember(jss::ticket_seq) ||
327  !context.params[jss::ticket][jss::ticket_seq].isIntegral())
328  {
329  jvResult[jss::error] = "malformedRequest";
330  }
331  else
332  {
333  auto const id = parseBase58<AccountID>(
334  context.params[jss::ticket][jss::account].asString());
335  if (!id)
336  jvResult[jss::error] = "malformedAddress";
337  else
338  uNodeIndex = getTicketIndex(
339  *id,
340  context.params[jss::ticket][jss::ticket_seq].asUInt());
341  }
342  }
343  else if (context.params.isMember(jss::nft_page))
344  {
345  expectedType = ltNFTOKEN_PAGE;
346 
347  if (context.params[jss::nft_page].isString())
348  {
349  if (!uNodeIndex.parseHex(
350  context.params[jss::nft_page].asString()))
351  {
352  uNodeIndex = beast::zero;
353  jvResult[jss::error] = "malformedRequest";
354  }
355  }
356  else
357  {
358  jvResult[jss::error] = "malformedRequest";
359  }
360  }
361  else if (context.params.isMember(jss::amm))
362  {
363  expectedType = ltAMM;
364  if (!context.params[jss::amm].isObject())
365  {
366  if (!uNodeIndex.parseHex(context.params[jss::amm].asString()))
367  {
368  uNodeIndex = beast::zero;
369  jvResult[jss::error] = "malformedRequest";
370  }
371  }
372  else if (
373  !context.params[jss::amm].isMember(jss::asset) ||
374  !context.params[jss::amm].isMember(jss::asset2))
375  {
376  jvResult[jss::error] = "malformedRequest";
377  }
378  else
379  {
380  try
381  {
382  auto const issue =
383  issueFromJson(context.params[jss::amm][jss::asset]);
384  auto const issue2 =
385  issueFromJson(context.params[jss::amm][jss::asset2]);
386  uNodeIndex = keylet::amm(issue, issue2).key;
387  }
388  catch (std::runtime_error const&)
389  {
390  jvResult[jss::error] = "malformedRequest";
391  }
392  }
393  }
394  else if (context.params.isMember(jss::bridge))
395  {
396  expectedType = ltBRIDGE;
397 
398  // return the keylet for the specified bridge or nullopt if the
399  // request is malformed
400  auto const maybeKeylet = [&]() -> std::optional<Keylet> {
401  try
402  {
403  if (!context.params.isMember(jss::bridge_account))
404  return std::nullopt;
405 
406  auto const& jsBridgeAccount =
407  context.params[jss::bridge_account];
408  if (!jsBridgeAccount.isString())
409  {
410  return std::nullopt;
411  }
412  auto const account =
413  parseBase58<AccountID>(jsBridgeAccount.asString());
414  if (!account || account->isZero())
415  {
416  return std::nullopt;
417  }
418 
419  // This may throw and is the reason for the `try` block. The
420  // try block has a larger scope so the `bridge` variable
421  // doesn't need to be an optional.
422  STXChainBridge const bridge(context.params[jss::bridge]);
423  STXChainBridge::ChainType const chainType =
425  account == bridge.lockingChainDoor());
426  if (account != bridge.door(chainType))
427  return std::nullopt;
428 
429  return keylet::bridge(bridge, chainType);
430  }
431  catch (...)
432  {
433  return std::nullopt;
434  }
435  }();
436 
437  if (maybeKeylet)
438  {
439  uNodeIndex = maybeKeylet->key;
440  }
441  else
442  {
443  uNodeIndex = beast::zero;
444  jvResult[jss::error] = "malformedRequest";
445  }
446  }
447  else if (context.params.isMember(jss::xchain_owned_claim_id))
448  {
449  expectedType = ltXCHAIN_OWNED_CLAIM_ID;
450  auto& claim_id = context.params[jss::xchain_owned_claim_id];
451  if (claim_id.isString())
452  {
453  // we accept a node id as specifier of a xchain claim id
454  if (!uNodeIndex.parseHex(claim_id.asString()))
455  {
456  uNodeIndex = beast::zero;
457  jvResult[jss::error] = "malformedRequest";
458  }
459  }
460  else if (
461  !claim_id.isObject() ||
462  !(claim_id.isMember(sfIssuingChainDoor.getJsonName()) &&
463  claim_id[sfIssuingChainDoor.getJsonName()].isString()) ||
464  !(claim_id.isMember(sfLockingChainDoor.getJsonName()) &&
465  claim_id[sfLockingChainDoor.getJsonName()].isString()) ||
466  !claim_id.isMember(sfIssuingChainIssue.getJsonName()) ||
467  !claim_id.isMember(sfLockingChainIssue.getJsonName()) ||
468  !claim_id.isMember(jss::xchain_owned_claim_id))
469  {
470  jvResult[jss::error] = "malformedRequest";
471  }
472  else
473  {
474  // if not specified with a node id, a claim_id is specified by
475  // four strings defining the bridge (locking_chain_door,
476  // locking_chain_issue, issuing_chain_door, issuing_chain_issue)
477  // and the claim id sequence number.
478  auto lockingChainDoor = parseBase58<AccountID>(
479  claim_id[sfLockingChainDoor.getJsonName()].asString());
480  auto issuingChainDoor = parseBase58<AccountID>(
481  claim_id[sfIssuingChainDoor.getJsonName()].asString());
482  Issue lockingChainIssue, issuingChainIssue;
483  bool valid = lockingChainDoor && issuingChainDoor;
484  if (valid)
485  {
486  try
487  {
488  lockingChainIssue = issueFromJson(
489  claim_id[sfLockingChainIssue.getJsonName()]);
490  issuingChainIssue = issueFromJson(
491  claim_id[sfIssuingChainIssue.getJsonName()]);
492  }
493  catch (std::runtime_error const& ex)
494  {
495  valid = false;
496  jvResult[jss::error] = "malformedRequest";
497  }
498  }
499 
500  if (valid && claim_id[jss::xchain_owned_claim_id].isIntegral())
501  {
502  auto seq = claim_id[jss::xchain_owned_claim_id].asUInt();
503 
504  STXChainBridge bridge_spec(
505  *lockingChainDoor,
506  lockingChainIssue,
507  *issuingChainDoor,
508  issuingChainIssue);
509  Keylet keylet = keylet::xChainClaimID(bridge_spec, seq);
510  uNodeIndex = keylet.key;
511  }
512  }
513  }
514  else if (context.params.isMember(
515  jss::xchain_owned_create_account_claim_id))
516  {
517  // see object definition in LedgerFormats.cpp
519  auto& claim_id =
520  context.params[jss::xchain_owned_create_account_claim_id];
521  if (claim_id.isString())
522  {
523  // we accept a node id as specifier of a xchain create account
524  // claim_id
525  if (!uNodeIndex.parseHex(claim_id.asString()))
526  {
527  uNodeIndex = beast::zero;
528  jvResult[jss::error] = "malformedRequest";
529  }
530  }
531  else if (
532  !claim_id.isObject() ||
533  !(claim_id.isMember(sfIssuingChainDoor.getJsonName()) &&
534  claim_id[sfIssuingChainDoor.getJsonName()].isString()) ||
535  !(claim_id.isMember(sfLockingChainDoor.getJsonName()) &&
536  claim_id[sfLockingChainDoor.getJsonName()].isString()) ||
537  !claim_id.isMember(sfIssuingChainIssue.getJsonName()) ||
538  !claim_id.isMember(sfLockingChainIssue.getJsonName()) ||
539  !claim_id.isMember(jss::xchain_owned_create_account_claim_id))
540  {
541  jvResult[jss::error] = "malformedRequest";
542  }
543  else
544  {
545  // if not specified with a node id, a create account claim_id is
546  // specified by four strings defining the bridge
547  // (locking_chain_door, locking_chain_issue, issuing_chain_door,
548  // issuing_chain_issue) and the create account claim id sequence
549  // number.
550  auto lockingChainDoor = parseBase58<AccountID>(
551  claim_id[sfLockingChainDoor.getJsonName()].asString());
552  auto issuingChainDoor = parseBase58<AccountID>(
553  claim_id[sfIssuingChainDoor.getJsonName()].asString());
554  Issue lockingChainIssue, issuingChainIssue;
555  bool valid = lockingChainDoor && issuingChainDoor;
556  if (valid)
557  {
558  try
559  {
560  lockingChainIssue = issueFromJson(
561  claim_id[sfLockingChainIssue.getJsonName()]);
562  issuingChainIssue = issueFromJson(
563  claim_id[sfIssuingChainIssue.getJsonName()]);
564  }
565  catch (std::runtime_error const& ex)
566  {
567  valid = false;
568  jvResult[jss::error] = "malformedRequest";
569  }
570  }
571 
572  if (valid &&
573  claim_id[jss::xchain_owned_create_account_claim_id]
574  .isIntegral())
575  {
576  auto seq =
577  claim_id[jss::xchain_owned_create_account_claim_id]
578  .asUInt();
579 
580  STXChainBridge bridge_spec(
581  *lockingChainDoor,
582  lockingChainIssue,
583  *issuingChainDoor,
584  issuingChainIssue);
585  Keylet keylet =
586  keylet::xChainCreateAccountClaimID(bridge_spec, seq);
587  uNodeIndex = keylet.key;
588  }
589  }
590  }
591  else
592  {
593  if (context.params.isMember("params") &&
594  context.params["params"].isArray() &&
595  context.params["params"].size() == 1 &&
596  context.params["params"][0u].isString())
597  {
598  if (!uNodeIndex.parseHex(
599  context.params["params"][0u].asString()))
600  {
601  uNodeIndex = beast::zero;
602  jvResult[jss::error] = "malformedRequest";
603  }
604  }
605  else
606  {
607  if (context.apiVersion < 2u)
608  jvResult[jss::error] = "unknownOption";
609  else
610  jvResult[jss::error] = "invalidParams";
611  }
612  }
613  }
614  catch (Json::error& e)
615  {
616  if (context.apiVersion > 1u)
617  {
618  // For apiVersion 2 onwards, any parsing failures that throw
619  // this
620  // exception return an invalidParam error.
621  uNodeIndex = beast::zero;
622  jvResult[jss::error] = "invalidParams";
623  }
624  else
625  throw;
626  }
627 
628  if (uNodeIndex.isNonZero())
629  {
630  auto const sleNode = lpLedger->read(keylet::unchecked(uNodeIndex));
631  if (context.params.isMember(jss::binary))
632  bNodeBinary = context.params[jss::binary].asBool();
633 
634  if (!sleNode)
635  {
636  // Not found.
637  jvResult[jss::error] = "entryNotFound";
638  }
639  else if (
640  (expectedType != ltANY) && (expectedType != sleNode->getType()))
641  {
642  jvResult[jss::error] = "unexpectedLedgerType";
643  }
644  else if (bNodeBinary)
645  {
646  Serializer s;
647 
648  sleNode->add(s);
649 
650  jvResult[jss::node_binary] = strHex(s.peekData());
651  jvResult[jss::index] = to_string(uNodeIndex);
652  }
653  else
654  {
655  jvResult[jss::node] = sleNode->getJson(JsonOptions::none);
656  jvResult[jss::index] = to_string(uNodeIndex);
657  }
658  }
659 
660  return jvResult;
661 }
662 
666 {
667  org::xrpl::rpc::v1::GetLedgerEntryRequest& request = context.params;
668  org::xrpl::rpc::v1::GetLedgerEntryResponse response;
669  grpc::Status status = grpc::Status::OK;
670 
672  if (auto status = RPC::ledgerFromRequest(ledger, context))
673  {
674  grpc::Status errorStatus;
675  if (status.toErrorCode() == rpcINVALID_PARAMS)
676  {
677  errorStatus = grpc::Status(
678  grpc::StatusCode::INVALID_ARGUMENT, status.message());
679  }
680  else
681  {
682  errorStatus =
683  grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
684  }
685  return {response, errorStatus};
686  }
687 
688  auto key = uint256::fromVoidChecked(request.key());
689  if (!key)
690  {
691  grpc::Status errorStatus{
692  grpc::StatusCode::INVALID_ARGUMENT, "index malformed"};
693  return {response, errorStatus};
694  }
695 
696  auto const sleNode = ledger->read(keylet::unchecked(*key));
697  if (!sleNode)
698  {
699  grpc::Status errorStatus{
700  grpc::StatusCode::NOT_FOUND, "object not found"};
701  return {response, errorStatus};
702  }
703  else
704  {
705  Serializer s;
706  sleNode->add(s);
707 
708  auto& stateObject = *response.mutable_ledger_object();
709  stateObject.set_data(s.peekData().data(), s.getLength());
710  stateObject.set_key(request.key());
711  *(response.mutable_ledger()) = request.ledger();
712  return {response, status};
713  }
714 }
715 } // namespace ripple
Json::error
Definition: json_errors.h:27
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:311
ripple::to_currency
bool to_currency(Currency &currency, std::string const &code)
Tries to convert a string to a Currency, returns true on success.
Definition: UintTypes.cpp:80
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::ltTICKET
@ ltTICKET
A ledger object which describes a ticket.
Definition: LedgerFormats.h:80
ripple::doLedgerEntry
Json::Value doLedgerEntry(RPC::JsonContext &)
Definition: LedgerEntry.cpp:42
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::Issue
A currency issued by an account.
Definition: Issue.h:35
Json::Value::isObject
bool isObject() const
Definition: json_value.cpp:1027
ripple::STXChainBridge::srcChain
static ChainType srcChain(bool wasLockingChainSend)
Definition: STXChainBridge.h:218
std::shared_ptr
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
Json::Value::isString
bool isString() const
Definition: json_value.cpp:1009
ripple::ltANY
@ ltANY
A special type, matching any ledger entry type.
Definition: LedgerFormats.h:201
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:537
ripple::STXChainBridge::ChainType
ChainType
Definition: STXChainBridge.h:42
ripple::sfLockingChainDoor
const SF_ACCOUNT sfLockingChainDoor
std::pair
ripple::keylet::amm
Keylet amm(Issue const &issue1, Issue const &issue2) noexcept
AMM entry.
Definition: Indexes.cpp:382
ripple::keylet::offer
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition: Indexes.cpp:230
ripple::keylet::xChainClaimID
Keylet xChainClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition: Indexes.cpp:413
Json::Value::isNull
bool isNull() const
isNull() tests to see if this field is null.
Definition: json_value.cpp:967
ripple::ltCHECK
@ ltCHECK
A ledger object which describes a check.
Definition: LedgerFormats.h:155
ripple::SField::getJsonName
Json::StaticString const & getJsonName() const
Definition: SField.h:192
ripple::base_uint< 256 >::fromVoidChecked
static std::optional< base_uint > fromVoidChecked(T const &from)
Definition: base_uint.h:319
ripple::RPC::lookupLedger
Status lookupLedger(std::shared_ptr< ReadView const > &ledger, JsonContext &context, Json::Value &result)
Look up a ledger from a request and fill a Json::Result with the data representing a ledger.
Definition: RPCHelpers.cpp:676
ripple::getTicketIndex
uint256 getTicketIndex(AccountID const &account, std::uint32_t ticketSeq)
Definition: Indexes.cpp:123
ripple::ltDIR_NODE
@ ltDIR_NODE
A ledger object which contains a list of object identifiers.
Definition: LedgerFormats.h:66
Json::Value::asBool
bool asBool() const
Definition: json_value.cpp:619
ripple::Keylet::key
uint256 key
Definition: Keylet.h:40
ripple::base_uint< 256 >
ripple::keylet::escrow
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Definition: Indexes.cpp:326
ripple::ltOFFER
@ ltOFFER
A ledger object which describes an offer on the DEX.
Definition: LedgerFormats.h:92
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:532
ripple::authorized
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
Definition: ServerHandler.cpp:85
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:141
ripple::sfLockingChainIssue
const SF_ISSUE sfLockingChainIssue
ripple::ltESCROW
@ ltESCROW
A ledger object describing a single escrow.
Definition: LedgerFormats.h:143
ripple::doLedgerEntryGrpc
std::pair< org::xrpl::rpc::v1::GetLedgerEntryResponse, grpc::Status > doLedgerEntryGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerEntryRequest > &context)
Definition: LedgerEntry.cpp:664
ripple::JsonOptions::none
@ none
ripple::keylet::bridge
Keylet bridge(STXChainBridge const &bridge, STXChainBridge::ChainType chainType)
Definition: Indexes.cpp:400
ripple::keylet::page
Keylet page(uint256 const &key, std::uint64_t index) noexcept
A page in a directory.
Definition: Indexes.cpp:317
ripple::RPC::GRPCContext
Definition: Context.h:70
ripple::ltDEPOSIT_PREAUTH
@ ltDEPOSIT_PREAUTH
A ledger object which describes a deposit preauthorization.
Definition: LedgerFormats.h:161
Json::Value::size
UInt size() const
Number of values in array or object.
Definition: json_value.cpp:706
std::runtime_error
STL class.
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::uint64_t
ripple::issueFromJson
Issue issueFromJson(Json::Value const &v)
Definition: Issue.cpp:78
ripple::keylet::line
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition: Indexes.cpp:201
ripple::keylet::unchecked
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition: Indexes.cpp:305
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::STXChainBridge
Definition: STXChainBridge.h:32
Json::Value::isArray
bool isArray() const
Definition: json_value.cpp:1015
ripple::Serializer
Definition: Serializer.h:40
ripple::RPC::GRPCContext::params
RequestType params
Definition: Context.h:72
ripple::ltNFTOKEN_PAGE
@ ltNFTOKEN_PAGE
A ledger object which contains a list of NFTs.
Definition: LedgerFormats.h:175
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID
@ ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID
A claim id for a cross chain create account transaction.
Definition: LedgerFormats.h:129
ripple::LedgerEntryType
LedgerEntryType
Identifiers for on-ledger objects.
Definition: LedgerFormats.h:53
ripple::ltBRIDGE
@ ltBRIDGE
The ledger object which lists details about sidechains.
Definition: LedgerFormats.h:99
ripple::ltACCOUNT_ROOT
@ ltACCOUNT_ROOT
A ledger object which describes an account.
Definition: LedgerFormats.h:59
ripple::Serializer::peekData
Blob const & peekData() const
Definition: Serializer.h:169
Json::Value::asUInt
UInt asUInt() const
Definition: json_value.cpp:545
Json::Value::isIntegral
bool isIntegral() const
Definition: json_value.cpp:991
ripple::RPC::Context::apiVersion
unsigned int apiVersion
Definition: Context.h:50
ripple::keylet::xChainCreateAccountClaimID
Keylet xChainCreateAccountClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition: Indexes.cpp:427
ripple::ltXCHAIN_OWNED_CLAIM_ID
@ ltXCHAIN_OWNED_CLAIM_ID
A claim id for a cross chain transaction.
Definition: LedgerFormats.h:123
std::optional
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:41
ripple::sfIssuingChainDoor
const SF_ACCOUNT sfIssuingChainDoor
ripple::ltRIPPLE_STATE
@ ltRIPPLE_STATE
A ledger object which describes a bidirectional trust line.
Definition: LedgerFormats.h:74
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
ripple::base_uint::parseHex
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:496
ripple::Serializer::getLength
int getLength() const
Definition: Serializer.h:200
ripple::sfIssuingChainIssue
const SF_ISSUE sfIssuingChainIssue
ripple::keylet::depositPreauth
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition: Indexes.cpp:295
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
std::vector::data
T data(T... args)
ripple::RPC::ledgerFromRequest
Status ledgerFromRequest(T &ledger, GRPCContext< R > &context)
Definition: RPCHelpers.cpp:395
ripple::ltAMM
@ ltAMM
The ledger object which tracks the AMM.
Definition: LedgerFormats.h:187
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::ltPAYCHAN
@ ltPAYCHAN
A ledger object describing a single unidirectional XRP payment channel.
Definition: LedgerFormats.h:149
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469