aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/server.cpp
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-07-15 19:20:13 +0200
committerMarcoFalke <falke.marco@gmail.com>2020-07-15 19:20:21 +0200
commit804ca266291279705384d384585714309274aa76 (patch)
tree5d559afbdeab09b5739a7880a76647c3953ea286 /src/rpc/server.cpp
parentd626a3be31d2b8ff3d5df2b39e91b1051656a28c (diff)
parentfa7592bfa8691eb0289b21da3571709a18391b0f (diff)
downloadbitcoin-804ca266291279705384d384585714309274aa76.tar.xz
Merge #19386: rpc: Assert that RPCArg names are equal to CRPCCommand ones (server)
fa7592bfa8691eb0289b21da3571709a18391b0f rpc: Update server to use new RPCHelpMan (MarcoFalke) aaaaad562790cd4dce1568ae193f5393aacacedf rpc: Add option to hide RPCArg (MarcoFalke) fa9708f94c01cb8bf2971bdf404af38c38fa341b rpc: Assert that passed arg names are equal to hardcoded ones (MarcoFalke) faaeb2b0b347b40ce456a951eec5e820587e5b02 rpc: Add CRPCCommand constructor which takes RPCHelpMan (MarcoFalke) fa8ec00061567e56333bb69c5623919d45a9a92d rpc: Check that left section is not multiline (MarcoFalke) Pull request description: This is split out from #18531 to just touch the RPC methods in server. Description from the main pr: ### Motivation RPCArg names in the rpc help are currently only used for documentation. However, in the future they could be used to teach the server the named arguments. Named arguments are currently registered by the `CRPCCommand`s and duplicate the RPCArg names from the documentation. This redundancy is fragile, and has lead to errors in the past (despite having linters to catch those kind of errors). See section "bugs found" for a list of bugs that have been found as a result of the changes here. ### Changes The changes here add an assert in the `CRPCCommand` constructor that the RPCArg names are identical to the ones in the `CRPCCommand`. ### Future work > Here or follow up, makes sense to also assert type of returned UniValue? Sure, but let's not get ahead of ourselves. I am going to submit any further works as follow-ups, including: * Removing the CRPCCommand arguments, now that they are asserted to be equal and thus redundant * Removing all python regex linters on the args, now that RPCMan can be used to generate any output, including the cli.cpp table * Auto-formatting and sanity checking the RPCExamples with RPCMan * Checking passed-in json in self-check. Removing redundant checks * Checking returned json against documentation to avoid regressions or false documentation * Compile the RPC documentation at compile-time to ensure it doesn't change at runtime and is completely static ### Bugs found * The assert identified issue #18607 * The changes itself fixed bug #19250 ACKs for top commit: laanwj: ACK fa7592bfa8691eb0289b21da3571709a18391b0f ryanofsky: Code review ACK fa7592bfa8691eb0289b21da3571709a18391b0f. Looks great! Just some hidden arg and Check() and comment cleanups since last review Tree-SHA512: e64b6a212f4a3aeedeee47557559bde104d5fd40cdc1746b27eb2f3d4c8885d5e6e4dd287595ea11cdbc6a939654fe103cae765fd505875444d851f0abb11308
Diffstat (limited to 'src/rpc/server.cpp')
-rw-r--r--src/rpc/server.cpp50
1 files changed, 27 insertions, 23 deletions
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index de8791a935..e5f6b1b9f1 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -130,11 +130,9 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest&
return strRet;
}
-UniValue help(const JSONRPCRequest& jsonRequest)
+static RPCHelpMan help()
{
- if (jsonRequest.fHelp || jsonRequest.params.size() > 1)
- throw std::runtime_error(
- RPCHelpMan{"help",
+ return RPCHelpMan{"help",
"\nList all commands, or get help for a specified command.\n",
{
{"command", RPCArg::Type::STR, /* default */ "all commands", "The command to get help on"},
@@ -143,32 +141,32 @@ UniValue help(const JSONRPCRequest& jsonRequest)
RPCResult::Type::STR, "", "The help text"
},
RPCExamples{""},
- }.ToString()
- );
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
+{
std::string strCommand;
if (jsonRequest.params.size() > 0)
strCommand = jsonRequest.params[0].get_str();
return tableRPC.help(strCommand, jsonRequest);
+},
+ };
}
-
-UniValue stop(const JSONRPCRequest& jsonRequest)
+static RPCHelpMan stop()
{
static const std::string RESULT{PACKAGE_NAME " stopping"};
- // Accept the deprecated and ignored 'detach' boolean argument
+ return RPCHelpMan{"stop",
// Also accept the hidden 'wait' integer argument (milliseconds)
// For instance, 'stop 1000' makes the call wait 1 second before returning
// to the client (intended for testing)
- if (jsonRequest.fHelp || jsonRequest.params.size() > 1)
- throw std::runtime_error(
- RPCHelpMan{"stop",
"\nRequest a graceful shutdown of " PACKAGE_NAME ".",
- {},
+ {
+ {"wait", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "how long to wait in ms", "", {}, /* hidden */ true},
+ },
RPCResult{RPCResult::Type::STR, "", "A string with the content '" + RESULT + "'"},
RPCExamples{""},
- }.ToString());
+ [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
+{
// Event loop will exit after current HTTP requests have been handled, so
// this reply will get back to the client.
StartShutdown();
@@ -176,11 +174,13 @@ UniValue stop(const JSONRPCRequest& jsonRequest)
UninterruptibleSleep(std::chrono::milliseconds{jsonRequest.params[0].get_int()});
}
return RESULT;
+},
+ };
}
-static UniValue uptime(const JSONRPCRequest& jsonRequest)
+static RPCHelpMan uptime()
{
- RPCHelpMan{"uptime",
+ return RPCHelpMan{"uptime",
"\nReturns the total uptime of the server.\n",
{},
RPCResult{
@@ -190,14 +190,16 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest)
HelpExampleCli("uptime", "")
+ HelpExampleRpc("uptime", "")
},
- }.Check(jsonRequest);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
return GetTime() - GetStartupTime();
}
+ };
+}
-static UniValue getrpcinfo(const JSONRPCRequest& request)
+static RPCHelpMan getrpcinfo()
{
- RPCHelpMan{"getrpcinfo",
+ return RPCHelpMan{"getrpcinfo",
"\nReturns details of the RPC server.\n",
{},
RPCResult{
@@ -217,8 +219,8 @@ static UniValue getrpcinfo(const JSONRPCRequest& request)
RPCExamples{
HelpExampleCli("getrpcinfo", "")
+ HelpExampleRpc("getrpcinfo", "")},
- }.Check(request);
-
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
LOCK(g_rpc_server_info.mutex);
UniValue active_commands(UniValue::VARR);
for (const RPCCommandExecutionInfo& info : g_rpc_server_info.active_commands) {
@@ -237,6 +239,8 @@ static UniValue getrpcinfo(const JSONRPCRequest& request)
return result;
}
+ };
+}
// clang-format off
static const CRPCCommand vRPCCommands[] =