103    org::xrpl::rpc::v1::GetLedgerRequest& request = context.
params;
 
  104    org::xrpl::rpc::v1::GetLedgerResponse response;
 
  105    grpc::Status status = grpc::Status::OK;
 
  110        grpc::Status errorStatus;
 
  113            errorStatus = grpc::Status(
 
  114                grpc::StatusCode::INVALID_ARGUMENT, status.message());
 
  119                grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
 
  121        return {response, errorStatus};
 
  125    addRaw(ledger->info(), s, 
true);
 
  129    if (request.transactions())
 
  133            for (
auto& i : ledger->txs)
 
  136                    i.first, 
"ripple::doLedgerGrpc : non-null transaction");
 
  137                if (request.expand())
 
  139                    auto txn = response.mutable_transactions_list()
 
  140                                   ->add_transactions();
 
  151                    auto const& hash = i.first->getTransactionID();
 
  152                    response.mutable_hashes_list()->add_hashes(
 
  153                        hash.data(), hash.size());
 
  160                << __func__ << 
" - Error deserializing transaction in ledger " 
  161                << ledger->info().seq
 
  162                << 
" . skipping transaction and following transactions. You " 
  163                   "should look into this further";
 
  167    if (request.get_objects())
 
  176            grpc::Status errorStatus{
 
  177                grpc::StatusCode::NOT_FOUND, 
"parent ledger not validated"};
 
  178            return {response, errorStatus};
 
  185            grpc::Status errorStatus{
 
  186                grpc::StatusCode::NOT_FOUND, 
"ledger not validated"};
 
  187            return {response, errorStatus};
 
  193        bool res = base->stateMap().compare(
 
  194            desired->stateMap(), differences, maxDifferences);
 
  197            grpc::Status errorStatus{
 
  198                grpc::StatusCode::RESOURCE_EXHAUSTED,
 
  199                "too many differences between specified ledgers"};
 
  200            return {response, errorStatus};
 
  203        for (
auto& [k, v] : differences)
 
  205            auto obj = response.mutable_ledger_objects()->add_objects();
 
  206            auto inBase = v.first;
 
  207            auto inDesired = v.second;
 
  209            obj->set_key(k.data(), k.size());
 
  213                    inDesired->size() > 0,
 
  214                    "ripple::doLedgerGrpc : non-empty desired");
 
  215                obj->set_data(inDesired->data(), inDesired->size());
 
  217            if (inBase && inDesired)
 
  219                    org::xrpl::rpc::v1::RawLedgerObject::MODIFIED);
 
  220            else if (inBase && !inDesired)
 
  221                obj->set_mod_type(org::xrpl::rpc::v1::RawLedgerObject::DELETED);
 
  223                obj->set_mod_type(org::xrpl::rpc::v1::RawLedgerObject::CREATED);
 
  224            auto const blob = inDesired ? inDesired->slice() : inBase->slice();
 
  225            auto const objectType =
 
  228            if (request.get_object_neighbors())
 
  230                if (!(inBase && inDesired))
 
  232                    auto lb = desired->stateMap().lower_bound(k);
 
  233                    auto ub = desired->stateMap().upper_bound(k);
 
  234                    if (lb != desired->stateMap().end())
 
  235                        obj->set_predecessor(
 
  236                            lb->key().data(), lb->key().size());
 
  237                    if (ub != desired->stateMap().end())
 
  238                        obj->set_successor(ub->key().data(), ub->key().size());
 
  239                    if (objectType == ltDIR_NODE)
 
  242                        if (!sle->isFieldPresent(sfOwner))
 
  245                            if (!inBase && inDesired)
 
  248                                    desired->stateMap().upper_bound(
 
  250                                if (firstBook != desired->stateMap().end() &&
 
  253                                    firstBook->key() == k)
 
  255                                    auto succ = response.add_book_successors();
 
  258                                        bookBase.key.size());
 
  259                                    succ->set_first_book(
 
  260                                        firstBook->key().data(),
 
  261                                        firstBook->key().size());
 
  264                            if (inBase && !inDesired)
 
  267                                    base->stateMap().upper_bound(bookBase.key);
 
  268                                if (oldFirstBook != base->stateMap().end() &&
 
  269                                    oldFirstBook->key() <
 
  271                                    oldFirstBook->key() == k)
 
  273                                    auto succ = response.add_book_successors();
 
  276                                        bookBase.key.size());
 
  278                                        desired->stateMap().upper_bound(
 
  282                                            desired->stateMap().end() &&
 
  283                                        newFirstBook->key() <
 
  286                                        succ->set_first_book(
 
  287                                            newFirstBook->key().data(),
 
  288                                            newFirstBook->key().size());
 
  297        response.set_objects_included(
true);
 
  298        response.set_object_neighbors_included(request.get_object_neighbors());
 
  299        response.set_skiplist_included(
true);
 
  306        std::chrono::duration_cast<std::chrono::milliseconds>(end - begin)
 
  309    JLOG(context.
j.
warn())
 
  310        << __func__ << 
" - Extract time = " << duration
 
  311        << 
" - num objects = " << response.ledger_objects().objects_size()
 
  312        << 
" - num txns = " << response.transactions_list().transactions_size()
 
  314        << duration / response.ledger_objects().objects_size()
 
  316        << duration / response.transactions_list().transactions_size();
 
  318    return {response, status};
 
 
Resource::Charge & loadType