1#include <xrpld/rpc/detail/Handler.h>
3#include <xrpld/rpc/Context.h>
4#include <xrpld/rpc/MethodNames.h>
5#include <xrpld/rpc/Role.h>
6#include <xrpld/rpc/Status.h>
7#include <xrpld/rpc/detail/SpecBridge.hpp>
8#include <xrpld/rpc/handlers/Handlers.h>
9#include <xrpld/rpc/handlers/ledger/Ledger.h>
10#include <xrpld/rpc/handlers/server_info/Version.h>
12#include <xrpl/basics/StringUtilities.h>
13#include <xrpl/beast/utility/instrumentation.h>
14#include <xrpl/json/json_value.h>
15#include <xrpl/protocol/ApiVersion.h>
16#include <xrpl/protocol/ErrorCodes.h>
18#include <rpcspec/Errors.hpp>
19#include <rpcspec/Types.hpp>
43template <json::Value (*Function)(JsonContext&)>
47 result = Function(context);
51 UNREACHABLE(
"xrpl::rpc::byRef : result is object");
59template <
typename HandlerImpl>
60concept SpecBasedHandler = std::derived_from<HandlerImpl, HandlerFor<typename HandlerImpl::Input>>;
62template <
typename HandlerImpl>
65template <
class HandlerImpl,
class Output>
68 HandlerImpl
const& handler,
70 std::expected<Output, ::rpc::Status>
const& output,
71 ::rpc::spec::Warnings
const& warnings)
73 if (not output.has_value())
75 injectSpecError(
object, output.error());
76 return std::get<ErrorCodeI>(output.error().code);
79 handler.writeResult(
object, *output);
80 injectSpecWarnings(
object, warnings);
85template <
class HandlerImpl>
86 requires SpecBasedHandler<HandlerImpl> or InputlessHandler<HandlerImpl>
91 context.apiVersion >= HandlerImpl::minApiVer &&
92 context.apiVersion <= HandlerImpl::maxApiVer,
93 "xrpl::rpc::handle : valid API version");
95 if constexpr (SpecBasedHandler<HandlerImpl>)
97 auto const input = HandlerImpl::parseInput(context.params, context.apiVersion);
98 if (not input.has_value())
100 injectSpecError(
object, input.error());
101 return std::get<ErrorCodeI>(input.error().code);
104 HandlerImpl handler(context);
105 auto const output = handler.process(*input);
106 auto const warnings = output.has_value()
107 ? HandlerImpl::spec(context.apiVersion).check(context.params)
108 : ::rpc::spec::Warnings{};
109 return respond(handler,
object, output, warnings);
113 HandlerImpl handler(context);
114 return respond(handler,
object, handler.process(), {});
118template <
typename HandlerImpl>
122 static_assert(HandlerImpl::minApiVer <= HandlerImpl::maxApiVer);
128 Method::of<&handle<HandlerImpl>>(),
130 HandlerImpl::condition,
131 HandlerImpl::minApiVer,
132 HandlerImpl::maxApiVer,
139constexpr auto kFunctionHandlerArray = std::to_array<Handler>({
143 .valueMethod = Method::of<&byRef<&doAccountInfo>>(),
149 .valueMethod = Method::of<&byRef<&doAccountCurrencies>>(),
155 .valueMethod = Method::of<&byRef<&doAccountLines>>(),
161 .valueMethod = Method::of<&byRef<&doAccountChannels>>(),
167 .valueMethod = Method::of<&byRef<&doAccountNFTs>>(),
173 .valueMethod = Method::of<&byRef<&doAccountObjects>>(),
179 .valueMethod = Method::of<&byRef<&doAccountOffers>>(),
185 .valueMethod = Method::of<&byRef<&doAccountTx>>(),
191 .valueMethod = Method::of<&byRef<&doAMMInfo>>(),
197 .valueMethod = Method::of<&byRef<&doBlackList>>(),
200 .hasCommandLineForm =
false,
204 .valueMethod = Method::of<&byRef<&doBookChanges>>(),
210 .valueMethod = Method::of<&byRef<&doBookOffers>>(),
216 .valueMethod = Method::of<&byRef<&doCanDelete>>(),
222 .valueMethod = Method::of<&byRef<&doChannelAuthorize>>(),
228 .valueMethod = Method::of<&byRef<&doChannelVerify>>(),
234 .valueMethod = Method::of<&byRef<&doConnect>>(),
240 .valueMethod = Method::of<&byRef<&doConsensusInfo>>(),
246 .valueMethod = Method::of<&byRef<&doDepositAuthorized>>(),
252 .valueMethod = Method::of<&byRef<&doFeature>>(),
258 .valueMethod = Method::of<&byRef<&doFee>>(),
261 .hasCommandLineForm =
false,
265 .valueMethod = Method::of<&byRef<&doFetchInfo>>(),
271 .valueMethod = Method::of<&byRef<&doGatewayBalances>>(),
277 .valueMethod = Method::of<&byRef<&doGetCounts>>(),
283 .valueMethod = Method::of<&byRef<&doGetAggregatePrice>>(),
286 .hasCommandLineForm =
false,
290 .valueMethod = Method::of<&byRef<&doLedgerAccept>>(),
296 .valueMethod = Method::of<&byRef<&doLedgerCleaner>>(),
299 .hasCommandLineForm =
false,
303 .valueMethod = Method::of<&byRef<&doLedgerClosed>>(),
309 .valueMethod = Method::of<&byRef<&doLedgerCurrent>>(),
315 .valueMethod = Method::of<&byRef<&doLedgerData>>(),
318 .hasCommandLineForm =
false,
322 .valueMethod = Method::of<&byRef<&doLedgerEntry>>(),
328 .valueMethod = Method::of<&byRef<&doLedgerHeader>>(),
336 .valueMethod = Method::of<&byRef<&doLedgerRequest>>(),
342 .valueMethod = Method::of<&byRef<&doLogLevel>>(),
348 .valueMethod = Method::of<&byRef<&doLogRotate>>(),
354 .valueMethod = Method::of<&byRef<&doManifest>>(),
360 .valueMethod = Method::of<&byRef<&doNFTBuyOffers>>(),
363 .hasCommandLineForm =
false,
367 .valueMethod = Method::of<&byRef<&doNFTSellOffers>>(),
370 .hasCommandLineForm =
false,
374 .valueMethod = Method::of<&byRef<&doNoRippleCheck>>(),
377 .hasCommandLineForm =
false,
381 .valueMethod = Method::of<&byRef<&doOwnerInfo>>(),
387 .valueMethod = Method::of<&byRef<&doPeers>>(),
393 .valueMethod = Method::of<&byRef<&doPathFind>>(),
399 .valueMethod = Method::of<&byRef<&doPing>>(),
405 .valueMethod = Method::of<&byRef<&doPrint>>(),
411 .valueMethod = Method::of<&byRef<&doRandom>>(),
417 .valueMethod = Method::of<&byRef<&doPeerReservationsAdd>>(),
423 .valueMethod = Method::of<&byRef<&doPeerReservationsDel>>(),
429 .valueMethod = Method::of<&byRef<&doPeerReservationsList>>(),
435 .valueMethod = Method::of<&byRef<&doRipplePathFind>>(),
441 .valueMethod = Method::of<&byRef<&doServerDefinitions>>(),
447 .valueMethod = Method::of<&byRef<&doServerInfo>>(),
453 .valueMethod = Method::of<&byRef<&doServerState>>(),
459 .valueMethod = Method::of<&byRef<&doSign>>(),
465 .valueMethod = Method::of<&byRef<&doSignFor>>(),
471 .valueMethod = Method::of<&byRef<&doSimulate>>(),
477 .valueMethod = Method::of<&byRef<&doStop>>(),
483 .valueMethod = Method::of<&byRef<&doSubmit>>(),
489 .valueMethod = Method::of<&byRef<&doSubmitMultiSigned>>(),
495 .valueMethod = Method::of<&byRef<&doTransactionEntry>>(),
501 .valueMethod = Method::of<&byRef<&doTxJson>>(),
507 .valueMethod = Method::of<&byRef<&doTxHistory>>(),
515 .valueMethod = Method::of<&byRef<&doTxReduceRelay>>(),
518 .hasCommandLineForm =
false,
522 .valueMethod = Method::of<&byRef<&doUnlList>>(),
528 .valueMethod = Method::of<&byRef<&doValidationCreate>>(),
534 .valueMethod = Method::of<&byRef<&doValidators>>(),
537 .hasCommandLineForm =
false,
541 .valueMethod = Method::of<&byRef<&doValidatorListSites>>(),
544 .hasCommandLineForm =
false,
548 .valueMethod = Method::of<&byRef<&doValidatorInfo>>(),
554 .valueMethod = Method::of<&byRef<&doVaultInfo>>(),
560 .valueMethod = Method::of<&byRef<&doWalletPropose>>(),
567 .valueMethod = Method::of<&byRef<&doSubscribe>>(),
573 .valueMethod = Method::of<&byRef<&doUnsubscribe>>(),
581constexpr auto kClassHandlerArray = std::to_array<Handler>({
582 handlerFrom<LedgerHandler>(),
583 handlerFrom<VersionHandler>(),
599 constexpr auto kFunctionIndices = std::make_index_sequence<
std::size(kFunctionHandlerArray)>{};
600 constexpr auto kClassIndices = std::make_index_sequence<
std::size(kClassHandlerArray)>{};
602 return []<std::size_t... Function, std::size_t... Class>(
603 std::index_sequence<Function...>, std::index_sequence<Class...>) {
604 return std::array<
Handler,
sizeof...(Function) +
sizeof...(Class)>{
605 kFunctionHandlerArray[Function]..., kClassHandlerArray[Class]...};
606 }(kFunctionIndices, kClassIndices);
610constexpr auto kHandlers = [] {
611 auto all = joinHandlers();
622 "xrpl::rpc : kHandlers must be sorted by name");
633 for (std::size_t i = 0; i < kHandlers.size(); ++i)
635 auto const& h = kHandlers[i];
636 if (h.name.empty() || h.minApiVer > h.maxApiVer ||
642 if (i > 0 && kHandlers[i - 1].name == h.name)
647 "xrpl::rpc : every handler needs a unique name and a valid API version range");
659template <std::size_t... I>
661checkedHandlerNames(std::index_sequence<I...>)
663 return std::array<NullTerminatedView,
sizeof...(I)>{NullTerminatedView{kHandlers[I].name}...};
667constexpr auto kHandlerNames = checkedHandlerNames(std::make_index_sequence<kHandlers.size()>{});
681 if (i == kHandlers.end() || i->name != name)
684 if (i->minApiVer <= version && version <= i->maxApiVer)
693 return kHandlerNames;
The function a handler dispatches to.
@ Object
object value (collection of name/value pairs).
constexpr std::string_view kAccountNfts
constexpr std::string_view kPing
constexpr std::string_view kAccountLines
constexpr std::string_view kBookOffers
constexpr std::string_view kNftSellOffers
constexpr std::string_view kAccountOffers
constexpr std::string_view kNorippleCheck
constexpr std::string_view kConnect
constexpr std::string_view kRipplePathFind
constexpr std::string_view kAccountCurrencies
constexpr std::string_view kLedgerCurrent
constexpr std::string_view kPeerReservationsAdd
constexpr std::string_view kChannelAuthorize
constexpr std::string_view kAccountChannels
Names of the RPC methods the server accepts.
constexpr std::string_view kPeerReservationsDel
constexpr std::string_view kLogLevel
constexpr std::string_view kSubmitMultisigned
constexpr std::string_view kWalletPropose
constexpr std::string_view kLedgerAccept
constexpr std::string_view kAccountTx
constexpr std::string_view kBookChanges
constexpr std::string_view kValidationCreate
constexpr std::string_view kConsensusInfo
constexpr std::string_view kOwnerInfo
constexpr std::string_view kDepositAuthorized
constexpr std::string_view kServerDefinitions
constexpr std::string_view kTxReduceRelay
constexpr std::string_view kAmmInfo
constexpr std::string_view kCanDelete
constexpr std::string_view kFee
constexpr std::string_view kLogrotate
constexpr std::string_view kLedgerData
constexpr std::string_view kLedgerEntry
constexpr std::string_view kChannelVerify
constexpr std::string_view kPeers
constexpr std::string_view kSign
constexpr std::string_view kGetCounts
constexpr std::string_view kValidatorListSites
constexpr std::string_view kPathFind
constexpr std::string_view kServerInfo
constexpr std::string_view kAccountObjects
constexpr std::string_view kManifest
constexpr std::string_view kLedgerHeader
constexpr std::string_view kNftBuyOffers
constexpr std::string_view kSubmit
constexpr std::string_view kStop
constexpr std::string_view kValidators
constexpr std::string_view kLedgerClosed
constexpr std::string_view kFetchInfo
constexpr std::string_view kTxHistory
constexpr std::string_view kSubscribe
constexpr std::string_view kValidatorInfo
constexpr std::string_view kTx
constexpr std::string_view kPrint
constexpr std::string_view kGetAggregatePrice
constexpr std::string_view kTransactionEntry
constexpr std::string_view kVaultInfo
constexpr std::string_view kSimulate
constexpr std::string_view kSignFor
constexpr std::string_view kBlacklist
constexpr std::string_view kPeerReservationsList
constexpr std::string_view kFeature
constexpr std::string_view kLedgerRequest
constexpr std::string_view kUnlList
constexpr std::string_view kLedgerCleaner
constexpr std::string_view kRandom
constexpr std::string_view kServerState
constexpr std::string_view kAccountInfo
constexpr std::string_view kUnsubscribe
constexpr std::string_view kGatewayBalances
API version numbers used in later API versions.
std::span< NullTerminatedView const > getHandlerNames()
Return the names of all methods, sorted and without duplicates.
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.
Handler const * getHandler(unsigned version, bool betaEnabled, std::string_view name)
static constexpr auto kApiMaximumValidVersion
static constexpr auto kApiMinimumSupportedVersion
static constexpr auto kApiBetaVersion
Status represents the results of an operation that might fail.
static constexpr Code kOK