rippled
Handler.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/rpc/handlers/Handlers.h>
21 #include <ripple/rpc/handlers/Version.h>
22 #include <ripple/rpc/impl/Handler.h>
23 #include <ripple/rpc/impl/RPCHelpers.h>
24 
25 namespace ripple {
26 namespace RPC {
27 namespace {
28 
30 template <typename Function>
31 Handler::Method<Json::Value>
32 byRef(Function const& f)
33 {
34  return [f](JsonContext& context, Json::Value& result) {
35  result = f(context);
36  if (result.type() != Json::objectValue)
37  {
38  assert(false);
39  result = RPC::makeObjectValue(result);
40  }
41 
42  return Status();
43  };
44 }
45 
46 template <class Object, class HandlerImpl>
47 Status
48 handle(JsonContext& context, Object& object)
49 {
50  HandlerImpl handler(context);
51 
52  auto status = handler.check();
53  if (status)
54  status.inject(object);
55  else
56  handler.writeResult(object);
57  return status;
58 };
59 
60 Handler const handlerArray[]{
61  // Some handlers not specified here are added to the table via addHandler()
62  // Request-response methods
63  {"account_info", byRef(&doAccountInfo), Role::USER, NO_CONDITION},
64  {"account_currencies",
65  byRef(&doAccountCurrencies),
66  Role::USER,
67  NO_CONDITION},
68  {"account_lines", byRef(&doAccountLines), Role::USER, NO_CONDITION},
69  {"account_channels", byRef(&doAccountChannels), Role::USER, NO_CONDITION},
70  {"account_objects", byRef(&doAccountObjects), Role::USER, NO_CONDITION},
71  {"account_offers", byRef(&doAccountOffers), Role::USER, NO_CONDITION},
72  {"account_tx", byRef(&doAccountTxJson), Role::USER, NO_CONDITION},
73  {"blacklist", byRef(&doBlackList), Role::ADMIN, NO_CONDITION},
74  {"book_offers", byRef(&doBookOffers), Role::USER, NO_CONDITION},
75  {"can_delete", byRef(&doCanDelete), Role::ADMIN, NO_CONDITION},
76  {"channel_authorize", byRef(&doChannelAuthorize), Role::USER, NO_CONDITION},
77  {"channel_verify", byRef(&doChannelVerify), Role::USER, NO_CONDITION},
78  {"connect", byRef(&doConnect), Role::ADMIN, NO_CONDITION},
79  {"consensus_info", byRef(&doConsensusInfo), Role::ADMIN, NO_CONDITION},
80  {"deposit_authorized",
81  byRef(&doDepositAuthorized),
82  Role::USER,
83  NO_CONDITION},
84  {"download_shard", byRef(&doDownloadShard), Role::ADMIN, NO_CONDITION},
85  {"gateway_balances", byRef(&doGatewayBalances), Role::USER, NO_CONDITION},
86  {"get_counts", byRef(&doGetCounts), Role::ADMIN, NO_CONDITION},
87  {"feature", byRef(&doFeature), Role::ADMIN, NO_CONDITION},
88  {"fee", byRef(&doFee), Role::USER, NEEDS_CURRENT_LEDGER},
89  {"fetch_info", byRef(&doFetchInfo), Role::ADMIN, NO_CONDITION},
90  {"ledger_accept",
91  byRef(&doLedgerAccept),
94  {"ledger_cleaner",
95  byRef(&doLedgerCleaner),
98  {"ledger_closed", byRef(&doLedgerClosed), Role::USER, NO_CONDITION},
99  {"ledger_current",
100  byRef(&doLedgerCurrent),
101  Role::USER,
103  {"ledger_data", byRef(&doLedgerData), Role::USER, NO_CONDITION},
104  {"ledger_entry", byRef(&doLedgerEntry), Role::USER, NO_CONDITION},
105  {"ledger_header", byRef(&doLedgerHeader), Role::USER, NO_CONDITION},
106  {"ledger_request", byRef(&doLedgerRequest), Role::ADMIN, NO_CONDITION},
107  {"log_level", byRef(&doLogLevel), Role::ADMIN, NO_CONDITION},
108  {"logrotate", byRef(&doLogRotate), Role::ADMIN, NO_CONDITION},
109  {"manifest", byRef(&doManifest), Role::USER, NO_CONDITION},
110  {"noripple_check", byRef(&doNoRippleCheck), Role::USER, NO_CONDITION},
111  {"owner_info", byRef(&doOwnerInfo), Role::USER, NEEDS_CURRENT_LEDGER},
112  {"peers", byRef(&doPeers), Role::ADMIN, NO_CONDITION},
113  {"path_find", byRef(&doPathFind), Role::USER, NEEDS_CURRENT_LEDGER},
114  {"ping", byRef(&doPing), Role::USER, NO_CONDITION},
115  {"print", byRef(&doPrint), Role::ADMIN, NO_CONDITION},
116  // { "profile", byRef (&doProfile), Role::USER,
117  // NEEDS_CURRENT_LEDGER },
118  {"random", byRef(&doRandom), Role::USER, NO_CONDITION},
119  {"peer_reservations_add",
120  byRef(&doPeerReservationsAdd),
121  Role::ADMIN,
122  NO_CONDITION},
123  {"peer_reservations_del",
124  byRef(&doPeerReservationsDel),
125  Role::ADMIN,
126  NO_CONDITION},
127  {"peer_reservations_list",
128  byRef(&doPeerReservationsList),
129  Role::ADMIN,
130  NO_CONDITION},
131  {"ripple_path_find", byRef(&doRipplePathFind), Role::USER, NO_CONDITION},
132  {"sign", byRef(&doSign), Role::USER, NO_CONDITION},
133  {"sign_for", byRef(&doSignFor), Role::USER, NO_CONDITION},
134  {"submit", byRef(&doSubmit), Role::USER, NEEDS_CURRENT_LEDGER},
135  {"submit_multisigned",
136  byRef(&doSubmitMultiSigned),
137  Role::USER,
139  {"server_info", byRef(&doServerInfo), Role::USER, NO_CONDITION},
140  {"server_state", byRef(&doServerState), Role::USER, NO_CONDITION},
141  {"crawl_shards", byRef(&doCrawlShards), Role::ADMIN, NO_CONDITION},
142  {"stop", byRef(&doStop), Role::ADMIN, NO_CONDITION},
143  {"transaction_entry", byRef(&doTransactionEntry), Role::USER, NO_CONDITION},
144  {"tx", byRef(&doTxJson), Role::USER, NEEDS_NETWORK_CONNECTION},
145  {"tx_history", byRef(&doTxHistory), Role::USER, NO_CONDITION},
146  {"unl_list", byRef(&doUnlList), Role::ADMIN, NO_CONDITION},
147  {"validation_create",
148  byRef(&doValidationCreate),
149  Role::ADMIN,
150  NO_CONDITION},
151  {"validators", byRef(&doValidators), Role::ADMIN, NO_CONDITION},
152  {"validator_list_sites",
153  byRef(&doValidatorListSites),
154  Role::ADMIN,
155  NO_CONDITION},
156  {"validator_info", byRef(&doValidatorInfo), Role::ADMIN, NO_CONDITION},
157  {"wallet_propose", byRef(&doWalletPropose), Role::ADMIN, NO_CONDITION},
158 
159  // Evented methods
160  {"subscribe", byRef(&doSubscribe), Role::USER, NO_CONDITION},
161  {"unsubscribe", byRef(&doUnsubscribe), Role::USER, NO_CONDITION},
162 };
163 
164 class HandlerTable
165 {
166 private:
167  template <std::size_t N>
168  explicit HandlerTable(const Handler (&entries)[N])
169  {
170  for (auto v = RPC::ApiMinimumSupportedVersion;
172  ++v)
173  {
174  for (std::size_t i = 0; i < N; ++i)
175  {
176  auto& innerTable = table_[versionToIndex(v)];
177  auto const& entry = entries[i];
178  assert(innerTable.find(entry.name_) == innerTable.end());
179  innerTable[entry.name_] = entry;
180  }
181 
182  // This is where the new-style handlers are added.
183  // This is also where different versions of handlers are added.
184  addHandler<LedgerHandler>(v);
185  addHandler<VersionHandler>(v);
186  }
187  }
188 
189 public:
190  static HandlerTable const&
191  instance()
192  {
193  static HandlerTable const handlerTable(handlerArray);
194  return handlerTable;
195  }
196 
197  Handler const*
198  getHandler(unsigned version, std::string name) const
199  {
200  if (version > RPC::ApiMaximumSupportedVersion ||
202  return nullptr;
203  auto& innerTable = table_[versionToIndex(version)];
204  auto i = innerTable.find(name);
205  return i == innerTable.end() ? nullptr : &i->second;
206  }
207 
209  getHandlerNames() const
210  {
212  for (int index = 0; index < table_.size(); ++index)
213  {
214  for (auto const& h : table_[index])
215  {
216  name_set.insert(h.second.name_);
217  }
218  }
219  return std::vector<char const*>(name_set.begin(), name_set.end());
220  }
221 
222 private:
224  table_;
225 
226  template <class HandlerImpl>
227  void
228  addHandler(unsigned version)
229  {
230  assert(
231  version >= RPC::ApiMinimumSupportedVersion &&
233  auto& innerTable = table_[versionToIndex(version)];
234  assert(innerTable.find(HandlerImpl::name()) == innerTable.end());
235 
236  Handler h;
237  h.name_ = HandlerImpl::name();
238  h.valueMethod_ = &handle<Json::Value, HandlerImpl>;
239  h.role_ = HandlerImpl::role();
240  h.condition_ = HandlerImpl::condition();
241 
242  innerTable[HandlerImpl::name()] = h;
243  }
244 
245  inline unsigned
246  versionToIndex(unsigned version) const
247  {
248  return version - RPC::ApiMinimumSupportedVersion;
249  }
250 };
251 
252 } // namespace
253 
254 Handler const*
255 getHandler(unsigned version, std::string const& name)
256 {
257  return HandlerTable::instance().getHandler(version, name);
258 }
259 
262 {
263  return HandlerTable::instance().getHandlerNames();
264 };
265 
266 } // namespace RPC
267 } // namespace ripple
ripple::doFeature
Json::Value doFeature(RPC::JsonContext &context)
Definition: Feature1.cpp:36
ripple::doLedgerAccept
Json::Value doLedgerAccept(RPC::JsonContext &)
Definition: LedgerAccept.cpp:35
ripple::doUnlList
Json::Value doUnlList(RPC::JsonContext &)
Definition: UnlList.cpp:28
ripple::doGetCounts
Json::Value doGetCounts(RPC::JsonContext &context)
Definition: GetCounts.cpp:154
ripple::doLedgerEntry
Json::Value doLedgerEntry(RPC::JsonContext &)
Definition: LedgerEntry.cpp:39
ripple::doLedgerCurrent
Json::Value doLedgerCurrent(RPC::JsonContext &)
Definition: LedgerCurrent.cpp:30
ripple::doAccountCurrencies
Json::Value doAccountCurrencies(RPC::JsonContext &context)
Definition: AccountCurrenciesHandler.cpp:32
std::string
STL class.
ripple::doValidationCreate
Json::Value doValidationCreate(RPC::JsonContext &)
Definition: ValidationCreate.cpp:45
ripple::doOwnerInfo
Json::Value doOwnerInfo(RPC::JsonContext &)
Definition: OwnerInfo.cpp:34
ripple::doPathFind
Json::Value doPathFind(RPC::JsonContext &)
Definition: PathFind.cpp:33
ripple::doDownloadShard
Json::Value doDownloadShard(RPC::JsonContext &context)
RPC command that downloads and import shard archives.
Definition: DownloadShard.cpp:49
ripple::doAccountInfo
Json::Value doAccountInfo(RPC::JsonContext &context)
Definition: AccountInfo.cpp:53
ripple::doRipplePathFind
Json::Value doRipplePathFind(RPC::JsonContext &)
Definition: RipplePathFind.cpp:32
ripple::doSignFor
Json::Value doSignFor(RPC::JsonContext &)
Definition: SignFor.cpp:35
std::unordered_set
STL class.
ripple::doAccountObjects
Json::Value doAccountObjects(RPC::JsonContext &context)
General RPC command that can retrieve objects in the account root.
Definition: AccountObjects.cpp:50
std::vector
STL class.
ripple::RPC::APINumberVersionSupported
constexpr unsigned int APINumberVersionSupported
Definition: RPCHelpers.h:215
ripple::doValidators
Json::Value doValidators(RPC::JsonContext &)
Definition: Validators.cpp:27
ripple::doValidatorListSites
Json::Value doValidatorListSites(RPC::JsonContext &)
Definition: ValidatorListSites.cpp:27
ripple::doChannelVerify
Json::Value doChannelVerify(RPC::JsonContext &)
Definition: PayChanClaim.cpp:99
ripple::RPC::NEEDS_NETWORK_CONNECTION
@ NEEDS_NETWORK_CONNECTION
Definition: Handler.h:41
ripple::doPrint
Json::Value doPrint(RPC::JsonContext &)
Definition: Print.cpp:29
ripple::doGatewayBalances
Json::Value doGatewayBalances(RPC::JsonContext &context)
Definition: GatewayBalances.cpp:53
ripple::doManifest
Json::Value doManifest(RPC::JsonContext &)
Definition: rpc/handlers/Manifest.cpp:29
ripple::doPeers
Json::Value doPeers(RPC::JsonContext &)
Definition: Peers.cpp:31
ripple::doSubmitMultiSigned
Json::Value doSubmitMultiSigned(RPC::JsonContext &)
Definition: SubmitMultiSigned.cpp:34
ripple::doCrawlShards
Json::Value doCrawlShards(RPC::JsonContext &context)
RPC command that reports stored shards by nodes.
Definition: CrawlShards.cpp:43
ripple::doTxHistory
Json::Value doTxHistory(RPC::JsonContext &)
Definition: TxHistory.cpp:38
ripple::RPC::ApiMinimumSupportedVersion
constexpr unsigned int ApiMinimumSupportedVersion
Definition: RPCHelpers.h:213
ripple::doLogLevel
Json::Value doLogLevel(RPC::JsonContext &)
Definition: LogLevel.cpp:32
ripple::doSubmit
Json::Value doSubmit(RPC::JsonContext &)
Definition: Submit.cpp:48
ripple::Role::ADMIN
@ ADMIN
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::doPing
Json::Value doPing(RPC::JsonContext &)
Definition: Ping.cpp:32
ripple::doLedgerRequest
Json::Value doLedgerRequest(RPC::JsonContext &)
Definition: LedgerRequest.cpp:38
ripple::Role::USER
@ USER
ripple::doChannelAuthorize
Json::Value doChannelAuthorize(RPC::JsonContext &)
Definition: PayChanClaim.cpp:44
ripple::RPC::NEEDS_CURRENT_LEDGER
@ NEEDS_CURRENT_LEDGER
Definition: Handler.h:42
ripple::doRandom
Json::Value doRandom(RPC::JsonContext &)
Definition: Random.cpp:39
ripple::doValidatorInfo
Json::Value doValidatorInfo(RPC::JsonContext &)
Definition: ValidatorInfo.cpp:30
ripple::doStop
Json::Value doStop(RPC::JsonContext &)
Definition: Stop.cpp:33
ripple::doWalletPropose
Json::Value doWalletPropose(RPC::JsonContext &)
Definition: WalletPropose.cpp:68
std::array
STL class.
ripple::RPC::NO_CONDITION
@ NO_CONDITION
Definition: Handler.h:40
ripple::RPC::ApiMaximumSupportedVersion
constexpr unsigned int ApiMaximumSupportedVersion
Definition: RPCHelpers.h:214
ripple::doCanDelete
Json::Value doCanDelete(RPC::JsonContext &context)
Definition: CanDelete.cpp:34
ripple::doConsensusInfo
Json::Value doConsensusInfo(RPC::JsonContext &context)
Definition: ConsensusInfo.cpp:29
ripple::doLedgerData
Json::Value doLedgerData(RPC::JsonContext &)
Definition: LedgerData.cpp:44
ripple::doAccountOffers
Json::Value doAccountOffers(RPC::JsonContext &context)
Definition: AccountOffers.cpp:57
ripple::doLogRotate
Json::Value doLogRotate(RPC::JsonContext &)
Definition: LogRotate.cpp:28
ripple::doNoRippleCheck
Json::Value doNoRippleCheck(RPC::JsonContext &)
Definition: NoRippleCheck.cpp:61
ripple::doLedgerClosed
Json::Value doLedgerClosed(RPC::JsonContext &)
Definition: LedgerClosed.cpp:29
ripple::doBookOffers
Json::Value doBookOffers(RPC::JsonContext &context)
Definition: BookOffers.cpp:35
std::experimental::filesystem::status
T status(T... args)
ripple::doPeerReservationsList
Json::Value doPeerReservationsList(RPC::JsonContext &)
Definition: Reservations.cpp:116
ripple::NodeStore::Status
Status
Return codes from Backend operations.
Definition: nodestore/Types.h:44
ripple::doTransactionEntry
Json::Value doTransactionEntry(RPC::JsonContext &)
Definition: TransactionEntry.cpp:36
ripple::doUnsubscribe
Json::Value doUnsubscribe(RPC::JsonContext &)
Definition: Unsubscribe.cpp:32
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::doBlackList
Json::Value doBlackList(RPC::JsonContext &context)
Definition: BlackList.cpp:28
std::unordered_set::begin
T begin(T... args)
ripple::doAccountTxJson
Json::Value doAccountTxJson(RPC::JsonContext &context)
Definition: AccountTx.cpp:526
std::unordered_set::insert
T insert(T... args)
ripple::doSign
Json::Value doSign(RPC::JsonContext &)
Definition: SignHandler.cpp:33
ripple::doPeerReservationsDel
Json::Value doPeerReservationsDel(RPC::JsonContext &)
Definition: Reservations.cpp:89
ripple::doTxJson
Json::Value doTxJson(RPC::JsonContext &)
Definition: Tx.cpp:322
ripple::RPC::makeObjectValue
Json::Value makeObjectValue(Value const &value, Json::StaticString const &field=jss::message)
Return a Json::objectValue with a single entry.
Definition: Handler.h:63
std::size_t
ripple::doAccountChannels
Json::Value doAccountChannels(RPC::JsonContext &context)
Definition: AccountChannels.cpp:68
ripple::doServerInfo
Json::Value doServerInfo(RPC::JsonContext &)
Definition: ServerInfo.cpp:31
std::unordered_set::end
T end(T... args)
ripple::doLedgerHeader
Json::Value doLedgerHeader(RPC::JsonContext &)
Definition: LedgerHeader.cpp:33
ripple::doFetchInfo
Json::Value doFetchInfo(RPC::JsonContext &context)
Definition: FetchInfo.cpp:28
ripple::doServerState
Json::Value doServerState(RPC::JsonContext &)
Definition: ServerState.cpp:31
ripple::doConnect
Json::Value doConnect(RPC::JsonContext &context)
Definition: Connect.cpp:38
ripple::doLedgerCleaner
Json::Value doLedgerCleaner(RPC::JsonContext &)
Definition: LedgerCleanerHandler.cpp:29
ripple::RPC::getHandlerNames
std::vector< char const * > getHandlerNames()
Return names of all methods.
Definition: Handler.cpp:261
ripple::doDepositAuthorized
Json::Value doDepositAuthorized(RPC::JsonContext &context)
Definition: DepositAuthorized.cpp:37
ripple::RPC::getHandler
Handler const * getHandler(unsigned version, std::string const &name)
Definition: Handler.cpp:255
ripple::doPeerReservationsAdd
Json::Value doPeerReservationsAdd(RPC::JsonContext &)
Definition: Reservations.cpp:36
ripple::doAccountLines
Json::Value doAccountLines(RPC::JsonContext &context)
Definition: AccountLines.cpp:83
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::doFee
Json::Value doFee(RPC::JsonContext &context)
Definition: Fee1.cpp:31
ripple::doSubscribe
Json::Value doSubscribe(RPC::JsonContext &)
Definition: Subscribe.cpp:37