rippled
LedgerHandler.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 <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/GRPCHelpers.h>
31 #include <ripple/rpc/impl/RPCHelpers.h>
32 
33 namespace ripple {
34 namespace RPC {
35 
36 LedgerHandler::LedgerHandler(JsonContext& context) : context_(context)
37 {
38 }
39 
40 Status
42 {
43  auto const& params = context_.params;
44  bool needsLedger = params.isMember(jss::ledger) ||
45  params.isMember(jss::ledger_hash) ||
46  params.isMember(jss::ledger_index) || context_.app.config().reporting();
47  if (!needsLedger)
48  return Status::OK;
49 
50  if (auto s = lookupLedger(ledger_, context_, result_))
51  return s;
52 
53  bool const full = params[jss::full].asBool();
54  bool const transactions = params[jss::transactions].asBool();
55  bool const accounts = params[jss::accounts].asBool();
56  bool const expand = params[jss::expand].asBool();
57  bool const binary = params[jss::binary].asBool();
58  bool const owner_funds = params[jss::owner_funds].asBool();
59  bool const queue = params[jss::queue].asBool();
60  auto type = chooseLedgerEntryType(params);
61  if (type.first)
62  return type.first;
63  type_ = type.second;
64 
65  options_ = (full ? LedgerFill::full : 0) |
66  (expand ? LedgerFill::expand : 0) |
67  (transactions ? LedgerFill::dumpTxrp : 0) |
68  (accounts ? LedgerFill::dumpState : 0) |
69  (binary ? LedgerFill::binary : 0) |
70  (owner_funds ? LedgerFill::ownerFunds : 0) |
71  (queue ? LedgerFill::dumpQueue : 0);
72 
73  if (full || accounts)
74  {
75  // Until some sane way to get full ledgers has been implemented,
76  // disallow retrieving all state nodes.
78  return rpcNO_PERMISSION;
79 
82  {
83  return rpcTOO_BUSY;
84  }
87  }
88  if (queue)
89  {
90  if (!ledger_ || !ledger_->open())
91  {
92  // It doesn't make sense to request the queue
93  // with a non-existant or closed/validated ledger.
94  return rpcINVALID_PARAMS;
95  }
96 
98  }
99 
100  return Status::OK;
101 }
102 
103 } // namespace RPC
104 
107 {
108  org::xrpl::rpc::v1::GetLedgerRequest& request = context.params;
109  org::xrpl::rpc::v1::GetLedgerResponse response;
110  grpc::Status status = grpc::Status::OK;
111 
113  if (RPC::ledgerFromRequest(ledger, context))
114  {
115  grpc::Status errorStatus{
116  grpc::StatusCode::NOT_FOUND, "ledger not found"};
117  return {response, errorStatus};
118  }
119 
120  Serializer s;
121  addRaw(ledger->info(), s, true);
122 
123  response.set_ledger_header(s.peekData().data(), s.getLength());
124 
125  if (request.transactions())
126  {
127  for (auto& i : ledger->txs)
128  {
129  assert(i.first);
130  if (request.expand())
131  {
132  auto txn =
133  response.mutable_transactions_list()->add_transactions();
134  Serializer sTxn = i.first->getSerializer();
135  txn->set_transaction_blob(sTxn.data(), sTxn.getLength());
136  if (i.second)
137  {
138  Serializer sMeta = i.second->getSerializer();
139  txn->set_metadata_blob(sMeta.data(), sMeta.getLength());
140  }
141  }
142  else
143  {
144  auto const& hash = i.first->getTransactionID();
145  response.mutable_hashes_list()->add_hashes(
146  hash.data(), hash.size());
147  }
148  }
149  }
150 
151  if (request.get_objects())
152  {
154  context.app.getLedgerMaster().getLedgerBySeq(ledger->seq() - 1);
155 
157  std::dynamic_pointer_cast<Ledger const>(parent);
158  if (!base)
159  {
160  grpc::Status errorStatus{
161  grpc::StatusCode::NOT_FOUND, "parent ledger not validated"};
162  return {response, errorStatus};
163  }
164 
166  std::dynamic_pointer_cast<Ledger const>(ledger);
167  if (!desired)
168  {
169  grpc::Status errorStatus{
170  grpc::StatusCode::NOT_FOUND, "ledger not validated"};
171  return {response, errorStatus};
172  }
173  SHAMap::Delta differences;
174 
175  int maxDifferences = std::numeric_limits<int>::max();
176 
177  bool res = base->stateMap().compare(
178  desired->stateMap(), differences, maxDifferences);
179  if (!res)
180  {
181  grpc::Status errorStatus{
182  grpc::StatusCode::RESOURCE_EXHAUSTED,
183  "too many differences between specified ledgers"};
184  return {response, errorStatus};
185  }
186 
187  for (auto& [k, v] : differences)
188  {
189  auto obj = response.mutable_ledger_objects()->add_objects();
190  auto inBase = v.first;
191  auto inDesired = v.second;
192 
193  obj->set_key(k.data(), k.size());
194  if (inDesired)
195  {
196  assert(inDesired->size() > 0);
197  obj->set_data(inDesired->data(), inDesired->size());
198  }
199  }
200  response.set_skiplist_included(true);
201  }
202 
203  response.set_validated(
204  RPC::isValidated(context.ledgerMaster, *ledger, context.app));
205 
206  return {response, status};
207 }
208 } // namespace ripple
ripple::ReadView::info
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
ripple::LedgerFill::dumpTxrp
@ dumpTxrp
Definition: LedgerToJson.h:46
ripple::RPC::Status::OK
static constexpr Code OK
Definition: Status.h:46
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::RPC::LedgerHandler::context_
JsonContext & context_
Definition: LedgerHandler.h:80
std::shared_ptr
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::TxQ::getTxs
std::vector< TxDetails > getTxs(ReadView const &view) const
Returns information about all transactions currently in the queue.
Definition: TxQ.cpp:1777
ripple::Resource::feeMediumBurdenRPC
const Charge feeMediumBurdenRPC
std::pair
ripple::addRaw
void addRaw(LedgerInfo const &info, Serializer &s, bool includeHash)
Definition: View.cpp:43
ripple::RPC::Context::loadType
Resource::Charge & loadType
Definition: Context.h:43
ripple::RPC::LedgerHandler::ledger_
std::shared_ptr< ReadView const > ledger_
Definition: LedgerHandler.h:81
ripple::LedgerFill::dumpQueue
@ dumpQueue
Definition: LedgerToJson.h:52
ripple::RPC::Context::ledgerMaster
LedgerMaster & ledgerMaster
Definition: Context.h:45
ripple::doLedgerGrpc
std::pair< org::xrpl::rpc::v1::GetLedgerResponse, grpc::Status > doLedgerGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerRequest > &context)
Definition: LedgerHandler.cpp:106
ripple::rpcTOO_BUSY
@ rpcTOO_BUSY
Definition: ErrorCodes.h:56
ripple::RPC::Context::role
Role role
Definition: Context.h:47
ripple::LedgerFill::expand
@ expand
Definition: LedgerToJson.h:48
ripple::RPC::lookupLedger
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:535
ripple::Application::getFeeTrack
virtual LoadFeeTrack & getFeeTrack()=0
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:75
ripple::LoadFeeTrack::isLoadedLocal
bool isLoadedLocal() const
Definition: LoadFeeTrack.h:123
ripple::Config::reporting
bool reporting() const
Definition: Config.h:267
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::Application::config
virtual Config & config()=0
ripple::Ledger::stateMap
SHAMap const & stateMap() const
Definition: Ledger.h:308
ripple::LedgerFill::full
@ full
Definition: LedgerToJson.h:49
ripple::RPC::GRPCContext
Definition: Context.h:70
ripple::Application::getTxQ
virtual TxQ & getTxQ()=0
ripple::RPC::Context::app
Application & app
Definition: Context.h:42
ripple::LedgerMaster::getLedgerBySeq
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
Definition: LedgerMaster.cpp:1740
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
std::map
STL class.
ripple::RPC::Status
Status represents the results of an operation that might fail.
Definition: Status.h:39
ripple::isUnlimited
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition: Role.cpp:94
ripple::Serializer
Definition: Serializer.h:39
ripple::LedgerFill::binary
@ binary
Definition: LedgerToJson.h:50
ripple::RPC::GRPCContext::params
RequestType params
Definition: Context.h:72
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::LedgerFill::ownerFunds
@ ownerFunds
Definition: LedgerToJson.h:51
ripple::RPC::isValidated
bool isValidated(LedgerMaster &ledgerMaster, ReadView const &ledger, Application &app)
Definition: RPCHelpers.cpp:464
ripple::RPC::LedgerHandler::LedgerHandler
LedgerHandler(JsonContext &)
Definition: LedgerHandler.cpp:36
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:260
ripple::RPC::chooseLedgerEntryType
std::pair< RPC::Status, LedgerEntryType > chooseLedgerEntryType(Json::Value const &params)
Definition: RPCHelpers.cpp:835
ripple::rpcNO_PERMISSION
@ rpcNO_PERMISSION
Definition: ErrorCodes.h:53
ripple::RPC::LedgerHandler::type_
LedgerEntryType type_
Definition: LedgerHandler.h:85
ripple::Serializer::peekData
Blob const & peekData() const
Definition: Serializer.h:166
ripple::RPC::LedgerHandler::check
Status check()
Definition: LedgerHandler.cpp:41
ripple::SHAMap::compare
bool compare(SHAMap const &otherMap, Delta &differences, int maxCount) const
Definition: SHAMapDelta.cpp:124
ripple::RPC::LedgerHandler::options_
int options_
Definition: LedgerHandler.h:84
ripple::RPC::LedgerHandler::queueTxs_
std::vector< TxQ::TxDetails > queueTxs_
Definition: LedgerHandler.h:82
ripple::LedgerFill::dumpState
@ dumpState
Definition: LedgerToJson.h:47
std::numeric_limits::max
T max(T... args)
ripple::Serializer::getLength
int getLength() const
Definition: Serializer.h:197
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
ripple::DataFormat::binary
@ binary
std::vector::data
T data(T... args)
ripple::RPC::ledgerFromRequest
Status ledgerFromRequest(T &ledger, GRPCContext< R > &context)
Definition: RPCHelpers.cpp:252
ripple::Resource::feeHighBurdenRPC
const Charge feeHighBurdenRPC
ripple::RPC::LedgerHandler::result_
Json::Value result_
Definition: LedgerHandler.h:83
ripple::ReadView::txs
txs_type txs
Definition: ReadView.h:390