diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index de1fbcb94c..ea7b5f0c9e 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -14,17 +14,26 @@ #include #include -static UniValue rpcNestedTest_rpc(const JSONRPCRequest& request) +static RPCHelpMan rpcNestedTest_rpc() { - if (request.fHelp) { - return "help message"; - } - return request.params.write(0, 0); + return RPCHelpMan{ + "rpcNestedTest", + "echo the passed string(s)", + { + {"arg1", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""}, + {"arg2", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""}, + {"arg3", RPCArg::Type::STR, RPCArg::Optional::OMITTED, ""}, + }, + {}, + RPCExamples{""}, + [](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + return request.params.write(0, 0); + }, + }; } -static const CRPCCommand vRPCCommands[] = -{ - { "test", "rpcNestedTest", &rpcNestedTest_rpc, {} }, +static const CRPCCommand vRPCCommands[] = { + {"test", "rpcNestedTest", &rpcNestedTest_rpc, {"arg1", "arg2", "arg3"}}, }; void RPCNestedTests::rpcNestedTests() diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 495e0e54c5..272c2ddf17 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -262,12 +262,7 @@ static RPCHelpMan generatetodescriptor() static RPCHelpMan generate() { return RPCHelpMan{"generate", "has been replaced by the -generate cli option. Refer to -help for more information.", {}, {}, RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - - if (request.fHelp) { - throw std::runtime_error(self.ToString()); - } else { throw JSONRPCError(RPC_METHOD_NOT_FOUND, self.ToString()); - } }}; } @@ -1234,11 +1229,9 @@ static RPCHelpMan estimaterawfee() // // ELEMENTS: -UniValue getnewblockhex(const JSONRPCRequest& request) +static RPCHelpMan getnewblockhex() { - if (request.fHelp || request.params.size() > 3) - throw std::runtime_error( - RPCHelpMan{"getnewblockhex", + return RPCHelpMan{"getnewblockhex", "\nGets hex representation of a proposed, unmined new block\n", { {"min_tx_age", RPCArg::Type::NUM, /* default */ "0", "How many seconds a transaction must have been in the mempool to be inluded in the block proposal. This may help with faster block convergence among functionaries using compact blocks."}, @@ -1261,9 +1254,9 @@ UniValue getnewblockhex(const JSONRPCRequest& request) }, RPCExamples{ HelpExampleCli("getnewblockhex", ""), - } - }.ToString()); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ int required_wait = !request.params[0].isNull() ? request.params[0].get_int() : 0; if (required_wait < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "min_tx_age must be non-negative."); @@ -1342,13 +1335,13 @@ UniValue getnewblockhex(const JSONRPCRequest& request) CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); ssBlock << pblocktemplate->block; return HexStr(ssBlock); +}, + }; } -UniValue combineblocksigs(const JSONRPCRequest& request) +static RPCHelpMan combineblocksigs() { - if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) - throw std::runtime_error( - RPCHelpMan{"combineblocksigs", + return RPCHelpMan{"combineblocksigs", "\nMerges signatures on a block proposal\n", { {"blockhex", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded block from getnewblockhex"}, @@ -1374,8 +1367,8 @@ UniValue combineblocksigs(const JSONRPCRequest& request) RPCExamples{ HelpExampleCli("combineblocksigs", " '[{\"pubkey\":\"hex\",\"sig\":\"hex\"}, ...]'"), }, - }.ToString()); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ if (!g_signed_blocks) { throw JSONRPCError(RPC_MISC_ERROR, "Signed blocks are not active for this network."); } @@ -1430,13 +1423,13 @@ UniValue combineblocksigs(const JSONRPCRequest& request) result.pushKV("hex", HexStr(ssBlock)); result.pushKV("complete", CheckProof(block, params)); return result; +}, + }; } -UniValue getcompactsketch(const JSONRPCRequest& request) +static RPCHelpMan getcompactsketch() { - if (request.fHelp || request.params.size() != 1) - throw std::runtime_error( - RPCHelpMan{"getcompactsketch block_hex", + return RPCHelpMan{"getcompactsketch", "\nGets hex representation of a proposed compact block sketch.\n" "It is consumed by `consumecompactsketch.`\n", { @@ -1447,9 +1440,9 @@ UniValue getcompactsketch(const JSONRPCRequest& request) }, RPCExamples{ HelpExampleCli("getcompactsketch", ""), - } - }.ToString()); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ CBlock block; std::vector block_bytes(ParseHex(request.params[0].get_str())); CDataStream ssBlock(block_bytes, SER_NETWORK, PROTOCOL_VERSION); @@ -1460,14 +1453,13 @@ UniValue getcompactsketch(const JSONRPCRequest& request) CDataStream ssCompactBlock(SER_NETWORK, PROTOCOL_VERSION); ssCompactBlock << cmpctblock; return HexStr(ssCompactBlock); - +}, + }; } -UniValue consumecompactsketch(const JSONRPCRequest& request) +static RPCHelpMan consumecompactsketch() { - if (request.fHelp || request.params.size() != 1) - throw std::runtime_error( - RPCHelpMan{"consumecompactsketch sketch", + return RPCHelpMan{"consumecompactsketch", "\nTakes hex representation of a proposed compact block sketch and fills it in\n" "using mempool. Returns the block if complete, and a list\n" "of missing transaction indices serialized as a native structure." @@ -1486,9 +1478,9 @@ UniValue consumecompactsketch(const JSONRPCRequest& request) }, RPCExamples{ HelpExampleCli("consumecompactsketch", ""), - } - }.ToString()); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue ret(UniValue::VOBJ); std::vector compact_block_bytes(ParseHex(request.params[0].get_str())); @@ -1540,13 +1532,13 @@ UniValue consumecompactsketch(const JSONRPCRequest& request) ret.pushKV("found_transactions", HexStr(ssFound)); } return ret; +}, + }; } -UniValue consumegetblocktxn(const JSONRPCRequest& request) +static RPCHelpMan consumegetblocktxn() { - if (request.fHelp || request.params.size() != 2) - throw std::runtime_error( - RPCHelpMan{"consumegetblocktxn", + return RPCHelpMan{"consumegetblocktxn", "Consumes a transaction request for a compact block sketch.", { {"full_block", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex serialied block that corresponds to the block request `block_tx_req`."}, @@ -1557,9 +1549,9 @@ UniValue consumegetblocktxn(const JSONRPCRequest& request) }, RPCExamples{ HelpExampleCli("consumegetblocktxn", "") - } - }.ToString()); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ CBlock block; std::vector block_bytes(ParseHex(request.params[0].get_str())); CDataStream ssBlock(block_bytes, SER_NETWORK, PROTOCOL_VERSION); @@ -1584,13 +1576,13 @@ UniValue consumegetblocktxn(const JSONRPCRequest& request) ssResp << resp; return HexStr(ssResp); +}, + }; } -UniValue finalizecompactblock(const JSONRPCRequest& request) +static RPCHelpMan finalizecompactblock() { - if (request.fHelp || request.params.size() != 3) - throw std::runtime_error( - RPCHelpMan{"finalizecompactblock", + return RPCHelpMan{"finalizecompactblock", "Takes the two transaction lists, fills out the compact block and attempts to finalize it.", { {"compact_hex", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex serialized compact block."}, @@ -1602,9 +1594,9 @@ UniValue finalizecompactblock(const JSONRPCRequest& request) }, RPCExamples{ HelpExampleCli("finalizecompactblock", " ") - } - }.ToString()); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ // Compact block std::vector compact_block_bytes(ParseHex(request.params[0].get_str())); CDataStream ssCompactBlock(compact_block_bytes, SER_NETWORK, PROTOCOL_VERSION); @@ -1653,13 +1645,13 @@ UniValue finalizecompactblock(const JSONRPCRequest& request) ssBlock << *pblock; return HexStr(ssBlock); +}, + }; } -UniValue testproposedblock(const JSONRPCRequest& request) +static RPCHelpMan testproposedblock() { - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) - throw std::runtime_error( - RPCHelpMan{"testproposedblock", + return RPCHelpMan{"testproposedblock", "\nChecks a block proposal for validity, and that it extends chaintip\n", { {"blockhex", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded block from getnewblockhex"}, @@ -1668,9 +1660,9 @@ UniValue testproposedblock(const JSONRPCRequest& request) RPCResults{}, RPCExamples{ HelpExampleCli("testproposedblock", "") - } - }.ToString()); - + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ CBlock block; if (!DecodeHexBlk(block, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); @@ -1709,6 +1701,8 @@ UniValue testproposedblock(const JSONRPCRequest& request) } return NullUniValue; +}, + }; } // END ELEMENTS @@ -1725,7 +1719,7 @@ static const CRPCCommand commands[] = { "mining", "getmininginfo", &getmininginfo, {} }, { "mining", "prioritisetransaction", &prioritisetransaction, {"txid","dummy","fee_delta"} }, { "mining", "getblocktemplate", &getblocktemplate, {"template_request"} }, - { "generating", "combineblocksigs", &combineblocksigs, {"blockhex","signatures"} }, + { "generating", "combineblocksigs", &combineblocksigs, {"blockhex","signatures","witnessScript"} }, { "mining", "submitheader", &submitheader, {"hexdata"} }, { "generating", "getnewblockhex", &getnewblockhex, {"min_tx_age", "proposed_parameters", "commit_data"} }, { "generating", "getcompactsketch", &getcompactsketch, {"block_hex"} }, diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 081fe36afb..68650ccd4f 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -654,8 +654,6 @@ static RPCHelpMan echo(const std::string& name) RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (request.fHelp) throw std::runtime_error(self.ToString()); - if (request.params[9].isStr()) { CHECK_NONFATAL(request.params[9].get_str() != "trigger_internal_bug"); } @@ -725,11 +723,9 @@ static RPCHelpMan getindexinfo() // // ELEMENTS CALLS -UniValue tweakfedpegscript(const JSONRPCRequest& request) +static RPCHelpMan tweakfedpegscript() { - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) - throw std::runtime_error( - RPCHelpMan{"tweakfedpegscript", + return RPCHelpMan{"tweakfedpegscript", "\nReturns a tweaked fedpegscript.\n", { {"claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Script to tweak the fedpegscript with. For example obtained as a result of getpeginaddress."}, @@ -743,8 +739,8 @@ UniValue tweakfedpegscript(const JSONRPCRequest& request) } }, RPCExamples{""}, - }.ToString()); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ if (!IsHex(request.params[0].get_str())) { throw JSONRPCError(RPC_TYPE_ERROR, "the first argument must be a hex string"); } @@ -772,6 +768,8 @@ UniValue tweakfedpegscript(const JSONRPCRequest& request) ret.pushKV("address", EncodeParentDestination(parent_addr)); return ret; +}, + }; } UniValue FormatPAKList(CPAKList &paklist) { @@ -793,11 +791,9 @@ UniValue FormatPAKList(CPAKList &paklist) { return paklist_value; } -UniValue getpakinfo(const JSONRPCRequest& request) +static RPCHelpMan getpakinfo() { - if (request.fHelp || request.params.size() != 0) - throw std::runtime_error( - RPCHelpMan{"getpakinfo", + return RPCHelpMan{"getpakinfo", "\nReturns relevant pegout authorization key (PAK) information about this node, both from blockchain data.\n", {}, RPCResult{ @@ -810,8 +806,8 @@ UniValue getpakinfo(const JSONRPCRequest& request) } }, RPCExamples{""}, - }.ToString()); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ LOCK(cs_main); UniValue ret(UniValue::VOBJ); @@ -819,9 +815,27 @@ UniValue getpakinfo(const JSONRPCRequest& request) ret.pushKV("block_paklist", FormatPAKList(paklist)); return ret; +}, + }; } -UniValue calcfastmerkleroot(const JSONRPCRequest& request) +static RPCHelpMan calcfastmerkleroot() +{ + return RPCHelpMan{"calcfastmerkleroot", + "\nhidden utility RPC for computing sha2 midstates\n", + { + {"leaves", RPCArg::Type::ARR, RPCArg::Optional::NO, "array of data to compute the fast merkle root of.", + { + {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "hex-encoded data"}, + }}, + }, + RPCResult{ + RPCResult::Type::STR_HEX, "", "merkle root of provided data" + }, + RPCExamples{ + HelpExampleCli("calcfastmerkleroot", "[\"a\", \"b\", \"c\"]") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { std::vector leaves; for (const UniValue& leaf : request.params[0].get_array().getValues()) { @@ -835,13 +849,13 @@ UniValue calcfastmerkleroot(const JSONRPCRequest& request) UniValue ret(UniValue::VOBJ); ret.setStr(root.GetHex()); return ret; +}, + }; } -UniValue dumpassetlabels(const JSONRPCRequest& request) +static RPCHelpMan dumpassetlabels() { - if (request.fHelp || request.params.size() != 0) - throw std::runtime_error( - RPCHelpMan{"dumpassetlabels", + return RPCHelpMan{"dumpassetlabels", "\nLists all known asset id/label pairs in this wallet. This list can be modified with `-assetdir` configuration argument.\n", {}, RPCResults{}, @@ -849,13 +863,15 @@ UniValue dumpassetlabels(const JSONRPCRequest& request) HelpExampleCli("dumpassetlabels", "" ) + HelpExampleRpc("dumpassetlabels", "" ) }, - }.ToString()); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ UniValue obj(UniValue::VOBJ); for (const auto& as : gAssetsDir.GetKnownAssets()) { obj.pushKV(gAssetsDir.GetLabel(as), as.GetHex()); } return obj; +}, + }; } class BlindingPubkeyAdderVisitor : public boost::static_visitor<> @@ -895,11 +911,9 @@ public: }; -UniValue createblindedaddress(const JSONRPCRequest& request) +static RPCHelpMan createblindedaddress() { - if (request.fHelp || request.params.size() != 2) - throw std::runtime_error( - RPCHelpMan{"createblindedaddress", + return RPCHelpMan{"createblindedaddress", "\nCreates a blinded address using the provided blinding key.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The unblinded address to be blinded."}, @@ -914,8 +928,8 @@ UniValue createblindedaddress(const JSONRPCRequest& request) "\nAs a json rpc call\n" + HelpExampleRpc("createblindedaddress", "HEZk3iQi1jC49bxUriTtynnXgWWWdAYx16, ec09811118b6febfa5ebe68642e5091c418fbace07e655da26b4a845a691fc2d") }, - }.ToString()); - + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ CTxDestination address = DecodeDestination(request.params[0].get_str()); if (!IsValidDestination(address)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script"); @@ -938,6 +952,8 @@ UniValue createblindedaddress(const JSONRPCRequest& request) // Append blinding key and return boost::apply_visitor(BlindingPubkeyAdderVisitor(key), address); return EncodeDestination(address); +}, + }; } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index f98ea63782..e72ef24d12 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -288,10 +288,10 @@ static RPCHelpMan addnode() std::string strCommand; if (!request.params[1].isNull()) strCommand = request.params[1].get_str(); - if (request.fHelp || request.params.size() != 2 || - (strCommand != "onetry" && strCommand != "add" && strCommand != "remove")) + if (strCommand != "onetry" && strCommand != "add" && strCommand != "remove") { throw std::runtime_error( self.ToString()); + } NodeContext& node = EnsureNodeContext(request.context); if(!node.connman) @@ -628,7 +628,7 @@ static RPCHelpMan setban() std::string strCommand; if (!request.params[1].isNull()) strCommand = request.params[1].get_str(); - if (request.fHelp || !help.IsValidNumArgs(request.params.size()) || (strCommand != "add" && strCommand != "remove")) { + if (strCommand != "add" && strCommand != "remove") { throw std::runtime_error(help.ToString()); } NodeContext& node = EnsureNodeContext(request.context); diff --git a/src/rpc/server.h b/src/rpc/server.h index b2358ac5b2..7d13edb8b0 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -85,7 +85,6 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface); */ void RPCRunLater(const std::string& name, std::function func, int64_t nSeconds); -typedef UniValue(*rpcfn_type)(const JSONRPCRequest& jsonRequest); typedef RPCHelpMan (*RpcMethodFnType)(); class CRPCCommand @@ -116,14 +115,6 @@ public: CHECK_NONFATAL(fn().GetArgNames() == args_in); } - //! Simplified constructor taking plain rpcfn_type function pointer. - CRPCCommand(const char* category, const char* name, rpcfn_type fn, std::initializer_list args) - : CRPCCommand(category, name, - [fn](const JSONRPCRequest& request, UniValue& result, bool) { result = fn(request); return true; }, - {args.begin(), args.end()}, intptr_t(fn)) - { - } - std::string category; std::string name; Actor actor; diff --git a/test/lint/lint-rpc-help.sh b/test/lint/lint-rpc-help.sh deleted file mode 100755 index faac5d43e2..0000000000 --- a/test/lint/lint-rpc-help.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2018 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -# -# Check that all RPC help texts are generated by RPCHelpMan. - -export LC_ALL=C - -EXIT_CODE=0 - -# Assume that all multiline strings passed into a runtime_error are help texts. -# This is potentially fragile, but the linter is only temporary and can safely -# be removed early 2019. - -non_autogenerated_help=$(grep --perl-regexp --null-data --only-matching 'runtime_error\(\n\s*".*\\n"\n' $(git ls-files -- "*.cpp")) -if [[ ${non_autogenerated_help} != "" ]]; then - echo "Must use RPCHelpMan to generate the help for the following RPC methods:" - echo "${non_autogenerated_help}" - echo - EXIT_CODE=1 -fi -exit ${EXIT_CODE}