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
28#include <xrpl/protocol/ErrorCodes.h>
29#include <xrpl/protocol/LedgerFormats.h>
30#include <xrpl/protocol/jss.h>
31
32namespace ripple {
33
34// Get state nodes from a ledger
35// Inputs:
36// limit: integer, maximum number of entries
37// marker: opaque, resume point
38// binary: boolean, format
39// type: string // optional, defaults to all ledger node types
40// Outputs:
41// ledger_hash: chosen ledger's hash
42// ledger_index: chosen ledger's index
43// state: array of state nodes
44// marker: resume point, if any
47{
49 auto const& params = context.params;
50
51 auto jvResult = RPC::lookupLedger(lpLedger, context);
52 if (!lpLedger)
53 return jvResult;
54
55 bool const isMarker = params.isMember(jss::marker);
57 if (isMarker)
58 {
59 Json::Value const& jMarker = params[jss::marker];
60 if (!(jMarker.isString() && key.parseHex(jMarker.asString())))
61 return RPC::expected_field_error(jss::marker, "valid");
62 }
63
64 bool const isBinary = params[jss::binary].asBool();
65
66 int limit = -1;
67 if (params.isMember(jss::limit))
68 {
69 Json::Value const& jLimit = params[jss::limit];
70 if (!jLimit.isIntegral())
71 return RPC::expected_field_error(jss::limit, "integer");
72
73 limit = jLimit.asInt();
74 }
75
76 auto maxLimit = RPC::Tuning::pageLength(isBinary);
77 if ((limit < 0) || ((limit > maxLimit) && (!isUnlimited(context.role))))
78 limit = maxLimit;
79
80 jvResult[jss::ledger_hash] = to_string(lpLedger->info().hash);
81 jvResult[jss::ledger_index] = lpLedger->info().seq;
82
83 if (!isMarker)
84 {
85 // Return base ledger data on first query
86 jvResult[jss::ledger] = getJson(LedgerFill(
87 *lpLedger, &context, isBinary ? LedgerFill::Options::binary : 0));
88 }
89
90 auto [rpcStatus, type] = RPC::chooseLedgerEntryType(params);
91 if (rpcStatus)
92 {
93 jvResult.clear();
94 rpcStatus.inject(jvResult);
95 return jvResult;
96 }
97 Json::Value& nodes = jvResult[jss::state];
98 if (nodes.type() == Json::nullValue)
99 {
101 }
102
103 auto e = lpLedger->sles.end();
104 for (auto i = lpLedger->sles.upper_bound(key); i != e; ++i)
105 {
106 auto sle = lpLedger->read(keylet::unchecked((*i)->key()));
107 if (limit-- <= 0)
108 {
109 // Stop processing before the current key.
110 auto k = sle->key();
111 jvResult[jss::marker] = to_string(--k);
112 break;
113 }
114
115 if (type == ltANY || sle->getType() == type)
116 {
117 if (isBinary)
118 {
119 Json::Value& entry = nodes.append(Json::objectValue);
120 entry[jss::data] = serializeHex(*sle);
121 entry[jss::index] = to_string(sle->key());
122 }
123 else
124 {
125 Json::Value& entry =
126 nodes.append(sle->getJson(JsonOptions::none));
127 entry[jss::index] = to_string(sle->key());
128 }
129 }
130 }
131
132 return jvResult;
133}
134
138{
139 org::xrpl::rpc::v1::GetLedgerDataRequest& request = context.params;
140 org::xrpl::rpc::v1::GetLedgerDataResponse response;
141 grpc::Status status = grpc::Status::OK;
142
144 if (auto status = RPC::ledgerFromRequest(ledger, context))
145 {
146 grpc::Status errorStatus;
147 if (status.toErrorCode() == rpcINVALID_PARAMS)
148 {
149 errorStatus = grpc::Status(
150 grpc::StatusCode::INVALID_ARGUMENT, status.message());
151 }
152 else
153 {
154 errorStatus =
155 grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
156 }
157 return {response, errorStatus};
158 }
159
160 uint256 startKey;
161 if (auto key = uint256::fromVoidChecked(request.marker()))
162 {
163 startKey = *key;
164 }
165 else if (request.marker().size() != 0)
166 {
167 grpc::Status errorStatus{
168 grpc::StatusCode::INVALID_ARGUMENT, "marker malformed"};
169 return {response, errorStatus};
170 }
171
172 auto e = ledger->sles.end();
173 if (request.end_marker().size() != 0)
174 {
175 auto const key = uint256::fromVoidChecked(request.end_marker());
176
177 if (!key)
178 return {
179 response,
180 {grpc::StatusCode::INVALID_ARGUMENT, "end marker malformed"}};
181
182 if (*key < startKey)
183 return {
184 response,
185 {grpc::StatusCode::INVALID_ARGUMENT,
186 "end marker out of range"}};
187
188 e = ledger->sles.upper_bound(*key);
189 }
190
191 int maxLimit = RPC::Tuning::pageLength(true);
192
193 for (auto i = ledger->sles.upper_bound(startKey); i != e; ++i)
194 {
195 auto sle = ledger->read(keylet::unchecked((*i)->key()));
196 if (maxLimit-- <= 0)
197 {
198 // Stop processing before the current key.
199 auto k = sle->key();
200 --k;
201 response.set_marker(k.data(), k.size());
202 break;
203 }
204 auto stateObject = response.mutable_ledger_objects()->add_objects();
205 Serializer s;
206 sle->add(s);
207 stateObject->set_data(s.peekData().data(), s.getLength());
208 stateObject->set_key(sle->key().data(), sle->key().size());
209 }
210 return {response, status};
211}
212
213} // 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:57
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:408
std::pair< RPC::Status, LedgerEntryType > chooseLedgerEntryType(Json::Value const &params)
Definition: RPCHelpers.cpp:931
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:622
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition: Indexes.cpp:360
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:46
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:136
RequestType params
Definition: Context.h:71
Json::Value params
Definition: Context.h:63