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>
27template <
typename Function>
29byRef(Function
const& f)
31 return [f](
JsonContext& context, json::Value& result) {
36 UNREACHABLE(
"xrpl::rpc::byRef : result is object");
45template <
class Object,
class HandlerImpl>
50 context.apiVersion >= HandlerImpl::minApiVer &&
51 context.apiVersion <= HandlerImpl::maxApiVer,
52 "xrpl::rpc::handle : valid API version");
53 HandlerImpl handler(context);
55 auto status = handler.check();
62 handler.writeResult(
object);
67template <
typename HandlerImpl>
73 &handle<json::Value, HandlerImpl>,
75 HandlerImpl::condition,
76 HandlerImpl::minApiVer,
77 HandlerImpl::maxApiVer};
83 {.name =
"account_info",
87 {.name =
"account_currencies",
91 {.name =
"account_lines",
95 {.name =
"account_channels",
99 {.name =
"account_nfts",
103 {.name =
"account_objects",
107 {.name =
"account_offers",
111 {.name =
"account_tx",
119 {.name =
"blacklist",
123 {.name =
"book_changes",
127 {.name =
"book_offers",
131 {.name =
"can_delete",
135 {.name =
"channel_authorize",
139 {.name =
"channel_verify",
147 {.name =
"consensus_info",
151 {.name =
"deposit_authorized",
160 .valueMethod = byRef(&
doFee),
163 {.name =
"fetch_info",
167 {.name =
"gateway_balances",
171 {.name =
"get_counts",
175 {.name =
"get_aggregate_price",
179 {.name =
"ledger_accept",
183 {.name =
"ledger_cleaner",
187 {.name =
"ledger_closed",
191 {.name =
"ledger_current",
195 {.name =
"ledger_data",
199 {.name =
"ledger_entry",
203 {.name =
"ledger_header",
209 {.name =
"ledger_request",
213 {.name =
"log_level",
217 {.name =
"logrotate",
225 {.name =
"nft_buy_offers",
229 {.name =
"nft_sell_offers",
233 {.name =
"noripple_check",
237 {.name =
"owner_info",
242 .valueMethod = byRef(&
doPeers),
245 {.name =
"path_find",
250 .valueMethod = byRef(&
doPing),
254 .valueMethod = byRef(&
doPrint),
263 {.name =
"peer_reservations_add",
267 {.name =
"peer_reservations_del",
271 {.name =
"peer_reservations_list",
275 {.name =
"ripple_path_find",
279 {.name =
"server_definitions",
283 {.name =
"server_info",
287 {.name =
"server_state",
292 .valueMethod = byRef(&
doSign),
304 .valueMethod = byRef(&
doStop),
311 {.name =
"submit_multisigned",
315 {.name =
"transaction_entry",
323 {.name =
"tx_history",
329 {.name =
"tx_reduce_relay",
337 {.name =
"validation_create",
341 {.name =
"validators",
345 {.name =
"validator_list_sites",
349 {.name =
"validator_info",
353 {.name =
"vault_info",
357 {.name =
"wallet_propose",
362 {.name =
"subscribe",
366 {.name =
"unsubscribe",
375 using handler_table_t = std::multimap<std::string, Handler>;
379 [[nodiscard]]
static bool
380 overlappingApiVersion(
381 std::pair<handler_table_t::iterator, handler_table_t::iterator>
range,
385 XRPL_ASSERT(minVer <= maxVer,
"xrpl::rpc::HandlerTable : valid API version range");
388 "xrpl::rpc::HandlerTable : valid max API version");
393 [minVer, maxVer](
auto const& item) {
394 return item.second.minApiVer <= maxVer && item.second.maxApiVer >= minVer;
398 template <std::
size_t N>
399 explicit HandlerTable(Handler
const (&entries)[N])
401 for (
auto const& entry : entries)
403 if (overlappingApiVersion(
407 std::string(
"Handler for ") +
entry.name +
408 " overlaps with an existing handler");
415 addHandler<LedgerHandler>();
416 addHandler<VersionHandler>();
420 static HandlerTable
const&
423 static HandlerTable
const kHandlerTable(kHandlerArray);
424 return kHandlerTable;
427 [[nodiscard]] Handler
const*
428 getHandler(
unsigned version,
bool betaEnabled, std::string
const& name)
const
434 auto const range = table_.equal_range(name);
436 return entry.second.minApiVer <= version && version <= entry.second.maxApiVer;
439 return i ==
range.second ? nullptr : &i->second;
442 [[nodiscard]] std::set<char const*>
445 std::set<char const*> ret;
446 for (
auto const& i : table_)
447 ret.
insert(i.second.name);
453 handler_table_t table_;
455 template <
class HandlerImpl>
459 static_assert(HandlerImpl::minApiVer <= HandlerImpl::maxApiVer);
463 if (overlappingApiVersion(
464 table_.equal_range(HandlerImpl::name),
465 HandlerImpl::minApiVer,
466 HandlerImpl::maxApiVer))
469 std::string(
"Handler for ") + HandlerImpl::name +
470 " overlaps with an existing handler");
473 table_.
insert({HandlerImpl::name, handlerFrom<HandlerImpl>()});
482 return HandlerTable::instance().getHandler(version, betaEnabled, name);
488 return HandlerTable::instance().getHandlerNames();
@ Object
object value (collection of name/value pairs).
API version numbers used in later API versions.
static constexpr auto kApiMaximumSupportedVersion
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 kApiMinimumSupportedVersion
Handler const * getHandler(unsigned version, bool betaEnabled, std::string const &name)
static constexpr auto kApiBetaVersion
std::set< char const * > getHandlerNames()
Return names of all methods.
json::Value entry(jtx::Env &env, jtx::Account const &account, jtx::Account const &authorize)
json::Value doConsensusInfo(rpc::JsonContext &context)
json::Value doPeers(rpc::JsonContext &context)
json::Value doAccountChannels(rpc::JsonContext &context)
json::Value doLedgerRequest(rpc::JsonContext &context)
json::Value doValidatorListSites(rpc::JsonContext &context)
json::Value doValidationCreate(rpc::JsonContext &context)
json::Value doAccountTx(rpc::JsonContext &context)
json::Value doRandom(rpc::JsonContext &)
json::Value doTransactionEntry(rpc::JsonContext &)
json::Value doLedgerData(rpc::JsonContext &)
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
json::Value doServerInfo(rpc::JsonContext &)
json::Value doPeerReservationsList(rpc::JsonContext &context)
json::Value doWalletPropose(rpc::JsonContext &context)
json::Value doRipplePathFind(rpc::JsonContext &)
json::Value doUnlList(rpc::JsonContext &context)
json::Value doFetchInfo(rpc::JsonContext &context)
json::Value doSignFor(rpc::JsonContext &context)
json::Value doStop(rpc::JsonContext &context)
json::Value doGetCounts(rpc::JsonContext &context)
json::Value doAccountNFTs(rpc::JsonContext &context)
General RPC command that can retrieve objects in the account root.
json::Value doOwnerInfo(rpc::JsonContext &context)
json::Value doConnect(rpc::JsonContext &context)
json::Value doNFTSellOffers(rpc::JsonContext &)
json::Value doNoRippleCheck(rpc::JsonContext &context)
json::Value doAccountLines(rpc::JsonContext &context)
json::Value doSimulate(rpc::JsonContext &)
json::Value doPeerReservationsDel(rpc::JsonContext &context)
json::Value doPathFind(rpc::JsonContext &)
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
json::Value doLedgerAccept(rpc::JsonContext &context)
json::Value doAccountInfo(rpc::JsonContext &context)
json::Value doUnsubscribe(rpc::JsonContext &)
json::Value doBookOffers(rpc::JsonContext &)
json::Value doLedgerCleaner(rpc::JsonContext &context)
json::Value doSubmitMultiSigned(rpc::JsonContext &)
json::Value doNFTBuyOffers(rpc::JsonContext &)
json::Value doAMMInfo(rpc::JsonContext &)
json::Value doAccountObjects(rpc::JsonContext &context)
json::Value doPeerReservationsAdd(rpc::JsonContext &context)
json::Value doAccountOffers(rpc::JsonContext &context)
json::Value doVaultInfo(rpc::JsonContext &)
json::Value doLedgerCurrent(rpc::JsonContext &)
json::Value doServerDefinitions(rpc::JsonContext &)
json::Value doManifest(rpc::JsonContext &)
json::Value doBlackList(rpc::JsonContext &context)
json::Value doChannelVerify(rpc::JsonContext &context)
json::Value doFeature(rpc::JsonContext &)
json::Value doDepositAuthorized(rpc::JsonContext &)
json::Value doLedgerEntry(rpc::JsonContext &)
json::Value doPrint(rpc::JsonContext &context)
json::Value doBookChanges(rpc::JsonContext &)
json::Value doLedgerHeader(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 doLogLevel(rpc::JsonContext &context)
json::Value doGatewayBalances(rpc::JsonContext &context)
json::Value doTxHistory(rpc::JsonContext &)
json::Value doSign(rpc::JsonContext &context)
json::Value doValidators(rpc::JsonContext &context)
json::Value doTxJson(rpc::JsonContext &)
json::Value doSubscribe(rpc::JsonContext &)
json::Value doServerState(rpc::JsonContext &)
json::Value doPing(rpc::JsonContext &)
json::Value doAccountCurrencies(rpc::JsonContext &context)
json::Value doFee(rpc::JsonContext &)
json::Value doSubmit(rpc::JsonContext &)
json::Value doCanDelete(rpc::JsonContext &context)
json::Value doLogRotate(rpc::JsonContext &context)
json::Value doLedgerClosed(rpc::JsonContext &)
json::Value doValidatorInfo(rpc::JsonContext &context)
json::Value doChannelAuthorize(rpc::JsonContext &context)
json::Value doTxReduceRelay(rpc::JsonContext &)
std::function< Status(JsonContext &, JsonValue &)> Method
Status represents the results of an operation that might fail.