1#include <xrpld/rpc/detail/Handler.h>
3#include <xrpld/rpc/Context.h>
4#include <xrpld/rpc/Role.h>
5#include <xrpld/rpc/handlers/Handlers.h>
6#include <xrpld/rpc/handlers/ledger/Ledger.h>
7#include <xrpld/rpc/handlers/server_info/Version.h>
9#include <xrpl/basics/contract.h>
10#include <xrpl/beast/utility/instrumentation.h>
11#include <xrpl/json/json_value.h>
12#include <xrpl/protocol/ApiVersion.h>
25template <
typename Function>
27byRef(Function
const& f)
29 return [f](
JsonContext& context, json::Value& result) {
34 UNREACHABLE(
"xrpl::RPC::byRef : result is object");
43template <
class Object,
class HandlerImpl>
48 context.apiVersion >= HandlerImpl::minApiVer &&
49 context.apiVersion <= HandlerImpl::maxApiVer,
50 "xrpl::RPC::handle : valid API version");
51 HandlerImpl handler(context);
53 auto status = handler.check();
60 handler.writeResult(
object);
65template <
typename HandlerImpl>
71 &handle<json::Value, HandlerImpl>,
73 HandlerImpl::condition,
74 HandlerImpl::minApiVer,
75 HandlerImpl::maxApiVer};
81 {.name =
"account_info",
85 {.name =
"account_currencies",
89 {.name =
"account_lines",
93 {.name =
"account_channels",
97 {.name =
"account_nfts",
101 {.name =
"account_objects",
105 {.name =
"account_offers",
109 {.name =
"account_tx",
117 {.name =
"blacklist",
121 {.name =
"book_changes",
125 {.name =
"book_offers",
129 {.name =
"can_delete",
133 {.name =
"channel_authorize",
137 {.name =
"channel_verify",
145 {.name =
"consensus_info",
149 {.name =
"deposit_authorized",
158 .valueMethod = byRef(&
doFee),
161 {.name =
"fetch_info",
165 {.name =
"gateway_balances",
169 {.name =
"get_counts",
173 {.name =
"get_aggregate_price",
177 {.name =
"ledger_accept",
181 {.name =
"ledger_cleaner",
185 {.name =
"ledger_closed",
189 {.name =
"ledger_current",
193 {.name =
"ledger_data",
197 {.name =
"ledger_entry",
201 {.name =
"ledger_header",
207 {.name =
"ledger_request",
211 {.name =
"log_level",
215 {.name =
"logrotate",
223 {.name =
"nft_buy_offers",
227 {.name =
"nft_sell_offers",
231 {.name =
"noripple_check",
235 {.name =
"owner_info",
240 .valueMethod = byRef(&
doPeers),
243 {.name =
"path_find",
248 .valueMethod = byRef(&
doPing),
252 .valueMethod = byRef(&
doPrint),
261 {.name =
"peer_reservations_add",
265 {.name =
"peer_reservations_del",
269 {.name =
"peer_reservations_list",
273 {.name =
"ripple_path_find",
277 {.name =
"server_definitions",
281 {.name =
"server_info",
285 {.name =
"server_state",
290 .valueMethod = byRef(&
doSign),
302 .valueMethod = byRef(&
doStop),
309 {.name =
"submit_multisigned",
313 {.name =
"transaction_entry",
321 {.name =
"tx_history",
327 {.name =
"tx_reduce_relay",
335 {.name =
"validation_create",
339 {.name =
"validators",
343 {.name =
"validator_list_sites",
347 {.name =
"validator_info",
351 {.name =
"vault_info",
355 {.name =
"wallet_propose",
360 {.name =
"subscribe",
364 {.name =
"unsubscribe",
373 using handler_table_t = std::multimap<std::string, Handler>;
377 [[nodiscard]]
static bool
378 overlappingApiVersion(
379 std::pair<handler_table_t::iterator, handler_table_t::iterator>
range,
383 XRPL_ASSERT(minVer <= maxVer,
"xrpl::RPC::HandlerTable : valid API version range");
386 "xrpl::RPC::HandlerTable : valid max API version");
391 [minVer, maxVer](
auto const& item) {
392 return item.second.minApiVer <= maxVer && item.second.maxApiVer >= minVer;
396 template <std::
size_t N>
397 explicit HandlerTable(Handler
const (&entries)[N])
399 for (
auto const& entry : entries)
401 if (overlappingApiVersion(
405 std::string(
"Handler for ") +
entry.name +
406 " overlaps with an existing handler");
413 addHandler<LedgerHandler>();
414 addHandler<VersionHandler>();
418 static HandlerTable
const&
421 static HandlerTable
const kHandlerTable(kHandlerArray);
422 return kHandlerTable;
425 [[nodiscard]] Handler
const*
426 getHandler(
unsigned version,
bool betaEnabled, std::string
const& name)
const
432 auto const range = table_.equal_range(name);
434 return entry.second.minApiVer <= version && version <= entry.second.maxApiVer;
437 return i ==
range.second ? nullptr : &i->second;
440 [[nodiscard]] std::set<char const*>
443 std::set<char const*> ret;
444 for (
auto const& i : table_)
445 ret.
insert(i.second.name);
451 handler_table_t table_;
453 template <
class HandlerImpl>
457 static_assert(HandlerImpl::minApiVer <= HandlerImpl::maxApiVer);
461 if (overlappingApiVersion(
462 table_.equal_range(HandlerImpl::name),
463 HandlerImpl::minApiVer,
464 HandlerImpl::maxApiVer))
467 std::string(
"Handler for ") + HandlerImpl::name +
468 " overlaps with an existing handler");
471 table_.
insert({HandlerImpl::name, handlerFrom<HandlerImpl>()});
480 return HandlerTable::instance().getHandler(version, betaEnabled, name);
486 return HandlerTable::instance().getHandlerNames();
@ Object
object value (collection of name/value pairs).
API version numbers used in later API versions.
std::set< char const * > getHandlerNames()
Return names of all methods.
Handler const * getHandler(unsigned version, bool betaEnabled, std::string const &name)
static constexpr auto kApiMinimumSupportedVersion
json::Value makeObjectValue(Value const &value, json::StaticString const &field=jss::message)
Return a json::ValueType::Object with a single entry.
static constexpr auto kApiMaximumValidVersion
static constexpr auto kApiBetaVersion
static constexpr auto kApiMaximumSupportedVersion
json::Value entry(jtx::Env &env, jtx::Account const &account, jtx::Account const &authorize)
json::Value doPing(RPC::JsonContext &)
json::Value doSubmitMultiSigned(RPC::JsonContext &)
json::Value doPeers(RPC::JsonContext &context)
json::Value doLedgerCurrent(RPC::JsonContext &)
json::Value doValidators(RPC::JsonContext &context)
json::Value doValidationCreate(RPC::JsonContext &context)
json::Value doManifest(RPC::JsonContext &)
json::Value doGetAggregatePrice(RPC::JsonContext &)
oracles: array of {account, oracle_document_id} base_asset: is the asset to be priced quote_asset: is...
json::Value doStop(RPC::JsonContext &context)
json::Value doAccountChannels(RPC::JsonContext &context)
json::Value doLedgerRequest(RPC::JsonContext &context)
json::Value doServerInfo(RPC::JsonContext &)
json::Value doWalletPropose(RPC::JsonContext &context)
json::Value doTransactionEntry(RPC::JsonContext &)
json::Value doServerState(RPC::JsonContext &)
json::Value doLogLevel(RPC::JsonContext &context)
json::Value doNoRippleCheck(RPC::JsonContext &context)
json::Value doAccountTx(RPC::JsonContext &context)
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
json::Value doFeature(RPC::JsonContext &)
json::Value doConnect(RPC::JsonContext &context)
json::Value doSign(RPC::JsonContext &context)
json::Value doGatewayBalances(RPC::JsonContext &context)
json::Value doAccountNFTs(RPC::JsonContext &context)
General RPC command that can retrieve objects in the account root.
json::Value doPrint(RPC::JsonContext &context)
json::Value doChannelAuthorize(RPC::JsonContext &context)
json::Value doAccountInfo(RPC::JsonContext &context)
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
json::Value doTxReduceRelay(RPC::JsonContext &)
json::Value doLedgerEntry(RPC::JsonContext &)
json::Value doGetCounts(RPC::JsonContext &context)
json::Value doPeerReservationsDel(RPC::JsonContext &context)
json::Value doPathFind(RPC::JsonContext &)
json::Value doVaultInfo(RPC::JsonContext &)
json::Value doLedgerData(RPC::JsonContext &)
json::Value doBookChanges(RPC::JsonContext &)
json::Value doRipplePathFind(RPC::JsonContext &)
json::Value doTxHistory(RPC::JsonContext &)
json::Value doAccountCurrencies(RPC::JsonContext &context)
json::Value doLedgerHeader(RPC::JsonContext &)
json::Value doSubscribe(RPC::JsonContext &)
json::Value doOwnerInfo(RPC::JsonContext &context)
json::Value doChannelVerify(RPC::JsonContext &context)
json::Value doValidatorInfo(RPC::JsonContext &context)
json::Value doDepositAuthorized(RPC::JsonContext &)
json::Value doLedgerClosed(RPC::JsonContext &)
json::Value doAMMInfo(RPC::JsonContext &)
json::Value doAccountOffers(RPC::JsonContext &context)
json::Value doFetchInfo(RPC::JsonContext &context)
json::Value doPeerReservationsList(RPC::JsonContext &context)
json::Value doCanDelete(RPC::JsonContext &context)
json::Value doAccountObjects(RPC::JsonContext &context)
json::Value doSimulate(RPC::JsonContext &)
json::Value doFee(RPC::JsonContext &)
json::Value doNFTSellOffers(RPC::JsonContext &)
json::Value doUnsubscribe(RPC::JsonContext &)
json::Value doUnlList(RPC::JsonContext &context)
json::Value doAccountLines(RPC::JsonContext &context)
json::Value doBlackList(RPC::JsonContext &context)
json::Value doSubmit(RPC::JsonContext &)
json::Value doServerDefinitions(RPC::JsonContext &)
json::Value doBookOffers(RPC::JsonContext &)
json::Value doPeerReservationsAdd(RPC::JsonContext &context)
json::Value doRandom(RPC::JsonContext &)
json::Value doConsensusInfo(RPC::JsonContext &context)
json::Value doLogRotate(RPC::JsonContext &context)
json::Value doLedgerCleaner(RPC::JsonContext &context)
json::Value doSignFor(RPC::JsonContext &context)
json::Value doLedgerAccept(RPC::JsonContext &context)
json::Value doTxJson(RPC::JsonContext &)
json::Value doNFTBuyOffers(RPC::JsonContext &)
json::Value doValidatorListSites(RPC::JsonContext &context)
std::function< Status(JsonContext &, JsonValue &)> Method
Status represents the results of an operation that might fail.