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 if (context.params.isMember(jss::did))
592  {
593  expectedType = ltDID;
594  auto const account =
595  parseBase58<AccountID>(context.params[jss::did].asString());
596  if (!account || account->isZero())
597  jvResult[jss::error] = "malformedAddress";
598  else
599  uNodeIndex = keylet::did(*account).key;
600  }
601  else
602  {
603  if (context.params.isMember("params") &&
604  context.params["params"].isArray() &&
605  context.params["params"].size() == 1 &&
606  context.params["params"][0u].isString())
607  {
608  if (!uNodeIndex.parseHex(
609  context.params["params"][0u].asString()))
610  {
611  uNodeIndex = beast::zero;
612  jvResult[jss::error] = "malformedRequest";
613  }
614  }
615  else
616  {
617  if (context.apiVersion < 2u)
618  jvResult[jss::error] = "unknownOption";
619  else
620  jvResult[jss::error] = "invalidParams";
621  }
622  }
623  }
624  catch (Json::error& e)
625  {
626  if (context.apiVersion > 1u)
627  {
628  // For apiVersion 2 onwards, any parsing failures that throw
629  // this
630  // exception return an invalidParam error.
631  uNodeIndex = beast::zero;
632  jvResult[jss::error] = "invalidParams";
633  }
634  else
635  throw;
636  }
637 
638  if (uNodeIndex.isNonZero())
639  {
640  auto const sleNode = lpLedger->read(keylet::unchecked(uNodeIndex));
641  if (context.params.isMember(jss::binary))
642  bNodeBinary = context.params[jss::binary].asBool();
643 
644  if (!sleNode)
645  {
646  // Not found.
647  jvResult[jss::error] = "entryNotFound";
648  }
649  else if (
650  (expectedType != ltANY) && (expectedType != sleNode->getType()))
651  {
652  jvResult[jss::error] = "unexpectedLedgerType";
653  }
654  else if (bNodeBinary)
655  {
656  Serializer s;
657 
658  sleNode->add(s);
659 
660  jvResult[jss::node_binary] = strHex(s.peekData());
661  jvResult[jss::index] = to_string(uNodeIndex);
662  }
663  else
664  {
665  jvResult[jss::node] = sleNode->getJson(JsonOptions::none);
666  jvResult[jss::index] = to_string(uNodeIndex);
667  }
668  }
669 
670  return jvResult;
671 }
672 
676 {
677  org::xrpl::rpc::v1::GetLedgerEntryRequest& request = context.params;
678  org::xrpl::rpc::v1::GetLedgerEntryResponse response;
679  grpc::Status status = grpc::Status::OK;
680 
682  if (auto status = RPC::ledgerFromRequest(ledger, context))
683  {
684  grpc::Status errorStatus;
685  if (status.toErrorCode() == rpcINVALID_PARAMS)
686  {
687  errorStatus = grpc::Status(
688  grpc::StatusCode::INVALID_ARGUMENT, status.message());
689  }
690  else
691  {
692  errorStatus =
693  grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
694  }
695  return {response, errorStatus};
696  }
697 
698  auto key = uint256::fromVoidChecked(request.key());
699  if (!key)
700  {
701  grpc::Status errorStatus{
702  grpc::StatusCode::INVALID_ARGUMENT, "index malformed"};
703  return {response, errorStatus};
704  }
705 
706  auto const sleNode = ledger->read(keylet::unchecked(*key));
707  if (!sleNode)
708  {
709  grpc::Status errorStatus{
710  grpc::StatusCode::NOT_FOUND, "object not found"};
711  return {response, errorStatus};
712  }
713  else
714  {
715  Serializer s;
716  sleNode->add(s);
717 
718  auto& stateObject = *response.mutable_ledger_object();
719  stateObject.set_data(s.peekData().data(), s.getLength());
720  stateObject.set_key(request.key());
721  *(response.mutable_ledger()) = request.ledger();
722  return {response, status};
723  }
724 }
725 } // 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:312
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:207
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:383
ripple::keylet::offer
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition: Indexes.cpp:231
ripple::keylet::did
Keylet did(AccountID const &account) noexcept
Definition: Indexes.cpp:442
ripple::keylet::xChainClaimID
Keylet xChainClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition: Indexes.cpp:414
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:124
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:327
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:142
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:674
ripple::ltDID
@ ltDID
The ledger object which tracks the DID.
Definition: LedgerFormats.h:193
ripple::JsonOptions::none
@ none
ripple::keylet::bridge
Keylet bridge(STXChainBridge const &bridge, STXChainBridge::ChainType chainType)
Definition: Indexes.cpp:401
ripple::keylet::page
Keylet page(uint256 const &key, std::uint64_t index) noexcept
A page in a directory.
Definition: Indexes.cpp:318
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:202
ripple::keylet::unchecked
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition: Indexes.cpp:306
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:428
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:296
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