rippled
Loading...
Searching...
No Matches
LedgerEntry.cpp
1#include <xrpld/rpc/Context.h>
2#include <xrpld/rpc/GRPCHandlers.h>
3#include <xrpld/rpc/detail/RPCHelpers.h>
4#include <xrpld/rpc/handlers/LedgerEntryHelpers.h>
5
6#include <xrpl/basics/StringUtilities.h>
7#include <xrpl/basics/strHex.h>
8#include <xrpl/beast/core/LexicalCast.h>
9#include <xrpl/json/json_errors.h>
10#include <xrpl/ledger/CredentialHelpers.h>
11#include <xrpl/ledger/ReadView.h>
12#include <xrpl/protocol/ErrorCodes.h>
13#include <xrpl/protocol/Indexes.h>
14#include <xrpl/protocol/LedgerFormats.h>
15#include <xrpl/protocol/RPCErr.h>
16#include <xrpl/protocol/STXChainBridge.h>
17#include <xrpl/protocol/jss.h>
18
19#include <functional>
20
21namespace ripple {
22
23static Expected<uint256, Json::Value>
25 Json::Value const& params,
26 Json::StaticString const fieldName,
27 std::string const& expectedType = "hex string or object")
28{
29 if (auto const uNodeIndex = LedgerEntryHelpers::parse<uint256>(params))
30 {
31 return *uNodeIndex;
32 }
34 "malformedRequest", fieldName, expectedType);
35}
36
37static Expected<uint256, Json::Value>
38parseIndex(Json::Value const& params, Json::StaticString const fieldName)
39{
40 return parseObjectID(params, fieldName, "hex string");
41}
42
43static Expected<uint256, Json::Value>
44parseAccountRoot(Json::Value const& params, Json::StaticString const fieldName)
45{
46 if (auto const account = LedgerEntryHelpers::parse<AccountID>(params))
47 {
48 return keylet::account(*account).key;
49 }
50
52 "malformedAddress", fieldName, "AccountID");
53}
54
55static Expected<uint256, Json::Value>
56parseAmendments(Json::Value const& params, Json::StaticString const fieldName)
57{
58 return parseObjectID(params, fieldName, "hex string");
59}
60
61static Expected<uint256, Json::Value>
62parseAMM(Json::Value const& params, Json::StaticString const fieldName)
63{
64 if (!params.isObject())
65 {
66 return parseObjectID(params, fieldName);
67 }
68
69 if (auto const value =
70 LedgerEntryHelpers::hasRequired(params, {jss::asset, jss::asset2});
71 !value)
72 {
73 return Unexpected(value.error());
74 }
75
76 try
77 {
78 auto const issue = issueFromJson(params[jss::asset]);
79 auto const issue2 = issueFromJson(params[jss::asset2]);
80 return keylet::amm(issue, issue2).key;
81 }
82 catch (std::runtime_error const&)
83 {
84 return LedgerEntryHelpers::malformedError("malformedRequest", "");
85 }
86}
87
88static Expected<uint256, Json::Value>
89parseBridge(Json::Value const& params, Json::StaticString const fieldName)
90{
91 if (!params.isMember(jss::bridge))
92 {
94 }
95
96 if (params[jss::bridge].isString())
97 {
98 return parseObjectID(params, fieldName);
99 }
100
101 auto const bridge =
102 LedgerEntryHelpers::parseBridgeFields(params[jss::bridge]);
103 if (!bridge)
104 return Unexpected(bridge.error());
105
106 auto const account = LedgerEntryHelpers::requiredAccountID(
107 params, jss::bridge_account, "malformedBridgeAccount");
108 if (!account)
109 return Unexpected(account.error());
110
111 STXChainBridge::ChainType const chainType =
112 STXChainBridge::srcChain(account.value() == bridge->lockingChainDoor());
113 if (account.value() != bridge->door(chainType))
114 return LedgerEntryHelpers::malformedError("malformedRequest", "");
115
116 return keylet::bridge(*bridge, chainType).key;
117}
118
119static Expected<uint256, Json::Value>
120parseCheck(Json::Value const& params, Json::StaticString const fieldName)
121{
122 return parseObjectID(params, fieldName, "hex string");
123}
124
125static Expected<uint256, Json::Value>
126parseCredential(Json::Value const& cred, Json::StaticString const fieldName)
127{
128 if (!cred.isObject())
129 {
130 return parseObjectID(cred, fieldName);
131 }
132
133 auto const subject = LedgerEntryHelpers::requiredAccountID(
134 cred, jss::subject, "malformedRequest");
135 if (!subject)
136 return Unexpected(subject.error());
137
138 auto const issuer = LedgerEntryHelpers::requiredAccountID(
139 cred, jss::issuer, "malformedRequest");
140 if (!issuer)
141 return Unexpected(issuer.error());
142
143 auto const credType = LedgerEntryHelpers::requiredHexBlob(
144 cred,
145 jss::credential_type,
147 "malformedRequest");
148 if (!credType)
149 return Unexpected(credType.error());
150
151 return keylet::credential(
152 *subject, *issuer, Slice(credType->data(), credType->size()))
153 .key;
154}
155
156static Expected<uint256, Json::Value>
157parseDelegate(Json::Value const& params, Json::StaticString const fieldName)
158{
159 if (!params.isObject())
160 {
161 return parseObjectID(params, fieldName);
162 }
163
164 auto const account = LedgerEntryHelpers::requiredAccountID(
165 params, jss::account, "malformedAddress");
166 if (!account)
167 return Unexpected(account.error());
168
169 auto const authorize = LedgerEntryHelpers::requiredAccountID(
170 params, jss::authorize, "malformedAddress");
171 if (!authorize)
172 return Unexpected(authorize.error());
173
174 return keylet::delegate(*account, *authorize).key;
175}
176
177static Expected<STArray, Json::Value>
179{
180 if (!jv.isArray())
182 "malformedAuthorizedCredentials",
183 jss::authorized_credentials,
184 "array");
185 STArray arr(sfAuthorizeCredentials, jv.size());
186 for (auto const& jo : jv)
187 {
188 if (!jo.isObject())
190 "malformedAuthorizedCredentials",
191 jss::authorized_credentials,
192 "array");
193 if (auto const value = LedgerEntryHelpers::hasRequired(
194 jo,
195 {jss::issuer, jss::credential_type},
196 "malformedAuthorizedCredentials");
197 !value)
198 {
199 return Unexpected(value.error());
200 }
201
202 auto const issuer = LedgerEntryHelpers::requiredAccountID(
203 jo, jss::issuer, "malformedAuthorizedCredentials");
204 if (!issuer)
205 return Unexpected(issuer.error());
206
207 auto const credentialType = LedgerEntryHelpers::requiredHexBlob(
208 jo,
209 jss::credential_type,
211 "malformedAuthorizedCredentials");
212 if (!credentialType)
213 return Unexpected(credentialType.error());
214
215 auto credential = STObject::makeInnerObject(sfCredential);
216 credential.setAccountID(sfIssuer, *issuer);
217 credential.setFieldVL(sfCredentialType, *credentialType);
218 arr.push_back(std::move(credential));
219 }
220
221 return arr;
222}
223
224static Expected<uint256, Json::Value>
226{
227 if (!dp.isObject())
228 {
229 return parseObjectID(dp, fieldName);
230 }
231
232 if ((dp.isMember(jss::authorized) ==
233 dp.isMember(jss::authorized_credentials)))
234 {
236 "malformedRequest",
237 "Must have exactly one of `authorized` and "
238 "`authorized_credentials`.");
239 }
240
241 auto const owner =
242 LedgerEntryHelpers::requiredAccountID(dp, jss::owner, "malformedOwner");
243 if (!owner)
244 {
245 return Unexpected(owner.error());
246 }
247
248 if (dp.isMember(jss::authorized))
249 {
250 if (auto const authorized =
251 LedgerEntryHelpers::parse<AccountID>(dp[jss::authorized]))
252 {
253 return keylet::depositPreauth(*owner, *authorized).key;
254 }
256 "malformedAuthorized", jss::authorized, "AccountID");
257 }
258
259 auto const& ac(dp[jss::authorized_credentials]);
260 auto const arr = parseAuthorizeCredentials(ac);
261 if (!arr.has_value())
262 return Unexpected(arr.error());
263 if (arr->empty() || (arr->size() > maxCredentialsArraySize))
264 {
266 "malformedAuthorizedCredentials",
267 jss::authorized_credentials,
268 "array");
269 }
270
271 auto const& sorted = credentials::makeSorted(arr.value());
272 if (sorted.empty())
273 {
274 // TODO: this error message is bad/inaccurate
276 "malformedAuthorizedCredentials",
277 jss::authorized_credentials,
278 "array");
279 }
280
281 return keylet::depositPreauth(*owner, std::move(sorted)).key;
282}
283
284static Expected<uint256, Json::Value>
285parseDID(Json::Value const& params, Json::StaticString const fieldName)
286{
287 auto const account = LedgerEntryHelpers::parse<AccountID>(params);
288 if (!account)
289 {
291 "malformedAddress", fieldName, "AccountID");
292 }
293
294 return keylet::did(*account).key;
295}
296
297static Expected<uint256, Json::Value>
299 Json::Value const& params,
300 Json::StaticString const fieldName)
301{
302 if (!params.isObject())
303 {
304 return parseObjectID(params, fieldName);
305 }
306
307 if (params.isMember(jss::sub_index) &&
308 (!params[jss::sub_index].isConvertibleTo(Json::uintValue) ||
309 params[jss::sub_index].isBool()))
310 {
312 "malformedRequest", jss::sub_index, "number");
313 }
314
315 if (params.isMember(jss::owner) == params.isMember(jss::dir_root))
316 {
318 "malformedRequest",
319 "Must have exactly one of `owner` and `dir_root` fields.");
320 }
321
322 std::uint64_t uSubIndex = params.get(jss::sub_index, 0).asUInt();
323
324 if (params.isMember(jss::dir_root))
325 {
326 if (auto const uDirRoot =
327 LedgerEntryHelpers::parse<uint256>(params[jss::dir_root]))
328 {
329 return keylet::page(*uDirRoot, uSubIndex).key;
330 }
331
333 "malformedDirRoot", jss::dir_root, "hash");
334 }
335
336 if (params.isMember(jss::owner))
337 {
338 auto const ownerID =
339 LedgerEntryHelpers::parse<AccountID>(params[jss::owner]);
340 if (!ownerID)
341 {
343 "malformedAddress", jss::owner, "AccountID");
344 }
345
346 return keylet::page(keylet::ownerDir(*ownerID), uSubIndex).key;
347 }
348
349 return LedgerEntryHelpers::malformedError("malformedRequest", "");
350}
351
352static Expected<uint256, Json::Value>
353parseEscrow(Json::Value const& params, Json::StaticString const fieldName)
354{
355 if (!params.isObject())
356 {
357 return parseObjectID(params, fieldName);
358 }
359
361 params, jss::owner, "malformedOwner");
362 if (!id)
363 return Unexpected(id.error());
364 auto const seq =
365 LedgerEntryHelpers::requiredUInt32(params, jss::seq, "malformedSeq");
366 if (!seq)
367 return Unexpected(seq.error());
368
369 return keylet::escrow(*id, *seq).key;
370}
371
372static Expected<uint256, Json::Value>
373parseFeeSettings(Json::Value const& params, Json::StaticString const fieldName)
374{
375 return parseObjectID(params, fieldName, "hex string");
376}
377
378static Expected<uint256, Json::Value>
379parseLedgerHashes(Json::Value const& params, Json::StaticString const fieldName)
380{
381 return parseObjectID(params, fieldName, "hex string");
382}
383
384static Expected<uint256, Json::Value>
385parseMPToken(Json::Value const& params, Json::StaticString const fieldName)
386{
387 if (!params.isObject())
388 {
389 return parseObjectID(params, fieldName);
390 }
391
392 auto const mptIssuanceID = LedgerEntryHelpers::requiredUInt192(
393 params, jss::mpt_issuance_id, "malformedMPTIssuanceID");
394 if (!mptIssuanceID)
395 return Unexpected(mptIssuanceID.error());
396
397 auto const account = LedgerEntryHelpers::requiredAccountID(
398 params, jss::account, "malformedAccount");
399 if (!account)
400 return Unexpected(account.error());
401
402 return keylet::mptoken(*mptIssuanceID, *account).key;
403}
404
405static Expected<uint256, Json::Value>
407 Json::Value const& params,
408 Json::StaticString const fieldName)
409{
410 auto const mptIssuanceID = LedgerEntryHelpers::parse<uint192>(params);
411 if (!mptIssuanceID)
413 "malformedMPTokenIssuance", fieldName, "Hash192");
414
415 return keylet::mptIssuance(*mptIssuanceID).key;
416}
417
418static Expected<uint256, Json::Value>
419parseNFTokenOffer(Json::Value const& params, Json::StaticString const fieldName)
420{
421 return parseObjectID(params, fieldName, "hex string");
422}
423
424static Expected<uint256, Json::Value>
425parseNFTokenPage(Json::Value const& params, Json::StaticString const fieldName)
426{
427 return parseObjectID(params, fieldName, "hex string");
428}
429
430static Expected<uint256, Json::Value>
431parseNegativeUNL(Json::Value const& params, Json::StaticString const fieldName)
432{
433 return parseObjectID(params, fieldName, "hex string");
434}
435
436static Expected<uint256, Json::Value>
437parseOffer(Json::Value const& params, Json::StaticString const fieldName)
438{
439 if (!params.isObject())
440 {
441 return parseObjectID(params, fieldName);
442 }
443
445 params, jss::account, "malformedAddress");
446 if (!id)
447 return Unexpected(id.error());
448
449 auto const seq = LedgerEntryHelpers::requiredUInt32(
450 params, jss::seq, "malformedRequest");
451 if (!seq)
452 return Unexpected(seq.error());
453
454 return keylet::offer(*id, *seq).key;
455}
456
457static Expected<uint256, Json::Value>
458parseOracle(Json::Value const& params, Json::StaticString const fieldName)
459{
460 if (!params.isObject())
461 {
462 return parseObjectID(params, fieldName);
463 }
464
466 params, jss::account, "malformedAccount");
467 if (!id)
468 return Unexpected(id.error());
469
470 auto const seq = LedgerEntryHelpers::requiredUInt32(
471 params, jss::oracle_document_id, "malformedDocumentID");
472 if (!seq)
473 return Unexpected(seq.error());
474
475 return keylet::oracle(*id, *seq).key;
476}
477
478static Expected<uint256, Json::Value>
479parsePayChannel(Json::Value const& params, Json::StaticString const fieldName)
480{
481 return parseObjectID(params, fieldName, "hex string");
482}
483
484static Expected<uint256, Json::Value>
486 Json::Value const& pd,
487 Json::StaticString const fieldName)
488{
489 if (pd.isString())
490 {
491 return parseObjectID(pd, fieldName);
492 }
493
494 if (!pd.isObject())
495 {
497 "malformedRequest", fieldName, "hex string or object");
498 }
499
500 auto const account = LedgerEntryHelpers::requiredAccountID(
501 pd, jss::account, "malformedAddress");
502 if (!account)
503 return Unexpected(account.error());
504
505 auto const seq =
506 LedgerEntryHelpers::requiredUInt32(pd, jss::seq, "malformedRequest");
507 if (!seq)
508 return Unexpected(seq.error());
509
510 return keylet::permissionedDomain(*account, pd[jss::seq].asUInt()).key;
511}
512
513static Expected<uint256, Json::Value>
515 Json::Value const& jvRippleState,
516 Json::StaticString const fieldName)
517{
518 Currency uCurrency;
519
520 if (!jvRippleState.isObject())
521 {
522 return parseObjectID(jvRippleState, fieldName);
523 }
524
525 if (auto const value = LedgerEntryHelpers::hasRequired(
526 jvRippleState, {jss::currency, jss::accounts});
527 !value)
528 {
529 return Unexpected(value.error());
530 }
531
532 if (!jvRippleState[jss::accounts].isArray() ||
533 jvRippleState[jss::accounts].size() != 2)
534 {
536 "malformedRequest", jss::accounts, "length-2 array of Accounts");
537 }
538
539 auto const id1 =
540 LedgerEntryHelpers::parse<AccountID>(jvRippleState[jss::accounts][0u]);
541 auto const id2 =
542 LedgerEntryHelpers::parse<AccountID>(jvRippleState[jss::accounts][1u]);
543 if (!id1 || !id2)
544 {
546 "malformedAddress", jss::accounts, "array of Accounts");
547 }
548 if (id1 == id2)
549 {
551 "malformedRequest", "Cannot have a trustline to self.");
552 }
553
554 if (!jvRippleState[jss::currency].isString() ||
555 jvRippleState[jss::currency] == "" ||
556 !to_currency(uCurrency, jvRippleState[jss::currency].asString()))
557 {
559 "malformedCurrency", jss::currency, "Currency");
560 }
561
562 return keylet::line(*id1, *id2, uCurrency).key;
563}
564
565static Expected<uint256, Json::Value>
566parseSignerList(Json::Value const& params, Json::StaticString const fieldName)
567{
568 return parseObjectID(params, fieldName, "hex string");
569}
570
571static Expected<uint256, Json::Value>
572parseTicket(Json::Value const& params, Json::StaticString const fieldName)
573{
574 if (!params.isObject())
575 {
576 return parseObjectID(params, fieldName);
577 }
578
580 params, jss::account, "malformedAddress");
581 if (!id)
582 return Unexpected(id.error());
583
584 auto const seq = LedgerEntryHelpers::requiredUInt32(
585 params, jss::ticket_seq, "malformedRequest");
586 if (!seq)
587 return Unexpected(seq.error());
588
589 return getTicketIndex(*id, *seq);
590}
591
592static Expected<uint256, Json::Value>
593parseVault(Json::Value const& params, Json::StaticString const fieldName)
594{
595 if (!params.isObject())
596 {
597 return parseObjectID(params, fieldName);
598 }
599
601 params, jss::owner, "malformedOwner");
602 if (!id)
603 return Unexpected(id.error());
604
605 auto const seq = LedgerEntryHelpers::requiredUInt32(
606 params, jss::seq, "malformedRequest");
607 if (!seq)
608 return Unexpected(seq.error());
609
610 return keylet::vault(*id, *seq).key;
611}
612
613static Expected<uint256, Json::Value>
615 Json::Value const& claim_id,
616 Json::StaticString const fieldName)
617{
618 if (!claim_id.isObject())
619 {
620 return parseObjectID(claim_id, fieldName);
621 }
622
623 auto const bridge_spec = LedgerEntryHelpers::parseBridgeFields(claim_id);
624 if (!bridge_spec)
625 return Unexpected(bridge_spec.error());
626
627 auto const seq = LedgerEntryHelpers::requiredUInt32(
628 claim_id, jss::xchain_owned_claim_id, "malformedXChainOwnedClaimID");
629 if (!seq)
630 {
631 return Unexpected(seq.error());
632 }
633
634 Keylet keylet = keylet::xChainClaimID(*bridge_spec, *seq);
635 return keylet.key;
636}
637
638static Expected<uint256, Json::Value>
640 Json::Value const& claim_id,
641 Json::StaticString const fieldName)
642{
643 if (!claim_id.isObject())
644 {
645 return parseObjectID(claim_id, fieldName);
646 }
647
648 auto const bridge_spec = LedgerEntryHelpers::parseBridgeFields(claim_id);
649 if (!bridge_spec)
650 return Unexpected(bridge_spec.error());
651
652 auto const seq = LedgerEntryHelpers::requiredUInt32(
653 claim_id,
654 jss::xchain_owned_create_account_claim_id,
655 "malformedXChainOwnedCreateAccountClaimID");
656 if (!seq)
657 {
658 return Unexpected(seq.error());
659 }
660
661 Keylet keylet = keylet::xChainCreateAccountClaimID(*bridge_spec, *seq);
662 return keylet.key;
663}
664
666 Json::Value const&,
667 Json::StaticString const);
668
675
676// {
677// ledger_hash : <ledger>
678// ledger_index : <ledger_index>
679// ...
680// }
683{
684 static auto ledgerEntryParsers = std::to_array<LedgerEntry>({
685#pragma push_macro("LEDGER_ENTRY")
686#undef LEDGER_ENTRY
687
688#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \
689 {jss::rpcName, parse##name, tag},
690
691#include <xrpl/protocol/detail/ledger_entries.macro>
692
693#undef LEDGER_ENTRY
694#pragma pop_macro("LEDGER_ENTRY")
695 {jss::index, parseIndex, ltANY},
696 // aliases
697 {jss::account_root, parseAccountRoot, ltACCOUNT_ROOT},
698 {jss::ripple_state, parseRippleState, ltRIPPLE_STATE},
699 });
700
701 auto hasMoreThanOneMember = [&]() {
702 int count = 0;
703
704 for (auto const& ledgerEntry : ledgerEntryParsers)
705 {
706 if (context.params.isMember(ledgerEntry.fieldName))
707 {
708 count++;
709 if (count > 1) // Early exit if more than one is found
710 return true;
711 }
712 }
713 return false; // Return false if <= 1 is found
714 }();
715
716 if (hasMoreThanOneMember)
717 {
718 return RPC::make_param_error("Too many fields provided.");
719 }
720
722 auto jvResult = RPC::lookupLedger(lpLedger, context);
723
724 if (!lpLedger)
725 return jvResult;
726
727 uint256 uNodeIndex;
728 LedgerEntryType expectedType = ltANY;
729
730 try
731 {
732 bool found = false;
733 for (auto const& ledgerEntry : ledgerEntryParsers)
734 {
735 if (context.params.isMember(ledgerEntry.fieldName))
736 {
737 expectedType = ledgerEntry.expectedType;
738 // `Bridge` is the only type that involves two fields at the
739 // `ledger_entry` param level.
740 // So that parser needs to have the whole `params` field.
741 // All other parsers only need the one field name's info.
742 Json::Value const& params = ledgerEntry.fieldName == jss::bridge
743 ? context.params
744 : context.params[ledgerEntry.fieldName];
745 auto const result =
746 ledgerEntry.parseFunction(params, ledgerEntry.fieldName);
747 if (!result)
748 return result.error();
749
750 uNodeIndex = result.value();
751 found = true;
752 break;
753 }
754 }
755 if (!found)
756 {
757 if (context.apiVersion < 2u)
758 {
759 jvResult[jss::error] = "unknownOption";
760 return jvResult;
761 }
762 return RPC::make_param_error("No ledger_entry params provided.");
763 }
764 }
765 catch (Json::error& e)
766 {
767 if (context.apiVersion > 1u)
768 {
769 // For apiVersion 2 onwards, any parsing failures that throw
770 // this exception return an invalidParam error.
772 }
773 else
774 throw;
775 }
776
777 if (uNodeIndex.isZero())
778 {
780 }
781
782 auto const sleNode = lpLedger->read(keylet::unchecked(uNodeIndex));
783
784 bool bNodeBinary = false;
785 if (context.params.isMember(jss::binary))
786 bNodeBinary = context.params[jss::binary].asBool();
787
788 if (!sleNode)
789 {
790 // Not found.
792 }
793
794 if ((expectedType != ltANY) && (expectedType != sleNode->getType()))
795 {
797 }
798
799 if (bNodeBinary)
800 {
801 Serializer s;
802
803 sleNode->add(s);
804
805 jvResult[jss::node_binary] = strHex(s.peekData());
806 jvResult[jss::index] = to_string(uNodeIndex);
807 }
808 else
809 {
810 jvResult[jss::node] = sleNode->getJson(JsonOptions::none);
811 jvResult[jss::index] = to_string(uNodeIndex);
812 }
813
814 return jvResult;
815}
816
820{
821 org::xrpl::rpc::v1::GetLedgerEntryRequest& request = context.params;
822 org::xrpl::rpc::v1::GetLedgerEntryResponse response;
823 grpc::Status status = grpc::Status::OK;
824
826 if (auto status = RPC::ledgerFromRequest(ledger, context))
827 {
828 grpc::Status errorStatus;
829 if (status.toErrorCode() == rpcINVALID_PARAMS)
830 {
831 errorStatus = grpc::Status(
832 grpc::StatusCode::INVALID_ARGUMENT, status.message());
833 }
834 else
835 {
836 errorStatus =
837 grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
838 }
839 return {response, errorStatus};
840 }
841
842 auto const key = uint256::fromVoidChecked(request.key());
843 if (!key)
844 {
845 grpc::Status errorStatus{
846 grpc::StatusCode::INVALID_ARGUMENT, "index malformed"};
847 return {response, errorStatus};
848 }
849
850 auto const sleNode = ledger->read(keylet::unchecked(*key));
851 if (!sleNode)
852 {
853 grpc::Status errorStatus{
854 grpc::StatusCode::NOT_FOUND, "object not found"};
855 return {response, errorStatus};
856 }
857
858 Serializer s;
859 sleNode->add(s);
860
861 auto& stateObject = *response.mutable_ledger_object();
862 stateObject.set_data(s.peekData().data(), s.getLength());
863 stateObject.set_key(request.key());
864 *(response.mutable_ledger()) = request.ledger();
865 return {response, status};
866}
867} // namespace ripple
Lightweight wrapper to tag static string.
Definition json_value.h:45
Represents a JSON value.
Definition json_value.h:131
bool isArray() const
UInt size() const
Number of values in array or object.
bool isString() const
UInt asUInt() const
bool isObject() const
bool isBool() const
bool asBool() const
bool isMember(char const *key) const
Return true if the object has a member named key.
Value get(UInt index, Value const &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
bool isConvertibleTo(ValueType other) const
void push_back(STObject const &object)
Definition STArray.h:193
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:76
static ChainType srcChain(bool wasLockingChainSend)
Blob const & peekData() const
Definition Serializer.h:183
int getLength() const
Definition Serializer.h:214
An immutable linear range of bytes.
Definition Slice.h:27
static std::optional< base_uint > fromVoidChecked(T const &from)
Definition base_uint.h:307
bool isZero() const
Definition base_uint.h:521
T data(T... args)
T is_same_v
@ uintValue
unsigned integer value
Definition json_value.h:22
Expected< STXChainBridge, Json::Value > parseBridgeFields(Json::Value const &params)
Unexpected< Json::Value > malformedError(std::string const &err, std::string const &message)
Unexpected< Json::Value > invalidFieldError(std::string const &err, Json::StaticString const field, std::string const &type)
Unexpected< Json::Value > missingFieldError(Json::StaticString const field, std::optional< std::string > err=std::nullopt)
Expected< bool, Json::Value > hasRequired(Json::Value const &params, std::initializer_list< Json::StaticString > fields, std::optional< std::string > err=std::nullopt)
Expected< AccountID, Json::Value > requiredAccountID(Json::Value const &params, Json::StaticString const fieldName, std::string const &err)
Expected< std::uint32_t, Json::Value > requiredUInt32(Json::Value const &params, Json::StaticString const fieldName, std::string const &err)
Expected< uint192, Json::Value > requiredUInt192(Json::Value const &params, Json::StaticString const fieldName, std::string const &err)
Expected< Blob, Json::Value > requiredHexBlob(Json::Value const &params, Json::StaticString const fieldName, std::size_t maxLength, std::string const &err)
Status ledgerFromRequest(T &ledger, GRPCContext< R > &context)
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
Json::Value make_param_error(std::string const &message)
Returns a new json object that indicates invalid parameters.
Definition ErrorCodes.h:252
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.
std::set< std::pair< AccountID, Slice > > makeSorted(STArray const &credentials)
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:521
Keylet oracle(AccountID const &account, std::uint32_t const &documentID) noexcept
Definition Indexes.cpp:501
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
Definition Indexes.cpp:446
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Definition Indexes.cpp:551
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
Definition Indexes.cpp:427
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:225
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Definition Indexes.cpp:507
Keylet xChainClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition Indexes.cpp:467
Keylet did(AccountID const &account) noexcept
Definition Indexes.cpp:495
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Definition Indexes.cpp:534
Keylet vault(AccountID const &owner, std::uint32_t seq) noexcept
Definition Indexes.cpp:545
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:165
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:361
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition Indexes.cpp:349
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
Definition Indexes.cpp:370
Keylet bridge(STXChainBridge const &bridge, STXChainBridge::ChainType chainType)
Definition Indexes.cpp:454
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition Indexes.cpp:355
Keylet xChainCreateAccountClaimID(STXChainBridge const &bridge, std::uint64_t seq)
Definition Indexes.cpp:481
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition Indexes.cpp:255
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition Indexes.cpp:323
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
static Expected< uint256, Json::Value > parseOracle(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseCredential(Json::Value const &cred, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseFeeSettings(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseXChainOwnedClaimID(Json::Value const &claim_id, Json::StaticString const fieldName)
Json::Value doLedgerEntry(RPC::JsonContext &)
static Expected< uint256, Json::Value > parsePayChannel(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseNFTokenOffer(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseCheck(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseEscrow(Json::Value const &params, Json::StaticString const fieldName)
@ rpcENTRY_NOT_FOUND
Definition ErrorCodes.h:142
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:65
@ rpcUNEXPECTED_LEDGER_TYPE
Definition ErrorCodes.h:143
static Expected< uint256, Json::Value > parseXChainOwnedCreateAccountClaimID(Json::Value const &claim_id, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseIndex(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseDelegate(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseDepositPreauth(Json::Value const &dp, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseSignerList(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parsePermissionedDomain(Json::Value const &pd, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseBridge(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseAMM(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseMPToken(Json::Value const &params, Json::StaticString const fieldName)
static Expected< STArray, Json::Value > parseAuthorizeCredentials(Json::Value const &jv)
Issue issueFromJson(Json::Value const &v)
Definition Issue.cpp:76
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:11
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:90
std::pair< org::xrpl::rpc::v1::GetLedgerEntryResponse, grpc::Status > doLedgerEntryGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerEntryRequest > &context)
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
Definition Protocol.h:87
static Expected< uint256, Json::Value > parseOffer(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseNegativeUNL(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseVault(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseMPTokenIssuance(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseNFTokenPage(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseDirectoryNode(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseAmendments(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseAccountRoot(Json::Value const &params, Json::StaticString const fieldName)
uint256 getTicketIndex(AccountID const &account, std::uint32_t uSequence)
Definition Indexes.cpp:137
static Expected< uint256, Json::Value > parseTicket(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseObjectID(Json::Value const &params, Json::StaticString const fieldName, std::string const &expectedType="hex string or object")
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
LedgerEntryType
Identifiers for on-ledger objects.
@ ltANY
A special type, matching any ledger entry type.
Expected< uint256, Json::Value >(*)(Json::Value const &, Json::StaticString const) FunctionType
static Expected< uint256, Json::Value > parseLedgerHashes(Json::Value const &params, Json::StaticString const fieldName)
@ credential
Credentials signature.
static Expected< uint256, Json::Value > parseDID(Json::Value const &params, Json::StaticString const fieldName)
static Expected< uint256, Json::Value > parseRippleState(Json::Value const &jvRippleState, Json::StaticString const fieldName)
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
Definition UintTypes.cpp:65
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
uint256 key
Definition Keylet.h:21
LedgerEntryType expectedType
Json::StaticString fieldName
FunctionType parseFunction
unsigned int apiVersion
Definition Context.h:30