rippled
Loading...
Searching...
No Matches
LedgerData.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 <xrpld/app/ledger/LedgerToJson.h>
21#include <xrpld/ledger/ReadView.h>
22#include <xrpld/rpc/Context.h>
23#include <xrpld/rpc/GRPCHandlers.h>
24#include <xrpld/rpc/Role.h>
25#include <xrpld/rpc/detail/RPCHelpers.h>
26#include <xrpld/rpc/detail/Tuning.h>
27#include <xrpl/protocol/ErrorCodes.h>
28#include <xrpl/protocol/LedgerFormats.h>
29#include <xrpl/protocol/jss.h>
30
31namespace ripple {
32
33// Get state nodes from a ledger
34// Inputs:
35// limit: integer, maximum number of entries
36// marker: opaque, resume point
37// binary: boolean, format
38// type: string // optional, defaults to all ledger node types
39// Outputs:
40// ledger_hash: chosen ledger's hash
41// ledger_index: chosen ledger's index
42// state: array of state nodes
43// marker: resume point, if any
46{
48 auto const& params = context.params;
49
50 auto jvResult = RPC::lookupLedger(lpLedger, context);
51 if (!lpLedger)
52 return jvResult;
53
54 bool const isMarker = params.isMember(jss::marker);
56 if (isMarker)
57 {
58 Json::Value const& jMarker = params[jss::marker];
59 if (!(jMarker.isString() && key.parseHex(jMarker.asString())))
60 return RPC::expected_field_error(jss::marker, "valid");
61 }
62
63 bool const isBinary = params[jss::binary].asBool();
64
65 int limit = -1;
66 if (params.isMember(jss::limit))
67 {
68 Json::Value const& jLimit = params[jss::limit];
69 if (!jLimit.isIntegral())
70 return RPC::expected_field_error(jss::limit, "integer");
71
72 limit = jLimit.asInt();
73 }
74
75 auto maxLimit = RPC::Tuning::pageLength(isBinary);
76 if ((limit < 0) || ((limit > maxLimit) && (!isUnlimited(context.role))))
77 limit = maxLimit;
78
79 jvResult[jss::ledger_hash] = to_string(lpLedger->info().hash);
80 jvResult[jss::ledger_index] = lpLedger->info().seq;
81
82 if (!isMarker)
83 {
84 // Return base ledger data on first query
85 jvResult[jss::ledger] = getJson(LedgerFill(
86 *lpLedger, &context, isBinary ? LedgerFill::Options::binary : 0));
87 }
88
89 auto [rpcStatus, type] = RPC::chooseLedgerEntryType(params);
90 if (rpcStatus)
91 {
92 jvResult.clear();
93 rpcStatus.inject(jvResult);
94 return jvResult;
95 }
96 Json::Value& nodes = jvResult[jss::state];
97 if (nodes.type() == Json::nullValue)
98 {
100 }
101
102 auto e = lpLedger->sles.end();
103 for (auto i = lpLedger->sles.upper_bound(key); i != e; ++i)
104 {
105 auto sle = lpLedger->read(keylet::unchecked((*i)->key()));
106 if (limit-- <= 0)
107 {
108 // Stop processing before the current key.
109 auto k = sle->key();
110 jvResult[jss::marker] = to_string(--k);
111 break;
112 }
113
114 if (type == ltANY || sle->getType() == type)
115 {
116 if (isBinary)
117 {
118 Json::Value& entry = nodes.append(Json::objectValue);
119 entry[jss::data] = serializeHex(*sle);
120 entry[jss::index] = to_string(sle->key());
121 }
122 else
123 {
124 Json::Value& entry =
125 nodes.append(sle->getJson(JsonOptions::none));
126 entry[jss::index] = to_string(sle->key());
127 }
128 }
129 }
130
131 return jvResult;
132}
133
137{
138 org::xrpl::rpc::v1::GetLedgerDataRequest& request = context.params;
139 org::xrpl::rpc::v1::GetLedgerDataResponse response;
140 grpc::Status status = grpc::Status::OK;
141
143 if (auto status = RPC::ledgerFromRequest(ledger, context))
144 {
145 grpc::Status errorStatus;
146 if (status.toErrorCode() == rpcINVALID_PARAMS)
147 {
148 errorStatus = grpc::Status(
149 grpc::StatusCode::INVALID_ARGUMENT, status.message());
150 }
151 else
152 {
153 errorStatus =
154 grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
155 }
156 return {response, errorStatus};
157 }
158
159 uint256 startKey;
160 if (auto key = uint256::fromVoidChecked(request.marker()))
161 {
162 startKey = *key;
163 }
164 else if (request.marker().size() != 0)
165 {
166 grpc::Status errorStatus{
167 grpc::StatusCode::INVALID_ARGUMENT, "marker malformed"};
168 return {response, errorStatus};
169 }
170
171 auto e = ledger->sles.end();
172 if (auto key = uint256::fromVoidChecked(request.end_marker()))
173 {
174 e = ledger->sles.upper_bound(*key);
175 }
176 else if (request.end_marker().size() != 0)
177 {
178 grpc::Status errorStatus{
179 grpc::StatusCode::INVALID_ARGUMENT, "end marker malformed"};
180 return {response, errorStatus};
181 }
182
183 int maxLimit = RPC::Tuning::pageLength(true);
184
185 for (auto i = ledger->sles.upper_bound(startKey); i != e; ++i)
186 {
187 auto sle = ledger->read(keylet::unchecked((*i)->key()));
188 if (maxLimit-- <= 0)
189 {
190 // Stop processing before the current key.
191 auto k = sle->key();
192 --k;
193 response.set_marker(k.data(), k.size());
194 break;
195 }
196 auto stateObject = response.mutable_ledger_objects()->add_objects();
197 Serializer s;
198 sle->add(s);
199 stateObject->set_data(s.peekData().data(), s.getLength());
200 stateObject->set_key(sle->key().data(), sle->key().size());
201 }
202 return {response, status};
203}
204
205} // namespace ripple
Represents a JSON value.
Definition: json_value.h:148
Int asInt() const
Definition: json_value.cpp:509
bool isString() const
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:897
ValueType type() const
Definition: json_value.cpp:356
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:475
bool isIntegral() const
uint256 key_type
Definition: ReadView.h:56
Blob const & peekData() const
Definition: Serializer.h:203
int getLength() const
Definition: Serializer.h:234
static std::optional< base_uint > fromVoidChecked(T const &from)
Definition: base_uint.h:326
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:503
T data(T... args)
@ nullValue
'null' value
Definition: json_value.h:37
@ arrayValue
array value (ordered list)
Definition: json_value.h:43
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:44
int constexpr pageLength(bool isBinary)
Maximum number of pages in a LedgerData response.
Status ledgerFromRequest(T &ledger, GRPCContext< R > &context)
Definition: RPCHelpers.cpp:407
std::pair< RPC::Status, LedgerEntryType > chooseLedgerEntryType(Json::Value const &params)
Definition: RPCHelpers.cpp:930
Json::Value expected_field_error(std::string const &name, std::string const &type)
Definition: ErrorCodes.h:339
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:621
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition: Indexes.cpp:359
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
std::string serializeHex(STObject const &o)
Serialize an object to a hex string.
Definition: serialize.h:41
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition: Role.cpp:125
Json::Value doLedgerData(RPC::JsonContext &)
Definition: LedgerData.cpp:45
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
@ ltANY
A special type, matching any ledger entry type.
Definition: LedgerFormats.h:78
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
std::pair< org::xrpl::rpc::v1::GetLedgerDataResponse, grpc::Status > doLedgerDataGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerDataRequest > &context)
Definition: LedgerData.cpp:135
RequestType params
Definition: Context.h:70
Json::Value params
Definition: Context.h:62