refactor: Build the RPC dispatch tables at compile time

A new MethodNames.h gives every RPC method a string_view constant,
shared by the handler table and the command-line parser table so the
two cannot drift apart. That lets a handler carry its name as a
string_view, and both tables become sorted constexpr arrays found by
binary search, replacing the HandlerTable singleton and its multimap
and RPCParser's runtime table. Their invariants -- a unique name, a
method, and a valid API version range -- are now a static_assert rather
than a logicError on the first request of the process. Handler::Method
becomes a plain function pointer: every method is a free function known
at compile time, so the std::function never captured anything, and
dropping it makes Handler a literal type, which is what a constexpr
table needs; it also makes doCommand's null-method branch dead, since
an empty std::function is no longer representable.

The names being program-lifetime constants removes work throughout.
getHandlerNames and commandLineMethodNames return a span over a
constexpr array instead of building a fresh std::set per call, one of
those on the startup path; PerfLogImp's rpc map keys on string_view, so
it needs neither a transparent hasher nor a string copy per key, and
reports counters through json::StaticString rather than duplicating
each key into the object. Command parameter counts become unsigned with
a named kUnlimitedParams; as ints with -1 for unlimited they were
compared against an unsigned size, so `count < minParams` promoted -1
and was always true, and only the `>= 0` guards kept that from being
reachable.

PerfLog no longer reaches into the RPC layer to learn which methods to
count: makePerfLog takes the names, so xrpld.perflog stops depending on
xrpld.rpc, and PerfLog_test uses five made-up labels, which drops
test.basics > xrpld.rpc as well. Both edges are gone from levelization.
Handler_test's benchmark now asks for kApiMinimumSupportedVersion
instead of a hardcoded 1 and fails if a lookup misses -- once API
versions 1 and 2 retire, getHandler(1, ...) would return at its bounds
check and the benchmark would have silently reported timings for that
check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Bart
2026-08-11 07:07:16 -04:00
parent 26cc683ec1
commit fb36b0adc0
19 changed files with 818 additions and 602 deletions

View File

@@ -82,7 +82,6 @@ test.app > xrpl.tx
test.basics > test.jtx
test.basics > xrpl.basics
test.basics > xrpl.core
test.basics > xrpld.rpc
test.basics > xrpl.json
test.basics > xrpl.protocol
test.beast > xrpl.basics
@@ -286,10 +285,10 @@ xrpld.perflog > xrpl.basics
xrpld.perflog > xrpl.config
xrpld.perflog > xrpl.core
xrpld.perflog > xrpld.app
xrpld.perflog > xrpld.rpc
xrpld.perflog > xrpl.json
xrpld.perflog > xrpl.nodestore
xrpld.perflog > xrpl.protocol
xrpld.perflog > xrpl.server
xrpld.rpc > xrpl.basics
xrpld.rpc > xrpl.config
xrpld.rpc > xrpl.core