20 #include <ripple/app/ledger/LedgerToJson.h>
21 #include <ripple/app/main/Application.h>
22 #include <ripple/app/misc/LoadFeeTrack.h>
23 #include <ripple/json/Object.h>
24 #include <ripple/protocol/ErrorCodes.h>
25 #include <ripple/protocol/jss.h>
26 #include <ripple/resource/Fees.h>
27 #include <ripple/rpc/GRPCHandlers.h>
28 #include <ripple/rpc/Role.h>
29 #include <ripple/rpc/handlers/LedgerHandler.h>
30 #include <ripple/rpc/impl/RPCHelpers.h>
43 bool needsLedger = params.
isMember(jss::ledger) ||
44 params.isMember(jss::ledger_hash) ||
52 bool const full = params[jss::full].asBool();
53 bool const transactions = params[jss::transactions].asBool();
54 bool const accounts = params[jss::accounts].asBool();
55 bool const expand = params[jss::expand].asBool();
56 bool const binary = params[jss::binary].asBool();
57 bool const owner_funds = params[jss::owner_funds].asBool();
58 bool const queue = params[jss::queue].asBool();
108 org::xrpl::rpc::v1::GetLedgerRequest& request = context.
params;
109 org::xrpl::rpc::v1::GetLedgerResponse response;
110 grpc::Status status = grpc::Status::OK;
115 grpc::Status errorStatus;
118 errorStatus = grpc::Status(
119 grpc::StatusCode::INVALID_ARGUMENT, status.message());
124 grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
126 return {response, errorStatus};
134 if (request.transactions())
138 for (
auto& i : ledger->
txs)
141 if (request.expand())
143 auto txn = response.mutable_transactions_list()
144 ->add_transactions();
155 auto const& hash = i.first->getTransactionID();
156 response.mutable_hashes_list()->add_hashes(
157 hash.data(), hash.size());
164 << __func__ <<
" - Error deserializing transaction in ledger "
166 <<
" . skipping transaction and following transactions. You "
167 "should look into this further";
171 if (request.get_objects())
177 std::dynamic_pointer_cast<Ledger const>(parent);
180 grpc::Status errorStatus{
181 grpc::StatusCode::NOT_FOUND,
"parent ledger not validated"};
182 return {response, errorStatus};
186 std::dynamic_pointer_cast<Ledger const>(ledger);
189 grpc::Status errorStatus{
190 grpc::StatusCode::NOT_FOUND,
"ledger not validated"};
191 return {response, errorStatus};
198 desired->
stateMap(), differences, maxDifferences);
201 grpc::Status errorStatus{
202 grpc::StatusCode::RESOURCE_EXHAUSTED,
203 "too many differences between specified ledgers"};
204 return {response, errorStatus};
207 for (
auto& [k, v] : differences)
209 auto obj = response.mutable_ledger_objects()->add_objects();
210 auto inBase = v.first;
211 auto inDesired = v.second;
213 obj->set_key(k.data(), k.size());
216 assert(inDesired->size() > 0);
217 obj->set_data(inDesired->data(), inDesired->size());
219 if (inBase && inDesired)
221 org::xrpl::rpc::v1::RawLedgerObject::MODIFIED);
222 else if (inBase && !inDesired)
223 obj->set_mod_type(org::xrpl::rpc::v1::RawLedgerObject::DELETED);
225 obj->set_mod_type(org::xrpl::rpc::v1::RawLedgerObject::CREATED);
226 auto const blob = inDesired ? inDesired->slice() : inBase->slice();
227 auto const objectType =
230 if (request.get_object_neighbors())
232 if (!(inBase && inDesired))
237 obj->set_predecessor(
238 lb->key().data(), lb->key().size());
240 obj->set_successor(ub->key().data(), ub->key().size());
243 auto sle = std::make_shared<SLE>(
SerialIter{blob}, k);
244 if (!sle->isFieldPresent(
sfOwner))
247 if (!inBase && inDesired)
255 firstBook->key() == k)
257 auto succ = response.add_book_successors();
260 bookBase.key.size());
261 succ->set_first_book(
262 firstBook->key().data(),
263 firstBook->key().size());
266 if (inBase && !inDesired)
271 oldFirstBook->key() <
273 oldFirstBook->key() == k)
275 auto succ = response.add_book_successors();
278 bookBase.key.size());
285 newFirstBook->key() <
288 succ->set_first_book(
289 newFirstBook->key().data(),
290 newFirstBook->key().size());
299 response.set_objects_included(
true);
300 response.set_object_neighbors_included(request.get_object_neighbors());
301 response.set_skiplist_included(
true);
304 response.set_validated(
309 std::chrono::duration_cast<std::chrono::milliseconds>(end - begin)
312 JLOG(context.
j.
warn())
313 << __func__ <<
" - Extract time = " << duration
314 <<
" - num objects = " << response.ledger_objects().objects_size()
315 <<
" - num txns = " << response.transactions_list().transactions_size()
317 << duration / response.ledger_objects().objects_size()
319 << duration / response.transactions_list().transactions_size();
321 return {response, status};