xrpld
Loading...
Searching...
No Matches
Handler.cpp
1#include <xrpld/rpc/detail/Handler.h>
2
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>
11
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>
17
18#include <rpcspec/Errors.hpp>
19#include <rpcspec/Types.hpp>
20
21#include <algorithm>
22#include <array>
23#include <concepts>
24#include <cstddef>
25#include <expected>
26#include <iterator>
27#include <span>
28#include <string_view>
29#include <utility>
30
31namespace xrpl::rpc {
32namespace {
33
34// Shorthand: the tables below name this type once per entry.
35using Method = Handler::Method;
36
43template <json::Value (*Function)(JsonContext&)>
45byRef(JsonContext& context, json::Value& result)
46{
47 result = Function(context);
48 if (result.type() != json::ValueType::Object)
49 {
50 // LCOV_EXCL_START
51 UNREACHABLE("xrpl::rpc::byRef : result is object");
52 result = rpc::makeObjectValue(result);
53 // LCOV_EXCL_STOP
54 }
55
56 return Status();
57}
58
59template <typename HandlerImpl>
60concept SpecBasedHandler = std::derived_from<HandlerImpl, HandlerFor<typename HandlerImpl::Input>>;
61
62template <typename HandlerImpl>
63concept InputlessHandler = requires(HandlerImpl& handler) { handler.process(); };
64
65template <class HandlerImpl, class Output>
67respond(
68 HandlerImpl const& handler,
69 json::Value& object,
70 std::expected<Output, ::rpc::Status> const& output,
71 ::rpc::spec::Warnings const& warnings)
72{
73 if (not output.has_value())
74 {
75 injectSpecError(object, output.error());
76 return std::get<ErrorCodeI>(output.error().code);
77 }
78
79 handler.writeResult(object, *output);
80 injectSpecWarnings(object, warnings);
81
82 return Status::kOK;
83}
84
85template <class HandlerImpl>
86 requires SpecBasedHandler<HandlerImpl> or InputlessHandler<HandlerImpl>
87Status
88handle(JsonContext& context, json::Value& object)
89{
90 XRPL_ASSERT(
91 context.apiVersion >= HandlerImpl::minApiVer &&
92 context.apiVersion <= HandlerImpl::maxApiVer,
93 "xrpl::rpc::handle : valid API version");
94
95 if constexpr (SpecBasedHandler<HandlerImpl>)
96 {
97 auto const input = HandlerImpl::parseInput(context.params, context.apiVersion);
98 if (not input.has_value())
99 {
100 injectSpecError(object, input.error());
101 return std::get<ErrorCodeI>(input.error().code);
102 }
103
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);
110 }
111 else
112 {
113 HandlerImpl handler(context);
114 return respond(handler, object, handler.process(), /* warnings= */ {});
115 }
116}
117
118template <typename HandlerImpl>
119constexpr Handler
120handlerFrom()
121{
122 static_assert(HandlerImpl::minApiVer <= HandlerImpl::maxApiVer);
123 static_assert(HandlerImpl::maxApiVer <= rpc::kApiMaximumValidVersion);
124 static_assert(rpc::kApiMinimumSupportedVersion <= HandlerImpl::minApiVer);
125
126 return {
127 HandlerImpl::name,
128 Method::of<&handle<HandlerImpl>>(),
129 HandlerImpl::role,
130 HandlerImpl::condition,
131 HandlerImpl::minApiVer,
132 HandlerImpl::maxApiVer,
133 };
134}
135
136// The handlers that name the function they dispatch to. The order is free:
137// getHandler() searches kHandlers below, which is this array and the next one
138// sorted together.
139constexpr auto kFunctionHandlerArray = std::to_array<Handler>({
140 // Request-response methods
141 {
142 .name = method::kAccountInfo,
143 .valueMethod = Method::of<&byRef<&doAccountInfo>>(),
144 .role = Role::USER,
145 .condition = Condition::NoCondition,
146 },
147 {
149 .valueMethod = Method::of<&byRef<&doAccountCurrencies>>(),
150 .role = Role::USER,
151 .condition = Condition::NoCondition,
152 },
153 {
154 .name = method::kAccountLines,
155 .valueMethod = Method::of<&byRef<&doAccountLines>>(),
156 .role = Role::USER,
157 .condition = Condition::NoCondition,
158 },
159 {
161 .valueMethod = Method::of<&byRef<&doAccountChannels>>(),
162 .role = Role::USER,
163 .condition = Condition::NoCondition,
164 },
165 {
166 .name = method::kAccountNfts,
167 .valueMethod = Method::of<&byRef<&doAccountNFTs>>(),
168 .role = Role::USER,
169 .condition = Condition::NoCondition,
170 },
171 {
173 .valueMethod = Method::of<&byRef<&doAccountObjects>>(),
174 .role = Role::USER,
175 .condition = Condition::NoCondition,
176 },
177 {
179 .valueMethod = Method::of<&byRef<&doAccountOffers>>(),
180 .role = Role::USER,
181 .condition = Condition::NoCondition,
182 },
183 {
184 .name = method::kAccountTx,
185 .valueMethod = Method::of<&byRef<&doAccountTx>>(),
186 .role = Role::USER,
187 .condition = Condition::NoCondition,
188 },
189 {
190 .name = method::kAmmInfo,
191 .valueMethod = Method::of<&byRef<&doAMMInfo>>(),
192 .role = Role::USER,
193 .condition = Condition::NoCondition,
194 },
195 {
196 .name = method::kBlacklist,
197 .valueMethod = Method::of<&byRef<&doBlackList>>(),
198 .role = Role::ADMIN,
199 .condition = Condition::NoCondition,
200 .hasCommandLineForm = false,
201 },
202 {
203 .name = method::kBookChanges,
204 .valueMethod = Method::of<&byRef<&doBookChanges>>(),
205 .role = Role::USER,
206 .condition = Condition::NoCondition,
207 },
208 {
209 .name = method::kBookOffers,
210 .valueMethod = Method::of<&byRef<&doBookOffers>>(),
211 .role = Role::USER,
212 .condition = Condition::NoCondition,
213 },
214 {
215 .name = method::kCanDelete,
216 .valueMethod = Method::of<&byRef<&doCanDelete>>(),
217 .role = Role::ADMIN,
218 .condition = Condition::NoCondition,
219 },
220 {
222 .valueMethod = Method::of<&byRef<&doChannelAuthorize>>(),
223 .role = Role::USER,
224 .condition = Condition::NoCondition,
225 },
226 {
228 .valueMethod = Method::of<&byRef<&doChannelVerify>>(),
229 .role = Role::USER,
230 .condition = Condition::NoCondition,
231 },
232 {
233 .name = method::kConnect,
234 .valueMethod = Method::of<&byRef<&doConnect>>(),
235 .role = Role::ADMIN,
236 .condition = Condition::NoCondition,
237 },
238 {
240 .valueMethod = Method::of<&byRef<&doConsensusInfo>>(),
241 .role = Role::ADMIN,
242 .condition = Condition::NoCondition,
243 },
244 {
246 .valueMethod = Method::of<&byRef<&doDepositAuthorized>>(),
247 .role = Role::USER,
248 .condition = Condition::NoCondition,
249 },
250 {
251 .name = method::kFeature,
252 .valueMethod = Method::of<&byRef<&doFeature>>(),
253 .role = Role::USER,
254 .condition = Condition::NoCondition,
255 },
256 {
257 .name = method::kFee,
258 .valueMethod = Method::of<&byRef<&doFee>>(),
259 .role = Role::USER,
261 .hasCommandLineForm = false,
262 },
263 {
264 .name = method::kFetchInfo,
265 .valueMethod = Method::of<&byRef<&doFetchInfo>>(),
266 .role = Role::ADMIN,
267 .condition = Condition::NoCondition,
268 },
269 {
271 .valueMethod = Method::of<&byRef<&doGatewayBalances>>(),
272 .role = Role::USER,
273 .condition = Condition::NoCondition,
274 },
275 {
276 .name = method::kGetCounts,
277 .valueMethod = Method::of<&byRef<&doGetCounts>>(),
278 .role = Role::ADMIN,
279 .condition = Condition::NoCondition,
280 },
281 {
283 .valueMethod = Method::of<&byRef<&doGetAggregatePrice>>(),
284 .role = Role::USER,
285 .condition = Condition::NoCondition,
286 .hasCommandLineForm = false,
287 },
288 {
289 .name = method::kLedgerAccept,
290 .valueMethod = Method::of<&byRef<&doLedgerAccept>>(),
291 .role = Role::ADMIN,
293 },
294 {
296 .valueMethod = Method::of<&byRef<&doLedgerCleaner>>(),
297 .role = Role::ADMIN,
299 .hasCommandLineForm = false,
300 },
301 {
302 .name = method::kLedgerClosed,
303 .valueMethod = Method::of<&byRef<&doLedgerClosed>>(),
304 .role = Role::USER,
305 .condition = Condition::NeedsClosedLedger,
306 },
307 {
309 .valueMethod = Method::of<&byRef<&doLedgerCurrent>>(),
310 .role = Role::USER,
312 },
313 {
314 .name = method::kLedgerData,
315 .valueMethod = Method::of<&byRef<&doLedgerData>>(),
316 .role = Role::USER,
317 .condition = Condition::NoCondition,
318 .hasCommandLineForm = false,
319 },
320 {
321 .name = method::kLedgerEntry,
322 .valueMethod = Method::of<&byRef<&doLedgerEntry>>(),
323 .role = Role::USER,
324 .condition = Condition::NoCondition,
325 },
326 {
327 .name = method::kLedgerHeader,
328 .valueMethod = Method::of<&byRef<&doLedgerHeader>>(),
329 .role = Role::USER,
330 .condition = Condition::NoCondition,
331 .minApiVer = 1,
332 .maxApiVer = 1,
333 },
334 {
336 .valueMethod = Method::of<&byRef<&doLedgerRequest>>(),
337 .role = Role::ADMIN,
338 .condition = Condition::NoCondition,
339 },
340 {
341 .name = method::kLogLevel,
342 .valueMethod = Method::of<&byRef<&doLogLevel>>(),
343 .role = Role::ADMIN,
344 .condition = Condition::NoCondition,
345 },
346 {
347 .name = method::kLogrotate,
348 .valueMethod = Method::of<&byRef<&doLogRotate>>(),
349 .role = Role::ADMIN,
350 .condition = Condition::NoCondition,
351 },
352 {
353 .name = method::kManifest,
354 .valueMethod = Method::of<&byRef<&doManifest>>(),
355 .role = Role::USER,
356 .condition = Condition::NoCondition,
357 },
358 {
359 .name = method::kNftBuyOffers,
360 .valueMethod = Method::of<&byRef<&doNFTBuyOffers>>(),
361 .role = Role::USER,
362 .condition = Condition::NoCondition,
363 .hasCommandLineForm = false,
364 },
365 {
367 .valueMethod = Method::of<&byRef<&doNFTSellOffers>>(),
368 .role = Role::USER,
369 .condition = Condition::NoCondition,
370 .hasCommandLineForm = false,
371 },
372 {
374 .valueMethod = Method::of<&byRef<&doNoRippleCheck>>(),
375 .role = Role::USER,
376 .condition = Condition::NoCondition,
377 .hasCommandLineForm = false,
378 },
379 {
380 .name = method::kOwnerInfo,
381 .valueMethod = Method::of<&byRef<&doOwnerInfo>>(),
382 .role = Role::USER,
384 },
385 {
386 .name = method::kPeers,
387 .valueMethod = Method::of<&byRef<&doPeers>>(),
388 .role = Role::ADMIN,
389 .condition = Condition::NoCondition,
390 },
391 {
392 .name = method::kPathFind,
393 .valueMethod = Method::of<&byRef<&doPathFind>>(),
394 .role = Role::USER,
396 },
397 {
398 .name = method::kPing,
399 .valueMethod = Method::of<&byRef<&doPing>>(),
400 .role = Role::USER,
401 .condition = Condition::NoCondition,
402 },
403 {
404 .name = method::kPrint,
405 .valueMethod = Method::of<&byRef<&doPrint>>(),
406 .role = Role::ADMIN,
407 .condition = Condition::NoCondition,
408 },
409 {
410 .name = method::kRandom,
411 .valueMethod = Method::of<&byRef<&doRandom>>(),
412 .role = Role::USER,
413 .condition = Condition::NoCondition,
414 },
415 {
417 .valueMethod = Method::of<&byRef<&doPeerReservationsAdd>>(),
418 .role = Role::ADMIN,
419 .condition = Condition::NoCondition,
420 },
421 {
423 .valueMethod = Method::of<&byRef<&doPeerReservationsDel>>(),
424 .role = Role::ADMIN,
425 .condition = Condition::NoCondition,
426 },
427 {
429 .valueMethod = Method::of<&byRef<&doPeerReservationsList>>(),
430 .role = Role::ADMIN,
431 .condition = Condition::NoCondition,
432 },
433 {
435 .valueMethod = Method::of<&byRef<&doRipplePathFind>>(),
436 .role = Role::USER,
437 .condition = Condition::NoCondition,
438 },
439 {
441 .valueMethod = Method::of<&byRef<&doServerDefinitions>>(),
442 .role = Role::USER,
443 .condition = Condition::NoCondition,
444 },
445 {
446 .name = method::kServerInfo,
447 .valueMethod = Method::of<&byRef<&doServerInfo>>(),
448 .role = Role::USER,
449 .condition = Condition::NoCondition,
450 },
451 {
452 .name = method::kServerState,
453 .valueMethod = Method::of<&byRef<&doServerState>>(),
454 .role = Role::USER,
455 .condition = Condition::NoCondition,
456 },
457 {
458 .name = method::kSign,
459 .valueMethod = Method::of<&byRef<&doSign>>(),
460 .role = Role::USER,
461 .condition = Condition::NoCondition,
462 },
463 {
464 .name = method::kSignFor,
465 .valueMethod = Method::of<&byRef<&doSignFor>>(),
466 .role = Role::USER,
467 .condition = Condition::NoCondition,
468 },
469 {
470 .name = method::kSimulate,
471 .valueMethod = Method::of<&byRef<&doSimulate>>(),
472 .role = Role::USER,
474 },
475 {
476 .name = method::kStop,
477 .valueMethod = Method::of<&byRef<&doStop>>(),
478 .role = Role::ADMIN,
479 .condition = Condition::NoCondition,
480 },
481 {
482 .name = method::kSubmit,
483 .valueMethod = Method::of<&byRef<&doSubmit>>(),
484 .role = Role::USER,
486 },
487 {
489 .valueMethod = Method::of<&byRef<&doSubmitMultiSigned>>(),
490 .role = Role::USER,
492 },
493 {
495 .valueMethod = Method::of<&byRef<&doTransactionEntry>>(),
496 .role = Role::USER,
497 .condition = Condition::NoCondition,
498 },
499 {
500 .name = method::kTx,
501 .valueMethod = Method::of<&byRef<&doTxJson>>(),
502 .role = Role::USER,
504 },
505 {
506 .name = method::kTxHistory,
507 .valueMethod = Method::of<&byRef<&doTxHistory>>(),
508 .role = Role::USER,
509 .condition = Condition::NoCondition,
510 .minApiVer = 1,
511 .maxApiVer = 1,
512 },
513 {
515 .valueMethod = Method::of<&byRef<&doTxReduceRelay>>(),
516 .role = Role::USER,
517 .condition = Condition::NoCondition,
518 .hasCommandLineForm = false,
519 },
520 {
521 .name = method::kUnlList,
522 .valueMethod = Method::of<&byRef<&doUnlList>>(),
523 .role = Role::ADMIN,
524 .condition = Condition::NoCondition,
525 },
526 {
528 .valueMethod = Method::of<&byRef<&doValidationCreate>>(),
529 .role = Role::ADMIN,
530 .condition = Condition::NoCondition,
531 },
532 {
533 .name = method::kValidators,
534 .valueMethod = Method::of<&byRef<&doValidators>>(),
535 .role = Role::ADMIN,
536 .condition = Condition::NoCondition,
537 .hasCommandLineForm = false,
538 },
539 {
541 .valueMethod = Method::of<&byRef<&doValidatorListSites>>(),
542 .role = Role::ADMIN,
543 .condition = Condition::NoCondition,
544 .hasCommandLineForm = false,
545 },
546 {
548 .valueMethod = Method::of<&byRef<&doValidatorInfo>>(),
549 .role = Role::ADMIN,
550 .condition = Condition::NoCondition,
551 },
552 {
553 .name = method::kVaultInfo,
554 .valueMethod = Method::of<&byRef<&doVaultInfo>>(),
555 .role = Role::USER,
556 .condition = Condition::NoCondition,
557 },
558 {
560 .valueMethod = Method::of<&byRef<&doWalletPropose>>(),
561 .role = Role::ADMIN,
562 .condition = Condition::NoCondition,
563 },
564 // Event methods
565 {
566 .name = method::kSubscribe,
567 .valueMethod = Method::of<&byRef<&doSubscribe>>(),
568 .role = Role::USER,
569 .condition = Condition::NoCondition,
570 },
571 {
572 .name = method::kUnsubscribe,
573 .valueMethod = Method::of<&byRef<&doUnsubscribe>>(),
574 .role = Role::USER,
575 .condition = Condition::NoCondition,
576 },
577});
578
579// The class-based handlers, which carry their name and API range as static
580// members rather than as a table entry, so they cannot go in the array above.
581constexpr auto kClassHandlerArray = std::to_array<Handler>({
582 handlerFrom<LedgerHandler>(),
583 handlerFrom<VersionHandler>(),
584});
585
596constexpr auto
597joinHandlers()
598{
599 constexpr auto kFunctionIndices = std::make_index_sequence<std::size(kFunctionHandlerArray)>{};
600 constexpr auto kClassIndices = std::make_index_sequence<std::size(kClassHandlerArray)>{};
601
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);
607}
608
609// The whole dispatch table.
610constexpr auto kHandlers = [] {
611 auto all = joinHandlers();
612
613 // Sorted by name, so a handler can be found by binary search.
615 return all;
616}();
617
618// getHandler() relies on this being sorted to binary search it, and
619// kHandlerNames below inherits the order.
620static_assert(
621 std::ranges::is_sorted(kHandlers, {}, &Handler::name),
622 "xrpl::rpc : kHandlers must be sorted by name");
623
624// A name must select exactly one handler, otherwise a request would have two
625// answers. Where a method's behaviour differs by API version, the handler
626// branches on context.apiVersion rather than being registered once per range.
627// Checked here, at compile time, rather than on the first dispatch.
628//
629// The method is not checked: Handler::Method has no default constructor, so an
630// entry that omits it does not compile.
631static_assert(
632 [] {
633 for (std::size_t i = 0; i < kHandlers.size(); ++i)
634 {
635 auto const& h = kHandlers[i];
636 if (h.name.empty() || h.minApiVer > h.maxApiVer ||
637 h.maxApiVer > rpc::kApiMaximumValidVersion ||
639 return false;
640
641 // Sorted, so a repeat can only be of the preceding entry.
642 if (i > 0 && kHandlers[i - 1].name == h.name)
643 return false;
644 }
645 return true;
646 }(),
647 "xrpl::rpc : every handler needs a unique name and a valid API version range");
648
659template <std::size_t... I>
660consteval auto
661checkedHandlerNames(std::index_sequence<I...>)
662{
663 return std::array<NullTerminatedView, sizeof...(I)>{NullTerminatedView{kHandlers[I].name}...};
664}
665
666// The handler names, which are already distinct and sorted.
667constexpr auto kHandlerNames = checkedHandlerNames(std::make_index_sequence<kHandlers.size()>{});
668
669} // namespace
670
671Handler const*
672getHandler(unsigned version, bool betaEnabled, std::string_view name)
673{
674 if (version < rpc::kApiMinimumSupportedVersion ||
675 version > (betaEnabled ? rpc::kApiBetaVersion : rpc::kApiMaximumSupportedVersion))
676 return nullptr;
677
678 // Names are unique, so the binary search finds the only candidate; it then
679 // answers this request only if it serves this version.
680 auto const i = std::ranges::lower_bound(kHandlers, name, {}, &Handler::name);
681 if (i == kHandlers.end() || i->name != name)
682 return nullptr;
683
684 if (i->minApiVer <= version && version <= i->maxApiVer)
685 return &*i;
686
687 return nullptr;
688}
689
692{
693 return kHandlerNames;
694}
695
696} // namespace xrpl::rpc
Represents a JSON value.
Definition json_value.h:117
ValueType type() const
The function a handler dispatches to.
Definition Handler.h:48
T is_sorted(T... args)
T lower_bound(T... args)
@ Object
object value (collection of name/value pairs).
Definition json_value.h:29
constexpr std::string_view kAccountNfts
Definition MethodNames.h:23
constexpr std::string_view kPing
Definition MethodNames.h:67
constexpr std::string_view kAccountLines
Definition MethodNames.h:22
constexpr std::string_view kBookOffers
Definition MethodNames.h:30
constexpr std::string_view kNftSellOffers
Definition MethodNames.h:59
constexpr std::string_view kAccountOffers
Definition MethodNames.h:25
constexpr std::string_view kNorippleCheck
Definition MethodNames.h:60
constexpr std::string_view kConnect
Definition MethodNames.h:34
constexpr std::string_view kRipplePathFind
Definition MethodNames.h:70
constexpr std::string_view kAccountCurrencies
Definition MethodNames.h:20
constexpr std::string_view kLedgerCurrent
Definition MethodNames.h:50
constexpr std::string_view kPeerReservationsAdd
Definition MethodNames.h:63
constexpr std::string_view kChannelAuthorize
Definition MethodNames.h:32
constexpr std::string_view kAccountChannels
Names of the RPC methods the server accepts.
Definition MethodNames.h:19
constexpr std::string_view kPeerReservationsDel
Definition MethodNames.h:64
constexpr std::string_view kLogLevel
Definition MethodNames.h:55
constexpr std::string_view kSubmitMultisigned
Definition MethodNames.h:79
constexpr std::string_view kWalletPropose
Definition MethodNames.h:93
constexpr std::string_view kLedgerAccept
Definition MethodNames.h:47
constexpr std::string_view kAccountTx
Definition MethodNames.h:26
constexpr std::string_view kBookChanges
Definition MethodNames.h:29
constexpr std::string_view kValidationCreate
Definition MethodNames.h:87
constexpr std::string_view kConsensusInfo
Definition MethodNames.h:35
constexpr std::string_view kOwnerInfo
Definition MethodNames.h:61
constexpr std::string_view kDepositAuthorized
Definition MethodNames.h:36
constexpr std::string_view kServerDefinitions
Definition MethodNames.h:71
constexpr std::string_view kTxReduceRelay
Definition MethodNames.h:84
constexpr std::string_view kAmmInfo
Definition MethodNames.h:27
constexpr std::string_view kCanDelete
Definition MethodNames.h:31
constexpr std::string_view kFee
Definition MethodNames.h:38
constexpr std::string_view kLogrotate
Definition MethodNames.h:56
constexpr std::string_view kLedgerData
Definition MethodNames.h:51
constexpr std::string_view kLedgerEntry
Definition MethodNames.h:52
constexpr std::string_view kChannelVerify
Definition MethodNames.h:33
constexpr std::string_view kPeers
Definition MethodNames.h:66
constexpr std::string_view kSign
Definition MethodNames.h:74
constexpr std::string_view kGetCounts
Definition MethodNames.h:42
constexpr std::string_view kValidatorListSites
Definition MethodNames.h:89
constexpr std::string_view kPathFind
Definition MethodNames.h:62
constexpr std::string_view kServerInfo
Definition MethodNames.h:72
constexpr std::string_view kAccountObjects
Definition MethodNames.h:24
constexpr std::string_view kManifest
Definition MethodNames.h:57
constexpr std::string_view kLedgerHeader
Definition MethodNames.h:53
constexpr std::string_view kNftBuyOffers
Definition MethodNames.h:58
constexpr std::string_view kSubmit
Definition MethodNames.h:78
constexpr std::string_view kStop
Definition MethodNames.h:77
constexpr std::string_view kValidators
Definition MethodNames.h:90
constexpr std::string_view kLedgerClosed
Definition MethodNames.h:49
constexpr std::string_view kFetchInfo
Definition MethodNames.h:39
constexpr std::string_view kTxHistory
Definition MethodNames.h:83
constexpr std::string_view kSubscribe
Definition MethodNames.h:80
constexpr std::string_view kValidatorInfo
Definition MethodNames.h:88
constexpr std::string_view kTx
Definition MethodNames.h:82
constexpr std::string_view kPrint
Definition MethodNames.h:68
constexpr std::string_view kGetAggregatePrice
Definition MethodNames.h:41
constexpr std::string_view kTransactionEntry
Definition MethodNames.h:81
constexpr std::string_view kVaultInfo
Definition MethodNames.h:91
constexpr std::string_view kSimulate
Definition MethodNames.h:76
constexpr std::string_view kSignFor
Definition MethodNames.h:75
constexpr std::string_view kBlacklist
Definition MethodNames.h:28
constexpr std::string_view kPeerReservationsList
Definition MethodNames.h:65
constexpr std::string_view kFeature
Definition MethodNames.h:37
constexpr std::string_view kLedgerRequest
Definition MethodNames.h:54
constexpr std::string_view kUnlList
Definition MethodNames.h:85
constexpr std::string_view kLedgerCleaner
Definition MethodNames.h:48
constexpr std::string_view kRandom
Definition MethodNames.h:69
constexpr std::string_view kServerState
Definition MethodNames.h:73
constexpr std::string_view kAccountInfo
Definition MethodNames.h:21
constexpr std::string_view kUnsubscribe
Definition MethodNames.h:86
constexpr std::string_view kGatewayBalances
Definition MethodNames.h:40
API version numbers used in later API versions.
Definition ApiVersion.h:36
std::span< NullTerminatedView const > getHandlerNames()
Return the names of all methods, sorted and without duplicates.
Definition Handler.cpp:691
static constexpr auto kApiMaximumSupportedVersion
Definition ApiVersion.h:43
json::Value makeObjectValue(Value const &value, json::StaticString const &field=jss::message)
Return a json::ValueType::Object with a single entry.
Definition Handler.h:120
Handler const * getHandler(unsigned version, bool betaEnabled, std::string_view name)
Definition Handler.cpp:672
static constexpr auto kApiMaximumValidVersion
Definition ApiVersion.h:47
static constexpr auto kApiMinimumSupportedVersion
Definition ApiVersion.h:42
static constexpr auto kApiBetaVersion
Definition ApiVersion.h:46
@ USER
Definition Role.h:27
@ ADMIN
Definition Role.h:27
T size(T... args)
T sort(T... args)
std::string_view name
Definition Handler.h:86
Status represents the results of an operation that might fail.
Definition Status.h:27
static constexpr Code kOK
Definition Status.h:33