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-existent 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 (auto status = RPC::ledgerFromRequest(ledger, context))
114  {
115  grpc::Status errorStatus;
116  if (status.toErrorCode() == rpcINVALID_PARAMS)
117  {
118  errorStatus = grpc::Status(
119  grpc::StatusCode::INVALID_ARGUMENT, status.message());
120  }
121  else
122  {
123  errorStatus =
124  grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
125  }
126  return {response, errorStatus};
127  }
128 
129  Serializer s;
130  addRaw(ledger->info(), s, true);
131 
132  response.set_ledger_header(s.peekData().data(), s.getLength());
133 
134  if (request.transactions())
135  {
136  for (auto& i : ledger->txs)
137  {
138  assert(i.first);
139  if (request.expand())
140  {
141  auto txn =
142  response.mutable_transactions_list()->add_transactions();
143  Serializer sTxn = i.first->getSerializer();
144  txn->set_transaction_blob(sTxn.data(), sTxn.getLength());
145  if (i.second)
146  {
147  Serializer sMeta = i.second->getSerializer();
148  txn->set_metadata_blob(sMeta.data(), sMeta.getLength());
149  }
150  }
151  else
152  {
153  auto const& hash = i.first->getTransactionID();
154  response.mutable_hashes_list()->add_hashes(
155  hash.data(), hash.size());
156  }
157  }
158  }
159 
160  if (request.get_objects())
161  {
163  context.app.getLedgerMaster().getLedgerBySeq(ledger->seq() - 1);
164 
166  std::dynamic_pointer_cast<Ledger const>(parent);
167  if (!base)
168  {
169  grpc::Status errorStatus{
170  grpc::StatusCode::NOT_FOUND, "parent ledger not validated"};
171  return {response, errorStatus};
172  }
173 
175  std::dynamic_pointer_cast<Ledger const>(ledger);
176  if (!desired)
177  {
178  grpc::Status errorStatus{
179  grpc::StatusCode::NOT_FOUND, "ledger not validated"};
180  return {response, errorStatus};
181  }
182  SHAMap::Delta differences;
183 
184  int maxDifferences = std::numeric_limits<int>::max();
185 
186  bool res = base->stateMap().compare(
187  desired->stateMap(), differences, maxDifferences);
188  if (!res)
189  {
190  grpc::Status errorStatus{
191  grpc::StatusCode::RESOURCE_EXHAUSTED,
192  "too many differences between specified ledgers"};
193  return {response, errorStatus};
194  }
195 
196  for (auto& [k, v] : differences)
197  {
198  auto obj = response.mutable_ledger_objects()->add_objects();
199  auto inBase = v.first;
200  auto inDesired = v.second;
201 
202  obj->set_key(k.data(), k.size());
203  if (inDesired)
204  {
205  assert(inDesired->size() > 0);
206  obj->set_data(inDesired->data(), inDesired->size());
207  }
208  if (inBase && inDesired)
209  obj->set_mod_type(
210  org::xrpl::rpc::v1::RawLedgerObject::MODIFIED);
211  else if (inBase && !inDesired)
212  obj->set_mod_type(org::xrpl::rpc::v1::RawLedgerObject::DELETED);
213  else
214  obj->set_mod_type(org::xrpl::rpc::v1::RawLedgerObject::CREATED);
215  }
216  response.set_skiplist_included(true);
217  }
218 
219  response.set_validated(
220  RPC::isValidated(context.ledgerMaster, *ledger, context.app));
221 
222  return {response, status};
223 }
224 } // 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:1780
ripple::Resource::feeMediumBurdenRPC
const Charge feeMediumBurdenRPC
std::pair
ripple::addRaw
void addRaw(LedgerInfo const &info, Serializer &s, bool includeHash)
Definition: View.cpp:164
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:540
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:308
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::Application::config
virtual Config & config()=0
ripple::Ledger::stateMap
SHAMap const & stateMap() const
Definition: Ledger.h:307
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:1767
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:468
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:840
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:168
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:199
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
std::vector::data
T data(T... args)
ripple::RPC::ledgerFromRequest
Status ledgerFromRequest(T &ledger, GRPCContext< R > &context)
Definition: RPCHelpers.cpp:253
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